Merge
authorlana
Tue, 29 Nov 2011 12:04:55 -0800
changeset 11114 005ec2ce55e9
parent 11112 6d340c7b6a32 (current diff)
parent 11059 b5060eae3b32 (diff)
child 11115 b91324cce2f3
Merge
langtools/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java
--- a/.hgtags	Tue Nov 29 11:39:59 2011 -0800
+++ b/.hgtags	Tue Nov 29 12:04:55 2011 -0800
@@ -135,3 +135,4 @@
 cc1f5ce8e504d350e0b0c28c5f84333f8d540132 jdk8-b11
 86db042b3385c338e17f7664447fdc7d406dd19e jdk8-b12
 4cc0ef72c812943743ef4765f1100e2fbe2b1a08 jdk8-b13
+9ffaa48dbfb0f5936c2b789867d0785faec7071d jdk8-b14
--- a/.hgtags-top-repo	Tue Nov 29 11:39:59 2011 -0800
+++ b/.hgtags-top-repo	Tue Nov 29 12:04:55 2011 -0800
@@ -135,3 +135,4 @@
 1defbc57940a56f0aa41e9dee87b71e8c8b71103 jdk8-b11
 8e2104d565baee473895d5eba20e39f85ab4bf9f jdk8-b12
 26fb81a1e9ceb9baffba216acd9ded62e9e9d5ab jdk8-b13
+23aa7f2c80a2fa354c80decf03e7c2018177ef4e jdk8-b14
--- a/corba/.hgtags	Tue Nov 29 11:39:59 2011 -0800
+++ b/corba/.hgtags	Tue Nov 29 12:04:55 2011 -0800
@@ -135,3 +135,4 @@
 0199e4fef5cc2bd234c65b93220459ef7a3bb3b1 jdk8-b11
 31d70911b712c6b4e580a3110363d5f044cfed7a jdk8-b12
 5b9d9b839d3d7fe02347827221c97c6d242a6f96 jdk8-b13
+e59c47de1ad8982ff3b0e843773a6902b36c2337 jdk8-b14
--- a/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -423,6 +423,13 @@
         impl.setByteBufferWithInfo(bbwi);
     }
 
+    /**
+     * return true if our ByteBuffer is sharing/equal to bb
+     */
+    protected final boolean isSharing(ByteBuffer bb) {
+        return (getByteBuffer() ==  bb);
+    }
+
     public final int getBufferLength() {
         return impl.getBufferLength();
     }
--- a/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2412,7 +2412,6 @@
 
         if (bbwi != null && getByteBuffer() != null)
         {
-            int bbHash = System.identityHashCode(bbwi.byteBuffer);
             MessageMediator messageMediator = parent.getMessageMediator();
             if (messageMediator != null)
             {
@@ -2420,19 +2419,12 @@
                              (CDROutputObject)messageMediator.getOutputObject();
                 if (outputObj != null)
                 {
-                    ByteBuffer outputBb = outputObj.getByteBuffer();
-
-                    int oBbHash = 0;
-                    if (outputBb != null)
+                    if (outputObj.isSharing(getByteBuffer()))
                     {
-                        oBbHash = System.identityHashCode(outputBb);
-                        if (bbHash == oBbHash)  // shared?
-                        {
-                            // Set OutputStream's ByteBuffer and bbwi to null
-                            // so its ByteBuffer cannot be released to the pool
-                            outputObj.setByteBuffer(null);
-                            outputObj.setByteBufferWithInfo(null);
-                        }
+                        // Set OutputStream's ByteBuffer and bbwi to null
+                        // so its ByteBuffer cannot be released to the pool
+                        outputObj.setByteBuffer(null);
+                        outputObj.setByteBufferWithInfo(null);
                     }
                 }
             }
--- a/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -357,6 +357,13 @@
         impl.setByteBuffer(byteBuffer);
     }
 
+    /**
+     * return true if our ByteBuffer is sharing/equal to bb
+     */
+    protected final boolean isSharing(ByteBuffer bb) {
+        return (getByteBuffer() ==  bb);
+    }
+
     public final boolean isLittleEndian() {
         return impl.isLittleEndian();
     }
--- a/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1902,7 +1902,6 @@
 
         if (getByteBufferWithInfo() != null && getByteBuffer() != null)
         {
-            int bbHash = System.identityHashCode(bbwi.byteBuffer);
             MessageMediator messageMediator = parent.getMessageMediator();
             if (messageMediator != null)
             {
@@ -1910,19 +1909,12 @@
                                (CDRInputObject)messageMediator.getInputObject();
                 if (inputObj != null)
                 {
-                    ByteBuffer inputBb = inputObj.getByteBuffer();
-
-                    int iBbHash = 0;
-                    if (inputBb != null)
+                    if (inputObj.isSharing(getByteBuffer()))
                     {
-                        iBbHash = System.identityHashCode(inputBb);
-                        if (bbHash == iBbHash)  // shared?
-                        {
-                            // Set InputStream's ByteBuffer and bbwi to null
-                            // so its ByteBuffer cannot be released to the pool
-                            inputObj.setByteBuffer(null);
-                            inputObj.setByteBufferWithInfo(null);
-                        }
+                        // Set InputStream's ByteBuffer and bbwi to null
+                        // so its ByteBuffer cannot be released to the pool
+                        inputObj.setByteBuffer(null);
+                        inputObj.setByteBufferWithInfo(null);
                     }
                 }
             }
--- a/hotspot/.hgtags	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/.hgtags	Tue Nov 29 12:04:55 2011 -0800
@@ -198,3 +198,5 @@
 1d3900713a67a0a39faf4e12c9c158d55aebef87 jdk8-b12
 3e609627e780736f372eb14d29bb9b5e53b21fbf hs23-b05
 b92ca8e229d29004f840c67e620833d23a346761 jdk8-b13
+088d09a130ff02d8f5f05e92256baabe412f0439 jdk8-b14
+6c2a55d4902f202e1c2de1df17b7da083a2c31e8 hs23-b06
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java	Tue Nov 29 12:04:55 2011 -0800
@@ -30,6 +30,7 @@
 import sun.jvm.hotspot.gc_implementation.parallelScavenge.*;
 import sun.jvm.hotspot.gc_implementation.shared.*;
 import sun.jvm.hotspot.memory.*;
+import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
 
 public class HeapSummary extends Tool {
@@ -134,6 +135,9 @@
       } else {
          throw new RuntimeException("unknown CollectedHeap type : " + heap.getClass());
       }
+
+      System.out.println();
+      printInternStringStatistics();
    }
 
    // Helper methods
@@ -248,4 +252,41 @@
          return -1;
       }
    }
+
+   private void printInternStringStatistics() {
+      class StringStat implements StringTable.StringVisitor {
+         private int count;
+         private long size;
+         private OopField stringValueField;
+
+         StringStat() {
+            VM vm = VM.getVM();
+            SystemDictionary sysDict = vm.getSystemDictionary();
+            InstanceKlass strKlass = sysDict.getStringKlass();
+            // String has a field named 'value' of type 'char[]'.
+            stringValueField = (OopField) strKlass.findField("value", "[C");
+         }
+
+         private long stringSize(Instance instance) {
+            // We include String content in size calculation.
+            return instance.getObjectSize() +
+                   stringValueField.getValue(instance).getObjectSize();
+         }
+
+         public void visit(Instance str) {
+            count++;
+            size += stringSize(str);
+         }
+
+         public void print() {
+            System.out.println(count +
+                  " interned Strings occupying " + size + " bytes.");
+         }
+      }
+
+      StringStat stat = new StringStat();
+      StringTable strTable = VM.getVM().getStringTable();
+      strTable.stringsDo(stat);
+      stat.print();
+   }
 }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java	Tue Nov 29 12:04:55 2011 -0800
@@ -63,47 +63,9 @@
    }
 
    public void run() {
-      printInternStringStatistics();
       printClassLoaderStatistics();
    }
 
-   private void printInternStringStatistics() {
-      class StringStat implements StringTable.StringVisitor {
-         private int count;
-         private long size;
-         private OopField stringValueField;
-
-         StringStat() {
-            VM vm = VM.getVM();
-            SystemDictionary sysDict = vm.getSystemDictionary();
-            InstanceKlass strKlass = sysDict.getStringKlass();
-            // String has a field named 'value' of type 'char[]'.
-            stringValueField = (OopField) strKlass.findField("value", "[C");
-         }
-
-         private long stringSize(Instance instance) {
-            // We include String content in size calculation.
-            return instance.getObjectSize() +
-                   stringValueField.getValue(instance).getObjectSize();
-         }
-
-         public void visit(Instance str) {
-            count++;
-            size += stringSize(str);
-         }
-
-         public void print() {
-            System.out.println(count +
-                  " intern Strings occupying " + size + " bytes.");
-         }
-      }
-
-      StringStat stat = new StringStat();
-      StringTable strTable = VM.getVM().getStringTable();
-      strTable.stringsDo(stat);
-      stat.print();
-   }
-
    private void printClassLoaderStatistics() {
       final PrintStream out = System.out;
       final PrintStream err = System.err;
--- a/hotspot/make/hotspot_version	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/make/hotspot_version	Tue Nov 29 12:04:55 2011 -0800
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=23
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=05
+HS_BUILD_NUMBER=06
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/hotspot/make/jprt.properties	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/make/jprt.properties	Tue Nov 29 12:04:55 2011 -0800
@@ -541,9 +541,20 @@
   ${jprt.my.windows.i586}-*-c2-servertest, \
   ${jprt.my.windows.x64}-*-c2-servertest
 
+jprt.make.rule.test.targets.standard.internalvmtests = \
+  ${jprt.my.solaris.sparc}-fastdebug-c2-internalvmtests, \
+  ${jprt.my.solaris.sparcv9}-fastdebug-c2-internalvmtests, \
+  ${jprt.my.solaris.i586}-fastdebug-c2-internalvmtests, \
+  ${jprt.my.solaris.x64}-fastdebug-c2-internalvmtests, \
+  ${jprt.my.linux.i586}-fastdebug-c2-internalvmtests, \
+  ${jprt.my.linux.x64}-fastdebug-c2-internalvmtests, \
+  ${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \
+  ${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
+  
 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.server}, \
+  ${jprt.make.rule.test.targets.standard.internalvmtests}
 
 jprt.make.rule.test.targets.embedded = \
   ${jprt.make.rule.test.targets.standard.client}
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -597,6 +597,10 @@
 inline void MacroAssembler::jmp( Register s1, int simm13a, RelocationHolder const& rspec ) { jmpl( s1, simm13a, G0, rspec); }
 
 inline bool MacroAssembler::is_far_target(address d) {
+  if (ForceUnreachable) {
+    // References outside the code cache should be treated as far
+    return d < CodeCache::low_bound() || d > CodeCache::high_bound();
+  }
   return !is_in_wdisp30_range(d, CodeCache::low_bound()) || !is_in_wdisp30_range(d, CodeCache::high_bound());
 }
 
@@ -679,28 +683,44 @@
 
 inline void MacroAssembler::load_contents(const AddressLiteral& addrlit, Register d, int offset) {
   assert_not_delayed();
-  sethi(addrlit, d);
+  if (ForceUnreachable) {
+    patchable_sethi(addrlit, d);
+  } else {
+    sethi(addrlit, d);
+  }
   ld(d, addrlit.low10() + offset, d);
 }
 
 
 inline void MacroAssembler::load_ptr_contents(const AddressLiteral& addrlit, Register d, int offset) {
   assert_not_delayed();
-  sethi(addrlit, d);
+  if (ForceUnreachable) {
+    patchable_sethi(addrlit, d);
+  } else {
+    sethi(addrlit, d);
+  }
   ld_ptr(d, addrlit.low10() + offset, d);
 }
 
 
 inline void MacroAssembler::store_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset) {
   assert_not_delayed();
-  sethi(addrlit, temp);
+  if (ForceUnreachable) {
+    patchable_sethi(addrlit, temp);
+  } else {
+    sethi(addrlit, temp);
+  }
   st(s, temp, addrlit.low10() + offset);
 }
 
 
 inline void MacroAssembler::store_ptr_contents(Register s, const AddressLiteral& addrlit, Register temp, int offset) {
   assert_not_delayed();
-  sethi(addrlit, temp);
+  if (ForceUnreachable) {
+    patchable_sethi(addrlit, temp);
+  } else {
+    sethi(addrlit, temp);
+  }
   st_ptr(s, temp, addrlit.low10() + offset);
 }
 
--- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -367,10 +367,10 @@
 
 void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
-  __ call(SharedRuntime::deopt_blob()->unpack_with_reexecution());
+  __ call(Runtime1::entry_for(Runtime1::deoptimize_id), relocInfo::runtime_call_type);
   __ delayed()->nop();
   ce->add_call_info_here(_info);
-  debug_only(__ should_not_reach_here());
+  DEBUG_ONLY(__ should_not_reach_here());
 }
 
 
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1116,7 +1116,7 @@
       } else {
         __ set(value_hi, O7);
       }
-      offset = store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false);
+      store(tmp, base, addr->disp() + hi_word_offset_in_bytes, T_INT, wide, false);
       break;
     }
     case T_OBJECT: {
--- a/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -766,7 +766,22 @@
 
         __ ret();
         __ delayed()->restore();
+      }
+      break;
 
+    case deoptimize_id:
+      {
+        __ set_info("deoptimize", dont_gc_arguments);
+        OopMap* oop_map = save_live_registers(sasm);
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize));
+        oop_maps = new OopMapSet();
+        oop_maps->add_gc_map(call_offset, oop_map);
+        restore_live_registers(sasm);
+        DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
+        assert(deopt_blob != NULL, "deoptimization blob must have been created");
+        AddressLiteral dest(deopt_blob->unpack_with_reexecution());
+        __ jump_to(dest, O0);
+        __ delayed()->restore();
       }
       break;
 
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -352,6 +352,7 @@
   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
@@ -363,6 +364,7 @@
     __ stop("load_stack_move of garbage value");
     __ BIND(L_ok);
   }
+#endif
   BLOCK_COMMENT("} load_stack_move");
 }
 
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -27,7 +27,7 @@
 
 // Adapters
 enum /* platform_dependent_constants */ {
-  adapter_code_size = NOT_LP64(22000 DEBUG_ONLY(+ 40000)) LP64_ONLY(32000 DEBUG_ONLY(+ 80000))
+  adapter_code_size = NOT_LP64(23000 DEBUG_ONLY(+ 40000)) LP64_ONLY(35000 DEBUG_ONLY(+ 50000))
 };
 
 public:
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Tue Nov 29 12:04:55 2011 -0800
@@ -1860,6 +1860,14 @@
 // Threshold size for cleararray.
 const int Matcher::init_array_short_size = 8 * BytesPerLong;
 
+// No additional cost for CMOVL.
+const int Matcher::long_cmove_cost() { return 0; }
+
+// CMOVF/CMOVD are expensive on T4 and on SPARC64.
+const int Matcher::float_cmove_cost() {
+  return (VM_Version::is_T4() || VM_Version::is_sparc64()) ? ConditionalMoveLimit : 0;
+}
+
 // Should the Matcher clone shifts on addressing modes, expecting them to
 // be subsumed into complex addressing expressions or compute them into
 // registers?  True for Intel but false for most RISCs
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -211,7 +211,7 @@
 #ifdef COMPILER2
   // T4 and newer Sparc cpus have fast RDPC.
   if (has_fast_rdpc() && FLAG_IS_DEFAULT(UseRDPCForConstantTableBase)) {
-//    FLAG_SET_DEFAULT(UseRDPCForConstantTableBase, true);
+    FLAG_SET_DEFAULT(UseRDPCForConstantTableBase, true);
   }
 
   // Currently not supported anywhere.
--- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -387,9 +387,9 @@
 
 void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
   __ bind(_entry);
-  __ call(RuntimeAddress(SharedRuntime::deopt_blob()->unpack_with_reexecution()));
+  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::deoptimize_id)));
   ce->add_call_info_here(_info);
-  debug_only(__ should_not_reach_here());
+  DEBUG_ONLY(__ should_not_reach_here());
 }
 
 
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1447,7 +1447,22 @@
         oop_maps = new OopMapSet();
         oop_maps->add_gc_map(call_offset, map);
         restore_live_registers(sasm, save_fpu_registers);
+      }
+      break;
 
+    case deoptimize_id:
+      {
+        StubFrame f(sasm, "deoptimize", dont_gc_arguments);
+        const int num_rt_args = 1;  // thread
+        OopMap* oop_map = save_live_registers(sasm, num_rt_args);
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize));
+        oop_maps = new OopMapSet();
+        oop_maps->add_gc_map(call_offset, oop_map);
+        restore_live_registers(sasm);
+        DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
+        assert(deopt_blob != NULL, "deoptimization blob must have been created");
+        __ leave();
+        __ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
       }
       break;
 
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -234,10 +234,12 @@
 void frame::patch_pc(Thread* thread, address pc) {
   address* pc_addr = &(((address*) sp())[-1]);
   if (TracePcPatching) {
-    tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "] ",
+    tty->print_cr("patch_pc at address " INTPTR_FORMAT " [" INTPTR_FORMAT " -> " INTPTR_FORMAT "]",
                   pc_addr, *pc_addr, pc);
   }
-  assert(_pc == *pc_addr, err_msg("must be: " INTPTR_FORMAT " == " INTPTR_FORMAT, _pc, *pc_addr));
+  // Either the return address is the original one or we are going to
+  // patch in the same address that's already there.
+  assert(_pc == *pc_addr || pc == *pc_addr, "must be");
   *pc_addr = pc;
   _cb = CodeCache::find_blob(pc);
   address original_pc = nmethod::get_deopt_original_pc(this);
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -382,6 +382,7 @@
     __ 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
@@ -393,6 +394,7 @@
     __ stop("load_stack_move of garbage value");
     __ BIND(L_ok);
   }
+#endif
   BLOCK_COMMENT("} load_stack_move");
 }
 
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -27,7 +27,7 @@
 
 // Adapters
 enum /* platform_dependent_constants */ {
-  adapter_code_size = NOT_LP64(30000 DEBUG_ONLY(+ 10000)) LP64_ONLY(80000 DEBUG_ONLY(+ 120000))
+  adapter_code_size = NOT_LP64(16000 DEBUG_ONLY(+ 15000)) LP64_ONLY(32000 DEBUG_ONLY(+ 80000))
 };
 
 public:
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -2797,17 +2797,25 @@
   // void Deoptimization::unpack_frames(JavaThread* thread, int exec_mode)
 
   // Use rbp because the frames look interpreted now
-  __ set_last_Java_frame(noreg, rbp, NULL);
-
+  // Save "the_pc" since it cannot easily be retrieved using the last_java_SP after we aligned SP.
+  // Don't need the precise return PC here, just precise enough to point into this code blob.
+  address the_pc = __ pc();
+  __ set_last_Java_frame(noreg, rbp, the_pc);
+
+  __ andptr(rsp, -(StackAlignmentInBytes));  // Fix stack alignment as required by ABI
   __ mov(c_rarg0, r15_thread);
   __ movl(c_rarg1, r14); // second arg: exec_mode
   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)));
+  // Revert SP alignment after call since we're going to do some SP relative addressing below
+  __ movptr(rsp, Address(r15_thread, JavaThread::last_Java_sp_offset()));
 
   // Set an oopmap for the call site
-  oop_maps->add_gc_map(__ pc() - start,
+  // Use the same PC we used for the last java frame
+  oop_maps->add_gc_map(the_pc - start,
                        new OopMap( frame_size_in_words, 0 ));
 
-  __ reset_last_Java_frame(true, false);
+  // Clear fp AND pc
+  __ reset_last_Java_frame(true, true);
 
   // Collect return values
   __ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes()));
@@ -2968,7 +2976,10 @@
                               // Prolog
 
   // Use rbp because the frames look interpreted now
-  __ set_last_Java_frame(noreg, rbp, NULL);
+  // Save "the_pc" since it cannot easily be retrieved using the last_java_SP after we aligned SP.
+  // Don't need the precise return PC here, just precise enough to point into this code blob.
+  address the_pc = __ pc();
+  __ set_last_Java_frame(noreg, rbp, the_pc);
 
   // Call C code.  Need thread but NOT official VM entry
   // crud.  We cannot block on this call, no GC can happen.  Call should
@@ -2977,14 +2988,17 @@
   //
   // BasicType unpack_frames(JavaThread* thread, int exec_mode);
 
+  __ andptr(rsp, -(StackAlignmentInBytes)); // Align SP as required by ABI
   __ mov(c_rarg0, r15_thread);
   __ movl(c_rarg1, Deoptimization::Unpack_uncommon_trap);
   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)));
 
   // Set an oopmap for the call site
-  oop_maps->add_gc_map(__ pc() - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
-
-  __ reset_last_Java_frame(true, false);
+  // Use the same PC we used for the last java frame
+  oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
+
+  // Clear fp AND pc
+  __ reset_last_Java_frame(true, true);
 
   // Pop self-frame.
   __ leave();                 // Epilog
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1609,6 +1609,12 @@
     // and sender_sp is fp+8
     intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
 
+#ifdef ASSERT
+    if (caller->is_interpreted_frame()) {
+      assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
+    }
+#endif
+
     interpreter_frame->interpreter_frame_set_locals(locals);
     BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
     BasicObjectLock* monbot = montop - moncount;
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1622,6 +1622,12 @@
     // sender_sp is fp+16 XXX
     intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1;
 
+#ifdef ASSERT
+    if (caller->is_interpreted_frame()) {
+      assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
+    }
+#endif
+
     interpreter_frame->interpreter_frame_set_locals(locals);
     BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
     BasicObjectLock* monbot = montop - moncount;
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Tue Nov 29 12:04:55 2011 -0800
@@ -1393,6 +1393,12 @@
 // Threshold size for cleararray.
 const int Matcher::init_array_short_size = 8 * BytesPerLong;
 
+// Needs 2 CMOV's for longs.
+const int Matcher::long_cmove_cost() { return 1; }
+
+// No CMOVF/CMOVD with SSE/SSE2
+const int Matcher::float_cmove_cost() { return (UseSSE>=1) ? ConditionalMoveLimit : 0; }
+
 // Should the Matcher clone shifts on addressing modes, expecting them to
 // be subsumed into complex addressing expressions or compute them into
 // registers?  True for Intel but false for most RISCs
@@ -7905,6 +7911,40 @@
 
 //----------Conditional Move---------------------------------------------------
 // Conditional move
+instruct jmovI_reg(cmpOp cop, eFlagsReg cr, eRegI dst, eRegI src) %{
+  predicate(!VM_Version::supports_cmov() );
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  format %{ "J$cop,us skip\t# signed cmove\n\t"
+            "MOV    $dst,$src\n"
+      "skip:" %}
+  ins_encode %{
+    Label Lskip;
+    // Invert sense of branch from sense of CMOV
+    __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
+    __ movl($dst$$Register, $src$$Register);
+    __ bind(Lskip);
+  %}
+  ins_pipe( pipe_cmov_reg );
+%}
+
+instruct jmovI_regU(cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src) %{
+  predicate(!VM_Version::supports_cmov() );
+  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
+  ins_cost(200);
+  format %{ "J$cop,us skip\t# unsigned cmove\n\t"
+            "MOV    $dst,$src\n"
+      "skip:" %}
+  ins_encode %{
+    Label Lskip;
+    // Invert sense of branch from sense of CMOV
+    __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
+    __ movl($dst$$Register, $src$$Register);
+    __ bind(Lskip);
+  %}
+  ins_pipe( pipe_cmov_reg );
+%}
+
 instruct cmovI_reg(eRegI dst, eRegI src, eFlagsReg cr, cmpOp cop ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Tue Nov 29 12:04:55 2011 -0800
@@ -1993,6 +1993,12 @@
 // Threshold size for cleararray.
 const int Matcher::init_array_short_size = 8 * BytesPerLong;
 
+// No additional cost for CMOVL.
+const int Matcher::long_cmove_cost() { return 0; }
+
+// No CMOVF/CMOVD with SSE2
+const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
+
 // Should the Matcher clone shifts on addressing modes, expecting them
 // to be subsumed into complex addressing expressions or compute them
 // into registers?  True for Intel but false for most RISCs
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -26,6 +26,7 @@
 #include "asm/codeBuffer.hpp"
 #include "compiler/disassembler.hpp"
 #include "utilities/copy.hpp"
+#include "utilities/xmlstream.hpp"
 
 // The structure of a CodeSection:
 //
@@ -81,7 +82,7 @@
 CodeBuffer::CodeBuffer(CodeBlob* blob) {
   initialize_misc("static buffer");
   initialize(blob->content_begin(), blob->content_size());
-  assert(verify_section_allocation(), "initial use of buffer OK");
+  verify_section_allocation();
 }
 
 void CodeBuffer::initialize(csize_t code_size, csize_t locs_size) {
@@ -108,17 +109,18 @@
     _insts.initialize_locs(locs_size / sizeof(relocInfo));
   }
 
-  assert(verify_section_allocation(), "initial use of blob is OK");
+  verify_section_allocation();
 }
 
 
 CodeBuffer::~CodeBuffer() {
+  verify_section_allocation();
+
   // If we allocate our code buffer from the CodeCache
   // via a BufferBlob, and it's not permanent, then
   // free the BufferBlob.
   // The rest of the memory will be freed when the ResourceObj
   // is released.
-  assert(verify_section_allocation(), "final storage configuration still OK");
   for (CodeBuffer* cb = this; cb != NULL; cb = cb->before_expand()) {
     // Previous incarnations of this buffer are held live, so that internal
     // addresses constructed before expansions will not be confused.
@@ -484,7 +486,7 @@
 
   // Done calculating sections; did it come out to the right end?
   assert(buf_offset == total_content_size(), "sanity");
-  assert(dest->verify_section_allocation(), "final configuration works");
+  dest->verify_section_allocation();
 }
 
 csize_t CodeBuffer::total_offset_of(CodeSection* cs) const {
@@ -632,7 +634,8 @@
 // CodeBuffer gets the final layout (consts, insts, stubs in order of
 // ascending address).
 void CodeBuffer::relocate_code_to(CodeBuffer* dest) const {
-  DEBUG_ONLY(address dest_end = dest->_total_start + dest->_total_size);
+  address dest_end = dest->_total_start + dest->_total_size;
+  address dest_filled = NULL;
   for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
     // pull code out of each section
     const CodeSection* cs = code_section(n);
@@ -654,6 +657,8 @@
       Copy::fill_to_bytes(dest_cs->end(), dest_cs->remaining(),
                           Assembler::code_fill_byte());
     }
+    // Keep track of the highest filled address
+    dest_filled = MAX2(dest_filled, dest_cs->end() + dest_cs->remaining());
 
     assert(cs->locs_start() != (relocInfo*)badAddress,
            "this section carries no reloc storage, but reloc was attempted");
@@ -668,6 +673,14 @@
       }
     }
   }
+
+  if (dest->blob() == NULL) {
+    // Destination is a final resting place, not just another buffer.
+    // Normalize uninitialized bytes in the final padding.
+    Copy::fill_to_bytes(dest_filled, dest_end - dest_filled,
+                        Assembler::code_fill_byte());
+
+  }
 }
 
 csize_t CodeBuffer::figure_expanded_capacities(CodeSection* which_cs,
@@ -799,7 +812,7 @@
   _decode_begin = NULL;  // sanity
 
   // Make certain that the new sections are all snugly inside the new blob.
-  assert(verify_section_allocation(), "expanded allocation is ship-shape");
+  verify_section_allocation();
 
 #ifndef PRODUCT
   if (PrintNMethods && (WizardMode || Verbose)) {
@@ -828,35 +841,48 @@
   DEBUG_ONLY(cb->_blob = (BufferBlob*)badAddress);
 }
 
-#ifdef ASSERT
-bool CodeBuffer::verify_section_allocation() {
+void CodeBuffer::verify_section_allocation() {
   address tstart = _total_start;
-  if (tstart == badAddress)  return true;  // smashed by set_blob(NULL)
+  if (tstart == badAddress)  return;  // smashed by set_blob(NULL)
   address tend   = tstart + _total_size;
   if (_blob != NULL) {
-    assert(tstart >= _blob->content_begin(), "sanity");
-    assert(tend   <= _blob->content_end(),   "sanity");
+
+    guarantee(tstart >= _blob->content_begin(), "sanity");
+    guarantee(tend   <= _blob->content_end(),   "sanity");
   }
   // Verify disjointness.
   for (int n = (int) SECT_FIRST; n < (int) SECT_LIMIT; n++) {
     CodeSection* sect = code_section(n);
     if (!sect->is_allocated() || sect->is_empty())  continue;
-    assert((intptr_t)sect->start() % sect->alignment() == 0
+    guarantee((intptr_t)sect->start() % sect->alignment() == 0
            || sect->is_empty() || _blob == NULL,
            "start is aligned");
     for (int m = (int) SECT_FIRST; m < (int) SECT_LIMIT; m++) {
       CodeSection* other = code_section(m);
       if (!other->is_allocated() || other == sect)  continue;
-      assert(!other->contains(sect->start()    ), "sanity");
+      guarantee(!other->contains(sect->start()    ), "sanity");
       // limit is an exclusive address and can be the start of another
       // section.
-      assert(!other->contains(sect->limit() - 1), "sanity");
+      guarantee(!other->contains(sect->limit() - 1), "sanity");
     }
-    assert(sect->end() <= tend, "sanity");
+    guarantee(sect->end() <= tend, "sanity");
+    guarantee(sect->end() <= sect->limit(), "sanity");
   }
-  return true;
 }
-#endif //ASSERT
+
+void CodeBuffer::log_section_sizes(const char* name) {
+  if (xtty != NULL) {
+    // log info about buffer usage
+    xtty->print_cr("<blob name='%s' size='%d'>", name, _total_size);
+    for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
+      CodeSection* sect = code_section(n);
+      if (!sect->is_allocated() || sect->is_empty())  continue;
+      xtty->print_cr("<sect index='%d' size='" SIZE_FORMAT "' free='" SIZE_FORMAT "'/>",
+                     n, sect->limit() - sect->start(), sect->limit() - sect->end());
+    }
+    xtty->print_cr("</blob>");
+  }
+}
 
 #ifndef PRODUCT
 
@@ -884,7 +910,6 @@
   _comments.add_comment(offset, comment);
 }
 
-
 class CodeComment: public CHeapObj {
  private:
   friend class CodeComments;
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -362,10 +362,8 @@
   // helper for CodeBuffer::expand()
   void take_over_code_from(CodeBuffer* cs);
 
-#ifdef ASSERT
   // ensure sections are disjoint, ordered, and contained in the blob
-  bool verify_section_allocation();
-#endif
+  void verify_section_allocation();
 
   // copies combined relocations to the blob, returns bytes copied
   // (if target is null, it is a dry run only, just for sizing)
@@ -393,7 +391,7 @@
     assert(code_start != NULL, "sanity");
     initialize_misc("static buffer");
     initialize(code_start, code_size);
-    assert(verify_section_allocation(), "initial use of buffer OK");
+    verify_section_allocation();
   }
 
   // (2) CodeBuffer referring to pre-allocated CodeBlob.
@@ -545,6 +543,9 @@
 
   void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
 
+  // Log a little info about section usage in the CodeBuffer
+  void log_section_sizes(const char* name);
+
 #ifndef PRODUCT
  public:
   // Printing / Decoding
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -51,6 +51,7 @@
 
  public:
   Canonicalizer(Compilation* c, Value x, int bci) : _compilation(c), _canonical(x), _bci(bci) {
+    NOT_PRODUCT(x->set_printable_bci(bci));
     if (CanonicalizeNodes) x->visit(this);
   }
   Value canonical() const                        { return _canonical; }
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -681,6 +681,23 @@
   }
 JRT_END
 
+// Cf. OptoRuntime::deoptimize_caller_frame
+JRT_ENTRY(void, Runtime1::deoptimize(JavaThread* thread))
+  // Called from within the owner thread, so no need for safepoint
+  RegisterMap reg_map(thread, false);
+  frame stub_frame = thread->last_frame();
+  assert(stub_frame.is_runtime_frame(), "sanity check");
+  frame caller_frame = stub_frame.sender(&reg_map);
+
+  // We are coming from a compiled method; check this is true.
+  assert(CodeCache::find_nmethod(caller_frame.pc()) != NULL, "sanity");
+
+  // Deoptimize the caller frame.
+  Deoptimization::deoptimize_frame(thread, caller_frame.id());
+
+  // Return to the now deoptimized frame.
+JRT_END
+
 
 static klassOop resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
   Bytecode_field field_access(caller, bci);
--- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -63,6 +63,7 @@
   stub(monitorenter_nofpu)             /* optimized version that does not preserve fpu registers */ \
   stub(monitorexit)                  \
   stub(monitorexit_nofpu)              /* optimized version that does not preserve fpu registers */ \
+  stub(deoptimize)                   \
   stub(access_field_patching)        \
   stub(load_klass_patching)          \
   stub(g1_pre_barrier_slow)          \
@@ -152,6 +153,8 @@
   static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock);
   static void monitorexit (JavaThread* thread, BasicObjectLock* lock);
 
+  static void deoptimize(JavaThread* thread);
+
   static int access_field_patching(JavaThread* thread);
   static int move_klass_patching(JavaThread* thread);
 
--- a/hotspot/src/share/vm/ci/ciMethodHandle.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/ci/ciMethodHandle.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -86,12 +86,12 @@
 }
 
 
-#ifndef PRODUCT
+#ifdef ASSERT
 // ------------------------------------------------------------------
 // ciMethodHandle::print_chain_impl
 //
 // Implementation of the print method.
-void ciMethodHandle::print_chain_impl(outputStream* st) {
+void ciMethodHandle::print_chain_impl() {
   ASSERT_IN_VM;
   MethodHandleChain::print(get_oop());
 }
@@ -101,7 +101,7 @@
 // ciMethodHandle::print_chain
 //
 // Implementation of the print_chain method.
-void ciMethodHandle::print_chain(outputStream* st) {
-  GUARDED_VM_ENTRY(print_chain_impl(st););
+void ciMethodHandle::print_chain() {
+  GUARDED_VM_ENTRY(print_chain_impl(););
 }
 #endif
--- a/hotspot/src/share/vm/ci/ciMethodHandle.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/ci/ciMethodHandle.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -45,7 +45,7 @@
   ciMethod* get_adapter(     bool is_invokedynamic);
 
 protected:
-  void print_chain_impl(outputStream* st) PRODUCT_RETURN;
+  void print_chain_impl() NOT_DEBUG_RETURN;
 
 public:
   ciMethodHandle(instanceHandle h_i) :
@@ -79,7 +79,7 @@
     return _invokedynamic_adapter;
   }
 
-  void print_chain(outputStream* st = tty) PRODUCT_RETURN;
+  void print_chain() NOT_DEBUG_RETURN;
 };
 
 #endif // SHARE_VM_CI_CIMETHODHANDLE_HPP
--- a/hotspot/src/share/vm/code/dependencies.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/code/dependencies.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -763,9 +763,14 @@
       // Method m is inherited into ctxk.
       return true;
     if (lm != NULL) {
-      if (!(lm->is_public() || lm->is_protected()))
+      if (!(lm->is_public() || lm->is_protected())) {
         // Method is [package-]private, so the override story is complex.
         return true;  // Must punt the assertion to true.
+      }
+      if (lm->is_static()) {
+        // Static methods don't override non-static so punt
+        return true;
+      }
       if (   !Dependencies::is_concrete_method(lm)
           && !Dependencies::is_concrete_method(m)
           && Klass::cast(lm->method_holder())->is_subtype_of(m->method_holder()))
@@ -1091,9 +1096,11 @@
 }
 
 bool Dependencies::is_concrete_method(methodOop m) {
-  if (m->is_abstract())  return false;
-  // %%% We could treat unexecuted methods as virtually abstract also.
-  // This would require a deoptimization barrier on first execution.
+  // Statics are irrelevant to virtual call sites.
+  if (m->is_static())  return false;
+
+  // We could also return false if m does not yet appear to be
+  // executed, if the VM version supports this distinction also.
   return !m->is_abstract();
 }
 
@@ -1113,7 +1120,7 @@
 
 bool Dependencies::is_concrete_klass(ciInstanceKlass* k) {
   if (k->is_abstract())  return false;
-  // We could return also false if k does not yet appear to be
+  // We could also return false if k does not yet appear to be
   // instantiated, if the VM version supports this distinction also.
   //if (k->is_not_instantiated())  return false;
   return true;
@@ -1123,7 +1130,7 @@
   // Statics are irrelevant to virtual call sites.
   if (m->is_static())  return false;
 
-  // We could return also false if m does not yet appear to be
+  // We could also return false if m does not yet appear to be
   // executed, if the VM version supports this distinction also.
   return !m->is_abstract();
 }
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1722,11 +1722,11 @@
       if (PrintCompilation) {
         const char* reason = ci_env.failure_reason();
         if (compilable == ciEnv::MethodCompilable_not_at_tier) {
-            tty->print_cr("%3d   COMPILE SKIPPED: %s (retry at different tier)", compile_id, reason);
+          tty->print_cr("%4d   COMPILE SKIPPED: %s (retry at different tier)", compile_id, reason);
         } else if (compilable == ciEnv::MethodCompilable_never) {
-          tty->print_cr("%3d   COMPILE SKIPPED: %s (not retryable)", compile_id, reason);
+          tty->print_cr("%4d   COMPILE SKIPPED: %s (not retryable)", compile_id, reason);
         } else if (compilable == ciEnv::MethodCompilable) {
-          tty->print_cr("%3d   COMPILE SKIPPED: %s", compile_id, reason);
+          tty->print_cr("%4d   COMPILE SKIPPED: %s", compile_id, reason);
         }
       }
     } else {
@@ -1743,6 +1743,14 @@
 
   collect_statistics(thread, time, task);
 
+  if (PrintCompilation && PrintCompilation2) {
+    tty->print("%7d ", (int) tty->time_stamp().milliseconds());  // print timestamp
+    tty->print("%4d ", compile_id);    // print compilation number
+    tty->print("%s ", (is_osr ? "%" : " "));
+    int code_size = (task->code() == NULL) ? 0 : task->code()->total_size();
+    tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, time.milliseconds(), task->num_inlined_bytecodes());
+  }
+
   if (compilable == ciEnv::MethodCompilable_never) {
     if (is_osr) {
       method->set_not_osr_compilable();
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -50,8 +50,8 @@
 int CompactibleFreeListSpace::_lockRank = Mutex::leaf + 3;
 
 // Defaults are 0 so things will break badly if incorrectly initialized.
-int CompactibleFreeListSpace::IndexSetStart  = 0;
-int CompactibleFreeListSpace::IndexSetStride = 0;
+size_t CompactibleFreeListSpace::IndexSetStart  = 0;
+size_t CompactibleFreeListSpace::IndexSetStride = 0;
 
 size_t MinChunkSize = 0;
 
@@ -62,7 +62,7 @@
   MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment;
 
   assert(IndexSetStart == 0 && IndexSetStride == 0, "already set");
-  IndexSetStart  = (int) MinChunkSize;
+  IndexSetStart  = MinChunkSize;
   IndexSetStride = MinObjAlignment;
 }
 
@@ -250,7 +250,7 @@
 }
 
 void CompactibleFreeListSpace::resetIndexedFreeListArray() {
-  for (int i = 1; i < IndexSetSize; i++) {
+  for (size_t i = 1; i < IndexSetSize; i++) {
     assert(_indexedFreeList[i].size() == (size_t) i,
       "Indexed free list sizes are incorrect");
     _indexedFreeList[i].reset(IndexSetSize);
@@ -337,7 +337,7 @@
 
 size_t CompactibleFreeListSpace::totalCountInIndexedFreeLists() const {
   size_t count = 0;
-  for (int i = (int)MinChunkSize; i < IndexSetSize; i++) {
+  for (size_t i = IndexSetStart; i < IndexSetSize; i++) {
     debug_only(
       ssize_t total_list_count = 0;
       for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
@@ -2200,7 +2200,7 @@
 
 void CompactibleFreeListSpace::clearFLCensus() {
   assert_locked();
-  int i;
+  size_t i;
   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
     FreeList *fl = &_indexedFreeList[i];
     fl->set_prevSweep(fl->count());
@@ -2494,7 +2494,7 @@
 
 void CompactibleFreeListSpace::verifyIndexedFreeLists() const {
   size_t i = 0;
-  for (; i < MinChunkSize; i++) {
+  for (; i < IndexSetStart; i++) {
     guarantee(_indexedFreeList[i].head() == NULL, "should be NULL");
   }
   for (; i < IndexSetSize; i++) {
@@ -2507,7 +2507,7 @@
   FreeChunk* tail =  _indexedFreeList[size].tail();
   size_t    num = _indexedFreeList[size].count();
   size_t      n = 0;
-  guarantee(((size >= MinChunkSize) && (size % IndexSetStride == 0)) || fc == NULL,
+  guarantee(((size >= IndexSetStart) && (size % IndexSetStride == 0)) || fc == NULL,
             "Slot should have been empty");
   for (; fc != NULL; fc = fc->next(), n++) {
     guarantee(fc->size() == size, "Size inconsistency");
@@ -2527,7 +2527,7 @@
     "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) || (MinChunkSize % 2 == 0),
+  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");
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -104,8 +104,8 @@
     SmallForDictionary  = 257,       // size < this then use _indexedFreeList
     IndexSetSize        = SmallForDictionary  // keep this odd-sized
   };
-  static int IndexSetStart;
-  static int IndexSetStride;
+  static size_t IndexSetStart;
+  static size_t IndexSetStride;
 
  private:
   enum FitStrategyOptions {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1518,6 +1518,7 @@
   size_t _regions_claimed;
   size_t _freed_bytes;
   FreeRegionList* _local_cleanup_list;
+  OldRegionSet* _old_proxy_set;
   HumongousRegionSet* _humongous_proxy_set;
   HRRSCleanupTask* _hrrs_cleanup_task;
   double _claimed_region_time;
@@ -1527,6 +1528,7 @@
   G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1,
                              int worker_num,
                              FreeRegionList* local_cleanup_list,
+                             OldRegionSet* old_proxy_set,
                              HumongousRegionSet* humongous_proxy_set,
                              HRRSCleanupTask* hrrs_cleanup_task);
   size_t freed_bytes() { return _freed_bytes; }
@@ -1557,9 +1559,11 @@
   void work(int i) {
     double start = os::elapsedTime();
     FreeRegionList local_cleanup_list("Local Cleanup List");
+    OldRegionSet old_proxy_set("Local Cleanup Old Proxy Set");
     HumongousRegionSet humongous_proxy_set("Local Cleanup Humongous Proxy Set");
     HRRSCleanupTask hrrs_cleanup_task;
     G1NoteEndOfConcMarkClosure g1_note_end(_g1h, i, &local_cleanup_list,
+                                           &old_proxy_set,
                                            &humongous_proxy_set,
                                            &hrrs_cleanup_task);
     if (G1CollectedHeap::use_parallel_gc_threads()) {
@@ -1573,6 +1577,7 @@
     // Now update the lists
     _g1h->update_sets_after_freeing_regions(g1_note_end.freed_bytes(),
                                             NULL /* free_list */,
+                                            &old_proxy_set,
                                             &humongous_proxy_set,
                                             true /* par */);
     {
@@ -1643,6 +1648,7 @@
 G1NoteEndOfConcMarkClosure(G1CollectedHeap* g1,
                            int worker_num,
                            FreeRegionList* local_cleanup_list,
+                           OldRegionSet* old_proxy_set,
                            HumongousRegionSet* humongous_proxy_set,
                            HRRSCleanupTask* hrrs_cleanup_task)
   : _g1(g1), _worker_num(worker_num),
@@ -1650,6 +1656,7 @@
     _freed_bytes(0),
     _claimed_region_time(0.0), _max_region_time(0.0),
     _local_cleanup_list(local_cleanup_list),
+    _old_proxy_set(old_proxy_set),
     _humongous_proxy_set(humongous_proxy_set),
     _hrrs_cleanup_task(hrrs_cleanup_task) { }
 
@@ -1665,6 +1672,7 @@
     _g1->free_region_if_empty(hr,
                               &_freed_bytes,
                               _local_cleanup_list,
+                              _old_proxy_set,
                               _humongous_proxy_set,
                               _hrrs_cleanup_task,
                               true /* par */);
@@ -1689,6 +1697,7 @@
     return;
   }
 
+  HRSPhaseSetter x(HRSPhaseCleanup);
   g1h->verify_region_sets_optional();
 
   if (VerifyDuringGC) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1203,6 +1203,7 @@
     Universe::print_heap_before_gc();
   }
 
+  HRSPhaseSetter x(HRSPhaseFullGC);
   verify_region_sets_optional();
 
   const bool do_clear_all_soft_refs = clear_all_soft_refs ||
@@ -1263,7 +1264,6 @@
     release_mutator_alloc_region();
     abandon_gc_alloc_regions();
     g1_rem_set()->cleanupHRRS();
-    tear_down_region_lists();
 
     // We should call this after we retire any currently active alloc
     // regions so that all the ALLOC / RETIRE events are generated
@@ -1278,7 +1278,7 @@
     g1_policy()->clear_incremental_cset();
     g1_policy()->stop_incremental_cset_building();
 
-    empty_young_list();
+    tear_down_region_sets(false /* free_list_only */);
     g1_policy()->set_full_young_gcs(true);
 
     // See the comments in g1CollectedHeap.hpp and
@@ -1301,9 +1301,7 @@
     }
 
     assert(free_regions() == 0, "we should not have added any free regions");
-    rebuild_region_lists();
-
-    _summary_bytes_used = recalculate_used();
+    rebuild_region_sets(false /* free_list_only */);
 
     // Enqueue any discovered reference objects that have
     // not been removed from the discovered lists.
@@ -1764,9 +1762,9 @@
   // Instead of tearing down / rebuilding the free lists here, we
   // could instead use the remove_all_pending() method on free_list to
   // remove only the ones that we need to remove.
-  tear_down_region_lists();  // We will rebuild them in a moment.
+  tear_down_region_sets(true /* free_list_only */);
   shrink_helper(shrink_bytes);
-  rebuild_region_lists();
+  rebuild_region_sets(true /* free_list_only */);
 
   _hrs.verify_optional();
   verify_region_sets_optional();
@@ -1799,6 +1797,7 @@
   _full_collection(false),
   _free_list("Master Free List"),
   _secondary_free_list("Secondary Free List"),
+  _old_set("Old Set"),
   _humongous_set("Master Humongous Set"),
   _free_regions_coming(false),
   _young_list(new YoungList(this)),
@@ -3007,7 +3006,10 @@
 
     if (failures) {
       gclog_or_tty->print_cr("Heap:");
-      print_on(gclog_or_tty, true /* extended */);
+      // It helps to have the per-region information in the output to
+      // help us track down what went wrong. This is why we call
+      // print_extended_on() instead of print_on().
+      print_extended_on(gclog_or_tty);
       gclog_or_tty->print_cr("");
 #ifndef PRODUCT
       if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) {
@@ -3033,13 +3035,7 @@
   }
 };
 
-void G1CollectedHeap::print() const { print_on(tty); }
-
 void G1CollectedHeap::print_on(outputStream* st) const {
-  print_on(st, PrintHeapAtGCExtended);
-}
-
-void G1CollectedHeap::print_on(outputStream* st, bool extended) const {
   st->print(" %-20s", "garbage-first heap");
   st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
             capacity()/K, used_unlocked()/K);
@@ -3057,13 +3053,14 @@
             survivor_regions, survivor_regions * HeapRegion::GrainBytes / K);
   st->cr();
   perm()->as_gen()->print_on(st);
-  if (extended) {
-    st->cr();
-    print_on_extended(st);
-  }
-}
-
-void G1CollectedHeap::print_on_extended(outputStream* st) const {
+}
+
+void G1CollectedHeap::print_extended_on(outputStream* st) const {
+  print_on(st);
+
+  // 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)");
   PrintRegionClosure blk(st);
   heap_region_iterate(&blk);
 }
@@ -3352,6 +3349,7 @@
     Universe::print_heap_before_gc();
   }
 
+  HRSPhaseSetter x(HRSPhaseEvacuation);
   verify_region_sets_optional();
   verify_dirty_young_regions();
 
@@ -3774,6 +3772,11 @@
       !retained_region->is_empty() &&
       !retained_region->isHumongous()) {
     retained_region->set_saved_mark();
+    // The retained region was added to the old region set when it was
+    // retired. We have to remove it now, since we don't allow regions
+    // we allocate to in the region sets. We'll re-add it later, when
+    // it's retired again.
+    _old_set.remove(retained_region);
     _old_gc_alloc_region.set(retained_region);
     _hr_printer.reuse(retained_region);
   }
@@ -5338,6 +5341,7 @@
 void G1CollectedHeap::free_region_if_empty(HeapRegion* hr,
                                      size_t* pre_used,
                                      FreeRegionList* free_list,
+                                     OldRegionSet* old_proxy_set,
                                      HumongousRegionSet* humongous_proxy_set,
                                      HRRSCleanupTask* hrrs_cleanup_task,
                                      bool par) {
@@ -5346,6 +5350,7 @@
       assert(hr->startsHumongous(), "we should only see starts humongous");
       free_humongous_region(hr, pre_used, free_list, humongous_proxy_set, par);
     } else {
+      _old_set.remove_with_proxy(hr, old_proxy_set);
       free_region(hr, pre_used, free_list, par);
     }
   } else {
@@ -5402,6 +5407,7 @@
 
 void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used,
                                        FreeRegionList* free_list,
+                                       OldRegionSet* old_proxy_set,
                                        HumongousRegionSet* humongous_proxy_set,
                                        bool par) {
   if (pre_used > 0) {
@@ -5417,6 +5423,10 @@
     MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
     _free_list.add_as_head(free_list);
   }
+  if (old_proxy_set != NULL && !old_proxy_set->is_empty()) {
+    MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag);
+    _old_set.update_from_proxy(old_proxy_set);
+  }
   if (humongous_proxy_set != NULL && !humongous_proxy_set->is_empty()) {
     MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag);
     _humongous_set.update_from_proxy(humongous_proxy_set);
@@ -5614,6 +5624,8 @@
         cur->set_young_index_in_cset(-1);
       cur->set_not_young();
       cur->set_evacuation_failed(false);
+      // The region is now considered to be old.
+      _old_set.add(cur);
     }
     cur = next;
   }
@@ -5629,6 +5641,7 @@
     young_time_ms += elapsed_ms;
 
   update_sets_after_freeing_regions(pre_used, &local_free_list,
+                                    NULL /* old_proxy_set */,
                                     NULL /* humongous_proxy_set */,
                                     false /* par */);
   policy->record_young_free_cset_time_ms(young_time_ms);
@@ -5740,52 +5753,106 @@
   return ret;
 }
 
-void G1CollectedHeap::empty_young_list() {
-  assert(heap_lock_held_for_gc(),
-              "the heap lock should already be held by or for this thread");
-
-  _young_list->empty_list();
-}
-
-// Done at the start of full GC.
-void G1CollectedHeap::tear_down_region_lists() {
-  _free_list.remove_all();
-}
-
-class RegionResetter: public HeapRegionClosure {
-  G1CollectedHeap* _g1h;
-  FreeRegionList _local_free_list;
+class TearDownRegionSetsClosure : public HeapRegionClosure {
+private:
+  OldRegionSet *_old_set;
 
 public:
-  RegionResetter() : _g1h(G1CollectedHeap::heap()),
-                     _local_free_list("Local Free List for RegionResetter") { }
+  TearDownRegionSetsClosure(OldRegionSet* old_set) : _old_set(old_set) { }
 
   bool doHeapRegion(HeapRegion* r) {
-    if (r->continuesHumongous()) return false;
-    if (r->top() > r->bottom()) {
-      if (r->top() < r->end()) {
-        Copy::fill_to_words(r->top(),
-                          pointer_delta(r->end(), r->top()));
-      }
+    if (r->is_empty()) {
+      // We ignore empty regions, we'll empty the free list afterwards
+    } else if (r->is_young()) {
+      // We ignore young regions, we'll empty the young list afterwards
+    } else if (r->isHumongous()) {
+      // We ignore humongous regions, we're not tearing down the
+      // humongous region set
     } else {
-      assert(r->is_empty(), "tautology");
-      _local_free_list.add_as_tail(r);
+      // The rest should be old
+      _old_set->remove(r);
     }
     return false;
   }
 
-  void update_free_lists() {
-    _g1h->update_sets_after_freeing_regions(0, &_local_free_list, NULL,
-                                            false /* par */);
+  ~TearDownRegionSetsClosure() {
+    assert(_old_set->is_empty(), "post-condition");
   }
 };
 
-// Done at the end of full GC.
-void G1CollectedHeap::rebuild_region_lists() {
-  // This needs to go at the end of the full GC.
-  RegionResetter rs;
-  heap_region_iterate(&rs);
-  rs.update_free_lists();
+void G1CollectedHeap::tear_down_region_sets(bool free_list_only) {
+  assert_at_safepoint(true /* should_be_vm_thread */);
+
+  if (!free_list_only) {
+    TearDownRegionSetsClosure cl(&_old_set);
+    heap_region_iterate(&cl);
+
+    // Need to do this after the heap iteration to be able to
+    // recognize the young regions and ignore them during the iteration.
+    _young_list->empty_list();
+  }
+  _free_list.remove_all();
+}
+
+class RebuildRegionSetsClosure : public HeapRegionClosure {
+private:
+  bool            _free_list_only;
+  OldRegionSet*   _old_set;
+  FreeRegionList* _free_list;
+  size_t          _total_used;
+
+public:
+  RebuildRegionSetsClosure(bool free_list_only,
+                           OldRegionSet* old_set, FreeRegionList* free_list) :
+    _free_list_only(free_list_only),
+    _old_set(old_set), _free_list(free_list), _total_used(0) {
+    assert(_free_list->is_empty(), "pre-condition");
+    if (!free_list_only) {
+      assert(_old_set->is_empty(), "pre-condition");
+    }
+  }
+
+  bool doHeapRegion(HeapRegion* r) {
+    if (r->continuesHumongous()) {
+      return false;
+    }
+
+    if (r->is_empty()) {
+      // Add free regions to the free list
+      _free_list->add_as_tail(r);
+    } else if (!_free_list_only) {
+      assert(!r->is_young(), "we should not come across young regions");
+
+      if (r->isHumongous()) {
+        // We ignore humongous regions, we left the humongous set unchanged
+      } else {
+        // The rest should be old, add them to the old set
+        _old_set->add(r);
+      }
+      _total_used += r->used();
+    }
+
+    return false;
+  }
+
+  size_t total_used() {
+    return _total_used;
+  }
+};
+
+void G1CollectedHeap::rebuild_region_sets(bool free_list_only) {
+  assert_at_safepoint(true /* should_be_vm_thread */);
+
+  RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_free_list);
+  heap_region_iterate(&cl);
+
+  if (!free_list_only) {
+    _summary_bytes_used = cl.total_used();
+  }
+  assert(_summary_bytes_used == recalculate_used(),
+         err_msg("inconsistent _summary_bytes_used, "
+                 "value: "SIZE_FORMAT" recalculated: "SIZE_FORMAT,
+                 _summary_bytes_used, recalculate_used()));
 }
 
 void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) {
@@ -5882,6 +5949,8 @@
   g1_policy()->record_bytes_copied_during_gc(allocated_bytes);
   if (ap == GCAllocForSurvived) {
     young_list()->add_survivor_region(alloc_region);
+  } else {
+    _old_set.add(alloc_region);
   }
   _hr_printer.retire(alloc_region);
 }
@@ -5913,15 +5982,17 @@
 
 class VerifyRegionListsClosure : public HeapRegionClosure {
 private:
+  FreeRegionList*     _free_list;
+  OldRegionSet*       _old_set;
   HumongousRegionSet* _humongous_set;
-  FreeRegionList*     _free_list;
   size_t              _region_count;
 
 public:
-  VerifyRegionListsClosure(HumongousRegionSet* humongous_set,
+  VerifyRegionListsClosure(OldRegionSet* old_set,
+                           HumongousRegionSet* humongous_set,
                            FreeRegionList* free_list) :
-    _humongous_set(humongous_set), _free_list(free_list),
-    _region_count(0) { }
+    _old_set(old_set), _humongous_set(humongous_set),
+    _free_list(free_list), _region_count(0) { }
 
   size_t region_count()      { return _region_count;      }
 
@@ -5938,6 +6009,8 @@
       _humongous_set->verify_next_region(hr);
     } else if (hr->is_empty()) {
       _free_list->verify_next_region(hr);
+    } else {
+      _old_set->verify_next_region(hr);
     }
     return false;
   }
@@ -5964,6 +6037,7 @@
     MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
     _secondary_free_list.verify();
   }
+  _old_set.verify();
   _humongous_set.verify();
 
   // If a concurrent region freeing operation is in progress it will
@@ -5987,12 +6061,14 @@
 
   // Finally, make sure that the region accounting in the lists is
   // consistent with what we see in the heap.
+  _old_set.verify_start();
   _humongous_set.verify_start();
   _free_list.verify_start();
 
-  VerifyRegionListsClosure cl(&_humongous_set, &_free_list);
+  VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_free_list);
   heap_region_iterate(&cl);
 
+  _old_set.verify_end();
   _humongous_set.verify_end();
   _free_list.verify_end();
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -239,6 +239,9 @@
   // master free list when appropriate.
   SecondaryFreeRegionList   _secondary_free_list;
 
+  // It keeps track of the old regions.
+  MasterOldRegionSet        _old_set;
+
   // It keeps track of the humongous regions.
   MasterHumongousRegionSet  _humongous_set;
 
@@ -248,10 +251,21 @@
   // The block offset table for the G1 heap.
   G1BlockOffsetSharedArray* _bot_shared;
 
-  // Move all of the regions off the free lists, then rebuild those free
-  // lists, before and after full GC.
-  void tear_down_region_lists();
-  void rebuild_region_lists();
+  // Tears down the region sets / lists so that they are empty and the
+  // regions on the heap do not belong to a region set / list. The
+  // only exception is the humongous set which we leave unaltered. If
+  // free_list_only is true, it will only tear down the master free
+  // list. It is called before a Full GC (free_list_only == false) or
+  // before heap shrinking (free_list_only == true).
+  void tear_down_region_sets(bool free_list_only);
+
+  // Rebuilds the region sets / lists so that they are repopulated to
+  // reflect the contents of the heap. The only exception is the
+  // humongous set which was not torn down in the first place. If
+  // free_list_only is true, it will only rebuild the master free
+  // list. It is called after a Full GC (free_list_only == false) or
+  // after heap shrinking (free_list_only == true).
+  void rebuild_region_sets(bool free_list_only);
 
   // The sequence of all heap regions in the heap.
   HeapRegionSeq _hrs;
@@ -1124,6 +1138,10 @@
     }
   }
 
+  void old_set_remove(HeapRegion* hr) {
+    _old_set.remove(hr);
+  }
+
   void set_free_regions_coming();
   void reset_free_regions_coming();
   bool free_regions_coming() { return _free_regions_coming; }
@@ -1153,6 +1171,7 @@
   void free_region_if_empty(HeapRegion* hr,
                             size_t* pre_used,
                             FreeRegionList* free_list,
+                            OldRegionSet* old_proxy_set,
                             HumongousRegionSet* humongous_proxy_set,
                             HRRSCleanupTask* hrrs_cleanup_task,
                             bool par);
@@ -1163,6 +1182,7 @@
   // (if par is true, it will do so by taking the ParGCRareEvent_lock).
   void update_sets_after_freeing_regions(size_t pre_used,
                                        FreeRegionList* free_list,
+                                       OldRegionSet* old_proxy_set,
                                        HumongousRegionSet* humongous_proxy_set,
                                        bool par);
 
@@ -1429,14 +1449,8 @@
 
   // Override; it uses the "prev" marking information
   virtual void verify(bool allow_dirty, bool silent);
-  // Default behavior by calling print(tty);
-  virtual void print() const;
-  // This calls print_on(st, PrintHeapAtGCExtended).
   virtual void print_on(outputStream* st) const;
-  // If extended is true, it will print out information for all
-  // regions in the heap by calling print_on_extended(st).
-  virtual void print_on(outputStream* st, bool extended) const;
-  virtual void print_on_extended(outputStream* st) const;
+  virtual void print_extended_on(outputStream* st) const;
 
   virtual void print_gc_threads_on(outputStream* st) const;
   virtual void gc_threads_do(ThreadClosure* tc) const;
@@ -1452,8 +1466,6 @@
   // asserted to be this type.
   static G1CollectedHeap* heap();
 
-  void empty_young_list();
-
   void set_region_short_lived_locked(HeapRegion* hr);
   // add appropriate methods for any other surv rate groups
 
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -3015,6 +3015,7 @@
       hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms,
                                                       avg_prediction);
       if (hr != NULL) {
+        _g1->old_set_remove(hr);
         double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
         time_remaining_ms -= predicted_time_ms;
         predicted_pause_time_ms += predicted_time_ms;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -236,6 +236,7 @@
     // at the end of the GC, so no point in updating those values here.
     _g1h->update_sets_after_freeing_regions(0, /* pre_used */
                                             NULL, /* free_list */
+                                            NULL, /* old_proxy_set */
                                             &_humongous_proxy_set,
                                             false /* par */);
   }
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -635,10 +635,18 @@
   ct_freq_note_card(_ct_bs->index_for(start));
 #endif
 
-  assert(!check_for_refs_into_cset || _cset_rs_update_cl[worker_i] != NULL, "sanity");
+  OopsInHeapRegionClosure* oops_in_heap_closure = NULL;
+  if (check_for_refs_into_cset) {
+    // ConcurrentG1RefineThreads have worker numbers larger than what
+    // _cset_rs_update_cl[] is set up to handle. But those threads should
+    // only be active outside of a collection which means that when they
+    // reach here they should have check_for_refs_into_cset == false.
+    assert((size_t)worker_i < n_workers(), "index of worker larger than _cset_rs_update_cl[].length");
+    oops_in_heap_closure = _cset_rs_update_cl[worker_i];
+  }
   UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
                                                _g1->g1_rem_set(),
-                                               _cset_rs_update_cl[worker_i],
+                                               oops_in_heap_closure,
                                                check_for_refs_into_cset,
                                                worker_i);
   update_rs_oop_cl.set_from(r);
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -722,7 +722,7 @@
     st->print(" F");
   else
     st->print("  ");
-  st->print(" %5d", _gc_time_stamp);
+  st->print(" TS %5d", _gc_time_stamp);
   st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT,
             prev_top_at_mark_start(), next_top_at_mark_start());
   G1OffsetTableContigSpace::print_on(st);
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -26,6 +26,7 @@
 #include "gc_implementation/g1/heapRegionSet.inline.hpp"
 
 size_t HeapRegionSetBase::_unrealistically_long_length = 0;
+HRSPhase HeapRegionSetBase::_phase = HRSPhaseNone;
 
 //////////////////// HeapRegionSetBase ////////////////////
 
@@ -192,6 +193,17 @@
   _verify_in_progress = false;
 }
 
+void HeapRegionSetBase::clear_phase() {
+  assert(_phase != HRSPhaseNone, "pre-condition");
+  _phase = HRSPhaseNone;
+}
+
+void HeapRegionSetBase::set_phase(HRSPhase phase) {
+  assert(_phase == HRSPhaseNone, "pre-condition");
+  assert(phase != HRSPhaseNone, "pre-condition");
+  _phase = phase;
+}
+
 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
   out->cr();
   out->print_cr("Set: %s ("PTR_FORMAT")", name(), this);
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -47,8 +47,18 @@
 
 class hrs_ext_msg;
 
+typedef enum {
+  HRSPhaseNone,
+  HRSPhaseEvacuation,
+  HRSPhaseCleanup,
+  HRSPhaseFullGC
+} HRSPhase;
+
+class HRSPhaseSetter;
+
 class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC {
   friend class hrs_ext_msg;
+  friend class HRSPhaseSetter;
 
 protected:
   static size_t calculate_region_num(HeapRegion* hr);
@@ -80,6 +90,15 @@
   size_t      _calc_total_capacity_bytes;
   size_t      _calc_total_used_bytes;
 
+  // This is here so that it can be used in the subclasses to assert
+  // something different depending on which phase the GC is in. This
+  // can be particularly helpful in the check_mt_safety() methods.
+  static HRSPhase _phase;
+
+  // Only used by HRSPhaseSetter.
+  static void clear_phase();
+  static void set_phase(HRSPhase phase);
+
   // verify_region() is used to ensure that the contents of a region
   // added to / removed from a set are consistent. Different sets
   // make different assumptions about the regions added to them. So
@@ -177,6 +196,16 @@
   }
 };
 
+class HRSPhaseSetter {
+public:
+  HRSPhaseSetter(HRSPhase phase) {
+    HeapRegionSetBase::set_phase(phase);
+  }
+  ~HRSPhaseSetter() {
+    HeapRegionSetBase::clear_phase();
+  }
+};
+
 // These two macros are provided for convenience, to keep the uses of
 // these two asserts a bit more concise.
 
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSets.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSets.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -26,6 +26,17 @@
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
 #include "gc_implementation/g1/heapRegionSets.hpp"
 
+// Note on the check_mt_safety() methods below:
+//
+// Verification of the "master" heap region sets / lists that are
+// maintained by G1CollectedHeap is always done during a STW pause and
+// by the VM thread at the start / end of the pause. The standard
+// verification methods all assert check_mt_safety(). This is
+// important as it ensures that verification is done without
+// concurrent updates taking place at the same time. It follows, that,
+// for the "master" heap region sets / lists, the check_mt_safety()
+// method should include the VM thread / STW case.
+
 //////////////////// FreeRegionList ////////////////////
 
 const char* FreeRegionList::verify_region_extra(HeapRegion* hr) {
@@ -33,7 +44,7 @@
     return "the region should not be young";
   }
   // The superclass will check that the region is empty and
-  // not-humongous.
+  // not humongous.
   return HeapRegionLinkedList::verify_region_extra(hr);
 }
 
@@ -58,12 +69,16 @@
   // (b) If we're not at a safepoint, operations on the master free
   // list should be invoked while holding the Heap_lock.
 
-  guarantee((SafepointSynchronize::is_at_safepoint() &&
-               (Thread::current()->is_VM_thread() ||
-                                            FreeList_lock->owned_by_self())) ||
-            (!SafepointSynchronize::is_at_safepoint() &&
-                                                Heap_lock->owned_by_self()),
-            hrs_ext_msg(this, "master free list MT safety protocol"));
+  if (SafepointSynchronize::is_at_safepoint()) {
+    guarantee(Thread::current()->is_VM_thread() ||
+              FreeList_lock->owned_by_self(),
+              hrs_ext_msg(this, "master free list MT safety protocol "
+                                "at a safepoint"));
+  } else {
+    guarantee(Heap_lock->owned_by_self(),
+              hrs_ext_msg(this, "master free list MT safety protocol "
+                                "outside a safepoint"));
+  }
 
   return FreeRegionList::check_mt_safety();
 }
@@ -81,6 +96,48 @@
   return FreeRegionList::check_mt_safety();
 }
 
+//////////////////// OldRegionSet ////////////////////
+
+const char* OldRegionSet::verify_region_extra(HeapRegion* hr) {
+  if (hr->is_young()) {
+    return "the region should not be young";
+  }
+  // The superclass will check that the region is not empty and not
+  // humongous.
+  return HeapRegionSet::verify_region_extra(hr);
+}
+
+//////////////////// MasterOldRegionSet ////////////////////
+
+bool MasterOldRegionSet::check_mt_safety() {
+  // Master Old Set MT safety protocol:
+  // (a) If we're at a safepoint, operations on the master old set
+  // should be invoked:
+  // - by the VM thread (which will serialize them), or
+  // - by the GC workers while holding the FreeList_lock, if we're
+  //   at a safepoint for an evacuation pause (this lock is taken
+  //   anyway when an GC alloc region is retired so that a new one
+  //   is allocated from the free list), or
+  // - by the GC workers while holding the OldSets_lock, if we're at a
+  //   safepoint for a cleanup pause.
+  // (b) If we're not at a safepoint, operations on the master old set
+  // should be invoked while holding the Heap_lock.
+
+  if (SafepointSynchronize::is_at_safepoint()) {
+    guarantee(Thread::current()->is_VM_thread() ||
+              _phase == HRSPhaseEvacuation && FreeList_lock->owned_by_self() ||
+              _phase == HRSPhaseCleanup && OldSets_lock->owned_by_self(),
+              hrs_ext_msg(this, "master old set MT safety protocol "
+                                "at a safepoint"));
+  } else {
+    guarantee(Heap_lock->owned_by_self(),
+              hrs_ext_msg(this, "master old set MT safety protocol "
+                                "outside a safepoint"));
+  }
+
+  return OldRegionSet::check_mt_safety();
+}
+
 //////////////////// HumongousRegionSet ////////////////////
 
 const char* HumongousRegionSet::verify_region_extra(HeapRegion* hr) {
@@ -103,11 +160,16 @@
   // (b) If we're not at a safepoint, operations on the master
   // humongous set should be invoked while holding the Heap_lock.
 
-  guarantee((SafepointSynchronize::is_at_safepoint() &&
-               (Thread::current()->is_VM_thread() ||
-                                             OldSets_lock->owned_by_self())) ||
-            (!SafepointSynchronize::is_at_safepoint() &&
-                                                 Heap_lock->owned_by_self()),
-            hrs_ext_msg(this, "master humongous set MT safety protocol"));
+  if (SafepointSynchronize::is_at_safepoint()) {
+    guarantee(Thread::current()->is_VM_thread() ||
+              OldSets_lock->owned_by_self(),
+              hrs_ext_msg(this, "master humongous set MT safety protocol "
+                                "at a safepoint"));
+  } else {
+    guarantee(Heap_lock->owned_by_self(),
+              hrs_ext_msg(this, "master humongous set MT safety protocol "
+                                "outside a safepoint"));
+  }
+
   return HumongousRegionSet::check_mt_safety();
 }
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSets.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSets.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -61,6 +61,30 @@
   SecondaryFreeRegionList(const char* name) : FreeRegionList(name) { }
 };
 
+//////////////////// OldRegionSet ////////////////////
+
+class OldRegionSet : public HeapRegionSet {
+protected:
+  virtual const char* verify_region_extra(HeapRegion* hr);
+
+  virtual bool regions_humongous() { return false; }
+  virtual bool regions_empty()     { return false; }
+
+public:
+  OldRegionSet(const char* name) : HeapRegionSet(name) { }
+};
+
+//////////////////// MasterOldRegionSet ////////////////////
+
+class MasterOldRegionSet : public OldRegionSet {
+private:
+protected:
+  virtual bool check_mt_safety();
+
+public:
+  MasterOldRegionSet(const char* name) : OldRegionSet(name) { }
+};
+
 //////////////////// HumongousRegionSet ////////////////////
 
 class HumongousRegionSet : public HeapRegionSet {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -863,8 +863,6 @@
   ensure_parsability(false);  // no need to retire TLABs for verification
 }
 
-void ParallelScavengeHeap::print() const { print_on(tty); }
-
 void ParallelScavengeHeap::print_on(outputStream* st) const {
   young_gen()->print_on(st);
   old_gen()->print_on(st);
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -246,8 +246,7 @@
   jlong millis_since_last_gc();
 
   void prepare_for_verify();
-  void print() const;
-  void print_on(outputStream* st) const;
+  virtual void print_on(outputStream* st) const;
   virtual void print_gc_threads_on(outputStream* st) const;
   virtual void gc_threads_do(ThreadClosure* tc) const;
   virtual void print_tracing_info() const;
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -590,13 +590,27 @@
   void pre_full_gc_dump();
   void post_full_gc_dump();
 
-  virtual void print() const = 0;
+  // Print heap information on the given outputStream.
   virtual void print_on(outputStream* st) const = 0;
+  // The default behavior is to call print_on() on tty.
+  virtual void print() const {
+    print_on(tty);
+  }
+  // Print more detailed heap information on the given
+  // outputStream. The default behaviour is to call print_on(). It is
+  // up to each subclass to override it and add any additional output
+  // it needs.
+  virtual void print_extended_on(outputStream* st) const {
+    print_on(st);
+  }
 
   // Print all GC threads (other than the VM thread)
   // used by this heap.
   virtual void print_gc_threads_on(outputStream* st) const = 0;
-  void print_gc_threads() { print_gc_threads_on(tty); }
+  // The default behavior is to call print_gc_threads_on() on tty.
+  void print_gc_threads() {
+    print_gc_threads_on(tty);
+  }
   // Iterator for all GC threads (other than VM thread)
   virtual void gc_threads_do(ThreadClosure* tc) const = 0;
 
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -42,12 +42,6 @@
     case _jvmti_force_gc:
       return "JvmtiEnv ForceGarbageCollection";
 
-    case _no_gc:
-      return "No GC";
-
-    case _allocation_failure:
-      return "Allocation Failure";
-
     case _gc_locker:
       return "GCLocker Initiated GC";
 
@@ -57,6 +51,12 @@
     case _heap_dump:
       return "Heap Dump Initiated GC";
 
+    case _no_gc:
+      return "No GC";
+
+    case _allocation_failure:
+      return "Allocation Failure";
+
     case _tenured_generation_full:
       return "Tenured Generation Full";
 
@@ -78,6 +78,9 @@
     case _old_generation_too_full_to_scavenge:
       return "Old Generation Too Full To Scavenge";
 
+    case _adaptive_size_policy:
+      return "Ergonomics";
+
     case _g1_inc_collection_pause:
       return "G1 Evacuation Pause";
 
--- a/hotspot/src/share/vm/interpreter/bytecode.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecode.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -234,6 +234,13 @@
                                                           is_invokespecial()   ||
                                                           is_invokedynamic(); }
 
+  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())));
+  }
+
   // 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);
 };
--- a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -241,7 +241,7 @@
         st->print_cr(" not secondary entry?", i);
         return false;
       }
-      i = cache->entry_at(i)->main_entry_index();
+      i = cache->entry_at(i)->main_entry_index() + constantPoolOopDesc::CPCACHE_INDEX_TAG;
       goto check_cache_index;
     } else {
       st->print_cr(" not in cache[*]?", i);
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -549,8 +549,8 @@
 
   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();
-    oop call_site     = *((oop*) thread->last_frame().interpreter_frame_tos_at(-1 * direction));
-    oop method_handle = *((oop*) thread->last_frame().interpreter_frame_tos_at( 0 * 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");
 
--- a/hotspot/src/share/vm/libadt/vectset.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/libadt/vectset.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -350,6 +350,21 @@
   return (int)_xor;
 }
 
+//------------------------------iterate----------------------------------------
+// Used by Set::print().
+class VSetI_ : public SetI_ {
+  VectorSetI vsi;
+public:
+  VSetI_( const VectorSet *vset, uint &elem ) : vsi(vset) { elem = vsi.elem; }
+
+  uint next(void) { ++vsi; return vsi.elem; }
+  int  test(void) { return vsi.test(); }
+};
+
+SetI_ *VectorSet::iterate(uint &elem) const {
+  return new(ResourceObj::C_HEAP) VSetI_(this, elem);
+}
+
 //=============================================================================
 //------------------------------next-------------------------------------------
 // Find and return the next element of a vector set, or return garbage and
--- a/hotspot/src/share/vm/libadt/vectset.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/libadt/vectset.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -151,7 +151,7 @@
 
 
 private:
-  SetI_ *iterate(uint&) const { ShouldNotCallThis(); return NULL; } // Removed
+  SetI_ *iterate(uint&) const;
 };
 
 //------------------------------Iteration--------------------------------------
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1270,7 +1270,6 @@
   rem_set()->verify();
 }
 
-void GenCollectedHeap::print() const { print_on(tty); }
 void GenCollectedHeap::print_on(outputStream* st) const {
   for (int i = 0; i < _n_gens; i++) {
     _gens[i]->print_on(st);
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -360,8 +360,7 @@
   void verify(bool allow_dirty, bool silent, VerifyOption option);
 
   // Override.
-  void print() const;
-  void print_on(outputStream* st) const;
+  virtual void print_on(outputStream* st) const;
   virtual void print_gc_threads_on(outputStream* st) const;
   virtual void gc_threads_do(ThreadClosure* tc) const;
   virtual void print_tracing_info() const;
--- a/hotspot/src/share/vm/memory/universe.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/memory/universe.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1281,11 +1281,17 @@
   }
 }
 
-void Universe::print() { print_on(gclog_or_tty); }
+void Universe::print() {
+  print_on(gclog_or_tty);
+}
 
-void Universe::print_on(outputStream* st) {
+void Universe::print_on(outputStream* st, bool extended) {
   st->print_cr("Heap");
-  heap()->print_on(st);
+  if (!extended) {
+    heap()->print_on(st);
+  } else {
+    heap()->print_extended_on(st);
+  }
 }
 
 void Universe::print_heap_at_SIGBREAK() {
@@ -1301,14 +1307,22 @@
   st->print_cr("{Heap before GC invocations=%u (full %u):",
                heap()->total_collections(),
                heap()->total_full_collections());
-  heap()->print_on(st);
+  if (!PrintHeapAtGCExtended) {
+    heap()->print_on(st);
+  } else {
+    heap()->print_extended_on(st);
+  }
 }
 
 void Universe::print_heap_after_gc(outputStream* st) {
   st->print_cr("Heap after GC invocations=%u (full %u):",
                heap()->total_collections(),
                heap()->total_full_collections());
-  heap()->print_on(st);
+  if (!PrintHeapAtGCExtended) {
+    heap()->print_on(st);
+  } else {
+    heap()->print_extended_on(st);
+  }
   st->print_cr("}");
 }
 
--- a/hotspot/src/share/vm/memory/universe.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/memory/universe.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -414,9 +414,13 @@
   static bool verify_in_progress() { return _verify_in_progress; }
   static void verify(bool allow_dirty = true, bool silent = false,
                      VerifyOption option = VerifyOption_Default );
-  static int  verify_count()                  { return _verify_count; }
+  static int  verify_count()       { return _verify_count; }
+  // The default behavior is to call print_on() on gclog_or_tty.
   static void print();
-  static void print_on(outputStream* st);
+  // The extended parameter determines which method on the heap will
+  // be called: print_on() (extended == false) or print_extended_on()
+  // (extended == true).
+  static void print_on(outputStream* st, bool extended = false);
   static void print_heap_at_SIGBREAK();
   static void print_heap_before_gc() { print_heap_before_gc(gclog_or_tty); }
   static void print_heap_after_gc()  { print_heap_after_gc(gclog_or_tty); }
--- a/hotspot/src/share/vm/oops/arrayOop.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/oops/arrayOop.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -23,9 +23,40 @@
  */
 
 #include "precompiled.hpp"
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
 #include "oops/arrayOop.hpp"
-#include "oops/objArrayOop.hpp"
-#include "oops/oop.inline.hpp"
-#include "oops/symbol.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+bool arrayOopDesc::check_max_length_overflow(BasicType type) {
+  julong length = max_array_length(type);
+  julong bytes_per_element = type2aelembytes(type);
+  julong bytes = length * bytes_per_element + header_size_in_bytes();
+  return (julong)(size_t)bytes == bytes;
+}
+
+bool arrayOopDesc::test_max_array_length() {
+  tty->print_cr("test_max_array_length");
 
-// <<this page is intentionally left blank>>
+  assert(check_max_length_overflow(T_BOOLEAN), "size_t overflow for boolean array");
+  assert(check_max_length_overflow(T_CHAR), "size_t overflow for char array");
+  assert(check_max_length_overflow(T_FLOAT), "size_t overflow for float array");
+  assert(check_max_length_overflow(T_DOUBLE), "size_t overflow for double array");
+  assert(check_max_length_overflow(T_BYTE), "size_t overflow for byte array");
+  assert(check_max_length_overflow(T_SHORT), "size_t overflow for short array");
+  assert(check_max_length_overflow(T_INT), "size_t overflow for int array");
+  assert(check_max_length_overflow(T_LONG), "size_t overflow for long array");
+  assert(check_max_length_overflow(T_OBJECT), "size_t overflow for object array");
+  assert(check_max_length_overflow(T_ARRAY), "size_t overflow for array array");
+  assert(check_max_length_overflow(T_NARROWOOP), "size_t overflow for narrowOop array");
+
+  // T_VOID and T_ADDRESS are not supported by max_array_length()
+
+  return true;
+}
+
+
+#endif //PRODUCT
--- a/hotspot/src/share/vm/oops/arrayOop.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/oops/arrayOop.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,20 +104,32 @@
 
   // Return the maximum length of an array of BasicType.  The length can passed
   // to typeArrayOop::object_size(scale, length, header_size) without causing an
-  // overflow.
+  // overflow. We also need to make sure that this will not overflow a size_t on
+  // 32 bit platforms when we convert it to a byte size.
   static int32_t max_array_length(BasicType type) {
     assert(type >= 0 && type < T_CONFLICT, "wrong type");
     assert(type2aelembytes(type) != 0, "wrong type");
-    const int bytes_per_element = type2aelembytes(type);
-    if (bytes_per_element < HeapWordSize) {
-      return max_jint;
-    }
 
-    const int32_t max_words = align_size_down(max_jint, MinObjAlignment);
-    const int32_t max_element_words = max_words - header_size(type);
-    const int32_t words_per_element = bytes_per_element >> LogHeapWordSize;
-    return max_element_words / words_per_element;
+    const size_t max_element_words_per_size_t =
+      align_size_down((SIZE_MAX/HeapWordSize - header_size(type)), MinObjAlignment);
+    const size_t max_elements_per_size_t =
+      HeapWordSize * max_element_words_per_size_t / type2aelembytes(type);
+    if ((size_t)max_jint < max_elements_per_size_t) {
+      // It should be ok to return max_jint here, but parts of the code
+      // (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for
+      // passing around the size (in words) of an object. So, we need to avoid
+      // overflowing an int when we add the header. See CRs 4718400 and 7110613.
+      return align_size_down(max_jint - header_size(type), MinObjAlignment);
+    }
+    return (int32_t)max_elements_per_size_t;
   }
+
+// for unit testing
+#ifndef PRODUCT
+  static bool check_max_length_overflow(BasicType type);
+  static int32_t old_max_array_length(BasicType type);
+  static bool test_max_array_length();
+#endif
 };
 
 #endif // SHARE_VM_OOPS_ARRAYOOP_HPP
--- a/hotspot/src/share/vm/oops/constantPoolKlass.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/oops/constantPoolKlass.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -532,7 +532,7 @@
     if (cp->tag_at(i).is_unresolved_klass()) {
       // This will force loading of the class
       klassOop klass = cp->klass_at(i, CHECK);
-      if (klass->is_instance()) {
+      if (klass->klass_part()->oop_is_instance()) {
         // Force initialization of class
         instanceKlass::cast(klass)->initialize(CHECK);
       }
--- a/hotspot/src/share/vm/opto/addnode.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/addnode.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -34,8 +34,6 @@
 
 // Portions of code courtesy of Clifford Click
 
-#define MAXFLOAT        ((float)3.40282346638528860e+38)
-
 // Classic Add functionality.  This covers all the usual 'add' behaviors for
 // an algebraic ring.  Add-integer, add-float, add-double, and binary-or are
 // all inherited from this class.  The various identity values are supplied
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -201,7 +201,7 @@
   diagnostic(bool, UnrollLimitCheck, true,                                  \
           "Additional overflow checks during loop unroll")                  \
                                                                             \
-  product(bool, OptimizeFill, false,                                        \
+  product(bool, OptimizeFill, true,                                         \
           "convert fill/copy loops into intrinsic")                         \
                                                                             \
   develop(bool, TraceOptimizeFill, false,                                   \
@@ -459,7 +459,7 @@
   product(bool, UseOptoBiasInlining, true,                                  \
           "Generate biased locking code in C2 ideal graph")                 \
                                                                             \
-  product(bool, OptimizeStringConcat, false,                                \
+  product(bool, OptimizeStringConcat, true,                                 \
           "Optimize the construction of Strings by StringBuilder")          \
                                                                             \
   notproduct(bool, PrintOptimizeStringConcat, false,                        \
--- a/hotspot/src/share/vm/opto/callGenerator.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -775,15 +775,15 @@
 
   Node* bol = NULL;
   int bc = jvms->method()->java_code_at_bci(jvms->bci());
-  if (bc == Bytecodes::_invokespecial) {
-    // This is the selectAlternative idiom for guardWithTest
+  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(kit.C, 3) CmpPNode(receiver, predicted_mh));
     bol = gvn.transform(new(kit.C, 2) BoolNode(cmp, BoolTest::eq) );
   } else {
-    assert(bc == Bytecodes::_invokedynamic, "must be");
     // Get the constant pool cache from the caller class.
     ciMethod* caller_method = jvms->method();
     ciBytecodeStream str(caller_method);
--- a/hotspot/src/share/vm/opto/compile.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/compile.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -346,15 +346,15 @@
 // Disconnect all useless nodes by disconnecting those at the boundary.
 void Compile::remove_useless_nodes(Unique_Node_List &useful) {
   uint next = 0;
-  while( next < useful.size() ) {
+  while (next < useful.size()) {
     Node *n = useful.at(next++);
     // Use raw traversal of out edges since this code removes out edges
     int max = n->outcnt();
-    for (int j = 0; j < max; ++j ) {
+    for (int j = 0; j < max; ++j) {
       Node* child = n->raw_out(j);
-      if( ! useful.member(child) ) {
-        assert( !child->is_top() || child != top(),
-                "If top is cached in Compile object it is in useful list");
+      if (! useful.member(child)) {
+        assert(!child->is_top() || child != top(),
+               "If top is cached in Compile object it is in useful list");
         // Only need to remove this out-edge to the useless node
         n->raw_del_out(j);
         --j;
@@ -362,7 +362,14 @@
       }
     }
     if (n->outcnt() == 1 && n->has_special_unique_user()) {
-      record_for_igvn( n->unique_out() );
+      record_for_igvn(n->unique_out());
+    }
+  }
+  // Remove useless macro and predicate opaq nodes
+  for (int i = C->macro_count()-1; i >= 0; i--) {
+    Node* n = C->macro_node(i);
+    if (!useful.member(n)) {
+      remove_macro_node(n);
     }
   }
   debug_only(verify_graph_edges(true/*check for no_dead_code*/);)
@@ -719,6 +726,7 @@
       while (_late_inlines.length() > 0) {
         CallGenerator* cg = _late_inlines.pop();
         cg->do_late_inline();
+        if (failing())  return;
       }
     }
     assert(_late_inlines.length() == 0, "should have been processed");
@@ -1691,13 +1699,20 @@
 
   // Perform escape analysis
   if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
+    if (has_loops()) {
+      // Cleanup graph (remove dead nodes).
+      TracePhase t2("idealLoop", &_t_idealLoop, true);
+      PhaseIdealLoop ideal_loop( igvn, false, true );
+      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;
 
     igvn.optimize();
-    print_method("Iter GVN 3", 2);
+    print_method("Iter GVN after EA", 2);
 
     if (failing())  return;
 
--- a/hotspot/src/share/vm/opto/escape.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -108,14 +108,16 @@
   // Add ConP(#NULL) and ConN(#NULL) nodes.
   Node* oop_null = igvn->zerocon(T_OBJECT);
   _oop_null = oop_null->_idx;
-  assert(_oop_null < C->unique(), "should be created already");
+  assert(_oop_null < nodes_size(), "should be created already");
   add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
 
   if (UseCompressedOops) {
     Node* noop_null = igvn->zerocon(T_NARROWOOP);
     _noop_null = noop_null->_idx;
-    assert(_noop_null < C->unique(), "should be created already");
+    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
   }
 }
 
@@ -174,6 +176,9 @@
 }
 
 void ConnectionGraph::set_escape_state(uint ni, PointsToNode::EscapeState es) {
+  // Don't change non-escaping state of NULL pointer.
+  if (ni == _noop_null || ni == _oop_null)
+    return;
   PointsToNode *npt = ptnode_adr(ni);
   PointsToNode::EscapeState old_es = npt->escape_state();
   if (es > old_es)
@@ -231,8 +236,8 @@
   }
   if (orig_es != es) {
     // cache the computed escape state
-    assert(es != PointsToNode::UnknownEscape, "should have computed an escape state");
-    ptnode_adr(idx)->set_escape_state(es);
+    assert(es > orig_es, "should have computed an escape state");
+    set_escape_state(idx, es);
   } // orig_es could be PointsToNode::UnknownEscape
   return es;
 }
@@ -334,7 +339,7 @@
         add_pointsto_edge(ni, etgt);
         if(etgt == _phantom_object) {
           // Special case - field set outside (globally escaping).
-          ptn->set_escape_state(PointsToNode::GlobalEscape);
+          set_escape_state(ni, PointsToNode::GlobalEscape);
         }
       } else if (et == PointsToNode::DeferredEdge) {
         deferred_edges->append(etgt);
@@ -373,16 +378,17 @@
 // whose offset matches "offset".
 void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) {
   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 po = pf->offset();
-    if (pf->edge_count() == 0) {
-      // we have not seen any stores to this field, assume it was set outside this method
+    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 (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) {
+    if (offset == offs || offset == Type::OffsetBot || offs == Type::OffsetBot) {
       add_deferred_edge(from_i, fi);
     }
   }
@@ -1036,7 +1042,7 @@
       PointsToNode::EscapeState es = escape_state(alloc);
       // We have an allocation or call which returns a Java object,
       // see if it is unescaped.
-      if (es != PointsToNode::NoEscape || !ptn->_scalar_replaceable)
+      if (es != PointsToNode::NoEscape || !ptn->scalar_replaceable())
         continue;
 
       // Find CheckCastPP for the allocate or for the return value of a call
@@ -1085,7 +1091,7 @@
         // so it could be eliminated.
         alloc->as_Allocate()->_is_scalar_replaceable = true;
       }
-      set_escape_state(n->_idx, es);
+      set_escape_state(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
@@ -1097,15 +1103,14 @@
       set_map(n->_idx, alloc);
       const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
       if (t == NULL)
-        continue;  // not a TypeInstPtr
+        continue;  // not a 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);
       igvn->hash_insert(n);
       record_for_optimizer(n);
-      if (alloc->is_Allocate() && ptn->_scalar_replaceable &&
-          (t->isa_instptr() || t->isa_aryptr())) {
+      if (alloc->is_Allocate() && (t->isa_instptr() || t->isa_aryptr())) {
 
         // First, put on the worklist all Field edges from Connection Graph
         // which is more accurate then putting immediate users from Ideal Graph.
@@ -1533,7 +1538,8 @@
     worklist_init.push(C->root());
   }
 
-  GrowableArray<int> cg_worklist;
+  GrowableArray<Node*> alloc_worklist;
+  GrowableArray<Node*> addp_worklist;
   PhaseGVN* igvn = _igvn;
   bool has_allocations = false;
 
@@ -1546,11 +1552,13 @@
     if (n->is_Allocate() || n->is_CallStaticJava() &&
         ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) {
       has_allocations = true;
+      if (n->is_Allocate())
+        alloc_worklist.append(n);
     }
     if(n->is_AddP()) {
       // Collect address nodes. Use them during stage 3 below
       // to build initial connection graph field edges.
-      cg_worklist.append(n->_idx);
+      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().
@@ -1576,10 +1584,9 @@
 
   // 3. Pass to create initial fields edges (JavaObject -F-> AddP)
   //    to reduce number of iterations during stage 4 below.
-  uint cg_length = cg_worklist.length();
-  for( uint next = 0; next < cg_length; ++next ) {
-    int ni = cg_worklist.at(next);
-    Node* n = ptnode_adr(ni)->_node;
+  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 = base->in(0);
@@ -1589,7 +1596,7 @@
     }
   }
 
-  cg_worklist.clear();
+  GrowableArray<int> cg_worklist;
   cg_worklist.append(_phantom_object);
   GrowableArray<uint>  worklist;
 
@@ -1648,73 +1655,44 @@
 
   Arena* arena = Thread::current()->resource_area();
   VectorSet visited(arena);
+
+  // 5. 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);
+    if (ptnode_adr(n->_idx)->escape_state() == PointsToNode::NoEscape) {
+      find_init_values(n, &visited, igvn);
+    }
+  }
+
   worklist.clear();
 
-  // 5. Remove deferred edges from the graph and adjust
-  //    escape state of nonescaping objects.
-  cg_length = cg_worklist.length();
-  for( uint next = 0; next < cg_length; ++next ) {
+  // 6. Remove deferred edges from the graph.
+  uint cg_length = cg_worklist.length();
+  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);
       Node *n = ptn->_node;
-      if (n->is_AddP()) {
-        // Search for objects which are not scalar replaceable
-        // and adjust their escape state.
-        adjust_escape_state(ni, igvn);
-      }
     }
   }
 
-  // 6. Propagate escape states.
-  worklist.clear();
-  bool has_non_escaping_obj = false;
-
-  // push all GlobalEscape nodes on the worklist
-  for( uint next = 0; next < cg_length; ++next ) {
-    int nk = cg_worklist.at(next);
-    if (ptnode_adr(nk)->escape_state() == PointsToNode::GlobalEscape)
-      worklist.push(nk);
-  }
-  // mark all nodes reachable from GlobalEscape nodes
-  while(worklist.length() > 0) {
-    PointsToNode* ptn = ptnode_adr(worklist.pop());
-    uint e_cnt = ptn->edge_count();
-    for (uint ei = 0; ei < e_cnt; ei++) {
-      uint npi = ptn->edge_target(ei);
-      PointsToNode *np = ptnode_adr(npi);
-      if (np->escape_state() < PointsToNode::GlobalEscape) {
-        np->set_escape_state(PointsToNode::GlobalEscape);
-        worklist.push(npi);
-      }
-    }
+  // 7. 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 ArgEscape nodes on the worklist
-  for( uint next = 0; next < cg_length; ++next ) {
-    int nk = cg_worklist.at(next);
-    if (ptnode_adr(nk)->escape_state() == PointsToNode::ArgEscape)
-      worklist.push(nk);
-  }
+  // 8. Propagate escape 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
-  while(worklist.length() > 0) {
-    PointsToNode* ptn = ptnode_adr(worklist.pop());
-    if (ptn->node_type() == PointsToNode::JavaObject)
-      has_non_escaping_obj = true; // Non GlobalEscape
-    uint e_cnt = ptn->edge_count();
-    for (uint ei = 0; ei < e_cnt; ei++) {
-      uint npi = ptn->edge_target(ei);
-      PointsToNode *np = ptnode_adr(npi);
-      if (np->escape_state() < PointsToNode::ArgEscape) {
-        np->set_escape_state(PointsToNode::ArgEscape);
-        worklist.push(npi);
-      }
-    }
-  }
-
-  GrowableArray<Node*> alloc_worklist;
+  bool has_non_escaping_obj = propagate_escape_state(&cg_worklist, &worklist, PointsToNode::ArgEscape);
 
   // push all NoEscape nodes on the worklist
   for( uint next = 0; next < cg_length; ++next ) {
@@ -1722,15 +1700,20 @@
     if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape)
       worklist.push(nk);
   }
+  alloc_worklist.clear();
   // mark all nodes reachable from NoEscape nodes
   while(worklist.length() > 0) {
-    PointsToNode* ptn = ptnode_adr(worklist.pop());
-    if (ptn->node_type() == PointsToNode::JavaObject)
-      has_non_escaping_obj = true; // Non GlobalEscape
+    uint nk = worklist.pop();
+    PointsToNode* ptn = ptnode_adr(nk);
+    if (ptn->node_type() == PointsToNode::JavaObject &&
+        !(nk == _noop_null || nk == _oop_null))
+      has_non_escaping_obj = true; // Non Escape
     Node* n = ptn->_node;
-    if (n->is_Allocate() && ptn->_scalar_replaceable ) {
+    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().
+      // for processing in split_unique_types(). Note,
+      // following code may change scalar_replaceable value.
       alloc_worklist.append(n);
     }
     uint e_cnt = ptn->edge_count();
@@ -1738,7 +1721,14 @@
       uint npi = ptn->edge_target(ei);
       PointsToNode *np = ptnode_adr(npi);
       if (np->escape_state() < PointsToNode::NoEscape) {
-        np->set_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) {
+        // Propagate scalar_replaceable value.
+        np->set_scalar_replaceable(false);
         worklist.push(npi);
       }
     }
@@ -1747,7 +1737,12 @@
   _collecting = false;
   assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
 
-  if (EliminateLocks) {
+  assert(ptnode_adr(_oop_null)->escape_state() == PointsToNode::NoEscape, "sanity");
+  if (UseCompressedOops) {
+    assert(ptnode_adr(_noop_null)->escape_state() == PointsToNode::NoEscape, "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++ ) {
@@ -1772,7 +1767,18 @@
   }
 #endif
 
-  bool has_scalar_replaceable_candidates = alloc_worklist.length() > 0;
+  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 ) {
 
@@ -1801,53 +1807,32 @@
   return has_non_escaping_obj;
 }
 
-// Adjust escape state after Connection Graph is built.
-void ConnectionGraph::adjust_escape_state(int nidx, PhaseTransform* phase) {
-  PointsToNode* ptn = ptnode_adr(nidx);
-  Node* n = ptn->_node;
-  assert(n->is_AddP(), "Should be called for AddP nodes only");
-  // Search for objects which are not scalar replaceable.
-  // Mark their escape state as ArgEscape to propagate the state
-  // to referenced objects.
-  // Note: currently there are no difference in compiler optimizations
-  // for ArgEscape objects and NoEscape objects which are not
-  // scalar replaceable.
+// 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;
-
-  int offset = ptn->offset();
-  Node* base = get_addp_base(n);
-  VectorSet* ptset = PointsTo(base);
-  int ptset_size = ptset->Size();
-
+  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.
   //
-  // 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
-  //
-  // Do a simple control flow analysis to distinguish above cases.
-  //
-  if (offset != Type::OffsetBot && ptset_size == 1) {
-    uint elem = ptset->getelem(); // Allocation node's index
-    // It does not matter if it is not Allocation node since
-    // only non-escaping allocations are scalar replaced.
-    if (ptnode_adr(elem)->_node->is_Allocate() &&
-        ptnode_adr(elem)->escape_state() == PointsToNode::NoEscape) {
-      AllocateNode* alloc = ptnode_adr(elem)->_node->as_Allocate();
-      InitializeNode* ini = alloc->initialization();
+  uint ae_cnt = pta->edge_count();
+  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 &&
+        offset != oopDesc::klass_offset_in_bytes() &&
+        !visited->test_set(offset)) {
 
       // Check only oop fields.
-      const Type* adr_type = n->as_AddP()->bottom_type();
+      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();
@@ -1857,12 +1842,20 @@
           // Ignore non field load (for example, klass load)
         }
       } else if (adr_type->isa_aryptr()) {
-        const Type* elemtype = adr_type->isa_aryptr()->elem();
-        basic_field_type = elemtype->array_element_basic_type();
+        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.
+        // 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 ||
@@ -1877,18 +1870,33 @@
             // Check for a store which follows allocation without branches.
             // For example, a volatile field store is not collected
             // by Initialize node. TODO: it would be nice to use idom() here.
-            for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-              store = n->fast_out(i);
-              if (store->is_Store() && store->in(0) != NULL) {
-                Node* ctrl = store->in(0);
-                while(!(ctrl == ini || ctrl == alloc || ctrl == NULL ||
-                        ctrl == C->root() || ctrl == C->top() || ctrl->is_Region() ||
-                        ctrl->is_IfTrue() || ctrl->is_IfFalse())) {
-                   ctrl = ctrl->in(0);
-                }
-                if (ctrl == ini || ctrl == alloc) {
-                  value = store->in(MemNode::ValueIn);
-                  break;
+            //
+            // Search all references to the same field which use different
+            // AddP nodes, for example, in the next case:
+            //
+            //    Point p[] = new Point[1];
+            //    if ( x ) { p[0] = new Point(); p[0].x = x; }
+            //    if ( p[0] != null ) { y = p[0].x; } // has CastPP
+            //
+            for (uint next = ei; (next < ae_cnt) && (value == NULL); next++) {
+              uint fpi = pta->edge_target(next); // Field (AddP)
+              PointsToNode *ptf = ptnode_adr(fpi);
+              if (ptf->offset() == offset) {
+                Node* nf = ptf->_node;
+                for (DUIterator_Fast imax, i = nf->fast_outs(imax); i < imax; i++) {
+                  store = nf->fast_out(i);
+                  if (store->is_Store() && store->in(0) != NULL) {
+                    Node* ctrl = store->in(0);
+                    while(!(ctrl == ini || ctrl == alloc || ctrl == NULL ||
+                            ctrl == C->root() || ctrl == C->top() || ctrl->is_Region() ||
+                            ctrl->is_IfTrue() || ctrl->is_IfFalse())) {
+                       ctrl = ctrl->in(0);
+                    }
+                    if (ctrl == ini || ctrl == alloc) {
+                      value = store->in(MemNode::ValueIn);
+                      break;
+                    }
+                  }
                 }
               }
             }
@@ -1897,21 +1905,35 @@
         if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
           // A field's initializing value was not recorded. Add NULL.
           uint null_idx = UseCompressedOops ? _noop_null : _oop_null;
-          add_pointsto_edge(nidx, null_idx);
+          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);
-      set_escape_state(npi, PointsToNode::ArgEscape);
-      ptnode_adr(npi)->_scalar_replaceable = false;
+      ptnode_adr(npi)->set_scalar_replaceable(false);
     }
   }
 
@@ -1930,20 +1952,62 @@
   // 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 scalar_replaceable to false)
+  // 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 ) {
-      set_escape_state(j.elem, PointsToNode::ArgEscape);
-      ptnode_adr(j.elem)->_scalar_replaceable = false;
+      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) {
+    PointsToNode* ptn = ptnode_adr(worklist->pop());
+    if (ptn->node_type() == PointsToNode::JavaObject) {
+      has_java_obj = true;
+    }
+    uint e_cnt = ptn->edge_count();
+    for (uint ei = 0; ei < e_cnt; ei++) {
+      uint npi = ptn->edge_target(ei);
+      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);
+}
+
 void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) {
 
     switch (call->Opcode()) {
@@ -2100,6 +2164,7 @@
       } 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);
@@ -2123,10 +2188,11 @@
       } 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)->_scalar_replaceable = false;
+          ptnode_adr(call_idx)->set_scalar_replaceable(false);
         }
       }
       set_escape_state(call_idx, es);
@@ -2168,11 +2234,12 @@
           // 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);
           add_pointsto_edge(resproj_idx, call_idx);
           copy_dependencies = true;
         } else if (call_analyzer->is_return_local()) {
           // determine whether any arguments are returned
-          set_escape_state(call_idx, PointsToNode::NoEscape);
+          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);
@@ -2189,7 +2256,6 @@
                   add_pointsto_edge(resproj_idx, arg->_idx);
                 else
                   add_deferred_edge(resproj_idx, arg->_idx);
-                arg_esp->_hidden_alias = true;
               }
             }
           }
@@ -2198,18 +2264,12 @@
             set_escape_state(call_idx, PointsToNode::GlobalEscape);
             add_pointsto_edge(resproj_idx, _phantom_object);
           }
-          copy_dependencies = true;
+          if (done) {
+            copy_dependencies = true;
+          }
         } else {
           set_escape_state(call_idx, PointsToNode::GlobalEscape);
           add_pointsto_edge(resproj_idx, _phantom_object);
-          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();
-              PointsToNode *arg_esp = ptnode_adr(arg->_idx);
-              arg_esp->_hidden_alias = true;
-            }
-          }
         }
         if (copy_dependencies)
           call_analyzer->copy_dependencies(_compile->dependencies());
--- a/hotspot/src/share/vm/opto/escape.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/escape.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -74,7 +74,7 @@
 // C2 does not have local variables.  However for the purposes of constructing
 // the connection graph, the following IR nodes are treated as local variables:
 //     Phi    (pointer values)
-//     LoadP
+//     LoadP, LoadN
 //     Proj#5 (value returned from callnodes including allocations)
 //     CheckCastPP, CastPP
 //
@@ -84,7 +84,7 @@
 //
 // The following node types are JavaObject:
 //
-//     top()
+//     phantom_object (general globally escaped object)
 //     Allocate
 //     AllocateArray
 //     Parm  (for incoming arguments)
@@ -93,6 +93,7 @@
 //     ConP
 //     LoadKlass
 //     ThreadLocal
+//     CallStaticJava (which returns Object)
 //
 // AddP nodes are fields.
 //
@@ -130,10 +131,12 @@
 
   typedef enum {
     UnknownEscape = 0,
-    NoEscape      = 1, // A scalar replaceable object with unique type.
-    ArgEscape     = 2, // An object passed as argument or referenced by
-                       // argument (and not globally escape during call).
-    GlobalEscape  = 3  // An object escapes the method and thread.
+    NoEscape      = 1, // An object does not escape method or thread and it is
+                       // not passed to call. It could be replaced with scalar.
+    ArgEscape     = 2, // An object does not escape method or thread but it is
+                       // passed as argument to call or referenced by argument
+                       // and it does not escape during call.
+    GlobalEscape  = 3  // An object escapes the method or thread.
   } EscapeState;
 
   typedef enum {
@@ -153,28 +156,25 @@
 
   NodeType             _type;
   EscapeState          _escape;
-  GrowableArray<uint>* _edges;   // outgoing edges
+  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
 
 public:
-  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  _hidden_alias;      // This node is an argument to a function.
-                            // which may return it creating a hidden alias.
-
   PointsToNode():
     _type(UnknownType),
     _escape(UnknownEscape),
     _edges(NULL),
     _node(NULL),
     _offset(-1),
-    _scalar_replaceable(true),
-    _hidden_alias(false) {}
+    _scalar_replaceable(true) {}
 
 
   EscapeState escape_state() const { return _escape; }
   NodeType node_type() const { return _type;}
   int offset() { return _offset;}
+  bool scalar_replaceable() { return _scalar_replaceable;}
 
   void set_offset(int offs) { _offset = offs;}
   void set_escape_state(EscapeState state) { _escape = state; }
@@ -182,6 +182,7 @@
     assert(_type == UnknownType || _type == ntype, "Can't change node type");
     _type = ntype;
   }
+  void set_scalar_replaceable(bool v) { _scalar_replaceable = v; }
 
   // count of outgoing edges
   uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
@@ -233,8 +234,8 @@
                                        // that pointer values loaded from
                                        // a field which has not been set
                                        // are assumed to point to.
-  uint                      _oop_null; // ConP(#NULL)
-  uint                     _noop_null; // ConN(#NULL)
+  uint                      _oop_null; // ConP(#NULL)->_idx
+  uint                     _noop_null; // ConN(#NULL)->_idx
 
   Compile *                  _compile; // Compile object for current compilation
   PhaseIterGVN *                _igvn; // Value numbering
@@ -339,8 +340,16 @@
   // 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(int nidx, PhaseTransform* phase);
+  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);
 
   // Compute the escape information
   bool compute_escape();
@@ -357,21 +366,6 @@
   // escape state of a node
   PointsToNode::EscapeState escape_state(Node *n);
 
-  // other information we have collected
-  bool is_scalar_replaceable(Node *n) {
-    if (_collecting || (n->_idx >= nodes_size()))
-      return false;
-    PointsToNode* ptn = ptnode_adr(n->_idx);
-    return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable;
-  }
-
-  bool hidden_alias(Node *n) {
-    if (_collecting || (n->_idx >= nodes_size()))
-      return true;
-    PointsToNode* ptn = ptnode_adr(n->_idx);
-    return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias;
-  }
-
 #ifndef PRODUCT
   void dump();
 #endif
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1883,7 +1883,7 @@
 //----------------------------build_and_optimize-------------------------------
 // Create a PhaseLoop.  Build the ideal Loop tree.  Map each Ideal Node to
 // its corresponding LoopNode.  If 'optimize' is true, do some loop cleanups.
-void PhaseIdealLoop::build_and_optimize(bool do_split_ifs) {
+void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts) {
   ResourceMark rm;
 
   int old_progress = C->major_progress();
@@ -2072,6 +2072,16 @@
   }
 #endif
 
+  if (skip_loop_opts) {
+    // Cleanup any modified bits
+    _igvn.optimize();
+
+    if (C->log() != NULL) {
+      log_loop_tree(_ltree_root, _ltree_root, C->log());
+    }
+    return;
+  }
+
   if (ReassociateInvariants) {
     // Reassociate invariants and prep for split_thru_phi
     for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
--- a/hotspot/src/share/vm/opto/loopnode.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/loopnode.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -747,11 +747,11 @@
     _dom_lca_tags(arena()), // Thread::resource_area
     _verify_me(NULL),
     _verify_only(true) {
-    build_and_optimize(false);
+    build_and_optimize(false, false);
   }
 
   // build the loop tree and perform any requested optimizations
-  void build_and_optimize(bool do_split_if);
+  void build_and_optimize(bool do_split_if, bool skip_loop_opts);
 
 public:
   // Dominators for the sea of nodes
@@ -762,13 +762,13 @@
   Node *dom_lca_internal( Node *n1, Node *n2 ) const;
 
   // Compute the Ideal Node to Loop mapping
-  PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs) :
+  PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs, bool skip_loop_opts = false) :
     PhaseTransform(Ideal_Loop),
     _igvn(igvn),
     _dom_lca_tags(arena()), // Thread::resource_area
     _verify_me(NULL),
     _verify_only(false) {
-    build_and_optimize(do_split_ifs);
+    build_and_optimize(do_split_ifs, skip_loop_opts);
   }
 
   // Verify that verify_me made the same decisions as a fresh run.
@@ -778,7 +778,7 @@
     _dom_lca_tags(arena()), // Thread::resource_area
     _verify_me(verify_me),
     _verify_only(false) {
-    build_and_optimize(false);
+    build_and_optimize(false, false);
   }
 
   // Build and verify the loop tree without modifying the graph.  This
--- a/hotspot/src/share/vm/opto/loopopts.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/loopopts.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -28,6 +28,7 @@
 #include "opto/connode.hpp"
 #include "opto/divnode.hpp"
 #include "opto/loopnode.hpp"
+#include "opto/matcher.hpp"
 #include "opto/mulnode.hpp"
 #include "opto/rootnode.hpp"
 #include "opto/subnode.hpp"
@@ -472,46 +473,50 @@
 // 1 or 2 items with a total of 1 or 2 ops executed speculatively.
 Node *PhaseIdealLoop::conditional_move( Node *region ) {
 
-  assert( region->is_Region(), "sanity check" );
-  if( region->req() != 3 ) return NULL;
+  assert(region->is_Region(), "sanity check");
+  if (region->req() != 3) return NULL;
 
   // Check for CFG diamond
   Node *lp = region->in(1);
   Node *rp = region->in(2);
-  if( !lp || !rp ) return NULL;
+  if (!lp || !rp) return NULL;
   Node *lp_c = lp->in(0);
-  if( lp_c == NULL || lp_c != rp->in(0) || !lp_c->is_If() ) return NULL;
+  if (lp_c == NULL || lp_c != rp->in(0) || !lp_c->is_If()) return NULL;
   IfNode *iff = lp_c->as_If();
 
-  // Check for highly predictable branch.  No point in CMOV'ing if
-  // we are going to predict accurately all the time.
-  // %%% This hides patterns produced by utility methods like Math.min.
-  if( iff->_prob < PROB_UNLIKELY_MAG(3) ||
-      iff->_prob > PROB_LIKELY_MAG(3) )
-    return NULL;
-
   // Check for ops pinned in an arm of the diamond.
   // Can't remove the control flow in this case
-  if( lp->outcnt() > 1 ) return NULL;
-  if( rp->outcnt() > 1 ) return NULL;
+  if (lp->outcnt() > 1) return NULL;
+  if (rp->outcnt() > 1) return NULL;
+
+  IdealLoopTree* r_loop = get_loop(region);
+  assert(r_loop == get_loop(iff), "sanity");
+  // Always convert to CMOVE if all results are used only outside this loop.
+  bool used_inside_loop = (r_loop == _ltree_root);
 
   // Check profitability
   int cost = 0;
   int phis = 0;
   for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
     Node *out = region->fast_out(i);
-    if( !out->is_Phi() ) continue; // Ignore other control edges, etc
+    if (!out->is_Phi()) continue; // Ignore other control edges, etc
     phis++;
     PhiNode* phi = out->as_Phi();
-    switch (phi->type()->basic_type()) {
-    case T_LONG:
-      cost++;                   // Probably encodes as 2 CMOV's
+    BasicType bt = phi->type()->basic_type();
+    switch (bt) {
+    case T_FLOAT:
+    case T_DOUBLE: {
+      cost += Matcher::float_cmove_cost(); // Could be very expensive
+      break;
+    }
+    case T_LONG: {
+      cost += Matcher::long_cmove_cost(); // May encodes as 2 CMOV's
+    }
     case T_INT:                 // These all CMOV fine
-    case T_FLOAT:
-    case T_DOUBLE:
-    case T_ADDRESS:             // (RawPtr)
+    case T_ADDRESS: {           // (RawPtr)
       cost++;
       break;
+    }
     case T_NARROWOOP: // Fall through
     case T_OBJECT: {            // Base oops are OK, but not derived oops
       const TypeOopPtr *tp = phi->type()->make_ptr()->isa_oopptr();
@@ -524,7 +529,7 @@
       // relevant bases.  This puts the allocator in the business of
       // manufacturing expensive instructions, generally a bad plan.
       // Just Say No to Conditionally-Moved Derived Pointers.
-      if( tp && tp->offset() != 0 )
+      if (tp && tp->offset() != 0)
         return NULL;
       cost++;
       break;
@@ -533,39 +538,64 @@
       return NULL;              // In particular, can't do memory or I/O
     }
     // Add in cost any speculative ops
-    for( uint j = 1; j < region->req(); j++ ) {
+    for (uint j = 1; j < region->req(); j++) {
       Node *proj = region->in(j);
       Node *inp = phi->in(j);
       if (get_ctrl(inp) == proj) { // Found local op
         cost++;
         // Check for a chain of dependent ops; these will all become
         // speculative in a CMOV.
-        for( uint k = 1; k < inp->req(); k++ )
+        for (uint k = 1; k < inp->req(); k++)
           if (get_ctrl(inp->in(k)) == proj)
-            return NULL;        // Too much speculative goo
+            cost += ConditionalMoveLimit; // Too much speculative goo
       }
     }
     // See if the Phi is used by a Cmp or Narrow oop Decode/Encode.
     // This will likely Split-If, a higher-payoff operation.
     for (DUIterator_Fast kmax, k = phi->fast_outs(kmax); k < kmax; k++) {
       Node* use = phi->fast_out(k);
-      if( use->is_Cmp() || use->is_DecodeN() || use->is_EncodeP() )
-        return NULL;
+      if (use->is_Cmp() || use->is_DecodeN() || use->is_EncodeP())
+        cost += ConditionalMoveLimit;
+      // Is there a use inside the loop?
+      // Note: check only basic types since CMoveP is pinned.
+      if (!used_inside_loop && is_java_primitive(bt)) {
+        IdealLoopTree* u_loop = get_loop(has_ctrl(use) ? get_ctrl(use) : use);
+        if (r_loop == u_loop || r_loop->is_member(u_loop)) {
+          used_inside_loop = true;
+        }
+      }
     }
   }
-  if( cost >= ConditionalMoveLimit ) return NULL; // Too much goo
   Node* bol = iff->in(1);
-  assert( bol->Opcode() == Op_Bool, "" );
+  assert(bol->Opcode() == Op_Bool, "");
   int cmp_op = bol->in(1)->Opcode();
   // It is expensive to generate flags from a float compare.
   // Avoid duplicated float compare.
-  if( phis > 1 && (cmp_op == Op_CmpF || cmp_op == Op_CmpD)) return NULL;
+  if (phis > 1 && (cmp_op == Op_CmpF || cmp_op == Op_CmpD)) return NULL;
+
+  float infrequent_prob = PROB_UNLIKELY_MAG(3);
+  // Ignore cost and blocks frequency if CMOVE can be moved outside the loop.
+  if (used_inside_loop) {
+    if (cost >= ConditionalMoveLimit) return NULL; // Too much goo
+
+    // BlockLayoutByFrequency optimization moves infrequent branch
+    // from hot path. No point in CMOV'ing in such case (110 is used
+    // instead of 100 to take into account not exactness of float value).
+    if (BlockLayoutByFrequency) {
+      infrequent_prob = MAX2(infrequent_prob, (float)BlockLayoutMinDiamondPercentage/110.0f);
+    }
+  }
+  // Check for highly predictable branch.  No point in CMOV'ing if
+  // we are going to predict accurately all the time.
+  if (iff->_prob < infrequent_prob ||
+      iff->_prob > (1.0f - infrequent_prob))
+    return NULL;
 
   // --------------
   // Now replace all Phis with CMOV's
   Node *cmov_ctrl = iff->in(0);
   uint flip = (lp->Opcode() == Op_IfTrue);
-  while( 1 ) {
+  while (1) {
     PhiNode* phi = NULL;
     for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
       Node *out = region->fast_out(i);
@@ -576,15 +606,15 @@
     }
     if (phi == NULL)  break;
 #ifndef PRODUCT
-    if( PrintOpto && VerifyLoopOptimizations ) tty->print_cr("CMOV");
+    if (PrintOpto && VerifyLoopOptimizations) tty->print_cr("CMOV");
 #endif
     // Move speculative ops
-    for( uint j = 1; j < region->req(); j++ ) {
+    for (uint j = 1; j < region->req(); j++) {
       Node *proj = region->in(j);
       Node *inp = phi->in(j);
       if (get_ctrl(inp) == proj) { // Found local op
 #ifndef PRODUCT
-        if( PrintOpto && VerifyLoopOptimizations ) {
+        if (PrintOpto && VerifyLoopOptimizations) {
           tty->print("  speculate: ");
           inp->dump();
         }
@@ -596,7 +626,15 @@
     register_new_node( cmov, cmov_ctrl );
     _igvn.replace_node( phi, cmov );
 #ifndef PRODUCT
-    if( VerifyLoopOptimizations ) verify();
+    if (TraceLoopOpts) {
+      tty->print("CMOV  ");
+      r_loop->dump_head();
+      if (Verbose) {
+        bol->in(1)->dump(1);
+        cmov->dump(1);
+      }
+    }
+    if (VerifyLoopOptimizations) verify();
 #endif
   }
 
@@ -676,14 +714,14 @@
 
   // Split 'n' through the merge point if it is profitable
   Node *phi = split_thru_phi( n, n_blk, policy );
-  if( !phi ) return n;
+  if (!phi) return n;
 
   // Found a Phi to split thru!
   // Replace 'n' with the new phi
   _igvn.replace_node( n, phi );
   // Moved a load around the loop, 'en-registering' something.
-  if( n_blk->Opcode() == Op_Loop && n->is_Load() &&
-      !phi->in(LoopNode::LoopBackControl)->is_Load() )
+  if (n_blk->is_Loop() && n->is_Load() &&
+      !phi->in(LoopNode::LoopBackControl)->is_Load())
     C->set_major_progress();
 
   return phi;
--- a/hotspot/src/share/vm/opto/machnode.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/machnode.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -484,6 +484,13 @@
   // Bind the offset lazily.
   if (offset == -1) {
     Compile::ConstantTable& constant_table = Compile::current()->constant_table();
+    // If called from Compile::scratch_emit_size assume the worst-case
+    // for load offsets: half the constant table size.
+    // NOTE: Don't return or calculate the actual offset (which might
+    // be zero) because that leads to problems with e.g. jumpXtnd on
+    // some architectures (cf. add-optimization in SPARC jumpXtnd).
+    if (Compile::current()->in_scratch_emit_size())
+      return constant_table.size() / 2;
     offset = constant_table.table_base_offset() + constant_table.find_offset(_constant);
     _constant.set_offset(offset);
   }
--- a/hotspot/src/share/vm/opto/matcher.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1915,7 +1915,7 @@
         set_dontcare(n);
         break;
       case Op_Jump:
-        mstack.push(n->in(1), Visit);         // Switch Value
+        mstack.push(n->in(1), Pre_Visit);     // Switch Value (could be shared)
         mstack.push(n->in(0), Pre_Visit);     // Visit Control input
         continue;                             // while (mstack.is_nonempty())
       case Op_StrComp:
--- a/hotspot/src/share/vm/opto/matcher.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -360,6 +360,12 @@
   // Anything this size or smaller may get converted to discrete scalar stores.
   static const int init_array_short_size;
 
+  // Some hardware needs 2 CMOV's for longs.
+  static const int long_cmove_cost();
+
+  // Some hardware have expensive CMOV for float and double.
+  static const int float_cmove_cost();
+
   // Should the Matcher clone shifts on addressing modes, expecting them to
   // be subsumed into complex addressing expressions or compute them into
   // registers?  True for Intel but false for most RISCs
--- a/hotspot/src/share/vm/opto/memnode.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1421,6 +1421,12 @@
     const TypeOopPtr *t_oop = addr_t->isa_oopptr();
     if (can_reshape && opt_mem->is_Phi() &&
         (t_oop != NULL) && t_oop->is_known_instance_field()) {
+      PhaseIterGVN *igvn = phase->is_IterGVN();
+      if (igvn != NULL && igvn->_worklist.member(opt_mem)) {
+        // Delay this transformation until memory Phi is processed.
+        phase->is_IterGVN()->_worklist.push(this);
+        return NULL;
+      }
       // Split instance field load through Phi.
       Node* result = split_through_phi(phase);
       if (result != NULL) return result;
--- a/hotspot/src/share/vm/opto/phaseX.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/phaseX.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -322,11 +322,12 @@
 void NodeHash::dump() {
   _total_inserts       += _inserts;
   _total_insert_probes += _insert_probes;
-  if( PrintCompilation && PrintOptoStatistics && Verbose && (_inserts > 0) ) { // PrintOptoGVN
-    if( PrintCompilation2 ) {
-      for( uint i=0; i<_max; i++ )
-      if( _table[i] )
-        tty->print("%d/%d/%d ",i,_table[i]->hash()&(_max-1),_table[i]->_idx);
+  if (PrintCompilation && PrintOptoStatistics && Verbose && (_inserts > 0)) {
+    if (WizardMode) {
+      for (uint i=0; i<_max; i++) {
+        if (_table[i])
+          tty->print("%d/%d/%d ",i,_table[i]->hash()&(_max-1),_table[i]->_idx);
+      }
     }
     tty->print("\nGVN Hash stats:  %d grows to %d max_size\n", _grows, _max);
     tty->print("  %d/%d (%8.1f%% full)\n", _inserts, _max, (double)_inserts/_max*100.0);
--- a/hotspot/src/share/vm/opto/runtime.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/runtime.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -338,6 +338,24 @@
     // inform GC that we won't do card marks for initializing writes.
     new_store_pre_barrier(thread);
   }
+
+  oop result = thread->vm_result();
+  if ((len > 0) && (result != NULL) &&
+      is_deoptimized_caller_frame(thread)) {
+    // Zero array here if the caller is deoptimized.
+    int size = ((typeArrayOop)result)->object_size();
+    BasicType elem_type = typeArrayKlass::cast(array_type)->element_type();
+    const size_t hs = arrayOopDesc::header_size(elem_type);
+    // Align to next 8 bytes to avoid trashing arrays's length.
+    const size_t aligned_hs = align_object_offset(hs);
+    HeapWord* obj = (HeapWord*)result;
+    if (aligned_hs > hs) {
+      Copy::zero_to_words(obj+hs, aligned_hs-hs);
+    }
+    // Optimized zeroing.
+    Copy::fill_to_aligned_words(obj+aligned_hs, size-aligned_hs);
+  }
+
 JRT_END
 
 // Note: multianewarray for one dimension is handled inline by GraphKit::new_array.
@@ -1130,12 +1148,22 @@
     assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
     frame caller_frame = stub_frame.sender(&reg_map);
 
-    // bypass VM_DeoptimizeFrame and deoptimize the frame directly
+    // Deoptimize the caller frame.
     Deoptimization::deoptimize_frame(thread, caller_frame.id());
   }
 }
 
 
+bool OptoRuntime::is_deoptimized_caller_frame(JavaThread *thread) {
+  // Called from within the owner thread, so no need for safepoint
+  RegisterMap reg_map(thread);
+  frame stub_frame = thread->last_frame();
+  assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check");
+  frame caller_frame = stub_frame.sender(&reg_map);
+  return caller_frame.is_deoptimized_frame();
+}
+
+
 const TypeFunc *OptoRuntime::register_finalizer_Type() {
   // create input type (domain)
   const Type **fields = TypeTuple::fields(1);
--- a/hotspot/src/share/vm/opto/runtime.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/opto/runtime.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -175,6 +175,7 @@
   static address handle_exception_C_helper(JavaThread* thread, nmethod*& nm);
   static address rethrow_C                (oopDesc* exception, JavaThread *thread, address return_pc );
   static void deoptimize_caller_frame     (JavaThread *thread, bool doit);
+  static bool is_deoptimized_caller_frame (JavaThread *thread);
 
   // CodeBlob support
   // ===================================================================
--- a/hotspot/src/share/vm/prims/jni.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/prims/jni.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -5042,7 +5042,8 @@
 void execute_internal_vm_tests() {
   if (ExecuteInternalVMTests) {
     assert(QuickSort::test_quick_sort(), "test_quick_sort failed");
-    tty->print_cr("All tests passed");
+    assert(arrayOopDesc::test_max_array_length(), "test_max_array_length failed");
+    tty->print_cr("All internal VM tests passed");
   }
 }
 
--- a/hotspot/src/share/vm/prims/jniCheck.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -107,7 +107,7 @@
     if (env != xenv) {                                                   \
       NativeReportJNIFatalError(thr, warn_wrong_jnienv);                 \
     }                                                                    \
-    __ENTRY(result_type, header, thr)
+    VM_ENTRY_BASE(result_type, header, thr)
 
 
 #define UNCHECKED() (unchecked_jni_NativeInterface)
--- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl	Tue Nov 29 12:04:55 2011 -0800
@@ -426,7 +426,7 @@
     <xsl:value-of select="$space"/>
     <xsl:text>ThreadInVMfromNative __tiv(current_thread);</xsl:text>
     <xsl:value-of select="$space"/>
-    <xsl:text>__ENTRY(jvmtiError, </xsl:text>
+    <xsl:text>VM_ENTRY_BASE(jvmtiError, </xsl:text>
     <xsl:apply-templates select="." mode="functionid"/>
     <xsl:text> , current_thread)</xsl:text>
     <xsl:value-of select="$space"/>
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -173,7 +173,7 @@
     // from native so as to resolve the jthread.
 
     ThreadInVMfromNative __tiv(current_thread);
-    __ENTRY(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)
+    VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)
     debug_only(VMNativeEntryWrapper __vew;)
 
     oop thread_oop = JNIHandles::resolve_external_guard(thread);
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -373,7 +373,7 @@
     JavaThread* current_thread = (JavaThread*) ThreadLocalStorage::thread();
     // transition code: native to VM
     ThreadInVMfromNative __tiv(current_thread);
-    __ENTRY(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)
+    VM_ENTRY_BASE(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)
     debug_only(VMNativeEntryWrapper __vew;)
 
     JvmtiEnv *jvmti_env = JvmtiEnv::create_a_jvmti(version);
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -206,9 +206,12 @@
   _adapter_code = MethodHandlesAdapterBlob::create(adapter_code_size);
   if (_adapter_code == NULL)
     vm_exit_out_of_memory(adapter_code_size, "CodeCache: no room for MethodHandles adapters");
-  CodeBuffer code(_adapter_code);
-  MethodHandlesAdapterGenerator g(&code);
-  g.generate();
+  {
+    CodeBuffer code(_adapter_code);
+    MethodHandlesAdapterGenerator g(&code);
+    g.generate();
+    code.log_section_sizes("MethodHandlesAdapterBlob");
+  }
 }
 
 //------------------------------------------------------------------------------
@@ -3079,26 +3082,26 @@
 JVM_END
 
 JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
-  oop call_site = JNIHandles::resolve_non_null(call_site_jh);
-  oop target    = JNIHandles::resolve(target_jh);
+  Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
+  Handle target   (THREAD, JNIHandles::resolve(target_jh));
   {
     // Walk all nmethods depending on this call site.
     MutexLocker mu(Compile_lock, thread);
     Universe::flush_dependents_on(call_site, target);
   }
-  java_lang_invoke_CallSite::set_target(call_site, target);
+  java_lang_invoke_CallSite::set_target(call_site(), target());
 }
 JVM_END
 
 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
-  oop call_site = JNIHandles::resolve_non_null(call_site_jh);
-  oop target    = JNIHandles::resolve(target_jh);
+  Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
+  Handle target   (THREAD, JNIHandles::resolve(target_jh));
   {
     // Walk all nmethods depending on this call site.
     MutexLocker mu(Compile_lock, thread);
     Universe::flush_dependents_on(call_site, target);
   }
-  java_lang_invoke_CallSite::set_target_volatile(call_site, target);
+  java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
 }
 JVM_END
 
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -302,21 +302,24 @@
 
 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);
-  // Catch VolatileCallSite.target stores (via
-  // CallSite.setTargetVolatile) and check call site dependencies.
-  if ((offset == java_lang_invoke_CallSite::target_offset_in_bytes()) && p->is_a(SystemDictionary::CallSite_klass())) {
-    oop call_site     = p;
-    oop method_handle = x;
-    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);
-    }
-  }
   void* addr = index_oop_from_field_offset_long(p, offset);
   OrderAccess::release();
   if (UseCompressedOops) {
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1577,18 +1577,9 @@
     sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
     add_property(buffer);
   }
-  if (AggressiveOpts && FLAG_IS_DEFAULT(DoEscapeAnalysis)) {
-    FLAG_SET_DEFAULT(DoEscapeAnalysis, true);
-  }
   if (AggressiveOpts && FLAG_IS_DEFAULT(BiasedLockingStartupDelay)) {
     FLAG_SET_DEFAULT(BiasedLockingStartupDelay, 500);
   }
-  if (AggressiveOpts && FLAG_IS_DEFAULT(OptimizeStringConcat)) {
-    FLAG_SET_DEFAULT(OptimizeStringConcat, true);
-  }
-  if (AggressiveOpts && FLAG_IS_DEFAULT(OptimizeFill)) {
-    FLAG_SET_DEFAULT(OptimizeFill, true);
-  }
 #endif
 
   if (AggressiveOpts) {
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -362,8 +362,6 @@
   intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames);
   // +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);
-  int callee_parameters = 0;
-  int callee_locals = 0;
   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
@@ -387,14 +385,16 @@
   // handles are used.  If the caller is interpreted get the real
   // value so that the proper amount of space can be added to it's
   // frame.
-  int caller_actual_parameters = callee_parameters;
+  bool caller_was_method_handle = false;
   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());
-    Symbol* signature = method->constants()->signature_ref_at(cur.index());
-    ArgumentSizeComputer asc(signature);
-    caller_actual_parameters = asc.size() + (cur.has_receiver() ? 1 : 0);
+    Bytecode_invoke cur = Bytecode_invoke_check(method, deopt_sender.interpreter_frame_bci());
+    if (cur.is_method_handle_invoke()) {
+      // 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.
+      caller_was_method_handle = true;
+    }
   }
 
   //
@@ -411,14 +411,15 @@
   // in the frame_sizes/frame_pcs so the assembly code can do a trivial walk.
   // so things look a little strange in this loop.
   //
+  int callee_parameters = 0;
+  int callee_locals = 0;
   for (int index = 0; index < array->frames(); index++ ) {
     // frame[number_of_frames - 1 ] = on_stack_size(youngest)
     // frame[number_of_frames - 2 ] = on_stack_size(sender(youngest))
     // frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest)))
     int caller_parms = callee_parameters;
-    if (index == array->frames() - 1) {
-      // Use the value from the interpreted caller
-      caller_parms = caller_actual_parameters;
+    if ((index == array->frames() - 1) && caller_was_method_handle) {
+      caller_parms = 0;
     }
     frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms,
                                                                                                     callee_parameters,
@@ -460,13 +461,13 @@
   // QQQ I'd rather see this pushed down into last_frame_adjust
   // and have it take the sender (aka caller).
 
-  if (deopt_sender.is_compiled_frame()) {
+  if (deopt_sender.is_compiled_frame() || caller_was_method_handle) {
     caller_adjustment = last_frame_adjust(0, callee_locals);
-  } else if (callee_locals > caller_actual_parameters) {
+  } else if (callee_locals > callee_parameters) {
     // The caller frame may need extending to accommodate
     // non-parameter locals of the first unpacked interpreted frame.
     // Compute that adjustment.
-    caller_adjustment = last_frame_adjust(caller_actual_parameters, callee_locals);
+    caller_adjustment = last_frame_adjust(callee_parameters, callee_locals);
   }
 
   // If the sender is deoptimized the we must retrieve the address of the handler
@@ -481,7 +482,7 @@
 
   UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
                                       caller_adjustment * BytesPerWord,
-                                      caller_actual_parameters,
+                                      caller_was_method_handle ? 0 : callee_parameters,
                                       number_of_frames,
                                       frame_sizes,
                                       frame_pcs,
--- a/hotspot/src/share/vm/runtime/frame.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1338,7 +1338,11 @@
     // Label values common to most frames
     values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no));
     values.describe(-1, sp(), err_msg("sp for #%d", frame_no));
-    values.describe(-1, fp(), err_msg("fp for #%d", frame_no));
+    if (is_compiled_frame()) {
+      values.describe(-1, sp() + _cb->frame_size(), err_msg("computed fp for #%d", frame_no));
+    } else {
+      values.describe(-1, fp(), err_msg("fp for #%d", frame_no));
+    }
   }
   if (is_interpreted_frame()) {
     methodOop m = interpreter_frame_method();
@@ -1450,9 +1454,8 @@
 }
 
 
-void FrameValues::print() {
+void FrameValues::print(JavaThread* thread) {
   _values.sort(compare);
-  JavaThread* thread = JavaThread::current();
 
   // Sometimes values like the fp can be invalid values if the
   // register map wasn't updated during the walk.  Trim out values
@@ -1460,12 +1463,22 @@
   int min_index = 0;
   int max_index = _values.length() - 1;
   intptr_t* v0 = _values.at(min_index).location;
-  while (!thread->is_in_stack((address)v0)) {
-    v0 = _values.at(++min_index).location;
-  }
   intptr_t* v1 = _values.at(max_index).location;
-  while (!thread->is_in_stack((address)v1)) {
-    v1 = _values.at(--max_index).location;
+
+  if (thread == Thread::current()) {
+    while (!thread->is_in_stack((address)v0)) {
+      v0 = _values.at(++min_index).location;
+    }
+    while (!thread->is_in_stack((address)v1)) {
+      v1 = _values.at(--max_index).location;
+    }
+  } else {
+    while (!thread->on_local_stack((address)v0)) {
+      v0 = _values.at(++min_index).location;
+    }
+    while (!thread->on_local_stack((address)v1)) {
+      v1 = _values.at(--max_index).location;
+    }
   }
   intptr_t* min = MIN2(v0, v1);
   intptr_t* max = MAX2(v0, v1);
--- a/hotspot/src/share/vm/runtime/frame.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/runtime/frame.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -516,7 +516,7 @@
   void describe(int owner, intptr_t* location, const char* description, int priority = 0);
 
   void validate();
-  void print();
+  void print(JavaThread* thread);
 };
 
 #endif
--- a/hotspot/src/share/vm/runtime/globals.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -577,8 +577,8 @@
   develop(bool, VerifyStack, false,                                         \
           "Verify stack of each thread when it is entering a runtime call") \
                                                                             \
-  develop(bool, ForceUnreachable, false,                                    \
-          "(amd64) Make all non code cache addresses to be unreachable with rip-rel forcing use of 64bit literal fixups") \
+  diagnostic(bool, ForceUnreachable, false,                                 \
+          "Make all non code cache addresses to be unreachable with forcing use of 64bit literal fixups") \
                                                                             \
   notproduct(bool, StressDerivedPointers, false,                            \
           "Force scavenge when a derived pointers is detected on stack "    \
@@ -904,7 +904,7 @@
   product(bool, AlwaysRestoreFPU, false,                                    \
           "Restore the FPU control word after every JNI call (expensive)")  \
                                                                             \
-  notproduct(bool, PrintCompilation2, false,                                \
+  diagnostic(bool, PrintCompilation2, false,                                \
           "Print additional statistics per compilation")                    \
                                                                             \
   diagnostic(bool, PrintAdapterHandlers, false,                             \
@@ -2580,7 +2580,7 @@
   diagnostic(bool, DebugInlinedCalls, true,                                 \
          "If false, restricts profiled locations to the root method only")  \
                                                                             \
-  product(bool, PrintVMOptions, NOT_EMBEDDED(trueInDebug) EMBEDDED_ONLY(false),\
+  product(bool, PrintVMOptions, false,                                      \
          "Print flags that appeared on the command line")                   \
                                                                             \
   product(bool, IgnoreUnrecognizedVMOptions, false,                         \
@@ -3364,7 +3364,7 @@
   notproduct(bool, ExitOnFullCodeCache, false,                              \
           "Exit the VM if we fill the code cache.")                         \
                                                                             \
-  product(bool, UseCodeCacheFlushing, false,                                \
+  product(bool, UseCodeCacheFlushing, true,                                 \
           "Attempt to clean the code cache before shutting off compiler")   \
                                                                             \
   product(intx,  MinCodeCacheFlushingInterval, 30,                          \
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp	Tue Nov 29 12:04:55 2011 -0800
@@ -72,9 +72,9 @@
   }
 };
 
-// InterfaceSupport provides functionality used by the __LEAF and __ENTRY
-// macros. These macros are used to guard entry points into the VM and
-// perform checks upon leave of the VM.
+// InterfaceSupport provides functionality used by the VM_LEAF_BASE and
+// VM_ENTRY_BASE macros. These macros are used to guard entry points into
+// the VM and perform checks upon leave of the VM.
 
 
 class InterfaceSupport: AllStatic {
@@ -433,7 +433,7 @@
 
 // LEAF routines do not lock, GC or throw exceptions
 
-#define __LEAF(result_type, header)                                  \
+#define VM_LEAF_BASE(result_type, header)                            \
   TRACE_CALL(result_type, header)                                    \
   debug_only(NoHandleMark __hm;)                                     \
   /* begin of body */
@@ -441,7 +441,7 @@
 
 // ENTRY routines may lock, GC and throw exceptions
 
-#define __ENTRY(result_type, header, thread)                         \
+#define VM_ENTRY_BASE(result_type, header, thread)                   \
   TRACE_CALL(result_type, header)                                    \
   HandleMarkCleaner __hm(thread);                                    \
   Thread* THREAD = thread;                                           \
@@ -450,7 +450,7 @@
 
 // QUICK_ENTRY routines behave like ENTRY but without a handle mark
 
-#define __QUICK_ENTRY(result_type, header, thread)                   \
+#define VM_QUICK_ENTRY_BASE(result_type, header, thread)             \
   TRACE_CALL(result_type, header)                                    \
   debug_only(NoHandleMark __hm;)                                     \
   Thread* THREAD = thread;                                           \
@@ -463,20 +463,20 @@
 #define IRT_ENTRY(result_type, header)                               \
   result_type header {                                               \
     ThreadInVMfromJava __tiv(thread);                                \
-    __ENTRY(result_type, header, thread)                             \
+    VM_ENTRY_BASE(result_type, header, thread)                       \
     debug_only(VMEntryWrapper __vew;)
 
 
 #define IRT_LEAF(result_type, header)                                \
   result_type header {                                               \
-    __LEAF(result_type, header)                                      \
+    VM_LEAF_BASE(result_type, header)                                \
     debug_only(No_Safepoint_Verifier __nspv(true);)
 
 
 #define IRT_ENTRY_NO_ASYNC(result_type, header)                      \
   result_type header {                                               \
     ThreadInVMfromJavaNoAsyncException __tiv(thread);                \
-    __ENTRY(result_type, header, thread)                             \
+    VM_ENTRY_BASE(result_type, header, thread)                       \
     debug_only(VMEntryWrapper __vew;)
 
 // Another special case for nmethod_entry_point so the nmethod that the
@@ -487,7 +487,7 @@
   result_type header {                                               \
     nmethodLocker _nmlock(nm);                                       \
     ThreadInVMfromJavaNoAsyncException __tiv(thread);                                \
-    __ENTRY(result_type, header, thread)
+    VM_ENTRY_BASE(result_type, header, thread)
 
 #define IRT_END }
 
@@ -497,20 +497,20 @@
 #define JRT_ENTRY(result_type, header)                               \
   result_type header {                                               \
     ThreadInVMfromJava __tiv(thread);                                \
-    __ENTRY(result_type, header, thread)                             \
+    VM_ENTRY_BASE(result_type, header, thread)                       \
     debug_only(VMEntryWrapper __vew;)
 
 
 #define JRT_LEAF(result_type, header)                                \
   result_type header {                                               \
-  __LEAF(result_type, header)                                        \
+  VM_LEAF_BASE(result_type, header)                                  \
   debug_only(JRT_Leaf_Verifier __jlv;)
 
 
 #define JRT_ENTRY_NO_ASYNC(result_type, header)                      \
   result_type header {                                               \
     ThreadInVMfromJavaNoAsyncException __tiv(thread);                \
-    __ENTRY(result_type, header, thread)                             \
+    VM_ENTRY_BASE(result_type, header, thread)                       \
     debug_only(VMEntryWrapper __vew;)
 
 // Same as JRT Entry but allows for return value after the safepoint
@@ -543,11 +543,11 @@
     assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
     ThreadInVMfromNative __tiv(thread);                              \
     debug_only(VMNativeEntryWrapper __vew;)                          \
-    __ENTRY(result_type, header, thread)
+    VM_ENTRY_BASE(result_type, header, thread)
 
 
 // Ensure that the VMNativeEntryWrapper constructor, which can cause
-// a GC, is called outside the NoHandleMark (set via __QUICK_ENTRY).
+// a GC, is called outside the NoHandleMark (set via VM_QUICK_ENTRY_BASE).
 #define JNI_QUICK_ENTRY(result_type, header)                         \
 extern "C" {                                                         \
   result_type JNICALL header {                                \
@@ -555,7 +555,7 @@
     assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
     ThreadInVMfromNative __tiv(thread);                              \
     debug_only(VMNativeEntryWrapper __vew;)                          \
-    __QUICK_ENTRY(result_type, header, thread)
+    VM_QUICK_ENTRY_BASE(result_type, header, thread)
 
 
 #define JNI_LEAF(result_type, header)                                \
@@ -563,7 +563,7 @@
   result_type JNICALL header {                                \
     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
     assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
-    __LEAF(result_type, header)
+    VM_LEAF_BASE(result_type, header)
 
 
 // Close the routine and the extern "C"
@@ -579,7 +579,7 @@
     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
     ThreadInVMfromNative __tiv(thread);                              \
     debug_only(VMNativeEntryWrapper __vew;)                          \
-    __ENTRY(result_type, header, thread)
+    VM_ENTRY_BASE(result_type, header, thread)
 
 
 #define JVM_ENTRY_NO_ENV(result_type, header)                        \
@@ -588,7 +588,7 @@
     JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();  \
     ThreadInVMfromNative __tiv(thread);                              \
     debug_only(VMNativeEntryWrapper __vew;)                          \
-    __ENTRY(result_type, header, thread)
+    VM_ENTRY_BASE(result_type, header, thread)
 
 
 #define JVM_QUICK_ENTRY(result_type, header)                         \
@@ -597,14 +597,14 @@
     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
     ThreadInVMfromNative __tiv(thread);                              \
     debug_only(VMNativeEntryWrapper __vew;)                          \
-    __QUICK_ENTRY(result_type, header, thread)
+    VM_QUICK_ENTRY_BASE(result_type, header, thread)
 
 
 #define JVM_LEAF(result_type, header)                                \
 extern "C" {                                                         \
   result_type JNICALL header {                                       \
     VM_Exit::block_if_vm_exited();                                   \
-    __LEAF(result_type, header)
+    VM_LEAF_BASE(result_type, header)
 
 
 #define JVM_END } }
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -1672,9 +1672,12 @@
   nmethod* nm = cb->as_nmethod_or_null();
   assert(nm, "must be");
 
-  // Don't fixup MethodHandle call sites as c2i/i2c adapters are used
-  // to implement MethodHandle actions.
-  if (nm->is_method_handle_return(caller_pc)) {
+  // 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;
   }
 
@@ -1693,8 +1696,8 @@
 
     // Expect to find a native call there (unless it was no-inline cache vtable dispatch)
     MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
-    if (NativeCall::is_call_before(caller_pc + frame::pc_return_offset)) {
-      NativeCall *call = nativeCall_before(caller_pc + frame::pc_return_offset);
+    if (NativeCall::is_call_before(return_pc)) {
+      NativeCall *call = nativeCall_before(return_pc);
       //
       // bug 6281185. We might get here after resolving a call site to a vanilla
       // virtual call. Because the resolvee uses the verified entry it may then
@@ -1744,7 +1747,6 @@
       }
     }
   }
-
 IRT_END
 
 
--- a/hotspot/src/share/vm/runtime/thread.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -2947,7 +2947,7 @@
     values.validate();
   } else {
     tty->print_cr("[Describe stack layout]");
-    values.print();
+    values.print(this);
   }
 }
 #endif
--- a/hotspot/src/share/vm/services/heapDumper.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/services/heapDumper.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -27,6 +27,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "gc_implementation/shared/vmGCOperations.hpp"
+#include "memory/gcLocker.inline.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/universe.hpp"
 #include "oops/objArrayKlass.hpp"
@@ -1709,11 +1710,16 @@
 
   HandleMark hm;
   CollectedHeap* ch = Universe::heap();
+
+  ch->ensure_parsability(false); // must happen, even if collection does
+                                 // not happen (e.g. due to GC_locker)
+
   if (_gc_before_heap_dump) {
-    ch->collect_as_vm_thread(GCCause::_heap_dump);
-  } else {
-    // make the heap parsable (no need to retire TLABs)
-    ch->ensure_parsability(false);
+    if (GC_locker::is_active()) {
+      warning("GC locker is held; pre-heapdump GC was skipped");
+    } else {
+      ch->collect_as_vm_thread(GCCause::_heap_dump);
+    }
   }
 
   // At this point we should be the only dumper active, so
--- a/hotspot/src/share/vm/utilities/quickSort.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/utilities/quickSort.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -23,13 +23,13 @@
  */
 
 #include "precompiled.hpp"
-#include "utilities/quickSort.hpp"
+
+/////////////// Unit tests ///////////////
 
 #ifndef PRODUCT
 
-// Unit tests
-
 #include "runtime/os.hpp"
+#include "utilities/quickSort.hpp"
 #include <stdlib.h>
 
 static int test_comparator(int a, int b) {
@@ -94,7 +94,7 @@
 }
 
 bool QuickSort::test_quick_sort() {
-  tty->print_cr("test_quick_sort\n");
+  tty->print_cr("test_quick_sort");
   {
     int* test_array = NULL;
     int* expected_array = NULL;
--- a/hotspot/src/share/vm/utilities/vmError.cpp	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.cpp	Tue Nov 29 12:04:55 2011 -0800
@@ -680,8 +680,10 @@
   STEP(190, "(printing heap information)" )
 
      if (_verbose && Universe::is_fully_initialized()) {
-       // print heap information before vm abort
-       Universe::print_on(st);
+       // Print heap information before vm abort. As we'd like as much
+       // information as possible in the report we ask for the
+       // extended (i.e., more detailed) version.
+       Universe::print_on(st, true /* extended */);
        st->cr();
      }
 
--- a/hotspot/test/Makefile	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/test/Makefile	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 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
@@ -219,6 +219,15 @@
 
 ################################################################
 
+# internalvmtests (run internal unit tests inside the VM)
+
+internalvmtests: prep $(PRODUCT_HOME)
+	$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -XX:+ExecuteInternalVMTests -version
+
+PHONY_LIST += internalvmtests
+
+################################################################
+
 # packtest
 
 # Expect JPRT to set JPRT_PACKTEST_HOME.
--- a/hotspot/test/compiler/6865265/StackOverflowBug.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/hotspot/test/compiler/6865265/StackOverflowBug.java	Tue Nov 29 12:04:55 2011 -0800
@@ -28,7 +28,7 @@
  * @summary JVM crashes with "missing exception handler" error
  * @author volker.simonis@sap.com
  *
- * @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss128k StackOverflowBug
+ * @run main/othervm -XX:CompileThreshold=100 -Xbatch -Xss224k StackOverflowBug
  */
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/7103261/Test7103261.java	Tue Nov 29 12:04:55 2011 -0800
@@ -0,0 +1,107 @@
+/*
+ * 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 7103261
+ * @summary crash with jittester on sparc
+ *
+ * @run main Test7103261
+ */
+
+// exercise implicit null checking in the compiler for various field types
+public class Test7103261 {
+    static Test7103261 null_value;
+    static Test7103261 nonnull_value = new Test7103261();
+    static Test7103261 nonnull_value2 = new Test7103261();
+
+    long l;
+    int i;
+    float f;
+    double d;
+    byte b;
+    char c;
+    short s;
+    boolean z;
+
+    public static void main(String[] args) {
+        constantStore();
+        valueTest(false);
+        valueTest(true);
+    }
+    static void constantStore() {
+        for (int field = 0; field < 8; field++) {
+            try {
+                Test7103261 o = nonnull_value;
+                for (int i = 0; i < 100000; i++) {
+                    switch (field) {
+                    case 0: o.l = 0; break;
+                    case 1: o.i = 0; break;
+                    case 2: o.f = 0; break;
+                    case 3: o.d = 0; break;
+                    case 4: o.b = 0; break;
+                    case 5: o.c = 0; break;
+                    case 6: o.s = 0; break;
+                    case 7: o.z = false; break;
+                    default: throw new InternalError();
+                    }
+                    if (i == 90000) {
+                        // hide nullness from optimizer
+                        o = null_value;
+                    }
+                }
+            } catch (NullPointerException npe) {
+            }
+        }
+    }
+    static void valueTest(boolean store) {
+        for (int field = 0; field < 8; field++) {
+            try {
+                Test7103261 o  = nonnull_value;
+                Test7103261 o2 = nonnull_value2;
+                for (int i = 0; i < 100000; i++) {
+                    switch (field) {
+                    case 0: o.l = o2.l; break;
+                    case 1: o.i = o2.i; break;
+                    case 2: o.f = o2.f; break;
+                    case 3: o.d = o2.d; break;
+                    case 4: o.b = o2.b; break;
+                    case 5: o.c = o2.c; break;
+                    case 6: o.s = o2.s; break;
+                    case 7: o.z = o2.z; break;
+                    default: throw new InternalError();
+                    }
+                    if (i == 90000) {
+                        // hide nullness from optimizer
+                        if (store)
+                            o = null_value;
+                        else
+                            o2 = null_value;
+                    }
+                }
+            } catch (NullPointerException npe) {
+            }
+        }
+    }
+}
--- a/jaxp/.hgtags	Tue Nov 29 11:39:59 2011 -0800
+++ b/jaxp/.hgtags	Tue Nov 29 12:04:55 2011 -0800
@@ -135,3 +135,4 @@
 d1b7a4f6dd2065fdeafbcdfd9dcc0072da8c6881 jdk8-b11
 ca977d167697a561c04894187fc1c4d927582ffa jdk8-b12
 bcc739229f6384786c7ac0b52c1822c85674dcf1 jdk8-b13
+9d0c9d638757cb09de18933b946fa04b4f3fb94f jdk8-b14
--- a/jaxws/.hgtags	Tue Nov 29 11:39:59 2011 -0800
+++ b/jaxws/.hgtags	Tue Nov 29 12:04:55 2011 -0800
@@ -135,3 +135,4 @@
 a12ab897a249feb7859a6e6cd84b49411f4c06ac jdk8-b11
 e6eed2ff5d5f62bdc815beb5276d23347600c760 jdk8-b12
 adf2a6b5fde14090beb9ebc40c4114132ddee731 jdk8-b13
+54c4bf4b83ecc191351747d5d28da849d34c0243 jdk8-b14
--- a/jdk/src/share/classes/java/lang/invoke/CallSite.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java	Tue Nov 29 12:04:55 2011 -0800
@@ -266,7 +266,7 @@
 
     /*package-private*/
     void setTargetNormal(MethodHandle newTarget) {
-        target = newTarget;
+        MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
     }
     /*package-private*/
     MethodHandle getTargetVolatile() {
@@ -274,7 +274,7 @@
     }
     /*package-private*/
     void setTargetVolatile(MethodHandle newTarget) {
-        unsafe.putObjectVolatile(this, TARGET_OFFSET, newTarget);
+        MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
     }
 
     // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Nov 29 12:04:55 2011 -0800
@@ -934,12 +934,4 @@
         return THROW_EXCEPTION;
     }
     static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
-
-    // Linkage support:
-    static void registerBootstrap(Class<?> callerClass, MethodHandle bootstrapMethod) {
-        MethodHandleNatives.registerBootstrap(callerClass, bootstrapMethod);
-    }
-    static MethodHandle getBootstrap(Class<?> callerClass) {
-        return MethodHandleNatives.getBootstrap(callerClass);
-    }
 }
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Tue Nov 29 12:04:55 2011 -0800
@@ -61,15 +61,6 @@
     /** Initialize a method type, once per form. */
     static native void init(MethodType self);
 
-    /** Tell the JVM about a class's bootstrap method. */
-    static native void registerBootstrap(Class<?> caller, MethodHandle bootstrapMethod);
-
-    /** Ask the JVM about a class's bootstrap method. */
-    static native MethodHandle getBootstrap(Class<?> caller);
-
-    /** Tell the JVM that we need to change the target of an invokedynamic. */
-    static native void setCallSiteTarget(CallSite site, MethodHandle target);
-
     /** Fetch the vmtarget field.
      *  It will be sanitized as necessary to avoid exposing non-Java references.
      *  This routine is for debugging and reflection.
@@ -122,6 +113,12 @@
 
     static final boolean COUNT_GWT;
 
+    /// CallSite support
+
+    /** Tell the JVM that we need to change the target of a CallSite. */
+    static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
+    static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
+
     private static native void registerNatives();
     static {
         registerNatives();
--- a/jdk/src/share/native/sun/awt/medialib/mlib_types.h	Tue Nov 29 11:39:59 2011 -0800
+++ b/jdk/src/share/native/sun/awt/medialib/mlib_types.h	Tue Nov 29 12:04:55 2011 -0800
@@ -59,13 +59,8 @@
 
 #if defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__GNUC__)
 
-#if defined(__linux__)
-#include <stdint.h>                     /* for uintptr_t */
-#include <malloc.h>                     /* for ptrdiff_t */
-#else
-#include <link.h>                       /* for uintptr_t */
-#include <stddef.h>                     /* for ptrdiff_t */
-#endif  /* __linux__ */
+#include <stdint.h>
+#include <stddef.h>
 
 #ifdef MLIB_OS64BIT
 
--- a/jdk/test/ProblemList.txt	Tue Nov 29 11:39:59 2011 -0800
+++ b/jdk/test/ProblemList.txt	Tue Nov 29 12:04:55 2011 -0800
@@ -195,9 +195,6 @@
 
 # jdk_lang
 
-# requires junit
-java/lang/invoke/InvokeDynamicPrintArgs.java                    generic-all
-
 # 7079093
 java/lang/instrument/ManifestTest.sh                            windows-all
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/CallSiteTest.java	Tue Nov 29 12:04:55 2011 -0800
@@ -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");
+    }
+}
--- a/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/jdk/test/java/lang/invoke/InvokeDynamicPrintArgs.java	Tue Nov 29 12:04:55 2011 -0800
@@ -38,8 +38,6 @@
 
 package test.java.lang.invoke;
 
-import org.junit.Test;
-
 import java.util.*;
 import java.io.*;
 
@@ -99,21 +97,6 @@
         System.setSecurityManager(new SM());
     }
 
-    @Test
-    public void testInvokeDynamicPrintArgs() throws IOException {
-        System.err.println(System.getProperties());
-        String testClassPath = System.getProperty("build.test.classes.dir");
-        if (testClassPath == null)  throw new RuntimeException();
-        String[] args = new String[]{
-            "--verify-specifier-count=3",
-            "--verbose",
-            "--expand-properties", "--classpath", testClassPath,
-            "--java", "test.java.lang.invoke.InvokeDynamicPrintArgs", "--check-output"
-        };
-        System.err.println("Indify: "+Arrays.toString(args));
-        indify.Indify.main(args);
-    }
-
     private static PrintStream oldOut;
     private static ByteArrayOutputStream buf;
     private static void openBuf() {
--- a/langtools/.hgtags	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/.hgtags	Tue Nov 29 12:04:55 2011 -0800
@@ -135,3 +135,4 @@
 4bf01f1c4e3464f378959d10f3983a0469181d94 jdk8-b11
 f2d6ed25857dfa7f269ac66e13666d648cb988c6 jdk8-b12
 ae25163501bc7477cd907e26a006a6f1b05fdb6d jdk8-b13
+58f1325d72b2bacc901f5189ee5e4e81e81ea657 jdk8-b14
--- a/langtools/make/build.properties	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/make/build.properties	Tue Nov 29 12:04:55 2011 -0800
@@ -196,3 +196,7 @@
 # An empty value means all tests
 # Override as desired to run a specific set of tests
 jtreg.tests =
+
+# Check style configuration
+# overridable name and version
+checkstyle.name.version = checkstyle-5.4
--- a/langtools/make/build.xml	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/make/build.xml	Tue Nov 29 12:04:55 2011 -0800
@@ -131,8 +131,10 @@
     <property name="dist.bin.dir" location="${dist.dir}/bin"/>
     <property name="dist.coverage.dir" location="${dist.dir}/coverage"/>
     <property name="dist.findbugs.dir" location="${dist.dir}/findbugs"/>
+    <property name="dist.checkstyle.dir" location="${dist.dir}/checkstyle"/>
     <property name="dist.lib.dir" location="${dist.dir}/lib"/>
     <property name="make.dir" location="make"/>
+    <property name="make.conf.dir" location="${make.dir}/conf"/>
     <property name="make.tools.dir" location="${make.dir}/tools"/>
     <property name="src.dir" location="src"/>
     <property name="src.bin.dir" location="${src.dir}/share/bin"/>
@@ -263,6 +265,41 @@
         <jtreg-tool name="all" tests="${jtreg.tests}"/>
     </target>
 
+    <target name="checkstyle" depends="-def-checkstyle"
+        description="Generates reports for code convention violations.">
+        <mkdir dir="${dist.checkstyle.dir}"/>
+        <checkstyle config="${make.conf.dir}/checkstyle-langtools.xml"
+              failureProperty="checkstyle.failure"
+              failOnViolation="false">
+            <formatter type="xml" tofile="${dist.checkstyle.dir}/checkstyle_report.xml"/>
+            <fileset dir="src" includes="**/*.java, **/*.properties"/>
+        </checkstyle>
+        <!-- transform the output to a simple html -->
+        <xslt  in="${dist.checkstyle.dir}/checkstyle_report.xml"
+               out="${dist.checkstyle.dir}/checkstyle_report.html"
+               style="${checkstyle.home}/contrib/checkstyle-simple.xsl"/>            
+        <!-- transform the output to a very simple emacs friendly text file -->
+        <xslt  in="${dist.checkstyle.dir}/checkstyle_report.xml"
+               out="${dist.checkstyle.dir}/checkstyle_report.tmp"
+               style="${make.conf.dir}/checkstyle-emacs.xsl"/>
+        <!-- beautify remove extra lines -->
+        <move file="${dist.checkstyle.dir}/checkstyle_report.tmp"
+             toFile="${dist.checkstyle.dir}/checkstyle_report.emacs.txt">
+            <filterchain>
+                <ignoreblank/>
+                <replaceregex byline="true" pattern="^File:" replace="${line.separator}File:"/>
+            </filterchain>
+        </move>
+    </target>
+    <!-- target can be invoked from an ide, the output of which can be used
+         to access and fix the errors directly.
+     -->
+    <target name="checkstyle-ide" depends="checkstyle">
+        <concat>
+            <fileset file="${dist.checkstyle.dir}/checkstyle_report.emacs.txt"/>
+        </concat>  
+    </target>
+    
     <target name="findbugs" depends="-def-findbugs,build-all-tools">
         <property name="findbugs.reportLevel" value="medium"/>
         <mkdir dir="${dist.findbugs.dir}"/>
@@ -406,6 +443,7 @@
         <echo level="info">target.java.home = ${target.java.home}</echo>
         <echo level="info">jtreg.home = ${jtreg.home}</echo>
         <echo level="info">findbugs.home = ${findbugs.home}</echo>
+        <echo level="info">checkstyle.home = ${checkstyle.home}</echo>
     </target>
 
     <target name="post-sanity" depends="-def-jtreg,sanity,build"
@@ -690,6 +728,10 @@
         <check name="findbugs" property="findbugs.home" marker="lib/findbugs.jar"/>
     </target>
 
+    <target name="-check-checkstyle.home" depends="-def-check">
+        <check name="checkstyle" property="checkstyle.home" marker="${checkstyle.name.version}.jar"/>
+    </target>
+    
     <target name="-check-jtreg.home" depends="-def-check">
         <check name="jtreg" property="jtreg.home" marker="lib/jtreg.jar"/>
     </target>
@@ -989,6 +1031,16 @@
         <taskdef classpathref="cobertura.classpath" resource="tasks.properties"/>
     </target>
 
+    <target name="-def-checkstyle" unless="checkstyle.defined"
+        depends="-check-checkstyle.home">
+        <taskdef resource="checkstyletask.properties">
+            <classpath>
+                <pathelement location="${checkstyle.home}/${checkstyle.name.version}-all.jar"/>
+            </classpath>
+        </taskdef>
+        <property name="checkstyle.defined" value="true"/>
+    </target>
+    
     <target name="-def-findbugs" unless="findbugs.defined"
         depends="-check-findbugs.home,-check-target.java.home">
         <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/make/conf/checkstyle-emacs.xsl	Tue Nov 29 12:04:55 2011 -0800
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="text" omit-xml-declaration="yes"/>
+
+<xsl:template match="/">
+Coding Style Check Results
+--------------------------
+Total files checked: <xsl:number level="any" value="count(descendant::file)"/>
+  Files with errors: <xsl:number level="any" value="count(descendant::file[error])"/>
+       Total errors: <xsl:number level="any" value="count(descendant::error)"/>
+    Errors per file: <xsl:number level="any" value="count(descendant::error) div count(descendant::file)"/>
+<xsl:apply-templates/>
+</xsl:template>
+
+<xsl:template match="file[error]">
+<xsl:apply-templates select="error"/>
+</xsl:template>
+
+<xsl:template match="error">
+<xsl:value-of select="../@name"/>:<xsl:value-of select="@line"/><xsl:text>: </xsl:text><xsl:value-of select="@message"/><xsl:text>
+</xsl:text>
+</xsl:template>
+
+</xsl:stylesheet>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/make/conf/checkstyle-langtools.xml	Tue Nov 29 12:04:55 2011 -0800
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+          "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
+          "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+   Checks for initial langtools code conventions, we are starting with
+   imports and import orders and this will grow to encompass other
+   violations over time. 
+-->
+
+<module name="Checker">
+    
+    <!-- Checks for whitespace. -->
+    <module name="FileTabCharacter">
+        <property name="fileExtensions" value=".java"/>
+    </module>
+
+    <!-- Miscellaneous other checks.                   -->
+    <module name="RegexpSingleline">
+        <property name="format" value="\s+$"/>
+        <property name="minimum" value="0"/>
+        <property name="maximum" value="0"/>
+        <property name="message" value="Line has trailing spaces."/>
+        <property name="fileExtensions" value=".java .html"/>
+    </module>
+
+    <module name="TreeWalker">
+    <!-- Checks for imports                              -->
+    <!--
+        <module name="AvoidStarImport"/>
+        <module name="IllegalImport"/>
+    -->
+        <module name="GenericWhitespace"/>
+        <module name="RedundantImport"/>
+        <module name="UnusedImports"/>  
+        <module name="ImportOrder">
+            <property name="groups" value="java, javax, org, com"/>
+            <property name="ordered" value="true"/>
+            <property name="separated" value="true"/>
+        </module>        
+        <module name="EmptyForInitializerPad">
+            <property name="option" value="space"/>
+        </module>
+        <module name="WhitespaceAfter"/>
+    </module>
+</module>
\ No newline at end of file
--- a/langtools/src/share/classes/com/sun/tools/apt/comp/Apt.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/apt/comp/Apt.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -214,7 +214,7 @@
                      AnnotationProcessorFactory providedFactory,
                      java.util.Set<Class<? extends AnnotationProcessorFactory> > productiveFactories) {
         Bark bark = Bark.instance(context);
-        java.io.PrintWriter out = bark.warnWriter;
+        java.io.PrintWriter out = bark.getWriter(Log.WriterKind.WARNING);
         Options options = Options.instance(context);
 
         Collection<TypeDeclaration> spectypedecls =     new LinkedHashSet<TypeDeclaration>();
--- a/langtools/src/share/classes/com/sun/tools/apt/main/Main.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/apt/main/Main.java	Tue Nov 29 12:04:55 2011 -0800
@@ -205,7 +205,7 @@
             String s = "  " + helpSynopsis();
             out.print(s);
             for (int j = s.length(); j < 29; j++) out.print(" ");
-            Bark.printLines(out, getLocalizedString(descrKey));
+            Bark.printRawLines(out, getLocalizedString(descrKey));
         }
 
     }
@@ -227,7 +227,7 @@
             String s = "  " + helpSynopsis();
             out.print(s);
             for (int j = s.length(); j < 29; j++) out.print(" ");
-            Bark.printLines(out, getLocalizedString(descrKey));
+            Bark.printRawLines(out, getLocalizedString(descrKey));
         }
 
     }
@@ -259,7 +259,7 @@
             String s = "  " + helpSynopsis();
             out.print(s);
             for (int j = s.length(); j < 29; j++) out.print(" ");
-            Log.printLines(out, getLocalizedString(descrKey));
+            Log.printRawLines(out, getLocalizedString(descrKey));
         }
     };
 
@@ -421,7 +421,7 @@
         },
         new AptOption("-version",               "opt.version") {
             boolean process(String option) {
-                Bark.printLines(out, ownName + " " + AptJavaCompiler.version());
+                Bark.printRawLines(out, ownName + " " + AptJavaCompiler.version());
                 return super.process(option);
             }
         },
@@ -660,11 +660,11 @@
     /** Print a string that explains usage.
      */
     void help() {
-        Bark.printLines(out, getLocalizedString("msg.usage.header", ownName));
+        Bark.printRawLines(out, getLocalizedString("msg.usage.header", ownName));
         for (int i=0; i < recognizedOptions.length; i++) {
             recognizedOptions[i].help();
         }
-        Bark.printLines(out, getLocalizedString("msg.usage.footer"));
+        Bark.printRawLines(out, getLocalizedString("msg.usage.footer"));
         out.println();
     }
 
@@ -675,7 +675,7 @@
             recognizedOptions[i].xhelp();
         }
         out.println();
-        Bark.printLines(out, getLocalizedString("msg.usage.nonstandard.footer"));
+        Bark.printRawLines(out, getLocalizedString("msg.usage.nonstandard.footer"));
     }
 
     /** Report a usage error.
@@ -688,7 +688,7 @@
     /** Report a warning.
      */
     void warning(String key, Object... args) {
-        Bark.printLines(out, ownName + ": "
+        Bark.printRawLines(out, ownName + ": "
                        + getLocalizedString(key, args));
     }
 
@@ -796,7 +796,7 @@
             origFilenames = processArgs((args=CommandLine.parse(args)));
 
             if (options.get("suppress-tool-api-removal-message") == null) {
-                Bark.printLines(out, getLocalizedString("misc.Deprecation"));
+                Bark.printRawLines(out, getLocalizedString("misc.Deprecation"));
             }
 
             if (origFilenames == null) {
@@ -808,7 +808,7 @@
                     return EXIT_OK;
             }
         } catch (java.io.FileNotFoundException e) {
-            Bark.printLines(out, ownName + ": " +
+            Bark.printRawLines(out, ownName + ": " +
                            getLocalizedString("err.file.not.found",
                                               e.getMessage()));
             return EXIT_SYSERR;
@@ -1183,7 +1183,7 @@
     /** Print a message reporting an internal error.
      */
     void bugMessage(Throwable ex) {
-        Bark.printLines(out, getLocalizedString("msg.bug",
+        Bark.printRawLines(out, getLocalizedString("msg.bug",
                                                AptJavaCompiler.version()));
         ex.printStackTrace(out);
     }
@@ -1191,34 +1191,34 @@
     /** Print a message reporting an fatal error.
      */
     void apMessage(AnnotationProcessingError ex) {
-        Bark.printLines(out, getLocalizedString("misc.Problem"));
+        Bark.printRawLines(out, getLocalizedString("misc.Problem"));
         ex.getCause().printStackTrace(out);
     }
 
     /** Print a message about sun.misc.Service problem.
      */
     void sceMessage(sun.misc.ServiceConfigurationError ex) {
-        Bark.printLines(out, getLocalizedString("misc.SunMiscService"));
+        Bark.printRawLines(out, getLocalizedString("misc.SunMiscService"));
         ex.printStackTrace(out);
     }
 
     /** Print a message reporting an fatal error.
      */
     void feMessage(Throwable ex) {
-        Bark.printLines(out, ex.toString());
+        Bark.printRawLines(out, ex.toString());
     }
 
     /** Print a message reporting an input/output error.
      */
     void ioMessage(Throwable ex) {
-        Bark.printLines(out, getLocalizedString("msg.io"));
+        Bark.printRawLines(out, getLocalizedString("msg.io"));
         ex.printStackTrace(out);
     }
 
     /** Print a message reporting an out-of-resources error.
      */
     void resourceMessage(Throwable ex) {
-        Bark.printLines(out, getLocalizedString("msg.resource"));
+        Bark.printRawLines(out, getLocalizedString("msg.resource"));
         ex.printStackTrace(out);
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTool.java	Tue Nov 29 12:04:55 2011 -0800
@@ -52,6 +52,7 @@
 import com.sun.tools.javac.util.ClientCodeException;
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.PrefixKind;
 import com.sun.tools.javac.util.Options;
 import com.sun.tools.javac.util.Pair;
 
@@ -156,15 +157,28 @@
         return new JavacFileManager(context, true, charset);
     }
 
+    @Override
     public JavacTask getTask(Writer out,
                              JavaFileManager fileManager,
                              DiagnosticListener<? super JavaFileObject> diagnosticListener,
                              Iterable<String> options,
                              Iterable<String> classes,
-                             Iterable<? extends JavaFileObject> compilationUnits)
+                             Iterable<? extends JavaFileObject> compilationUnits) {
+        Context context = new Context();
+        return getTask(out, fileManager, diagnosticListener,
+                options, classes, compilationUnits,
+                context);
+    }
+
+    public JavacTask getTask(Writer out,
+                             JavaFileManager fileManager,
+                             DiagnosticListener<? super JavaFileObject> diagnosticListener,
+                             Iterable<String> options,
+                             Iterable<String> classes,
+                             Iterable<? extends JavaFileObject> compilationUnits,
+                             Context context)
     {
         try {
-            Context context = new Context();
             ClientCodeWrapper ccw = ClientCodeWrapper.instance(context);
 
             final String kindMsg = "All compilation units must be of SOURCE kind";
@@ -212,9 +226,10 @@
             return;
 
         Options optionTable = Options.instance(context);
+        Log log = Log.instance(context);
 
         JavacOption[] recognizedOptions =
-            RecognizedOptions.getJavacToolOptions(new GrumpyHelper());
+            RecognizedOptions.getJavacToolOptions(new GrumpyHelper(log));
         Iterator<String> flags = options.iterator();
         while (flags.hasNext()) {
             String flag = flags.next();
@@ -227,7 +242,7 @@
                 if (fileManager.handleOption(flag, flags)) {
                     continue;
                 } else {
-                    String msg = Main.getLocalizedString("err.invalid.flag", flag);
+                    String msg = log.localize(PrefixKind.JAVAC, "err.invalid.flag", flag);
                     throw new IllegalArgumentException(msg);
                 }
             }
@@ -235,7 +250,7 @@
             JavacOption option = recognizedOptions[j];
             if (option.hasArg()) {
                 if (!flags.hasNext()) {
-                    String msg = Main.getLocalizedString("err.req.arg", flag);
+                    String msg = log.localize(PrefixKind.JAVAC, "err.req.arg", flag);
                     throw new IllegalArgumentException(msg);
                 }
                 String operand = flags.next();
@@ -250,6 +265,8 @@
                     throw new IllegalArgumentException(flag);
             }
         }
+
+        optionTable.notifyListeners();
     }
 
     public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) {
@@ -267,7 +284,7 @@
 
     public int isSupportedOption(String option) {
         JavacOption[] recognizedOptions =
-            RecognizedOptions.getJavacToolOptions(new GrumpyHelper());
+            RecognizedOptions.getJavacToolOptions(new GrumpyHelper(null));
         for (JavacOption o : recognizedOptions) {
             if (o.matches(option))
                 return o.hasArg() ? 1 : 0;
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Tue Nov 29 12:04:55 2011 -0800
@@ -59,6 +59,7 @@
 import com.sun.tools.javac.comp.MemberEnter;
 import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.model.JavacElements;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree;
@@ -140,8 +141,8 @@
                 }
 
                 public long getEndPosition(CompilationUnitTree file, Tree tree) {
-                    Map<JCTree,Integer> endPositions = ((JCCompilationUnit) file).endPositions;
-                    return TreeInfo.getEndPos((JCTree) tree, endPositions);
+                    EndPosTable endPosTable = ((JCCompilationUnit) file).endPositions;
+                    return TreeInfo.getEndPos((JCTree) tree, endPosTable);
                 }
             };
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java	Tue Nov 29 12:04:55 2011 -0800
@@ -40,6 +40,7 @@
 import com.sun.tools.javac.code.Type.*;
 
 import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.parser.EndPosTable;
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.BLOCK;
@@ -127,7 +128,7 @@
 
     /** A hash table mapping syntax trees to their ending source positions.
      */
-    Map<JCTree, Integer> endPositions;
+    EndPosTable endPosTable;
 
 /**************************************************************************
  * Global mappings
@@ -2195,9 +2196,8 @@
         } else {
             make_at(tree.pos());
             T result = super.translate(tree);
-            if (endPositions != null && result != tree) {
-                Integer endPos = endPositions.remove(tree);
-                if (endPos != null) endPositions.put(result, endPos);
+            if (endPosTable != null && result != tree) {
+                endPosTable.replaceTree(tree, result);
             }
             return result;
         }
@@ -3675,7 +3675,7 @@
         try {
             attrEnv = env;
             this.make = make;
-            endPositions = env.toplevel.endPositions;
+            endPosTable = env.toplevel.endPositions;
             currentClass = null;
             currentMethodDef = null;
             outermostClassDef = (cdef.hasTag(CLASSDEF)) ? (JCClassDecl)cdef : null;
@@ -3704,7 +3704,7 @@
             // note that recursive invocations of this method fail hard
             attrEnv = null;
             this.make = null;
-            endPositions = null;
+            endPosTable = null;
             currentClass = null;
             currentMethodDef = null;
             outermostClassDef = null;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java	Tue Nov 29 12:04:55 2011 -0800
@@ -31,6 +31,7 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.parser.EndPosTable;
 
 /** This class contains the CharacterRangeTable for some method
  *  and the hashtable for mapping trees or lists of trees to their
@@ -54,9 +55,9 @@
      */
     private Map<Object,SourceRange> positions = new HashMap<Object,SourceRange>();
 
-    /** The hashtable for ending positions stored in the parser.
+    /** The object for ending positions stored in the parser.
      */
-    private Map<JCTree, Integer> endPositions;
+    private EndPosTable endPosTable;
 
     /** The tree of the method this table is intended for.
      *  We should traverse this tree to get source ranges.
@@ -65,9 +66,9 @@
 
     /** Constructor
      */
-    public CRTable(JCTree.JCMethodDecl tree, Map<JCTree, Integer> endPositions) {
+    public CRTable(JCTree.JCMethodDecl tree, EndPosTable endPosTable) {
         this.methodTree = tree;
-        this.endPositions = endPositions;
+        this.endPosTable = endPosTable;
     }
 
     /** Create a new CRTEntry and add it to the entries.
@@ -534,10 +535,7 @@
             if (tree == null) return Position.NOPOS;
             if (tree.hasTag(JCTree.Tag.BLOCK))
                 return ((JCBlock) tree).endpos;
-            Integer endpos = endPositions.get(tree);
-            if (endpos != null)
-                return endpos.intValue();
-            return Position.NOPOS;
+            return endPosTable.getEndPos(tree);
         }
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Nov 29 12:04:55 2011 -0800
@@ -2539,7 +2539,7 @@
      *  @param arg An argument for substitution into the output string.
      */
     private void printCCF(String key, Object arg) {
-        log.printNoteLines(key, arg);
+        log.printLines(key, arg);
     }
 
 
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Nov 29 12:04:55 2011 -0800
@@ -892,8 +892,9 @@
             if ((flags & INTERFACE) != 0) flags |= ABSTRACT; // Interfaces are always ABSTRACT
             if (inner.name.isEmpty()) flags &= ~FINAL; // Anonymous class: unset FINAL flag
             if (dumpInnerClassModifiers) {
-                log.errWriter.println("INNERCLASS  " + inner.name);
-                log.errWriter.println("---" + flagNames(flags));
+                PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+                pw.println("INNERCLASS  " + inner.name);
+                pw.println("---" + flagNames(flags));
             }
             databuf.appendChar(pool.get(inner));
             databuf.appendChar(
@@ -911,8 +912,9 @@
         int flags = adjustFlags(v.flags());
         databuf.appendChar(flags);
         if (dumpFieldModifiers) {
-            log.errWriter.println("FIELD  " + fieldName(v));
-            log.errWriter.println("---" + flagNames(v.flags()));
+            PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+            pw.println("FIELD  " + fieldName(v));
+            pw.println("---" + flagNames(v.flags()));
         }
         databuf.appendChar(pool.put(fieldName(v)));
         databuf.appendChar(pool.put(typeSig(v.erasure(types))));
@@ -934,8 +936,9 @@
         int flags = adjustFlags(m.flags());
         databuf.appendChar(flags);
         if (dumpMethodModifiers) {
-            log.errWriter.println("METHOD  " + fieldName(m));
-            log.errWriter.println("---" + flagNames(m.flags()));
+            PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+            pw.println("METHOD  " + fieldName(m));
+            pw.println("---" + flagNames(m.flags()));
         }
         databuf.appendChar(pool.put(fieldName(m)));
         databuf.appendChar(pool.put(typeSig(m.externalType(types))));
@@ -1483,9 +1486,10 @@
         if ((flags & INTERFACE) == 0) flags |= ACC_SUPER;
         if (c.isInner() && c.name.isEmpty()) flags &= ~FINAL;
         if (dumpClassModifiers) {
-            log.errWriter.println();
-            log.errWriter.println("CLASSFILE  " + c.getQualifiedName());
-            log.errWriter.println("---" + flagNames(flags));
+            PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+            pw.println();
+            pw.println("CLASSFILE  " + c.getQualifiedName());
+            pw.println("---" + flagNames(flags));
         }
         databuf.appendChar(flags);
 
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Nov 29 12:04:55 2011 -0800
@@ -26,8 +26,6 @@
 package com.sun.tools.javac.jvm;
 import java.util.*;
 
-import javax.lang.model.element.ElementKind;
-
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
@@ -39,6 +37,7 @@
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.jvm.Code.*;
 import com.sun.tools.javac.jvm.Items.*;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.tree.JCTree.*;
 
 import static com.sun.tools.javac.code.Flags.*;
@@ -197,9 +196,10 @@
      */
     private int nerrs = 0;
 
-    /** A hash table mapping syntax trees to their ending source positions.
+    /** An object containing mappings of syntax trees to their
+     *  ending source positions.
      */
-    private Map<JCTree, Integer> endPositions;
+    EndPosTable endPosTable;
 
     /** Generate code to load an integer constant.
      *  @param n     The integer to be loaded.
@@ -482,20 +482,14 @@
                         JCStatement init = make.at(vdef.pos()).
                             Assignment(sym, vdef.init);
                         initCode.append(init);
-                        if (endPositions != null) {
-                            Integer endPos = endPositions.remove(vdef);
-                            if (endPos != null) endPositions.put(init, endPos);
-                        }
+                        endPosTable.replaceTree(vdef, init);
                     } else if (sym.getConstValue() == null) {
                         // Initialize class (static) variables only if
                         // they are not compile-time constants.
                         JCStatement init = make.at(vdef.pos).
                             Assignment(sym, vdef.init);
                         clinitCode.append(init);
-                        if (endPositions != null) {
-                            Integer endPos = endPositions.remove(vdef);
-                            if (endPos != null) endPositions.put(init, endPos);
-                        }
+                        endPosTable.replaceTree(vdef, init);
                     } else {
                         checkStringConstant(vdef.init.pos(), sym.getConstValue());
                     }
@@ -2217,7 +2211,7 @@
             attrEnv = env;
             ClassSymbol c = cdef.sym;
             this.toplevel = env.toplevel;
-            this.endPositions = toplevel.endPositions;
+            this.endPosTable = toplevel.endPositions;
             // If this is a class definition requiring Miranda methods,
             // add them.
             if (generateIproxies &&
@@ -2253,7 +2247,7 @@
             attrEnv = null;
             this.env = null;
             toplevel = null;
-            endPositions = null;
+            endPosTable = null;
             nerrs = 0;
         }
     }
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Tue Nov 29 12:04:55 2011 -0800
@@ -48,17 +48,18 @@
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
 
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Lint.LintCategory;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.comp.*;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.jvm.*;
+import com.sun.tools.javac.parser.*;
+import com.sun.tools.javac.processing.*;
 import com.sun.tools.javac.tree.*;
 import com.sun.tools.javac.tree.JCTree.*;
-import com.sun.tools.javac.parser.*;
-import com.sun.tools.javac.comp.*;
-import com.sun.tools.javac.jvm.*;
-import com.sun.tools.javac.processing.*;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.Log.WriterKind;
 
 import static javax.tools.StandardLocation.CLASS_OUTPUT;
 import static com.sun.tools.javac.main.OptionName.*;
@@ -1602,7 +1603,7 @@
     }
 
     protected void printNote(String lines) {
-        Log.printLines(log.noticeWriter, lines);
+        log.printRawLines(Log.WriterKind.NOTICE, lines);
     }
 
     /** Print numbers of errors and warnings.
@@ -1614,8 +1615,8 @@
                 key = "count." + kind;
             else
                 key = "count." + kind + ".plural";
-            log.printErrLines(key, String.valueOf(count));
-            log.errWriter.flush();
+            log.printLines(WriterKind.ERROR, key, String.valueOf(count));
+            log.flush(Log.WriterKind.ERROR);
         }
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavacOption.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,11 @@
 
 package com.sun.tools.javac.main;
 
-import java.io.PrintWriter;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.PrefixKind;
+import com.sun.tools.javac.util.Log.WriterKind;
 import com.sun.tools.javac.util.Options;
 
 /**
@@ -177,14 +178,14 @@
         /** Print a line of documentation describing this option, if standard.
          * @param out the stream to which to write the documentation
          */
-        void help(PrintWriter out) {
-            String s = "  " + helpSynopsis();
-            out.print(s);
-            for (int j = Math.min(s.length(), 28); j < 29; j++) out.print(" ");
-            Log.printLines(out, Main.getLocalizedString(descrKey));
+        void help(Log log) {
+            log.printRawLines(WriterKind.NOTICE,
+                    String.format("  %-26s %s",
+                        helpSynopsis(log),
+                        log.localize(PrefixKind.JAVAC, descrKey)));
         }
 
-        String helpSynopsis() {
+        String helpSynopsis(Log log) {
             StringBuilder sb = new StringBuilder();
             sb.append(name);
             if (argsNameKey == null) {
@@ -202,7 +203,7 @@
             } else {
                 if (!hasSuffix)
                     sb.append(" ");
-                sb.append(Main.getLocalizedString(argsNameKey));
+                sb.append(log.localize(PrefixKind.JAVAC, argsNameKey));
             }
 
             return sb.toString();
@@ -211,7 +212,7 @@
         /** Print a line of documentation describing this option, if non-standard.
          *  @param out the stream to which to write the documentation
          */
-        void xhelp(PrintWriter out) {}
+        void xhelp(Log log) {}
 
         /** Process the option (with arg). Return true if error detected.
          */
@@ -271,9 +272,9 @@
             super(name, descrKey, kind, choices);
         }
         @Override
-        void help(PrintWriter out) {}
+        void help(Log log) {}
         @Override
-        void xhelp(PrintWriter out) { super.help(out); }
+        void xhelp(Log log) { super.help(log); }
         @Override
         public OptionKind getKind() { return OptionKind.EXTENDED; }
     };
@@ -288,9 +289,9 @@
             super(name, argsNameKey, null);
         }
         @Override
-        void help(PrintWriter out) {}
+        void help(Log log) {}
         @Override
-        void xhelp(PrintWriter out) {}
+        void xhelp(Log log) {}
         @Override
         public OptionKind getKind() { return OptionKind.HIDDEN; }
     };
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java	Tue Nov 29 12:04:55 2011 -0800
@@ -33,7 +33,6 @@
 import java.security.MessageDigest;
 import java.util.Collection;
 import java.util.LinkedHashSet;
-import java.util.MissingResourceException;
 import java.util.Set;
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
@@ -46,6 +45,8 @@
 import com.sun.tools.javac.main.JavacOption.Option;
 import com.sun.tools.javac.main.RecognizedOptions.OptionHelper;
 import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.Log.WriterKind;
+import com.sun.tools.javac.util.Log.PrefixKind;
 import com.sun.tools.javac.processing.AnnotationProcessingError;
 
 import static com.sun.tools.javac.main.OptionName.*;
@@ -67,6 +68,10 @@
      */
     PrintWriter out;
 
+    /** The log to use for diagnostic output.
+     */
+    Log log;
+
     /**
      * If true, certain errors will cause an exception, such as command line
      * arg errors, or exceptions in user provided code.
@@ -98,6 +103,7 @@
 
         public void setOut(PrintWriter out) {
             Main.this.out = out;
+            Main.this.log.setWriters(out);
         }
 
         public void error(String key, Object... args) {
@@ -105,11 +111,11 @@
         }
 
         public void printVersion() {
-            Log.printLines(out, getLocalizedString("version", ownName,  JavaCompiler.version()));
+            log.printLines(PrefixKind.JAVAC, "version", ownName,  JavaCompiler.version());
         }
 
         public void printFullVersion() {
-            Log.printLines(out, getLocalizedString("fullVersion", ownName,  JavaCompiler.fullVersion()));
+            log.printLines(PrefixKind.JAVAC, "fullVersion", ownName,  JavaCompiler.fullVersion());
         }
 
         public void printHelp() {
@@ -158,39 +164,38 @@
     /** Print a string that explains usage.
      */
     void help() {
-        Log.printLines(out, getLocalizedString("msg.usage.header", ownName));
+        log.printLines(PrefixKind.JAVAC, "msg.usage.header", ownName);
         for (int i=0; i<recognizedOptions.length; i++) {
-            recognizedOptions[i].help(out);
+            recognizedOptions[i].help(log);
         }
-        out.println();
+        log.printNewline();
     }
 
     /** Print a string that explains usage for X options.
      */
     void xhelp() {
         for (int i=0; i<recognizedOptions.length; i++) {
-            recognizedOptions[i].xhelp(out);
+            recognizedOptions[i].xhelp(log);
         }
-        out.println();
-        Log.printLines(out, getLocalizedString("msg.usage.nonstandard.footer"));
+        log.printNewline();
+        log.printLines(PrefixKind.JAVAC, "msg.usage.nonstandard.footer");
     }
 
     /** Report a usage error.
      */
     void error(String key, Object... args) {
         if (apiMode) {
-            String msg = getLocalizedString(key, args);
+            String msg = log.localize(PrefixKind.JAVAC, key, args);
             throw new PropagatedException(new IllegalStateException(msg));
         }
         warning(key, args);
-        Log.printLines(out, getLocalizedString("msg.usage", ownName));
+        log.printLines(PrefixKind.JAVAC, "msg.usage", ownName);
     }
 
     /** Report a warning.
      */
     void warning(String key, Object... args) {
-        Log.printLines(out, ownName + ": "
-                       + getLocalizedString(key, args));
+        log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args));
     }
 
     public Option getOption(String flag) {
@@ -307,6 +312,8 @@
             showClass(showClass);
         }
 
+        options.notifyListeners();
+
         return filenames;
     }
     // where
@@ -352,6 +359,9 @@
                        List<JavaFileObject> fileObjects,
                        Iterable<? extends Processor> processors)
     {
+        context.put(Log.outKey, out);
+        log = Log.instance(context);
+
         if (options == null)
             options = Options.instance(context); // creates a new one
 
@@ -390,20 +400,17 @@
                     return Result.CMDERR;
                 }
             } catch (java.io.FileNotFoundException e) {
-                Log.printLines(out, ownName + ": " +
-                               getLocalizedString("err.file.not.found",
-                                                  e.getMessage()));
+                warning("err.file.not.found", e.getMessage());
                 return Result.SYSERR;
             }
 
             boolean forceStdOut = options.isSet("stdout");
             if (forceStdOut) {
-                out.flush();
+                log.flush();
                 out = new PrintWriter(System.out, true);
+                log.setWriters(out);
             }
 
-            context.put(Log.outKey, out);
-
             // allow System property in following line as a Mustang legacy
             boolean batchMode = (options.isUnset("nonBatchMode")
                         && System.getProperty("nonBatchMode") == null);
@@ -415,8 +422,6 @@
             comp = JavaCompiler.instance(context);
             if (comp == null) return Result.SYSERR;
 
-            Log log = Log.instance(context);
-
             if (!files.isEmpty()) {
                 // add filenames to fileObjects
                 comp = JavaCompiler.instance(context);
@@ -433,10 +438,10 @@
 
             if (log.expectDiagKeys != null) {
                 if (log.expectDiagKeys.isEmpty()) {
-                    Log.printLines(log.noticeWriter, "all expected diagnostics found");
+                    log.printRawLines("all expected diagnostics found");
                     return Result.OK;
                 } else {
-                    Log.printLines(log.noticeWriter, "expected diagnostic keys not found: " + log.expectDiagKeys);
+                    log.printRawLines("expected diagnostic keys not found: " + log.expectDiagKeys);
                     return Result.ERROR;
                 }
             }
@@ -491,52 +496,50 @@
     /** Print a message reporting an internal error.
      */
     void bugMessage(Throwable ex) {
-        Log.printLines(out, getLocalizedString("msg.bug",
-                                               JavaCompiler.version()));
-        ex.printStackTrace(out);
+        log.printLines(PrefixKind.JAVAC, "msg.bug", JavaCompiler.version());
+        ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
     }
 
     /** Print a message reporting a fatal error.
      */
     void feMessage(Throwable ex) {
-        Log.printLines(out, ex.getMessage());
+        log.printRawLines(ex.getMessage());
         if (ex.getCause() != null && options.isSet("dev")) {
-            ex.getCause().printStackTrace(out);
+            ex.getCause().printStackTrace(log.getWriter(WriterKind.NOTICE));
         }
     }
 
     /** Print a message reporting an input/output error.
      */
     void ioMessage(Throwable ex) {
-        Log.printLines(out, getLocalizedString("msg.io"));
-        ex.printStackTrace(out);
+        log.printLines(PrefixKind.JAVAC, "msg.io");
+        ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
     }
 
     /** Print a message reporting an out-of-resources error.
      */
     void resourceMessage(Throwable ex) {
-        Log.printLines(out, getLocalizedString("msg.resource"));
-//      System.out.println("(name buffer len = " + Name.names.length + " " + Name.nc);//DEBUG
-        ex.printStackTrace(out);
+        log.printLines(PrefixKind.JAVAC, "msg.resource");
+        ex.printStackTrace(log.getWriter(WriterKind.NOTICE));
     }
 
     /** Print a message reporting an uncaught exception from an
      * annotation processor.
      */
     void apMessage(AnnotationProcessingError ex) {
-        Log.printLines(out,
-                       getLocalizedString("msg.proc.annotation.uncaught.exception"));
-        ex.getCause().printStackTrace(out);
+        log.printLines("msg.proc.annotation.uncaught.exception");
+        ex.getCause().printStackTrace(log.getWriter(WriterKind.NOTICE));
     }
 
     /** Display the location and checksum of a class. */
     void showClass(String className) {
-        out.println("javac: show class: " + className);
+        PrintWriter pw = log.getWriter(WriterKind.NOTICE);
+        pw.println("javac: show class: " + className);
         URL url = getClass().getResource('/' + className.replace('.', '/') + ".class");
         if (url == null)
-            out.println("  class not found");
+            pw.println("  class not found");
         else {
-            out.println("  " + url);
+            pw.println("  " + url);
             try {
                 final String algorithm = "MD5";
                 byte[] digest;
@@ -553,9 +556,9 @@
                 StringBuilder sb = new StringBuilder();
                 for (byte b: digest)
                     sb.append(String.format("%02x", b));
-                out.println("  " + algorithm + " checksum: " + sb);
+                pw.println("  " + algorithm + " checksum: " + sb);
             } catch (Exception e) {
-                out.println("  cannot compute digest: " + e);
+                pw.println("  cannot compute digest: " + e);
             }
         }
     }
@@ -566,35 +569,35 @@
      * Internationalization
      *************************************************************************/
 
-    /** Find a localized string in the resource bundle.
-     *  @param key     The key for the localized string.
-     */
-    public static String getLocalizedString(String key, Object... args) { // FIXME sb private
-        try {
-            if (messages == null)
-                messages = new JavacMessages(javacBundleName);
-            return messages.getLocalizedString("javac." + key, args);
-        }
-        catch (MissingResourceException e) {
-            throw new Error("Fatal Error: Resource for javac is missing", e);
-        }
-    }
+//    /** Find a localized string in the resource bundle.
+//     *  @param key     The key for the localized string.
+//     */
+//    public static String getLocalizedString(String key, Object... args) { // FIXME sb private
+//        try {
+//            if (messages == null)
+//                messages = new JavacMessages(javacBundleName);
+//            return messages.getLocalizedString("javac." + key, args);
+//        }
+//        catch (MissingResourceException e) {
+//            throw new Error("Fatal Error: Resource for javac is missing", e);
+//        }
+//    }
+//
+//    public static void useRawMessages(boolean enable) {
+//        if (enable) {
+//            messages = new JavacMessages(javacBundleName) {
+//                    @Override
+//                    public String getLocalizedString(String key, Object... args) {
+//                        return key;
+//                    }
+//                };
+//        } else {
+//            messages = new JavacMessages(javacBundleName);
+//        }
+//    }
 
-    public static void useRawMessages(boolean enable) {
-        if (enable) {
-            messages = new JavacMessages(javacBundleName) {
-                    @Override
-                    public String getLocalizedString(String key, Object... args) {
-                        return key;
-                    }
-                };
-        } else {
-            messages = new JavacMessages(javacBundleName);
-        }
-    }
-
-    private static final String javacBundleName =
+    public static final String javacBundleName =
         "com.sun.tools.javac.resources.javac";
-
-    private static JavacMessages messages;
+//
+//    private static JavacMessages messages;
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/RecognizedOptions.java	Tue Nov 29 12:04:55 2011 -0800
@@ -25,16 +25,6 @@
 
 package com.sun.tools.javac.main;
 
-import com.sun.tools.javac.code.Lint;
-import com.sun.tools.javac.code.Source;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.jvm.Target;
-import com.sun.tools.javac.main.JavacOption.HiddenOption;
-import com.sun.tools.javac.main.JavacOption.Option;
-import com.sun.tools.javac.main.JavacOption.XOption;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Options;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.PrintWriter;
@@ -44,6 +34,19 @@
 import java.util.Set;
 import javax.lang.model.SourceVersion;
 
+import com.sun.tools.javac.code.Lint;
+import com.sun.tools.javac.code.Source;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.jvm.Target;
+import com.sun.tools.javac.main.JavacOption.HiddenOption;
+import com.sun.tools.javac.main.JavacOption.Option;
+import com.sun.tools.javac.main.JavacOption.XOption;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Log.PrefixKind;
+import com.sun.tools.javac.util.Options;
+
 import static com.sun.tools.javac.main.OptionName.*;
 
 /**
@@ -79,13 +82,18 @@
     }
 
     public static class GrumpyHelper implements OptionHelper {
+        private Log log;
+
+        public GrumpyHelper(Log log) {
+            this.log = log;
+        }
 
         public void setOut(PrintWriter out) {
             throw new IllegalArgumentException();
         }
 
         public void error(String key, Object... args) {
-            throw new IllegalArgumentException(Main.getLocalizedString(key, args));
+            throw new IllegalArgumentException(log.localize(PrefixKind.JAVAC, key, args));
         }
 
         public void printVersion() {
@@ -400,9 +408,9 @@
         },
         new Option(A,                "opt.arg.key.equals.value","opt.A") {
             @Override
-            String helpSynopsis() {
+            String helpSynopsis(Log log) {
                 hasSuffix = true;
-                return super.helpSynopsis();
+                return super.helpSynopsis(log);
             }
 
             @Override
@@ -444,9 +452,9 @@
         // It's actually implemented by the launcher.
         new Option(J,                   "opt.arg.flag",         "opt.J") {
             @Override
-            String helpSynopsis() {
+            String helpSynopsis(Log log) {
                 hasSuffix = true;
-                return super.helpSynopsis();
+                return super.helpSynopsis(log);
             }
             @Override
             public boolean process(Options options, String option) {
@@ -570,9 +578,9 @@
         // It's actually implemented by the CommandLine class.
         new Option(AT,                   "opt.arg.file",         "opt.AT") {
             @Override
-            String helpSynopsis() {
+            String helpSynopsis(Log log) {
                 hasSuffix = true;
-                return super.helpSynopsis();
+                return super.helpSynopsis(log);
             }
             @Override
             public boolean process(Options options, String option) {
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java	Tue Nov 29 11:39:59 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.javac.parser;
-
-import java.util.Map;
-import java.util.HashMap;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.TreeInfo;
-
-import static com.sun.tools.javac.tree.JCTree.*;
-
-/**
- * This class is similar to Parser except that it stores ending
- * positions for the tree nodes.
- *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own risk.
- * This code and its internal interfaces are subject to change or
- * deletion without notice.</b></p>
- */
-public class EndPosParser extends JavacParser {
-
-    public EndPosParser(ParserFactory fac, Lexer S, boolean keepDocComments, boolean keepLineMap) {
-        super(fac, S, keepDocComments, keepLineMap);
-        this.S = S;
-        endPositions = new HashMap<JCTree,Integer>();
-    }
-
-    private Lexer S;
-
-    /** A hashtable to store ending positions
-     *  of source ranges indexed by the tree nodes.
-     *  Defined only if option flag genEndPos is set.
-     */
-    Map<JCTree, Integer> endPositions;
-
-    /** {@inheritDoc} */
-    @Override
-    protected void storeEnd(JCTree tree, int endpos) {
-        int errorEndPos = getErrorEndPos();
-        endPositions.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected <T extends JCTree> T to(T t) {
-        storeEnd(t, token.endPos);
-        return t;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected <T extends JCTree> T toP(T t) {
-        storeEnd(t, S.prevToken().endPos);
-        return t;
-    }
-
-    @Override
-    public JCCompilationUnit parseCompilationUnit() {
-        JCCompilationUnit t = super.parseCompilationUnit();
-        t.endPositions = endPositions;
-        return t;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    JCExpression parExpression() {
-        int pos = token.pos;
-        JCExpression t = super.parExpression();
-        return toP(F.at(pos).Parens(t));
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int getEndPos(JCTree tree) {
-        return TreeInfo.getEndPos(tree, endPositions);
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/EndPosTable.java	Tue Nov 29 12:04:55 2011 -0800
@@ -0,0 +1,56 @@
+/*
+ * 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 com.sun.tools.javac.parser;
+
+import com.sun.tools.javac.tree.JCTree;
+
+/**
+ * Specifies the methods to access a mappings of syntax trees to end positions.
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk.  This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+public interface EndPosTable {
+
+    /**
+     * This method will return the end position of a given tree, otherwise a
+     * Positions.NOPOS will be returned.
+     * @param tree JCTree
+     * @return position of the source tree or Positions.NOPOS for non-existent mapping
+     */
+    public int getEndPos(JCTree tree);
+
+    /**
+     * Give an old tree and a new tree, the old tree will be replaced with
+     * the new tree, the position of the new tree will be that of the old
+     * tree.
+     * not exist.
+     * @param oldtree a JCTree to be replaced
+     * @param newtree a JCTree to be replaced with
+     * @return position of the old tree or Positions.NOPOS for non-existent mapping
+     */
+    public int replaceTree(JCTree oldtree, JCTree newtree);
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue Nov 29 12:04:55 2011 -0800
@@ -83,12 +83,16 @@
     /** The name table. */
     private Names names;
 
+    /** End position mappings container */
+    private final AbstractEndPosTable endPosTable;
+
     /** Construct a parser from a given scanner, tree factory and log.
      */
     protected JavacParser(ParserFactory fac,
                      Lexer S,
                      boolean keepDocComments,
-                     boolean keepLineMap) {
+                     boolean keepLineMap,
+                     boolean keepEndPositions) {
         this.S = S;
         nextToken(); // prime the pump
         this.F = fac.F;
@@ -110,8 +114,14 @@
         docComments = keepDocComments ? new HashMap<JCTree,String>() : null;
         this.keepLineMap = keepLineMap;
         this.errorTree = F.Erroneous();
+        endPosTable = newEndPosTable(keepEndPositions);
     }
 
+    protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
+        return  keepEndPositions
+                ? new SimpleEndPosTable()
+                : new EmptyEndPosTable();
+    }
     /** Switch: Should generics be recognized?
      */
     boolean allowGenerics;
@@ -389,37 +399,21 @@
 
 /* -------- source positions ------- */
 
-    private int errorEndPos = -1;
-
     private void setErrorEndPos(int errPos) {
-        if (errPos > errorEndPos)
-            errorEndPos = errPos;
+        endPosTable.setErrorEndPos(errPos);
     }
 
-    protected int getErrorEndPos() {
-        return errorEndPos;
+    private void storeEnd(JCTree tree, int endpos) {
+        endPosTable.storeEnd(tree, endpos);
     }
 
-    /**
-     * Store ending position for a tree.
-     * @param tree   The tree.
-     * @param endpos The ending position to associate with the tree.
-     */
-    protected void storeEnd(JCTree tree, int endpos) {}
+    private <T extends JCTree> T to(T t) {
+        return endPosTable.to(t);
+    }
 
-    /**
-     * Store ending position for a tree.  The ending position should
-     * be the ending position of the current token.
-     * @param t The tree.
-     */
-    protected <T extends JCTree> T to(T t) { return t; }
-
-    /**
-     * Store ending position for a tree.  The ending position should
-     * be greater of the ending position of the previous token and errorEndPos.
-     * @param t The tree.
-     */
-    protected <T extends JCTree> T toP(T t) { return t; }
+    private <T extends JCTree> T toP(T t) {
+        return endPosTable.toP(t);
+    }
 
     /** Get the start position for a tree node.  The start position is
      * defined to be the position of the first character of the first
@@ -439,7 +433,7 @@
      * @param tree  The tree node
      */
     public int getEndPos(JCTree tree) {
-        return Position.NOPOS;
+        return endPosTable.getEndPos(tree);
     }
 
 
@@ -1362,7 +1356,7 @@
             int pos = token.pos;
             nextToken();
             accept(CLASS);
-            if (token.pos == errorEndPos) {
+            if (token.pos == endPosTable.errorEndPos) {
                 // error recovery
                 Name name = null;
                 if (token.kind == IDENTIFIER) {
@@ -1542,10 +1536,11 @@
     /** ParExpression = "(" Expression ")"
      */
     JCExpression parExpression() {
+        int pos = token.pos;
         accept(LPAREN);
         JCExpression t = parseExpression();
         accept(RPAREN);
-        return t;
+        return toP(F.at(pos).Parens(t));
     }
 
     /** Block = "{" BlockStatements "}"
@@ -1661,7 +1656,7 @@
             // error recovery
             if (token.pos == lastErrPos)
                 return stats.toList();
-            if (token.pos <= errorEndPos) {
+            if (token.pos <= endPosTable.errorEndPos) {
                 skip(false, true, true, true);
                 lastErrPos = token.pos;
             }
@@ -2270,7 +2265,7 @@
         boolean checkForImports = true;
         boolean firstTypeDecl = true;
         while (token.kind != EOF) {
-            if (token.pos <= errorEndPos) {
+            if (token.pos <= endPosTable.errorEndPos) {
                 // error recovery
                 skip(checkForImports, false, false, false);
                 if (token.kind == EOF)
@@ -2304,6 +2299,7 @@
             toplevel.docComments = docComments;
         if (keepLineMap)
             toplevel.lineMap = S.getLineMap();
+        toplevel.endPositions = this.endPosTable;
         return toplevel;
     }
 
@@ -2494,7 +2490,7 @@
             while (token.kind != RBRACE && token.kind != EOF) {
                 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
                                                                 false));
-                if (token.pos <= errorEndPos) {
+                if (token.pos <= endPosTable.errorEndPos) {
                     // error recovery
                    skip(false, true, true, false);
                 }
@@ -2556,7 +2552,7 @@
      */
     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
         accept(LBRACE);
-        if (token.pos <= errorEndPos) {
+        if (token.pos <= endPosTable.errorEndPos) {
             // error recovery
             skip(false, true, false, false);
             if (token.kind == LBRACE)
@@ -2565,7 +2561,7 @@
         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
         while (token.kind != RBRACE && token.kind != EOF) {
             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
-            if (token.pos <= errorEndPos) {
+            if (token.pos <= endPosTable.errorEndPos) {
                // error recovery
                skip(false, true, true, false);
            }
@@ -2697,7 +2693,7 @@
                 defaultValue = null;
             }
             accept(SEMI);
-            if (token.pos <= errorEndPos) {
+            if (token.pos <= endPosTable.errorEndPos) {
                 // error recovery
                 skip(false, true, false, false);
                 if (token.kind == LBRACE) {
@@ -3028,4 +3024,112 @@
             allowTWR = true;
         }
     }
+
+    /*
+     * a functional source tree and end position mappings
+     */
+    protected class SimpleEndPosTable extends AbstractEndPosTable {
+
+        private final Map<JCTree, Integer> endPosMap;
+
+        SimpleEndPosTable() {
+            endPosMap = new HashMap<JCTree, Integer>();
+        }
+
+        protected void storeEnd(JCTree tree, int endpos) {
+            endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
+        }
+
+        protected <T extends JCTree> T to(T t) {
+            storeEnd(t, token.endPos);
+            return t;
+        }
+
+        protected <T extends JCTree> T toP(T t) {
+            storeEnd(t, S.prevToken().endPos);
+            return t;
+        }
+
+        public int getEndPos(JCTree tree) {
+            Integer value = endPosMap.get(tree);
+            return (value == null) ? Position.NOPOS : value;
+        }
+
+        public int replaceTree(JCTree oldTree, JCTree newTree) {
+            Integer pos = endPosMap.remove(oldTree);
+            if (pos != null) {
+                endPosMap.put(newTree, pos);
+                return pos;
+            }
+            return Position.NOPOS;
+        }
+    }
+
+    /*
+     * a default skeletal implementation without any mapping overhead.
+     */
+    protected class EmptyEndPosTable extends AbstractEndPosTable {
+
+        protected void storeEnd(JCTree tree, int endpos) { /* empty */ }
+
+        protected <T extends JCTree> T to(T t) {
+            return t;
+        }
+
+        protected <T extends JCTree> T toP(T t) {
+            return t;
+        }
+
+        public int getEndPos(JCTree tree) {
+            return Position.NOPOS;
+        }
+
+        public int replaceTree(JCTree oldTree, JCTree newTree) {
+            return Position.NOPOS;
+        }
+
+    }
+
+    protected abstract class AbstractEndPosTable implements EndPosTable {
+
+        /**
+         * Store the last error position.
+         */
+        protected int errorEndPos;
+
+        /**
+         * Store ending position for a tree, the value of which is the greater
+         * of last error position and the given ending position.
+         * @param tree   The tree.
+         * @param endpos The ending position to associate with the tree.
+         */
+        protected abstract void storeEnd(JCTree tree, int endpos);
+
+        /**
+         * Store current token's ending position for a tree, the value of which
+         * will be the greater of last error position and the ending position of
+         * the current token.
+         * @param t The tree.
+         */
+        protected abstract <T extends JCTree> T to(T t);
+
+        /**
+         * Store current token's ending position for a tree, the value of which
+         * will be the greater of last error position and the ending position of
+         * the previous token.
+         * @param t The tree.
+         */
+        protected abstract <T extends JCTree> T toP(T t);
+
+        /**
+         * Set the error position during the parsing phases, the value of which
+         * will be set only if it is greater than the last stored error position.
+         * @param errPos The error position
+         */
+        protected void setErrorEndPos(int errPos) {
+            if (errPos > errorEndPos) {
+                errorEndPos = errPos;
+            }
+        }
+    }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,10 +75,6 @@
 
     public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
         Lexer lexer = scannerFactory.newScanner(input, keepDocComments);
-        if (keepEndPos) {
-            return new EndPosParser(this, lexer, keepDocComments, keepLineMap);
-        } else {
-            return new JavacParser(this, lexer, keepDocComments, keepLineMap);
-        }
+        return new JavacParser(this, lexer, keepDocComments, keepLineMap, keepEndPos);
     }
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Tue Nov 29 12:04:55 2011 -0800
@@ -688,7 +688,7 @@
                 ps.removeSupportedOptions(unmatchedProcessorOptions);
 
                 if (printProcessorInfo || verbose) {
-                    log.printNoteLines("x.print.processor.info",
+                    log.printLines("x.print.processor.info",
                             ps.processor.getClass().getName(),
                             matchedNames.toString(),
                             processingResult);
@@ -1014,7 +1014,7 @@
             if (printRounds || verbose) {
                 List<ClassSymbol> tlc = lastRound ? List.<ClassSymbol>nil() : topLevelClasses;
                 Set<TypeElement> ap = lastRound ? Collections.<TypeElement>emptySet() : annotationsPresent;
-                log.printNoteLines("x.print.rounds",
+                log.printLines("x.print.rounds",
                         number,
                         "{" + tlc.toString(", ") + "}",
                         ap,
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Nov 29 12:04:55 2011 -0800
@@ -792,7 +792,7 @@
 compiler.err.cant.apply.diamond=\
     cannot infer type arguments for {0}
 
-# 0: message segment, 1: message segment
+# 0: message segment or type, 1: message segment
 compiler.err.cant.apply.diamond.1=\
     cannot infer type arguments for {0};\n\
     reason: {1}
@@ -854,7 +854,7 @@
 compiler.misc.varargs.trustme.on.virtual.varargs=\
     Instance method {0} is not final.
 
-# 0: type, 1: kind, 2: symbol
+# 0: type, 1: symbol kind, 2: symbol
 compiler.misc.inaccessible.varargs.type=\
     formal varargs element type {0} is not accessible from {1} {2}
 
@@ -1631,6 +1631,7 @@
 compiler.misc.diamond.non.generic=\
     cannot use ''<>'' with non-generic class {0}
 
+# 0: unused
 compiler.misc.diamond.and.explicit.params=\
     cannot use ''<>'' with explicit type parameters for constructor
 
@@ -1712,7 +1713,7 @@
 ## The second argument {1} is the location name
 ## The third argument {2} is the location type (only when {1} is a variable name)
 
-# 0: symbol kind, 1: symbol, 2: unused
+# 0: symbol kind, 1: type or symbol, 2: unused
 compiler.misc.location=\
     {0} {1}
 
@@ -1847,6 +1848,7 @@
 compiler.misc.varargs.clash.with=\
     {0} in {1} overrides {2} in {3}
 
+# 0: unused
 compiler.misc.diamond.and.anon.class=\
     cannot use ''<>'' with anonymous inner classes
 
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Nov 29 12:04:55 2011 -0800
@@ -39,6 +39,7 @@
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Scope.*;
 import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.source.tree.*;
 
 import static com.sun.tools.javac.code.BoundKind.*;
@@ -450,7 +451,7 @@
     }
 
     // for default DiagnosticPosition
-    public int getEndPosition(Map<JCTree, Integer> endPosTable) {
+    public int getEndPosition(EndPosTable endPosTable) {
         return TreeInfo.getEndPos(this, endPosTable);
     }
 
@@ -467,7 +468,7 @@
      * @param docComments      A hashtable that stores all documentation comments
      *                         indexed by the tree nodes they refer to.
      *                         defined only if option -s is set.
-     * @param endPositions     A hashtable that stores ending positions of source
+     * @param endPositions     An object encapsulating ending positions of source
      *                         ranges indexed by the tree nodes they belong to.
      *                         Defined only if option -Xjcov is set.
      */
@@ -481,7 +482,7 @@
         public StarImportScope starImportScope;
         public Position.LineMap lineMap = null;
         public Map<JCTree, String> docComments = null;
-        public Map<JCTree, Integer> endPositions = null;
+        public EndPosTable endPositions = null;
         protected JCCompilationUnit(List<JCAnnotation> packageAnnotations,
                         JCExpression pid,
                         List<JCTree> defs,
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Tue Nov 29 12:04:55 2011 -0800
@@ -28,10 +28,10 @@
 import com.sun.source.tree.Tree;
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.Env;
-import java.util.Map;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.tree.JCTree.*;
 
 import static com.sun.tools.javac.code.Flags.*;
@@ -346,17 +346,17 @@
 
     /** The end position of given tree, given  a table of end positions generated by the parser
      */
-    public static int getEndPos(JCTree tree, Map<JCTree, Integer> endPositions) {
+    public static int getEndPos(JCTree tree, EndPosTable endPosTable) {
         if (tree == null)
             return Position.NOPOS;
 
-        if (endPositions == null) {
+        if (endPosTable == null) {
             // fall back on limited info in the tree
             return endPos(tree);
         }
 
-        Integer mapPos = endPositions.get(tree);
-        if (mapPos != null)
+        int mapPos = endPosTable.getEndPos(tree);
+        if (mapPos != Position.NOPOS)
             return mapPos;
 
         switch(tree.getTag()) {
@@ -364,7 +364,7 @@
             case SL_ASG: case SR_ASG: case USR_ASG:
             case PLUS_ASG: case MINUS_ASG: case MUL_ASG:
             case DIV_ASG: case MOD_ASG:
-                return getEndPos(((JCAssignOp) tree).rhs, endPositions);
+                return getEndPos(((JCAssignOp) tree).rhs, endPosTable);
             case OR: case AND: case BITOR:
             case BITXOR: case BITAND: case EQ:
             case NE: case LT: case GT:
@@ -372,62 +372,62 @@
             case SR: case USR: case PLUS:
             case MINUS: case MUL: case DIV:
             case MOD:
-                return getEndPos(((JCBinary) tree).rhs, endPositions);
+                return getEndPos(((JCBinary) tree).rhs, endPosTable);
             case CASE:
-                return getEndPos(((JCCase) tree).stats.last(), endPositions);
+                return getEndPos(((JCCase) tree).stats.last(), endPosTable);
             case CATCH:
-                return getEndPos(((JCCatch) tree).body, endPositions);
+                return getEndPos(((JCCatch) tree).body, endPosTable);
             case CONDEXPR:
-                return getEndPos(((JCConditional) tree).falsepart, endPositions);
+                return getEndPos(((JCConditional) tree).falsepart, endPosTable);
             case FORLOOP:
-                return getEndPos(((JCForLoop) tree).body, endPositions);
+                return getEndPos(((JCForLoop) tree).body, endPosTable);
             case FOREACHLOOP:
-                return getEndPos(((JCEnhancedForLoop) tree).body, endPositions);
+                return getEndPos(((JCEnhancedForLoop) tree).body, endPosTable);
             case IF: {
                 JCIf node = (JCIf)tree;
                 if (node.elsepart == null) {
-                    return getEndPos(node.thenpart, endPositions);
+                    return getEndPos(node.thenpart, endPosTable);
                 } else {
-                    return getEndPos(node.elsepart, endPositions);
+                    return getEndPos(node.elsepart, endPosTable);
                 }
             }
             case LABELLED:
-                return getEndPos(((JCLabeledStatement) tree).body, endPositions);
+                return getEndPos(((JCLabeledStatement) tree).body, endPosTable);
             case MODIFIERS:
-                return getEndPos(((JCModifiers) tree).annotations.last(), endPositions);
+                return getEndPos(((JCModifiers) tree).annotations.last(), endPosTable);
             case SYNCHRONIZED:
-                return getEndPos(((JCSynchronized) tree).body, endPositions);
+                return getEndPos(((JCSynchronized) tree).body, endPosTable);
             case TOPLEVEL:
-                return getEndPos(((JCCompilationUnit) tree).defs.last(), endPositions);
+                return getEndPos(((JCCompilationUnit) tree).defs.last(), endPosTable);
             case TRY: {
                 JCTry node = (JCTry)tree;
                 if (node.finalizer != null) {
-                    return getEndPos(node.finalizer, endPositions);
+                    return getEndPos(node.finalizer, endPosTable);
                 } else if (!node.catchers.isEmpty()) {
-                    return getEndPos(node.catchers.last(), endPositions);
+                    return getEndPos(node.catchers.last(), endPosTable);
                 } else {
-                    return getEndPos(node.body, endPositions);
+                    return getEndPos(node.body, endPosTable);
                 }
             }
             case WILDCARD:
-                return getEndPos(((JCWildcard) tree).inner, endPositions);
+                return getEndPos(((JCWildcard) tree).inner, endPosTable);
             case TYPECAST:
-                return getEndPos(((JCTypeCast) tree).expr, endPositions);
+                return getEndPos(((JCTypeCast) tree).expr, endPosTable);
             case TYPETEST:
-                return getEndPos(((JCInstanceOf) tree).clazz, endPositions);
+                return getEndPos(((JCInstanceOf) tree).clazz, endPosTable);
             case POS:
             case NEG:
             case NOT:
             case COMPL:
             case PREINC:
             case PREDEC:
-                return getEndPos(((JCUnary) tree).arg, endPositions);
+                return getEndPos(((JCUnary) tree).arg, endPosTable);
             case WHILELOOP:
-                return getEndPos(((JCWhileLoop) tree).body, endPositions);
+                return getEndPos(((JCWhileLoop) tree).body, endPosTable);
             case ERRONEOUS: {
                 JCErroneous node = (JCErroneous)tree;
                 if (node.errs != null && node.errs.nonEmpty())
-                    return getEndPos(node.errs.last(), endPositions);
+                    return getEndPos(node.errs.last(), endPosTable);
             }
         }
         return Position.NOPOS;
@@ -444,7 +444,7 @@
             public JCTree getTree() { return tree; }
             public int getStartPosition() { return TreeInfo.getStartPos(tree); }
             public int getPreferredPosition() { return endPos; }
-            public int getEndPosition(Map<JCTree, Integer> endPosTable) {
+            public int getEndPosition(EndPosTable endPosTable) {
                 return TreeInfo.getEndPos(tree, endPosTable);
             }
         };
--- a/langtools/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/BaseFileManager.java	Tue Nov 29 12:04:55 2011 -0800
@@ -166,7 +166,7 @@
     // where
         private static JavacOption[] javacFileManagerOptions =
             RecognizedOptions.getJavacFileManagerOptions(
-            new RecognizedOptions.GrumpyHelper());
+            new RecognizedOptions.GrumpyHelper(Log.instance(new Context())));
 
     public int isSupportedOption(String option) {
         for (JavacOption o : javacFileManagerOptions) {
--- a/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/DiagnosticSource.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
 import javax.tools.JavaFileObject;
 
 import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.tree.JCTree;
 
 import static com.sun.tools.javac.util.LayoutCharacters.*;
@@ -128,11 +129,11 @@
         }
     }
 
-    public Map<JCTree, Integer> getEndPosTable() {
+    public EndPosTable getEndPosTable() {
         return endPosTable;
     }
 
-    public void setEndPosTable(Map<JCTree, Integer> t) {
+    public void setEndPosTable(EndPosTable t) {
         if (endPosTable != null && endPosTable != t)
             throw new IllegalStateException("endPosTable already set");
         endPosTable = t;
@@ -199,7 +200,7 @@
     /** The underlying file object. */
     protected JavaFileObject fileObject;
 
-    protected Map<JCTree, Integer> endPosTable;
+    protected EndPosTable endPosTable;
 
     /** A soft reference to the content of the file object. */
     protected SoftReference<char[]> refBuf;
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JCDiagnostic.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 
 import com.sun.tools.javac.api.DiagnosticFormatter;
 import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.tree.JCTree;
 
 import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
@@ -70,7 +71,16 @@
             this(JavacMessages.instance(context), "compiler");
             context.put(diagnosticFactoryKey, this);
 
-            Options options = Options.instance(context);
+            final Options options = Options.instance(context);
+            initOptions(options);
+            options.addListener(new Runnable() {
+               public void run() {
+                   initOptions(options);
+               }
+            });
+        }
+
+        private void initOptions(Options options) {
             if (options.isSet("onlySyntaxErrorsUnrecoverable"))
                 defaultErrorFlags.add(DiagnosticFlag.RECOVERABLE);
         }
@@ -304,7 +314,7 @@
         /** If there is a tree node, and if endPositions are available, get
          *  the end position of the tree node. Otherwise, just returns the
          *  same as getPreferredPosition(). */
-        int getEndPosition(Map<JCTree, Integer> endPosTable);
+        int getEndPosition(EndPosTable endPosTable);
     }
 
     /**
@@ -328,7 +338,7 @@
             return pos;
         }
 
-        public int getEndPosition(Map<JCTree, Integer> endPosTable) {
+        public int getEndPosition(EndPosTable endPosTable) {
             return pos;
         }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/util/JavacMessages.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/JavacMessages.java	Tue Nov 29 12:04:55 2011 -0800
@@ -82,14 +82,14 @@
     }
 
     /** Creates a JavacMessages object.
-     * @param bundleName the name to identify the resource buundle of localized messages.
+     * @param bundleName the name to identify the resource bundle of localized messages.
      */
     public JavacMessages(String bundleName) throws MissingResourceException {
         this(bundleName, null);
     }
 
     /** Creates a JavacMessages object.
-     * @param bundleName the name to identify the resource buundle of localized messages.
+     * @param bundleName the name to identify the resource bundle of localized messages.
      */
     public JavacMessages(String bundleName, Locale locale) throws MissingResourceException {
         bundleNames = List.nil();
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Log.java	Tue Nov 29 12:04:55 2011 -0800
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.util;
 
+import com.sun.tools.javac.main.Main;
 import java.io.*;
 import java.util.Arrays;
 import java.util.EnumSet;
@@ -37,6 +38,7 @@
 
 import com.sun.tools.javac.api.DiagnosticFormatter;
 import com.sun.tools.javac.main.OptionName;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType;
@@ -60,19 +62,31 @@
     public static final Context.Key<PrintWriter> outKey =
         new Context.Key<PrintWriter>();
 
-    //@Deprecated
-    public final PrintWriter errWriter;
+    /* TODO: Should unify this with prefix handling in JCDiagnostic.Factory. */
+    public enum PrefixKind {
+        JAVAC("javac."),
+        COMPILER_MISC("compiler.misc.");
+        PrefixKind(String v) {
+            value = v;
+        }
+        public String key(String k) {
+            return value + k;
+        }
+        final String value;
+    }
 
-    //@Deprecated
-    public final PrintWriter warnWriter;
+    public enum WriterKind { NOTICE, WARNING, ERROR };
+
+    protected PrintWriter errWriter;
 
-    //@Deprecated
-    public final PrintWriter noticeWriter;
+    protected PrintWriter warnWriter;
+
+    protected PrintWriter noticeWriter;
 
     /** The maximum number of errors/warnings that are reported.
      */
-    public final int MaxErrors;
-    public final int MaxWarnings;
+    protected int MaxErrors;
+    protected int MaxWarnings;
 
     /** Switch: prompt user on each error.
      */
@@ -131,28 +145,40 @@
         this.warnWriter = warnWriter;
         this.noticeWriter = noticeWriter;
 
-        Options options = Options.instance(context);
-        this.dumpOnError = options.isSet(DOE);
-        this.promptOnError = options.isSet(PROMPT);
-        this.emitWarnings = options.isUnset(XLINT_CUSTOM, "none");
-        this.suppressNotes = options.isSet("suppressNotes");
-        this.MaxErrors = getIntOption(options, XMAXERRS, getDefaultMaxErrors());
-        this.MaxWarnings = getIntOption(options, XMAXWARNS, getDefaultMaxWarnings());
-
-        boolean rawDiagnostics = options.isSet("rawDiagnostics");
-        messages = JavacMessages.instance(context);
-        this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) :
-                                              new BasicDiagnosticFormatter(options, messages);
         @SuppressWarnings("unchecked") // FIXME
         DiagnosticListener<? super JavaFileObject> dl =
             context.get(DiagnosticListener.class);
         this.diagListener = dl;
 
-        String ek = options.get("expectKeys");
-        if (ek != null)
-            expectDiagKeys = new HashSet<String>(Arrays.asList(ek.split(", *")));
+        messages = JavacMessages.instance(context);
+        messages.add(Main.javacBundleName);
+
+        final Options options = Options.instance(context);
+        initOptions(options);
+        options.addListener(new Runnable() {
+            public void run() {
+                initOptions(options);
+            }
+        });
     }
     // where
+        private void initOptions(Options options) {
+            this.dumpOnError = options.isSet(DOE);
+            this.promptOnError = options.isSet(PROMPT);
+            this.emitWarnings = options.isUnset(XLINT_CUSTOM, "none");
+            this.suppressNotes = options.isSet("suppressNotes");
+            this.MaxErrors = getIntOption(options, XMAXERRS, getDefaultMaxErrors());
+            this.MaxWarnings = getIntOption(options, XMAXWARNS, getDefaultMaxWarnings());
+
+            boolean rawDiagnostics = options.isSet("rawDiagnostics");
+            this.diagFormatter = rawDiagnostics ? new RawDiagnosticFormatter(options) :
+                                                  new BasicDiagnosticFormatter(options, messages);
+
+            String ek = options.get("expectKeys");
+            if (ek != null)
+                expectDiagKeys = new HashSet<String>(Arrays.asList(ek.split(", *")));
+        }
+
         private int getIntOption(Options options, OptionName optionName, int defaultValue) {
             String s = options.get(optionName);
             try {
@@ -180,7 +206,7 @@
 
     /** The default writer for diagnostics
      */
-    static final PrintWriter defaultWriter(Context context) {
+    static PrintWriter defaultWriter(Context context) {
         PrintWriter result = context.get(outKey);
         if (result == null)
             context.put(outKey, result = new PrintWriter(System.err));
@@ -225,9 +251,9 @@
         return diagListener != null;
     }
 
-    public void setEndPosTable(JavaFileObject name, Map<JCTree, Integer> table) {
+    public void setEndPosTable(JavaFileObject name, EndPosTable endPosTable) {
         name.getClass(); // null check
-        getSource(name).setEndPosTable(table);
+        getSource(name).setEndPosTable(endPosTable);
     }
 
     /** Return current sourcefile.
@@ -248,6 +274,30 @@
         this.diagFormatter = diagFormatter;
     }
 
+    public PrintWriter getWriter(WriterKind kind) {
+        switch (kind) {
+            case NOTICE:    return noticeWriter;
+            case WARNING:   return warnWriter;
+            case ERROR:     return errWriter;
+            default:        throw new IllegalArgumentException();
+        }
+    }
+
+    public void setWriter(WriterKind kind, PrintWriter pw) {
+        pw.getClass();
+        switch (kind) {
+            case NOTICE:    noticeWriter = pw;  break;
+            case WARNING:   warnWriter = pw;    break;
+            case ERROR:     errWriter = pw;     break;
+            default:        throw new IllegalArgumentException();
+        }
+    }
+
+    public void setWriters(PrintWriter pw) {
+        pw.getClass();
+        noticeWriter = warnWriter = errWriter = pw;
+    }
+
     /** Flush the logs
      */
     public void flush() {
@@ -256,6 +306,10 @@
         noticeWriter.flush();
     }
 
+    public void flush(WriterKind kind) {
+        getWriter(kind).flush();
+    }
+
     /** Returns true if an error needs to be reported for a given
      * source name and pos.
      */
@@ -275,7 +329,6 @@
     public void prompt() {
         if (promptOnError) {
             System.err.println(localize("resume.abort"));
-            char ch;
             try {
                 while (true) {
                     switch (System.in.read()) {
@@ -302,7 +355,7 @@
             return;
         int col = source.getColumnNumber(pos, false);
 
-        printLines(writer, line);
+        printRawLines(writer, line);
         for (int i = 0; i < col - 1; i++) {
             writer.print((line.charAt(i) == '\t') ? "\t" : " ");
         }
@@ -310,10 +363,48 @@
         writer.flush();
     }
 
+    public void printNewline() {
+        noticeWriter.println();
+    }
+
+    public void printNewline(WriterKind wk) {
+        getWriter(wk).println();
+    }
+
+    public void printLines(String key, Object... args) {
+        printRawLines(noticeWriter, localize(key, args));
+    }
+
+    public void printLines(PrefixKind pk, String key, Object... args) {
+        printRawLines(noticeWriter, localize(pk, key, args));
+    }
+
+    public void printLines(WriterKind wk, String key, Object... args) {
+        printRawLines(getWriter(wk), localize(key, args));
+    }
+
+    public void printLines(WriterKind wk, PrefixKind pk, String key, Object... args) {
+        printRawLines(getWriter(wk), localize(pk, key, args));
+    }
+
     /** Print the text of a message, translating newlines appropriately
      *  for the platform.
      */
-    public static void printLines(PrintWriter writer, String msg) {
+    public void printRawLines(String msg) {
+        printRawLines(noticeWriter, msg);
+    }
+
+    /** Print the text of a message, translating newlines appropriately
+     *  for the platform.
+     */
+    public void printRawLines(WriterKind kind, String msg) {
+        printRawLines(getWriter(kind), msg);
+    }
+
+    /** Print the text of a message, translating newlines appropriately
+     *  for the platform.
+     */
+    public static void printRawLines(PrintWriter writer, String msg) {
         int nl;
         while ((nl = msg.indexOf('\n')) != -1) {
             writer.println(msg.substring(0, nl));
@@ -322,30 +413,16 @@
         if (msg.length() != 0) writer.println(msg);
     }
 
-    /** Print the text of a message to the errWriter stream,
-     *  translating newlines appropriately for the platform.
-     */
-    public void printErrLines(String key, Object... args) {
-        printLines(errWriter, localize(key, args));
-    }
-
-    /** Print the text of a message to the noticeWriter stream,
-     *  translating newlines appropriately for the platform.
-     */
-    public void printNoteLines(String key, Object... args) {
-        printLines(noticeWriter, localize(key, args));
-    }
-
     /**
      * Print the localized text of a "verbose" message to the
      * noticeWriter stream.
      */
     public void printVerbose(String key, Object... args) {
-        printLines(noticeWriter, localize("verbose." + key, args));
+        printRawLines(noticeWriter, localize("verbose." + key, args));
     }
 
     protected void directError(String key, Object... args) {
-        printErrLines(key, args);
+        printRawLines(errWriter, localize(key, args));
         errWriter.flush();
     }
 
@@ -431,7 +508,7 @@
 
         PrintWriter writer = getWriterForDiagnosticType(diag.getType());
 
-        printLines(writer, diagFormatter.format(diag, messages.getCurrentLocale()));
+        printRawLines(writer, diagFormatter.format(diag, messages.getCurrentLocale()));
 
         if (promptOnError) {
             switch (diag.getType()) {
@@ -474,7 +551,7 @@
      *  @param args   Fields to substitute into the string.
      */
     public static String getLocalizedString(String key, Object ... args) {
-        return JavacMessages.getDefaultLocalizedString("compiler.misc." + key, args);
+        return JavacMessages.getDefaultLocalizedString(PrefixKind.COMPILER_MISC.key(key), args);
     }
 
     /** Find a localized string in the resource bundle.
@@ -482,9 +559,23 @@
      *  @param args   Fields to substitute into the string.
      */
     public String localize(String key, Object... args) {
-        return messages.getLocalizedString("compiler.misc." + key, args);
+        return localize(PrefixKind.COMPILER_MISC, key, args);
     }
 
+    /** Find a localized string in the resource bundle.
+     *  @param key    The key for the localized string.
+     *  @param args   Fields to substitute into the string.
+     */
+    public String localize(PrefixKind pk, String key, Object... args) {
+        if (useRawMessages)
+            return pk.key(key);
+        else
+            return messages.getLocalizedString(pk.key(key), args);
+    }
+    // where
+        // backdoor hook for testing, should transition to use -XDrawDiagnostics
+        private static boolean useRawMessages = false;
+
 /***************************************************************************
  * raw error messages without internationalization; used for experimentation
  * and quick prototyping
@@ -494,12 +585,12 @@
      */
     private void printRawError(int pos, String msg) {
         if (source == null || pos == Position.NOPOS) {
-            printLines(errWriter, "error: " + msg);
+            printRawLines(errWriter, "error: " + msg);
         } else {
             int line = source.getLineNumber(pos);
             JavaFileObject file = source.getFile();
             if (file != null)
-                printLines(errWriter,
+                printRawLines(errWriter,
                            file.getName() + ":" +
                            line + ": " + msg);
             printErrLine(pos, errWriter);
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Options.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Options.java	Tue Nov 29 12:04:55 2011 -0800
@@ -157,6 +157,19 @@
         return values.size();
     }
 
+    // light-weight notification mechanism
+
+    private List<Runnable> listeners = List.nil();
+
+    public void addListener(Runnable listener) {
+        listeners = listeners.prepend(listener);
+    }
+
+    public void notifyListeners() {
+        for (Runnable r: listeners)
+            r.run();
+    }
+
     /** Check for a lint suboption. */
     public boolean lint(String s) {
         // return true if either the specific option is enabled, or
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java	Tue Nov 29 12:04:55 2011 -0800
@@ -31,6 +31,7 @@
 import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Options;
 
 import java.io.IOException;
@@ -76,9 +77,6 @@
 
     private DocletInvoker docletInvoker;
 
-    private static final int F_VERBOSE = 1 << 0;
-    private static final int F_WARNINGS = 1 << 2;
-
     /* Treat warnings as errors. */
     private boolean rejectWarnings = false;
 
@@ -171,11 +169,11 @@
             messager.error(null, "main.out.of.memory");
             failed = true;
         } catch (Error ee) {
-            ee.printStackTrace();
+            ee.printStackTrace(System.err);
             messager.error(null, "main.fatal.error");
             failed = true;
         } catch (Exception ee) {
-            ee.printStackTrace();
+            ee.printStackTrace(System.err);
             messager.error(null, "main.fatal.exception");
             failed = true;
         } finally {
@@ -211,7 +209,7 @@
             messager.error(null, "main.cant.read", e.getMessage());
             exit();
         } catch (IOException e) {
-            e.printStackTrace();
+            e.printStackTrace(System.err);
             exit();
         }
 
@@ -225,7 +223,9 @@
         // options that may be set up below.
         Messager.preRegister(context,
                 messager.programName,
-                messager.errWriter, messager.warnWriter, messager.noticeWriter);
+                messager.getWriter(Log.WriterKind.ERROR),
+                messager.getWriter(Log.WriterKind.WARNING),
+                messager.getWriter(Log.WriterKind.NOTICE));
 
         Options compOpts = Options.instance(context);
         boolean docClasses = false;
--- a/langtools/test/tools/javac/6304921/TestLog.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/test/tools/javac/6304921/TestLog.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 import javax.tools.JavaFileObject;
 import javax.tools.SimpleJavaFileObject;
 import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.parser.Parser;
 import com.sun.tools.javac.parser.ParserFactory;
 import com.sun.tools.javac.tree.JCTree;
@@ -97,9 +98,9 @@
     }
 
     private static class LogTester extends TreeScanner {
-        LogTester(Log log, java.util.Map<JCTree, Integer> endPositions) {
+        LogTester(Log log, EndPosTable endPosTable) {
             this.log = log;
-            this.endPositions = endPositions;
+            this.endPosTable = endPosTable;
         }
 
         public void visitIf(JCTree.JCIf tree) {
@@ -117,7 +118,7 @@
         }
 
         private Log log;
-        private java.util.Map<JCTree, Integer> endPositions;
+        private EndPosTable endPosTable;
     }
 
     private static class StringJavaFileObject extends SimpleJavaFileObject {
--- a/langtools/test/tools/javac/6410653/T6410653.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/test/tools/javac/6410653/T6410653.java	Tue Nov 29 12:04:55 2011 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
  * @author  Peter von der Ah\u00e9
  */
 
-import java.lang.reflect.Method;
+import java.lang.reflect.Field;
 import java.io.File;
 import java.io.ByteArrayOutputStream;
 import javax.tools.*;
@@ -39,12 +39,13 @@
         String source = new File(testSrc, "T6410653.java").getPath();
         ClassLoader cl = ToolProvider.getSystemToolClassLoader();
         Tool compiler = ToolProvider.getSystemJavaCompiler();
-        Class<?> main = Class.forName("com.sun.tools.javac.main.Main", true, cl);
-        Method useRawMessages = main.getMethod("useRawMessages", boolean.class);
-        useRawMessages.invoke(null, true);
+        Class<?> log = Class.forName("com.sun.tools.javac.util.Log", true, cl);
+        Field useRawMessages = log.getDeclaredField("useRawMessages");
+        useRawMessages.setAccessible(true);
+        useRawMessages.setBoolean(null, true);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         compiler.run(null, null, out, "-d", source, source);
-        useRawMessages.invoke(null, false);
+        useRawMessages.setBoolean(null, false);
         if (!out.toString().equals(String.format("%s%n%s%n",
                                                  "javac: javac.err.file.not.directory",
                                                  "javac.msg.usage"))) {
--- a/langtools/test/tools/javac/diags/ArgTypeCompilerFactory.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/test/tools/javac/diags/ArgTypeCompilerFactory.java	Tue Nov 29 12:04:55 2011 -0800
@@ -105,13 +105,11 @@
 
             Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
 
-            JavacTaskImpl t = (JavacTaskImpl) tool.getTask(out, fm, null, opts, null, fos);
-            Context c = t.getContext();
+            Context c = new Context();
             ArgTypeMessages.preRegister(c);
             ArgTypeJavaCompiler.preRegister(c);
-            Boolean ok = t.call();
-
-            return ok;
+            JavacTaskImpl t = (JavacTaskImpl) tool.getTask(out, fm, null, opts, null, fos, c);
+            return t.call();
         }
     }
 
--- a/langtools/test/tools/javac/failover/CheckAttributedTree.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/test/tools/javac/failover/CheckAttributedTree.java	Tue Nov 29 12:04:55 2011 -0800
@@ -55,12 +55,8 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.nio.charset.Charset;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 import javax.tools.Diagnostic;
 import javax.tools.DiagnosticListener;
 import javax.tools.JavaFileObject;
@@ -72,8 +68,8 @@
 import com.sun.tools.javac.api.JavacTool;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCImport;
 import com.sun.tools.javac.tree.TreeInfo;
@@ -421,7 +417,7 @@
         }
 
         JavaFileObject sourcefile;
-        Map<JCTree, Integer> endPosTable;
+        EndPosTable endPosTable;
         Info encl;
     }
 
@@ -437,7 +433,7 @@
             end = Integer.MAX_VALUE;
         }
 
-        Info(JCTree tree, Map<JCTree, Integer> endPosTable) {
+        Info(JCTree tree, EndPosTable endPosTable) {
             this.tree = tree;
             tag = tree.getTag();
             start = TreeInfo.getStartPos(tree);
--- a/langtools/test/tools/javac/tree/TreePosTest.java	Tue Nov 29 11:39:59 2011 -0800
+++ b/langtools/test/tools/javac/tree/TreePosTest.java	Tue Nov 29 12:04:55 2011 -0800
@@ -73,6 +73,7 @@
 import com.sun.source.util.JavacTask;
 import com.sun.tools.javac.api.JavacTool;
 import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.parser.EndPosTable;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCNewClass;
@@ -435,7 +436,7 @@
         }
 
         JavaFileObject sourcefile;
-        Map<JCTree, Integer> endPosTable;
+        EndPosTable endPosTable;
         Info encl;
 
     }
@@ -452,7 +453,7 @@
             end = Integer.MAX_VALUE;
         }
 
-        Info(JCTree tree, Map<JCTree, Integer> endPosTable) {
+        Info(JCTree tree, EndPosTable endPosTable) {
             this.tree = tree;
             tag = tree.getTag();
             start = TreeInfo.getStartPos(tree);