changeset 2381:b2949bf39900

Merge
author never
date Fri, 25 Mar 2011 18:19:22 -0400
parents 322a41ec766c f731b22cd52d
children 29524004ce17 7e88bdae86ec
files
diffstat 131 files changed, 1932 insertions(+), 1273 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Mar 25 11:29:30 2011 -0700
+++ b/.hgtags	Fri Mar 25 18:19:22 2011 -0400
@@ -154,3 +154,5 @@
 0e531ab5ba04967a0e9aa6aef65e6eb3a0dcf632 jdk7-b132
 a8d643a4db47c7b58e0bcb49c77b5c3610de86a8 hs21-b03
 1b3a350709e4325d759bb453ff3fb6a463270488 jdk7-b133
+447e6faab4a8755d4860c2366630729dbaec111c jdk7-b134
+3c76374706ea8a77e15aec8310e831e5734f8775 hs21-b04
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/FieldImpl.java	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/FieldImpl.java	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@
 
     // get the value of static field
     ValueImpl getValue() {
-        return getValue(saField.getFieldHolder());
+        return getValue(saField.getFieldHolder().getJavaMirror());
     }
 
     // get the value of this Field from a specific Oop
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/StringTable.java	Fri Mar 25 18:19:22 2011 -0400
@@ -44,12 +44,10 @@
   private static synchronized void initialize(TypeDataBase db) {
     Type type = db.lookupType("StringTable");
     theTableField  = type.getAddressField("_the_table");
-    stringTableSize = db.lookupIntConstant("StringTable::string_table_size").intValue();
   }
 
   // Fields
   private static AddressField theTableField;
-  private static int stringTableSize;
 
   // Accessors
   public static StringTable getTheTable() {
@@ -57,10 +55,6 @@
     return (StringTable) VMObjectFactory.newObject(StringTable.class, tmp);
   }
 
-  public static int getStringTableSize() {
-    return stringTableSize;
-  }
-
   public StringTable(Address addr) {
     super(addr);
   }
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, 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
@@ -87,7 +87,7 @@
     innerClasses         = new OopField(type.getOopField("_inner_classes"), Oop.getHeaderSize());
     nonstaticFieldSize   = new CIntField(type.getCIntegerField("_nonstatic_field_size"), Oop.getHeaderSize());
     staticFieldSize      = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
-    staticOopFieldSize   = new CIntField(type.getCIntegerField("_static_oop_field_size"), Oop.getHeaderSize());
+    staticOopFieldCount   = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize());
     nonstaticOopMapSize  = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize());
     isMarkedDependent    = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize());
     initState            = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize());
@@ -140,7 +140,7 @@
   private static OopField  innerClasses;
   private static CIntField nonstaticFieldSize;
   private static CIntField staticFieldSize;
-  private static CIntField staticOopFieldSize;
+  private static CIntField staticOopFieldCount;
   private static CIntField nonstaticOopMapSize;
   private static CIntField isMarkedDependent;
   private static CIntField initState;
@@ -261,8 +261,7 @@
   public Symbol    getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
   public TypeArray getInnerClasses()        { return (TypeArray)    innerClasses.getValue(this); }
   public long      getNonstaticFieldSize()  { return                nonstaticFieldSize.getValue(this); }
-  public long      getStaticFieldSize()     { return                staticFieldSize.getValue(this); }
-  public long      getStaticOopFieldSize()  { return                staticOopFieldSize.getValue(this); }
+  public long      getStaticOopFieldCount() { return                staticOopFieldCount.getValue(this); }
   public long      getNonstaticOopMapSize() { return                nonstaticOopMapSize.getValue(this); }
   public boolean   getIsMarkedDependent()   { return                isMarkedDependent.getValue(this) != 0; }
   public long      getVtableLen()           { return                vtableLen.getValue(this); }
@@ -453,7 +452,7 @@
       visitor.doOop(innerClasses, true);
       visitor.doCInt(nonstaticFieldSize, true);
       visitor.doCInt(staticFieldSize, true);
-      visitor.doCInt(staticOopFieldSize, true);
+      visitor.doCInt(staticOopFieldCount, true);
       visitor.doCInt(nonstaticOopMapSize, true);
       visitor.doCInt(isMarkedDependent, true);
       visitor.doCInt(initState, true);
@@ -692,7 +691,7 @@
   public long getObjectSize() {
     long bodySize =    alignObjectOffset(getVtableLen() * getHeap().getOopSize())
                      + alignObjectOffset(getItableLen() * getHeap().getOopSize())
-                     + (getStaticFieldSize() + getNonstaticOopMapSize()) * getHeap().getOopSize();
+                     + (getNonstaticOopMapSize()) * getHeap().getOopSize();
     return alignObjectSize(headerSize + bodySize);
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/IntField.java	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/IntField.java	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 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
@@ -40,7 +40,12 @@
     super(holder, fieldArrayIndex);
   }
 
-  public int getValue(Oop obj) { return obj.getHandle().getJIntAt(getOffset()); }
+  public int getValue(Oop obj) {
+    if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
+      throw new InternalError(obj.toString());
+    }
+    return obj.getHandle().getJIntAt(getOffset());
+  }
   public void setValue(Oop obj, int value) throws MutationException {
     // Fix this: setJIntAt is missing in Address
   }
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopField.java	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopField.java	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2002, 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
@@ -41,11 +41,17 @@
   }
 
   public Oop getValue(Oop obj) {
+    if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
+      throw new InternalError();
+    }
     return obj.getHeap().newOop(getValueAsOopHandle(obj));
   }
 
   /** Debugging support */
   public OopHandle getValueAsOopHandle(Oop obj) {
+    if (!isVMField() && !obj.isInstance() && !obj.isArray()) {
+      throw new InternalError(obj.toString());
+    }
     return obj.getHandle().getOopHandleAt(getOffset());
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, 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
@@ -274,13 +274,7 @@
        // hc_klass is a HotSpot magic field and hence we can't
        // find it from InstanceKlass for java.lang.Class.
        TypeDataBase db = VM.getVM().getTypeDataBase();
-       int hcKlassOffset = (int) Instance.getHeaderSize();
-       try {
-          hcKlassOffset += (db.lookupIntConstant("java_lang_Class::hc_klass_offset").intValue() *
-                           VM.getVM().getHeapOopSize());
-       } catch (RuntimeException re) {
-          // ignore, currently java_lang_Class::hc_klass_offset is zero
-       }
+       int hcKlassOffset = (int) db.lookupType("java_lang_Class").getCIntegerField("klass_offset").getValue();
        if (VM.getVM().isCompressedOopsEnabled()) {
          hcKlassField = new NarrowOopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
        } else {
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, 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
@@ -839,13 +839,13 @@
   }
 
   private void readSystemProperties() {
-     InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
+     final InstanceKlass systemKls = getSystemDictionary().getSystemKlass();
      systemKls.iterate(new DefaultOopVisitor() {
                                ObjectReader objReader = new ObjectReader();
                                public void doOop(sun.jvm.hotspot.oops.OopField field, boolean isVMField) {
                                   if (field.getID().getName().equals("props")) {
                                      try {
-                                        sysProps = (Properties) objReader.readObject(field.getValue(getObj()));
+                                        sysProps = (Properties) objReader.readObject(field.getValue(systemKls.getJavaMirror()));
                                      } catch (Exception e) {
                                         if (Assert.ASSERTS_ENABLED) {
                                            e.printStackTrace();
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2008, 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
@@ -746,7 +746,7 @@
             out.writeByte((byte)kind);
             if (ik != null) {
                 // static field
-                writeField(field, ik);
+                writeField(field, ik.getJavaMirror());
             }
         }
     }
--- a/agent/test/jdi/sasanity.sh	Fri Mar 25 11:29:30 2011 -0700
+++ b/agent/test/jdi/sasanity.sh	Fri Mar 25 18:19:22 2011 -0400
@@ -43,6 +43,7 @@
 fi
 
 jdk=$1
+shift
 OS=`uname`
 
 if [ "$OS" != "Linux" ]; then
@@ -68,7 +69,7 @@
 
 tmp=/tmp/sagsetup
 rm -f $tmp
-$jdk/bin/java sagtarg > $tmp &
+$jdk/bin/java $* sagtarg > $tmp &
 pid=$!
 while [ ! -s $tmp ] ; do
   # Kludge alert!
--- a/make/hotspot_version	Fri Mar 25 11:29:30 2011 -0700
+++ b/make/hotspot_version	Fri Mar 25 18:19:22 2011 -0400
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=21
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=04
+HS_BUILD_NUMBER=05
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -301,7 +301,8 @@
     // thread.
     assert(_obj != noreg, "must be a valid register");
     assert(_oop_index >= 0, "must have oop index");
-    __ ld_ptr(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
+    __ load_heap_oop(_obj, java_lang_Class::klass_offset_in_bytes(), G3);
+    __ ld_ptr(G3, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc), G3);
     __ cmp(G2_thread, G3);
     __ br(Assembler::notEqual, false, Assembler::pn, call_patch);
     __ delayed()->nop();
--- a/src/cpu/sparc/vm/dump_sparc.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/sparc/vm/dump_sparc.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -80,13 +80,19 @@
     for (int j = 0; j < num_virtuals; ++j) {
       dummy_vtable[num_virtuals * i + j] = (void*)masm->pc();
       __ save(SP, -256, SP);
+      int offset = (i << 8) + j;
+      Register src = G0;
+      if (!Assembler::is_simm13(offset)) {
+        __ sethi(offset, L0);
+        src = L0;
+        offset = offset & ((1 << 10) - 1);
+      }
       __ brx(Assembler::always, false, Assembler::pt, common_code);
 
       // Load L0 with a value indicating vtable/offset pair.
       // -- bits[ 7..0]  (8 bits) which virtual method in table?
-      // -- bits[12..8]  (5 bits) which virtual method table?
-      // -- must fit in 13-bit instruction immediate field.
-      __ delayed()->set((i << 8) + j, L0);
+      // -- bits[13..8]  (6 bits) which virtual method table?
+      __ delayed()->or3(src, offset, L0);
     }
   }
 
--- a/src/cpu/sparc/vm/globals_sparc.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/sparc/vm/globals_sparc.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, 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
@@ -51,6 +51,7 @@
 define_pd_global(intx, OptoLoopAlignment,     16);  // = 4*wordSize
 define_pd_global(intx, InlineFrequencyCount,  50);  // we can use more inlining on the SPARC
 define_pd_global(intx, InlineSmallCode,       1500);
+
 #ifdef _LP64
 // Stack slots are 2X larger in LP64 than in the 32 bit VM.
 define_pd_global(intx, ThreadStackSize,       1024);
@@ -71,4 +72,6 @@
 
 define_pd_global(bool, UseMembar,            false);
 
+// GC Ergo Flags
+define_pd_global(intx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
 #endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP
--- a/src/cpu/sparc/vm/nativeInst_sparc.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/sparc/vm/nativeInst_sparc.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -52,6 +52,22 @@
   ICache::invalidate_range(instaddr, 7 * BytesPerInstWord);
 }
 
+void NativeInstruction::verify_data64_sethi(address instaddr, intptr_t x) {
+  ResourceMark rm;
+  unsigned char buffer[10 * BytesPerInstWord];
+  CodeBuffer buf(buffer, 10 * BytesPerInstWord);
+  MacroAssembler masm(&buf);
+
+  Register destreg = inv_rd(*(unsigned int *)instaddr);
+  // Generate the proper sequence into a temporary buffer and compare
+  // it with the original sequence.
+  masm.patchable_sethi(x, destreg);
+  int len = buffer - masm.pc();
+  for (int i = 0; i < len; i++) {
+    assert(instaddr[i] == buffer[i], "instructions must match");
+  }
+}
+
 void NativeInstruction::verify() {
   // make sure code pattern is actually an instruction address
   address addr = addr_at(0);
--- a/src/cpu/sparc/vm/nativeInst_sparc.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/sparc/vm/nativeInst_sparc.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -254,6 +254,7 @@
   // sethi.  This only does the sethi.  The disp field (bottom 10 bits)
   // must be handled separately.
   static void set_data64_sethi(address instaddr, intptr_t x);
+  static void verify_data64_sethi(address instaddr, intptr_t x);
 
   // combine the fields of a sethi/simm13 pair (simm13 = or, add, jmpl, ld/st)
   static int data32(int sethi_insn, int arith_insn) {
--- a/src/cpu/sparc/vm/relocInfo_sparc.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/sparc/vm/relocInfo_sparc.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -30,7 +30,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/safepoint.hpp"
 
-void Relocation::pd_set_data_value(address x, intptr_t o) {
+void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
   NativeInstruction* ip = nativeInstruction_at(addr());
   jint inst = ip->long_at(0);
   assert(inst != NativeInstruction::illegal_instruction(), "no breakpoint");
@@ -83,7 +83,11 @@
     guarantee(Assembler::is_simm13(simm13), "offset can't overflow simm13");
     inst &= ~Assembler::simm(    -1, 13);
     inst |=  Assembler::simm(simm13, 13);
-    ip->set_long_at(0, inst);
+    if (verify_only) {
+      assert(ip->long_at(0) == inst, "instructions must match");
+    } else {
+      ip->set_long_at(0, inst);
+    }
     }
     break;
 
@@ -97,19 +101,36 @@
       jint np = oopDesc::encode_heap_oop((oop)x);
       inst &= ~Assembler::hi22(-1);
       inst |=  Assembler::hi22((intptr_t)np);
-      ip->set_long_at(0, inst);
+      if (verify_only) {
+        assert(ip->long_at(0) == inst, "instructions must match");
+      } else {
+        ip->set_long_at(0, inst);
+      }
       inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
       guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
-      ip->set_long_at(NativeInstruction::nop_instruction_size, ip->set_data32_simm13( inst2, (intptr_t)np));
+      if (verify_only) {
+        assert(ip->long_at(NativeInstruction::nop_instruction_size) == NativeInstruction::set_data32_simm13( inst2, (intptr_t)np),
+               "instructions must match");
+      } else {
+        ip->set_long_at(NativeInstruction::nop_instruction_size, NativeInstruction::set_data32_simm13( inst2, (intptr_t)np));
+      }
       break;
     }
-    ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
+    if (verify_only) {
+      ip->verify_data64_sethi( ip->addr_at(0), (intptr_t)x );
+    } else {
+      ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
+    }
 #else
     guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
     inst &= ~Assembler::hi22(     -1);
     inst |=  Assembler::hi22((intptr_t)x);
     // (ignore offset; it doesn't play into the sethi)
-    ip->set_long_at(0, inst);
+    if (verify_only) {
+      assert(ip->long_at(0) == inst, "instructions must match");
+    } else {
+      ip->set_long_at(0, inst);
+    }
 #endif
     }
     break;
--- a/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -313,10 +313,13 @@
     }
     assert(_obj != noreg, "must be a valid register");
     Register tmp = rax;
-    if (_obj == tmp) tmp = rbx;
+    Register tmp2 = rbx;
     __ push(tmp);
+    __ push(tmp2);
+    __ load_heap_oop(tmp2, Address(_obj, java_lang_Class::klass_offset_in_bytes()));
     __ get_thread(tmp);
-    __ cmpptr(tmp, Address(_obj, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
+    __ cmpptr(tmp, Address(tmp2, instanceKlass::init_thread_offset_in_bytes() + sizeof(klassOopDesc)));
+    __ pop(tmp2);
     __ pop(tmp);
     __ jcc(Assembler::notEqual, call_patch);
 
--- a/src/cpu/x86/vm/globals_x86.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/x86/vm/globals_x86.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, 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
@@ -72,4 +72,6 @@
 
 define_pd_global(bool, UseMembar,            false);
 
+// GC Ergo Flags
+define_pd_global(intx, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
 #endif // CPU_X86_VM_GLOBALS_X86_HPP
--- a/src/cpu/x86/vm/relocInfo_x86.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/x86/vm/relocInfo_x86.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -31,7 +31,7 @@
 #include "runtime/safepoint.hpp"
 
 
-void Relocation::pd_set_data_value(address x, intptr_t o) {
+void Relocation::pd_set_data_value(address x, intptr_t o, bool verify_only) {
 #ifdef AMD64
   x += o;
   typedef Assembler::WhichOperand WhichOperand;
@@ -40,19 +40,35 @@
          which == Assembler::narrow_oop_operand ||
          which == Assembler::imm_operand, "format unpacks ok");
   if (which == Assembler::imm_operand) {
-    *pd_address_in_code() = x;
+    if (verify_only) {
+      assert(*pd_address_in_code() == x, "instructions must match");
+    } else {
+      *pd_address_in_code() = x;
+    }
   } else if (which == Assembler::narrow_oop_operand) {
     address disp = Assembler::locate_operand(addr(), which);
-    *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
+    if (verify_only) {
+      assert(*(uint32_t*) disp == oopDesc::encode_heap_oop((oop)x), "instructions must match");
+    } else {
+      *(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
+    }
   } else {
     // Note:  Use runtime_call_type relocations for call32_operand.
     address ip = addr();
     address disp = Assembler::locate_operand(ip, which);
     address next_ip = Assembler::locate_next_instruction(ip);
-    *(int32_t*) disp = x - next_ip;
+    if (verify_only) {
+      assert(*(int32_t*) disp == (x - next_ip), "instructions must match");
+    } else {
+      *(int32_t*) disp = x - next_ip;
+    }
   }
 #else
-  *pd_address_in_code() = x + o;
+  if (verify_only) {
+    assert(*pd_address_in_code() == (x + o), "instructions must match");
+  } else {
+    *pd_address_in_code() = x + o;
+  }
 #endif // AMD64
 }
 
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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.
  * Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -281,7 +281,7 @@
 
     if (method->is_static()) {
       istate->set_oop_temp(
-        method->constants()->pool_holder()->klass_part()->java_mirror());
+        method->constants()->pool_holder()->java_mirror());
       mirror = istate->oop_temp_addr();
       *(dst++) = &mirror;
     }
@@ -667,7 +667,7 @@
       (BasicObjectLock *) stack->alloc(monitor_words * wordSize);
     oop object;
     if (method->is_static())
-      object = method->constants()->pool_holder()->klass_part()->java_mirror();
+      object = method->constants()->pool_holder()->java_mirror();
     else
       object = (oop) locals[0];
     monitor->set_obj(object);
--- a/src/os/windows/vm/os_windows.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/os/windows/vm/os_windows.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -3297,9 +3297,14 @@
          "possibility of dangling Thread pointer");
 
   OSThread* osthread = thread->osthread();
-  bool interrupted;
-  interrupted = osthread->interrupted();
-  if (clear_interrupted == true) {
+  bool interrupted = osthread->interrupted();
+  // There is no synchronization between the setting of the interrupt
+  // and it being cleared here. It is critical - see 6535709 - that
+  // we only clear the interrupt state, and reset the interrupt event,
+  // if we are going to report that we were indeed interrupted - else
+  // an interrupt can be "lost", leading to spurious wakeups or lost wakeups
+  // depending on the timing
+  if (interrupted && clear_interrupted) {
     osthread->set_interrupted(false);
     ResetEvent(osthread->interrupt_event());
   } // Otherwise leave the interrupted state alone
--- a/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1471,9 +1471,9 @@
   if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
     if (state_before != NULL) {
       // build a patching constant
-      obj = new Constant(new ClassConstant(holder), state_before);
+      obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before);
     } else {
-      obj = new Constant(new ClassConstant(holder));
+      obj = new Constant(new InstanceConstant(holder->java_mirror()));
     }
   }
 
--- a/src/share/vm/c1/c1_Runtime1.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -808,7 +808,7 @@
         { klassOop klass = resolve_field_return_klass(caller_method, bci, CHECK);
           // Save a reference to the class that has to be checked for initialization
           init_klass = KlassHandle(THREAD, klass);
-          k = klass;
+          k = klass->java_mirror();
         }
         break;
       case Bytecodes::_new:
--- a/src/share/vm/ci/ciCPCache.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/ci/ciCPCache.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,8 +46,7 @@
 // ciCPCache::is_f1_null_at
 bool ciCPCache::is_f1_null_at(int index) {
   VM_ENTRY_MARK;
-  oop f1 = entry_at(index)->f1();
-  return (f1 == NULL);
+  return entry_at(index)->is_f1_null();
 }
 
 
--- a/src/share/vm/ci/ciField.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/ci/ciField.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -213,7 +213,7 @@
     //    may change.  The three examples are java.lang.System.in,
     //    java.lang.System.out, and java.lang.System.err.
 
-    Handle k = _holder->get_klassOop();
+    KlassHandle k = _holder->get_klassOop();
     assert( SystemDictionary::System_klass() != NULL, "Check once per vm");
     if( k() == SystemDictionary::System_klass() ) {
       // Check offsets for case 2: System.in, System.out, or System.err
@@ -225,36 +225,38 @@
       }
     }
 
+    Handle mirror = k->java_mirror();
+
     _is_constant = true;
     switch(type()->basic_type()) {
     case T_BYTE:
-      _constant_value = ciConstant(type()->basic_type(), k->byte_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset));
       break;
     case T_CHAR:
-      _constant_value = ciConstant(type()->basic_type(), k->char_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->char_field(_offset));
       break;
     case T_SHORT:
-      _constant_value = ciConstant(type()->basic_type(), k->short_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->short_field(_offset));
       break;
     case T_BOOLEAN:
-      _constant_value = ciConstant(type()->basic_type(), k->bool_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->bool_field(_offset));
       break;
     case T_INT:
-      _constant_value = ciConstant(type()->basic_type(), k->int_field(_offset));
+      _constant_value = ciConstant(type()->basic_type(), mirror->int_field(_offset));
       break;
     case T_FLOAT:
-      _constant_value = ciConstant(k->float_field(_offset));
+      _constant_value = ciConstant(mirror->float_field(_offset));
       break;
     case T_DOUBLE:
-      _constant_value = ciConstant(k->double_field(_offset));
+      _constant_value = ciConstant(mirror->double_field(_offset));
       break;
     case T_LONG:
-      _constant_value = ciConstant(k->long_field(_offset));
+      _constant_value = ciConstant(mirror->long_field(_offset));
       break;
     case T_OBJECT:
     case T_ARRAY:
       {
-        oop o = k->obj_field(_offset);
+        oop o = mirror->obj_field(_offset);
 
         // A field will be "constant" if it is known always to be
         // a non-null reference to an instance of a particular class,
--- a/src/share/vm/ci/ciInstance.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/ci/ciInstance.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -138,3 +138,9 @@
   st->print(" type=");
   klass()->print(st);
 }
+
+
+ciKlass* ciInstance::java_lang_Class_klass() {
+  VM_ENTRY_MARK;
+  return CURRENT_ENV->get_object(java_lang_Class::as_klassOop(get_oop()))->as_klass();
+}
--- a/src/share/vm/ci/ciInstance.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/ci/ciInstance.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -64,6 +64,8 @@
 
   // Constant value of a field at the specified offset.
   ciConstant field_value_by_offset(int field_offset);
+
+  ciKlass* java_lang_Class_klass();
 };
 
 #endif // SHARE_VM_CI_CIINSTANCE_HPP
--- a/src/share/vm/ci/ciInstanceKlass.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/ci/ciInstanceKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -85,7 +85,6 @@
     if (h_k() != SystemDictionary::Object_klass()) {
       super();
     }
-    java_mirror();
     //compute_nonstatic_fields();  // done outside of constructor
   }
 
@@ -320,6 +319,9 @@
 // Get the instance of java.lang.Class corresponding to this klass.
 // Cache it on this->_java_mirror.
 ciInstance* ciInstanceKlass::java_mirror() {
+  if (is_shared()) {
+    return ciKlass::java_mirror();
+  }
   if (_java_mirror == NULL) {
     _java_mirror = ciKlass::java_mirror();
   }
--- a/src/share/vm/ci/ciObjectFactory.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/ci/ciObjectFactory.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -663,7 +663,7 @@
   if (key->is_perm() && _non_perm_count == 0) {
     return emptyBucket;
   } else if (key->is_instance()) {
-    if (key->klass() == SystemDictionary::Class_klass()) {
+    if (key->klass() == SystemDictionary::Class_klass() && JavaObjectsInPerm) {
       // class mirror instances are always perm
       return emptyBucket;
     }
--- a/src/share/vm/classfile/classFileParser.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/classfile/classFileParser.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -37,6 +37,7 @@
 #include "memory/universe.inline.hpp"
 #include "oops/constantPoolOop.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/klass.inline.hpp"
 #include "oops/klassOop.hpp"
 #include "oops/klassVtable.hpp"
@@ -2606,54 +2607,6 @@
 }
 
 
-static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
-  KlassHandle h_k (THREAD, fd->field_holder());
-  assert(h_k.not_null() && fd->is_static(), "just checking");
-  if (fd->has_initial_value()) {
-    BasicType t = fd->field_type();
-    switch (t) {
-      case T_BYTE:
-        h_k()->byte_field_put(fd->offset(), fd->int_initial_value());
-              break;
-      case T_BOOLEAN:
-        h_k()->bool_field_put(fd->offset(), fd->int_initial_value());
-              break;
-      case T_CHAR:
-        h_k()->char_field_put(fd->offset(), fd->int_initial_value());
-              break;
-      case T_SHORT:
-        h_k()->short_field_put(fd->offset(), fd->int_initial_value());
-              break;
-      case T_INT:
-        h_k()->int_field_put(fd->offset(), fd->int_initial_value());
-        break;
-      case T_FLOAT:
-        h_k()->float_field_put(fd->offset(), fd->float_initial_value());
-        break;
-      case T_DOUBLE:
-        h_k()->double_field_put(fd->offset(), fd->double_initial_value());
-        break;
-      case T_LONG:
-        h_k()->long_field_put(fd->offset(), fd->long_initial_value());
-        break;
-      case T_OBJECT:
-        {
-          #ifdef ASSERT
-          TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK);
-          assert(fd->signature() == sym, "just checking");
-          #endif
-          oop string = fd->string_initial_value(CHECK);
-          h_k()->obj_field_put(fd->offset(), string);
-        }
-        break;
-      default:
-        THROW_MSG(vmSymbols::java_lang_ClassFormatError(),
-                  "Illegal ConstantValue attribute in class file");
-    }
-  }
-}
-
-
 void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
   constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS) {
   // This code is for compatibility with earlier jdk's that do not
@@ -2769,8 +2722,8 @@
 }
 
 
-void ClassFileParser::java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
-  FieldAllocationCount *fac_ptr, TRAPS) {
+void ClassFileParser::java_lang_Class_fix_pre(int* nonstatic_field_size,
+                                              FieldAllocationCount *fac_ptr) {
   // Add fake fields for java.lang.Class instances
   //
   // This is not particularly nice. We should consider adding a
@@ -2787,10 +2740,13 @@
   // versions because when the offsets are computed at bootstrap
   // time we don't know yet which version of the JDK we're running in.
 
-  // The values below are fake but will force two non-static oop fields and
+  // The values below are fake but will force three non-static oop fields and
   // a corresponding non-static oop map block to be allocated.
   const int extra = java_lang_Class::number_of_fake_oop_fields;
   fac_ptr->nonstatic_oop_count += extra;
+
+  // Reserve some leading space for fake ints
+  *nonstatic_field_size += align_size_up(java_lang_Class::hc_number_of_fake_int_fields * BytesPerInt, heapOopSize) / heapOopSize;
 }
 
 
@@ -3205,9 +3161,7 @@
     int next_nonstatic_field_offset;
 
     // Calculate the starting byte offsets
-    next_static_oop_offset      = (instanceKlass::header_size() +
-                                  align_object_offset(vtable_size) +
-                                  align_object_offset(itable_size)) * wordSize;
+    next_static_oop_offset      = instanceMirrorKlass::offset_of_static_fields();
     next_static_double_offset   = next_static_oop_offset +
                                   (fac.static_oop_count * heapOopSize);
     if ( fac.static_double_count &&
@@ -3226,15 +3180,16 @@
                                   fac.static_byte_count ), wordSize );
     static_field_size           = (next_static_type_offset -
                                   next_static_oop_offset) / wordSize;
+
+    // Add fake fields for java.lang.Class instances (also see below)
+    if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
+      java_lang_Class_fix_pre(&nonstatic_field_size, &fac);
+    }
+
     first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
                                    nonstatic_field_size * heapOopSize;
     next_nonstatic_field_offset = first_nonstatic_field_offset;
 
-    // Add fake fields for java.lang.Class instances (also see below)
-    if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) {
-      java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
-    }
-
     // adjust the vmentry field declaration in java.lang.invoke.MethodHandle
     if (EnableMethodHandles && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) {
       java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
@@ -3566,7 +3521,7 @@
     }
 
     // We can now create the basic klassOop for this klass
-    klassOop ik = oopFactory::new_instanceKlass(vtable_size, itable_size,
+    klassOop ik = oopFactory::new_instanceKlass(name, vtable_size, itable_size,
                                                 static_field_size,
                                                 total_oop_map_count,
                                                 rt, CHECK_(nullHandle));
@@ -3588,7 +3543,7 @@
     this_klass->set_class_loader(class_loader());
     this_klass->set_nonstatic_field_size(nonstatic_field_size);
     this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
-    this_klass->set_static_oop_field_size(fac.static_oop_count);
+    this_klass->set_static_oop_field_count(fac.static_oop_count);
     cp->set_pool_holder(this_klass());
     error_handler.set_in_error(false);   // turn off error handler for cp
     this_klass->set_constants(cp());
@@ -3649,9 +3604,6 @@
     // Make sure this is the end of class file stream
     guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
 
-    // Initialize static fields
-    this_klass->do_local_static_fields(&initialize_static_field, CHECK_(nullHandle));
-
     // VerifyOops believes that once this has been set, the object is completely loaded.
     // Compute transitive closure of interfaces this class implements
     this_klass->set_transitive_interfaces(transitive_interfaces());
@@ -3685,6 +3637,9 @@
       check_illegal_static_method(this_klass, CHECK_(nullHandle));
     }
 
+    // Allocate mirror and initialize static fields
+    java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
+
     ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()),
                                              false /* not shared class */);
 
--- a/src/share/vm/classfile/classFileParser.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/classfile/classFileParser.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -154,11 +154,12 @@
   // Add the "discovered" field to java.lang.ref.Reference if
   // it does not exist.
   void java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr,
-    constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS);
+                                       constantPoolHandle cp,
+                                       FieldAllocationCount *fac_ptr, TRAPS);
   // Adjust the field allocation counts for java.lang.Class to add
   // fake fields.
-  void java_lang_Class_fix_pre(objArrayHandle* methods_ptr,
-    FieldAllocationCount *fac_ptr, TRAPS);
+  void java_lang_Class_fix_pre(int* nonstatic_field_size,
+                               FieldAllocationCount *fac_ptr);
   // Adjust the next_nonstatic_oop_offset to place the fake fields
   // before any Java fields.
   void java_lang_Class_fix_post(int* next_nonstatic_oop_offset);
--- a/src/share/vm/classfile/javaClasses.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -33,6 +33,7 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/klass.hpp"
 #include "oops/klassOop.hpp"
 #include "oops/methodOop.hpp"
@@ -161,7 +162,7 @@
 }
 
 Handle java_lang_String::create_tenured_from_unicode(jchar* unicode, int length, TRAPS) {
-  return basic_create_from_unicode(unicode, length, true, CHECK_NH);
+  return basic_create_from_unicode(unicode, length, JavaObjectsInPerm, CHECK_NH);
 }
 
 oop java_lang_String::create_oop_from_unicode(jchar* unicode, int length, TRAPS) {
@@ -391,6 +392,75 @@
   }
 }
 
+static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
+  Handle mirror (THREAD, fd->field_holder()->java_mirror());
+  assert(mirror.not_null() && fd->is_static(), "just checking");
+  if (fd->has_initial_value()) {
+    BasicType t = fd->field_type();
+    switch (t) {
+      case T_BYTE:
+        mirror()->byte_field_put(fd->offset(), fd->int_initial_value());
+              break;
+      case T_BOOLEAN:
+        mirror()->bool_field_put(fd->offset(), fd->int_initial_value());
+              break;
+      case T_CHAR:
+        mirror()->char_field_put(fd->offset(), fd->int_initial_value());
+              break;
+      case T_SHORT:
+        mirror()->short_field_put(fd->offset(), fd->int_initial_value());
+              break;
+      case T_INT:
+        mirror()->int_field_put(fd->offset(), fd->int_initial_value());
+        break;
+      case T_FLOAT:
+        mirror()->float_field_put(fd->offset(), fd->float_initial_value());
+        break;
+      case T_DOUBLE:
+        mirror()->double_field_put(fd->offset(), fd->double_initial_value());
+        break;
+      case T_LONG:
+        mirror()->long_field_put(fd->offset(), fd->long_initial_value());
+        break;
+      case T_OBJECT:
+        {
+          #ifdef ASSERT
+          TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK);
+          assert(fd->signature() == sym, "just checking");
+          #endif
+          oop string = fd->string_initial_value(CHECK);
+          mirror()->obj_field_put(fd->offset(), string);
+        }
+        break;
+      default:
+        THROW_MSG(vmSymbols::java_lang_ClassFormatError(),
+                  "Illegal ConstantValue attribute in class file");
+    }
+  }
+}
+
+
+// During bootstrap, java.lang.Class wasn't loaded so static field
+// offsets were computed without the size added it.  Go back and
+// update all the static field offsets to included the size.
+static void fixup_static_field(fieldDescriptor* fd, TRAPS) {
+  if (fd->is_static()) {
+    int real_offset = fd->offset() + instanceMirrorKlass::offset_of_static_fields();
+    typeArrayOop fields = instanceKlass::cast(fd->field_holder())->fields();
+    fields->short_at_put(fd->index() + instanceKlass::low_offset,  extract_low_short_from_int(real_offset));
+    fields->short_at_put(fd->index() + instanceKlass::high_offset, extract_high_short_from_int(real_offset));
+  }
+}
+
+void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
+  assert(instanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already");
+
+  if (k->oop_is_instance()) {
+    // Fixup the offsets
+    instanceKlass::cast(k())->do_local_static_fields(&fixup_static_field, CHECK);
+  }
+  create_mirror(k, CHECK);
+}
 
 oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
   assert(k->java_mirror() == NULL, "should only assign mirror once");
@@ -400,12 +470,17 @@
   // class is put into the system dictionary.
   int computed_modifiers = k->compute_modifier_flags(CHECK_0);
   k->set_modifier_flags(computed_modifiers);
-  if (SystemDictionary::Class_klass_loaded()) {
+  if (SystemDictionary::Class_klass_loaded() && (k->oop_is_instance() || k->oop_is_javaArray())) {
     // Allocate mirror (java.lang.Class instance)
-    Handle mirror = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0);
+    Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
     // Setup indirections
     mirror->obj_field_put(klass_offset,  k());
     k->set_java_mirror(mirror());
+
+    instanceMirrorKlass* mk = instanceMirrorKlass::cast(mirror->klass());
+    java_lang_Class::set_oop_size(mirror(), mk->instance_size(k));
+    java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
+
     // It might also have a component mirror.  This mirror must already exist.
     if (k->oop_is_javaArray()) {
       Handle comp_mirror;
@@ -428,6 +503,9 @@
         arrayKlass::cast(k->as_klassOop())->set_component_mirror(comp_mirror());
         set_array_klass(comp_mirror(), k->as_klassOop());
       }
+    } else if (k->oop_is_instance()) {
+      // Initialize static fields
+      instanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
     }
     return mirror();
   } else {
@@ -436,21 +514,46 @@
 }
 
 
+
+int  java_lang_Class::oop_size(oop java_class) {
+  assert(oop_size_offset != 0, "must be set");
+  return java_class->int_field(oop_size_offset);
+}
+void java_lang_Class::set_oop_size(oop java_class, int size) {
+  assert(oop_size_offset != 0, "must be set");
+  java_class->int_field_put(oop_size_offset, size);
+}
+int  java_lang_Class::static_oop_field_count(oop java_class) {
+  assert(static_oop_field_count_offset != 0, "must be set");
+  return java_class->int_field(static_oop_field_count_offset);
+}
+void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
+  assert(static_oop_field_count_offset != 0, "must be set");
+  java_class->int_field_put(static_oop_field_count_offset, size);
+}
+
+
+
+
 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
   // This should be improved by adding a field at the Java level or by
   // introducing a new VM klass (see comment in ClassFileParser)
-  oop java_class = instanceKlass::cast(SystemDictionary::Class_klass())->allocate_permanent_instance(CHECK_0);
+  oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0);
   if (type != T_VOID) {
     klassOop aklass = Universe::typeArrayKlassObj(type);
     assert(aklass != NULL, "correct bootstrap");
     set_array_klass(java_class, aklass);
   }
+  instanceMirrorKlass* mk = instanceMirrorKlass::cast(SystemDictionary::Class_klass());
+  java_lang_Class::set_oop_size(java_class, mk->instance_size(oop(NULL)));
+  java_lang_Class::set_static_oop_field_count(java_class, 0);
   return java_class;
 }
 
 
 klassOop java_lang_Class::as_klassOop(oop java_class) {
   //%note memory_2
+  assert(java_lang_Class::is_instance(java_class), "must be a Class object");
   klassOop k = klassOop(java_class->obj_field(klass_offset));
   assert(k == NULL || k->is_klass(), "type check");
   return k;
@@ -2152,7 +2255,7 @@
 // Support for java_lang_ref_Reference
 oop java_lang_ref_Reference::pending_list_lock() {
   instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
-  char *addr = (((char *)ik->start_of_static_fields()) + static_lock_offset);
+  address addr = ik->static_field_addr(static_lock_offset);
   if (UseCompressedOops) {
     return oopDesc::load_decode_heap_oop((narrowOop *)addr);
   } else {
@@ -2162,7 +2265,7 @@
 
 HeapWord *java_lang_ref_Reference::pending_list_addr() {
   instanceKlass* ik = instanceKlass::cast(SystemDictionary::Reference_klass());
-  char *addr = (((char *)ik->start_of_static_fields()) + static_pending_offset);
+  address addr = ik->static_field_addr(static_pending_offset);
   // XXX This might not be HeapWord aligned, almost rather be char *.
   return (HeapWord*)addr;
 }
@@ -2185,16 +2288,14 @@
 
 jlong java_lang_ref_SoftReference::clock() {
   instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
-  int offset = ik->offset_of_static_fields() + static_clock_offset;
-
-  return SystemDictionary::SoftReference_klass()->long_field(offset);
+  jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
+  return *offset;
 }
 
 void java_lang_ref_SoftReference::set_clock(jlong value) {
   instanceKlass* ik = instanceKlass::cast(SystemDictionary::SoftReference_klass());
-  int offset = ik->offset_of_static_fields() + static_clock_offset;
-
-  SystemDictionary::SoftReference_klass()->long_field_put(offset, value);
+  jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
+  *offset = value;
 }
 
 
@@ -2625,26 +2726,18 @@
 
 
 // Support for java_lang_System
-
-void java_lang_System::compute_offsets() {
-  assert(offset_of_static_fields == 0, "offsets should be initialized only once");
-
-  instanceKlass* ik = instanceKlass::cast(SystemDictionary::System_klass());
-  offset_of_static_fields = ik->offset_of_static_fields();
+int java_lang_System::in_offset_in_bytes() {
+  return (instanceMirrorKlass::offset_of_static_fields() + static_in_offset);
 }
 
-int java_lang_System::in_offset_in_bytes() {
-  return (offset_of_static_fields + static_in_offset);
+
+int java_lang_System::out_offset_in_bytes() {
+  return (instanceMirrorKlass::offset_of_static_fields() + static_out_offset);
 }
 
 
-int java_lang_System::out_offset_in_bytes() {
-  return (offset_of_static_fields + static_out_offset);
-}
-
-
 int java_lang_System::err_offset_in_bytes() {
-  return (offset_of_static_fields + static_err_offset);
+  return (instanceMirrorKlass::offset_of_static_fields() + static_err_offset);
 }
 
 
@@ -2657,6 +2750,8 @@
 int java_lang_Class::array_klass_offset;
 int java_lang_Class::resolved_constructor_offset;
 int java_lang_Class::number_of_fake_oop_fields;
+int java_lang_Class::oop_size_offset;
+int java_lang_Class::static_oop_field_count_offset;
 int java_lang_Throwable::backtrace_offset;
 int java_lang_Throwable::detailMessage_offset;
 int java_lang_Throwable::cause_offset;
@@ -2700,7 +2795,6 @@
 int java_lang_ref_SoftReference::timestamp_offset;
 int java_lang_ref_SoftReference::static_clock_offset;
 int java_lang_ClassLoader::parent_offset;
-int java_lang_System::offset_of_static_fields;
 int java_lang_System::static_in_offset;
 int java_lang_System::static_out_offset;
 int java_lang_System::static_err_offset;
@@ -2817,10 +2911,19 @@
   java_lang_String::count_offset  = java_lang_String::offset_offset + sizeof (jint);
   java_lang_String::hash_offset   = java_lang_String::count_offset + sizeof (jint);
 
-  // Do the Class Class
-  java_lang_Class::klass_offset = java_lang_Class::hc_klass_offset * x + header;
-  java_lang_Class::array_klass_offset = java_lang_Class::hc_array_klass_offset * x + header;
-  java_lang_Class::resolved_constructor_offset = java_lang_Class::hc_resolved_constructor_offset * x + header;
+  {
+    // Do the Class Class
+    int offset = header;
+    java_lang_Class::oop_size_offset = header;
+    offset += BytesPerInt;
+    java_lang_Class::static_oop_field_count_offset = offset;
+    offset = align_size_up(offset + BytesPerInt, x);
+    java_lang_Class::klass_offset = offset;
+    offset += x;
+    java_lang_Class::array_klass_offset = offset;
+    offset += x;
+    java_lang_Class::resolved_constructor_offset = offset;
+  }
 
   // This is NOT an offset
   java_lang_Class::number_of_fake_oop_fields = java_lang_Class::hc_number_of_fake_oop_fields;
@@ -2877,7 +2980,6 @@
 void JavaClasses::compute_offsets() {
 
   java_lang_Class::compute_offsets();
-  java_lang_System::compute_offsets();
   java_lang_Thread::compute_offsets();
   java_lang_ThreadGroup::compute_offsets();
   if (EnableMethodHandles) {
@@ -2961,10 +3063,10 @@
     tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name);
     return false;
   }
-  if (fd.offset() == hardcoded_offset + h_klass->offset_of_static_fields()) {
+  if (fd.offset() == hardcoded_offset + instanceMirrorKlass::offset_of_static_fields()) {
     return true;
   } else {
-    tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - h_klass->offset_of_static_fields());
+    tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - instanceMirrorKlass::offset_of_static_fields());
     return false;
   }
 }
--- a/src/share/vm/classfile/javaClasses.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -138,10 +138,8 @@
   // The fake offsets are added by the class loader when java.lang.Class is loaded
 
   enum {
-    hc_klass_offset                = 0,
-    hc_array_klass_offset          = 1,
-    hc_resolved_constructor_offset = 2,
-    hc_number_of_fake_oop_fields   = 3
+    hc_number_of_fake_oop_fields   = 3,
+    hc_number_of_fake_int_fields   = 2
   };
 
   static int klass_offset;
@@ -149,6 +147,9 @@
   static int array_klass_offset;
   static int number_of_fake_oop_fields;
 
+  static int oop_size_offset;
+  static int static_oop_field_count_offset;
+
   static void compute_offsets();
   static bool offsets_computed;
   static int classRedefinedCount_offset;
@@ -157,6 +158,7 @@
  public:
   // Instance creation
   static oop  create_mirror(KlassHandle k, TRAPS);
+  static void fixup_mirror(KlassHandle k, TRAPS);
   static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
   // Conversion
   static klassOop as_klassOop(oop java_class);
@@ -191,6 +193,12 @@
   static void set_classRedefinedCount(oop the_class_mirror, int value);
   // Support for parallelCapable field
   static bool parallelCapable(oop the_class_mirror);
+
+  static int oop_size(oop java_class);
+  static void set_oop_size(oop java_class, int size);
+  static int static_oop_field_count(oop java_class);
+  static void set_static_oop_field_count(oop java_class, int size);
+
   // Debugging
   friend class JavaClasses;
   friend class instanceKlass;   // verification code accesses offsets
@@ -1165,13 +1173,10 @@
    hc_static_err_offset = 2
   };
 
-  static int offset_of_static_fields;
   static int  static_in_offset;
   static int static_out_offset;
   static int static_err_offset;
 
-  static void compute_offsets();
-
  public:
   static int  in_offset_in_bytes();
   static int out_offset_in_bytes();
--- a/src/share/vm/classfile/symbolTable.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/classfile/symbolTable.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -530,7 +530,7 @@
 
   Handle string;
   // try to reuse the string if possible
-  if (!string_or_null.is_null() && string_or_null()->is_perm()) {
+  if (!string_or_null.is_null() && (!JavaObjectsInPerm || string_or_null()->is_perm())) {
     string = string_or_null;
   } else {
     string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL);
@@ -662,7 +662,7 @@
     for ( ; p != NULL; p = p->next()) {
       oop s = p->literal();
       guarantee(s != NULL, "interned string is NULL");
-      guarantee(s->is_perm(), "interned string not in permspace");
+      guarantee(s->is_perm() || !JavaObjectsInPerm, "interned string not in permspace");
 
       int length;
       jchar* chars = java_lang_String::as_unicode_string(s, length);
--- a/src/share/vm/classfile/symbolTable.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/classfile/symbolTable.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -216,18 +216,14 @@
   oop basic_add(int index, Handle string_or_null, jchar* name, int len,
                 unsigned int hashValue, TRAPS);
 
-  // Table size
-  enum {
-    string_table_size = 1009
-  };
-
   oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
 
-  StringTable() : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>)) {}
+  StringTable() : Hashtable<oop>((int)StringTableSize,
+                                 sizeof (HashtableEntry<oop>)) {}
 
   StringTable(HashtableBucket* t, int number_of_entries)
-    : Hashtable<oop>(string_table_size, sizeof (HashtableEntry<oop>), t,
-                number_of_entries) {}
+    : Hashtable<oop>((int)StringTableSize, sizeof (HashtableEntry<oop>), t,
+                     number_of_entries) {}
 
 public:
   // The string table
@@ -241,7 +237,7 @@
   static void create_table(HashtableBucket* t, int length,
                            int number_of_entries) {
     assert(_the_table == NULL, "One string table allowed.");
-    assert(length == string_table_size * sizeof(HashtableBucket),
+    assert((size_t)length == StringTableSize * sizeof(HashtableBucket),
            "bad shared string size.");
     _the_table = new StringTable(t, number_of_entries);
   }
--- a/src/share/vm/code/codeCache.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/code/codeCache.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -337,7 +337,6 @@
     if (is_live) {
       // Perform cur->oops_do(f), maybe just once per nmethod.
       f->do_code_blob(cur);
-      cur->fix_oop_relocations();
     }
   }
 
@@ -552,6 +551,19 @@
 }
 
 
+void CodeCache::verify_oops() {
+  MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+  VerifyOopClosure voc;
+  FOR_ALL_ALIVE_BLOBS(cb) {
+    if (cb->is_nmethod()) {
+      nmethod *nm = (nmethod*)cb;
+      nm->oops_do(&voc);
+      nm->verify_oop_relocations();
+    }
+  }
+}
+
+
 address CodeCache::first_address() {
   assert_locked_or_safepoint(CodeCache_lock);
   return (address)_heap->begin();
--- a/src/share/vm/code/codeCache.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/code/codeCache.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -122,6 +122,7 @@
   // GC support
   static void gc_epilogue();
   static void gc_prologue();
+  static void verify_oops();
   // If "unloading_occurred" is true, then unloads (i.e., breaks root links
   // to) any unmarked codeBlobs in the cache.  Sets "marked_for_unloading"
   // to "true" iff some code got unloaded.
--- a/src/share/vm/code/nmethod.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/code/nmethod.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -653,6 +653,9 @@
     _pc_desc_cache.reset_to(NULL);
 
     code_buffer->copy_oops_to(this);
+    if (ScavengeRootsInCode && detect_scavenge_root_oops()) {
+      CodeCache::add_scavenge_root_nmethod(this);
+    }
     debug_only(verify_scavenge_root_oops());
     CodeCache::commit(this);
   }
@@ -1105,6 +1108,20 @@
 }
 
 
+void nmethod::verify_oop_relocations() {
+  // Ensure sure that the code matches the current oop values
+  RelocIterator iter(this, NULL, NULL);
+  while (iter.next()) {
+    if (iter.type() == relocInfo::oop_type) {
+      oop_Relocation* reloc = iter.oop_reloc();
+      if (!reloc->oop_is_immediate()) {
+        reloc->verify_oop_relocation();
+      }
+    }
+  }
+}
+
+
 ScopeDesc* nmethod::scope_desc_at(address pc) {
   PcDesc* pd = pc_desc_at(pc);
   guarantee(pd != NULL, "scope must be present");
@@ -1823,6 +1840,7 @@
     assert(cur != NULL, "not NULL-terminated");
     nmethod* next = cur->_oops_do_mark_link;
     cur->_oops_do_mark_link = NULL;
+    cur->fix_oop_relocations();
     NOT_PRODUCT(if (TraceScavenge)  cur->print_on(tty, "oops_do, unmark\n"));
     cur = next;
   }
--- a/src/share/vm/code/nmethod.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/code/nmethod.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -459,6 +459,7 @@
 public:
   void fix_oop_relocations(address begin, address end) { fix_oop_relocations(begin, end, false); }
   void fix_oop_relocations()                           { fix_oop_relocations(NULL, NULL, false); }
+  void verify_oop_relocations();
 
   bool is_at_poll_return(address pc);
   bool is_at_poll_or_poll_return(address pc);
--- a/src/share/vm/code/relocInfo.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/code/relocInfo.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -798,6 +798,14 @@
 }
 
 
+void oop_Relocation::verify_oop_relocation() {
+  if (!oop_is_immediate()) {
+    // get the oop from the pool, and re-insert it into the instruction:
+    verify_value(value());
+  }
+}
+
+
 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
                                                 oop* &oop_addr, bool *is_optimized) {
   assert(ic_call != NULL, "ic_call address must be set");
--- a/src/share/vm/code/relocInfo.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/code/relocInfo.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -765,7 +765,8 @@
 
  protected:
   // platform-dependent utilities for decoding and patching instructions
-  void       pd_set_data_value       (address x, intptr_t off); // a set or mem-ref
+  void       pd_set_data_value       (address x, intptr_t off, bool verify_only = false); // a set or mem-ref
+  void       pd_verify_data_value    (address x, intptr_t off) { pd_set_data_value(x, off, true); }
   address    pd_call_destination     (address orig_addr = NULL);
   void       pd_set_call_destination (address x);
   void       pd_swap_in_breakpoint   (address x, short* instrs, int instrlen);
@@ -880,6 +881,12 @@
     else
       pd_set_data_value(x, o);
   }
+  void        verify_value(address x) {
+    if (addr_in_const())
+      assert(*(address*)addr() == x, "must agree");
+    else
+      pd_verify_data_value(x, offset());
+  }
 
   // The "o" (displacement) argument is relevant only to split relocations
   // on RISC machines.  In some CPUs (SPARC), the set-hi and set-lo ins'ns
@@ -950,6 +957,8 @@
 
   void fix_oop_relocation();        // reasserts oop value
 
+  void verify_oop_relocation();
+
   address value()  { return (address) *oop_addr(); }
 
   bool oop_is_immediate()  { return oop_index() == 0; }
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -292,13 +292,15 @@
 void CMSCollector::ref_processor_init() {
   if (_ref_processor == NULL) {
     // Allocate and initialize a reference processor
-    _ref_processor = ReferenceProcessor::create_ref_processor(
-        _span,                               // span
-        _cmsGen->refs_discovery_is_atomic(), // atomic_discovery
-        _cmsGen->refs_discovery_is_mt(),     // mt_discovery
-        &_is_alive_closure,
-        ParallelGCThreads,
-        ParallelRefProcEnabled);
+    _ref_processor =
+      new ReferenceProcessor(_span,                               // span
+                             (ParallelGCThreads > 1) && ParallelRefProcEnabled, // mt processing
+                             (int) ParallelGCThreads,             // mt processing degree
+                             _cmsGen->refs_discovery_is_mt(),     // mt discovery
+                             (int) MAX2(ConcGCThreads, ParallelGCThreads), // mt discovery degree
+                             _cmsGen->refs_discovery_is_atomic(), // discovery is not atomic
+                             &_is_alive_closure,                  // closure for liveness info
+                             false);                              // next field updates do not need write barrier
     // Initialize the _ref_processor field of CMSGen
     _cmsGen->set_ref_processor(_ref_processor);
 
@@ -641,7 +643,7 @@
   }
 
   // Support for multi-threaded concurrent phases
-  if (CollectedHeap::use_parallel_gc_threads() && CMSConcurrentMTEnabled) {
+  if (CMSConcurrentMTEnabled) {
     if (FLAG_IS_DEFAULT(ConcGCThreads)) {
       // just for now
       FLAG_SET_DEFAULT(ConcGCThreads, (ParallelGCThreads + 3)/4);
@@ -1689,6 +1691,8 @@
     MutexLockerEx y(CGC_lock, Mutex::_no_safepoint_check_flag);
     _full_gc_requested = true;
     CGC_lock->notify();   // nudge CMS thread
+  } else {
+    assert(gc_count > full_gc_count, "Error: causal loop");
   }
 }
 
@@ -1988,17 +1992,16 @@
   // Temporarily widen the span of the weak reference processing to
   // the entire heap.
   MemRegion new_span(GenCollectedHeap::heap()->reserved_region());
-  ReferenceProcessorSpanMutator x(ref_processor(), new_span);
-
+  ReferenceProcessorSpanMutator rp_mut_span(ref_processor(), new_span);
   // Temporarily, clear the "is_alive_non_header" field of the
   // reference processor.
-  ReferenceProcessorIsAliveMutator y(ref_processor(), NULL);
-
+  ReferenceProcessorIsAliveMutator rp_mut_closure(ref_processor(), NULL);
   // Temporarily make reference _processing_ single threaded (non-MT).
-  ReferenceProcessorMTProcMutator z(ref_processor(), false);
-
+  ReferenceProcessorMTProcMutator rp_mut_mt_processing(ref_processor(), false);
   // Temporarily make refs discovery atomic
-  ReferenceProcessorAtomicMutator w(ref_processor(), true);
+  ReferenceProcessorAtomicMutator rp_mut_atomic(ref_processor(), true);
+  // Temporarily make reference _discovery_ single threaded (non-MT)
+  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
 
   ref_processor()->set_enqueuing_is_done(false);
   ref_processor()->enable_discovery();
@@ -4263,9 +4266,7 @@
 
   // Refs discovery is already non-atomic.
   assert(!ref_processor()->discovery_is_atomic(), "Should be non-atomic");
-  // Mutate the Refs discovery so it is MT during the
-  // multi-threaded marking phase.
-  ReferenceProcessorMTMutator mt(ref_processor(), num_workers > 1);
+  assert(ref_processor()->discovery_is_mt(), "Discovery should be MT");
   DEBUG_ONLY(RememberKlassesChecker cmx(should_unload_classes());)
   conc_workers()->start_task(&tsk);
   while (tsk.yielded()) {
@@ -4318,6 +4319,8 @@
   ResourceMark rm;
   HandleMark   hm;
 
+  // Temporarily make refs discovery single threaded (non-MT)
+  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false);
   MarkFromRootsClosure markFromRootsClosure(this, _span, &_markBitMap,
     &_markStack, &_revisitStack, CMSYield && asynch);
   // the last argument to iterate indicates whether the iteration
@@ -4356,10 +4359,6 @@
   verify_overflow_empty();
   _abort_preclean = false;
   if (CMSPrecleaningEnabled) {
-    // Precleaning is currently not MT but the reference processor
-    // may be set for MT.  Disable it temporarily here.
-    ReferenceProcessor* rp = ref_processor();
-    ReferenceProcessorMTProcMutator z(rp, false);
     _eden_chunk_index = 0;
     size_t used = get_eden_used();
     size_t capacity = get_eden_capacity();
@@ -4502,11 +4501,16 @@
          _collectorState == AbortablePreclean, "incorrect state");
   ResourceMark rm;
   HandleMark   hm;
+
+  // Precleaning is currently not MT but the reference processor
+  // may be set for MT.  Disable it temporarily here.
+  ReferenceProcessor* rp = ref_processor();
+  ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(rp, false);
+
   // Do one pass of scrubbing the discovered reference lists
   // to remove any reference objects with strongly-reachable
   // referents.
   if (clean_refs) {
-    ReferenceProcessor* rp = ref_processor();
     CMSPrecleanRefsYieldClosure yield_cl(this);
     assert(rp->span().equals(_span), "Spans should be equal");
     CMSKeepAliveClosure keep_alive(this, _span, &_markBitMap,
@@ -5576,8 +5580,10 @@
   // in the multi-threaded case, but we special-case n=1 here to get
   // repeatable measurements of the 1-thread overhead of the parallel code.
   if (n_workers > 1) {
-    // Make refs discovery MT-safe
-    ReferenceProcessorMTMutator mt(ref_processor(), true);
+    // Make refs discovery MT-safe, if it isn't already: it may not
+    // necessarily be so, since it's possible that we are doing
+    // ST marking.
+    ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), true);
     GenCollectedHeap::StrongRootsScope srs(gch);
     workers->run_task(&tsk);
   } else {
@@ -5703,14 +5709,19 @@
                       CMSBitMap*       mark_bit_map,
                       AbstractWorkGang* workers,
                       OopTaskQueueSet* task_queues):
+    // XXX Should superclass AGTWOQ also know about AWG since it knows
+    // about the task_queues used by the AWG? Then it could initialize
+    // the terminator() object. See 6984287. The set_for_termination()
+    // below is a temporary band-aid for the regression in 6984287.
     AbstractGangTaskWOopQueues("Process referents by policy in parallel",
       task_queues),
     _task(task),
     _collector(collector), _span(span), _mark_bit_map(mark_bit_map)
-    {
-      assert(_collector->_span.equals(_span) && !_span.is_empty(),
-             "Inconsistency in _span");
-    }
+  {
+    assert(_collector->_span.equals(_span) && !_span.is_empty(),
+           "Inconsistency in _span");
+    set_for_termination(workers->active_workers());
+  }
 
   OopTaskQueueSet* task_queues() { return queues(); }
 
@@ -5872,8 +5883,7 @@
       // That is OK as long as the Reference lists are balanced (see
       // balance_all_queues() and balance_queues()).
 
-
-      rp->set_mt_degree(ParallelGCThreads);
+      rp->set_active_mt_degree(ParallelGCThreads);
       CMSRefProcTaskExecutor task_executor(*this);
       rp->process_discovered_references(&_is_alive_closure,
                                         &cmsKeepAliveClosure,
@@ -5920,14 +5930,18 @@
     }
 
     {
-      TraceTime t("scrub symbol & string tables", PrintGCDetails, false, gclog_or_tty);
-      // Now clean up stale oops in StringTable
-      StringTable::unlink(&_is_alive_closure);
+      TraceTime t("scrub symbol table", PrintGCDetails, false, gclog_or_tty);
       // Clean up unreferenced symbols in symbol table.
       SymbolTable::unlink();
     }
   }
 
+  if (should_unload_classes() || !JavaObjectsInPerm) {
+    TraceTime t("scrub string table", PrintGCDetails, false, gclog_or_tty);
+    // Now clean up stale oops in StringTable
+    StringTable::unlink(&_is_alive_closure);
+  }
+
   verify_work_stacks_empty();
   // Restore any preserved marks as a result of mark stack or
   // work queue overflow
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1133,7 +1133,7 @@
     // rare that the cost of the CAS's involved is in the
     // noise. That's a measurement that should be done, and
     // the code simplified if that turns out to be the case.
-    return false;
+    return ConcGCThreads > 1;
   }
 
   // Override
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,7 +51,7 @@
 volatile jint ConcurrentMarkSweepThread::_pending_yields      = 0;
 volatile jint ConcurrentMarkSweepThread::_pending_decrements  = 0;
 
-volatile bool ConcurrentMarkSweepThread::_icms_enabled   = false;
+volatile jint ConcurrentMarkSweepThread::_icms_disabled   = 0;
 volatile bool ConcurrentMarkSweepThread::_should_run     = false;
 // When icms is enabled, the icms thread is stopped until explicitly
 // started.
@@ -84,7 +84,7 @@
     }
   }
   _sltMonitor = SLT_lock;
-  set_icms_enabled(CMSIncrementalMode);
+  assert(!CMSIncrementalMode || icms_is_enabled(), "Error");
 }
 
 void ConcurrentMarkSweepThread::run() {
@@ -341,11 +341,11 @@
 
 void ConcurrentMarkSweepThread::icms_wait() {
   assert(UseConcMarkSweepGC && CMSIncrementalMode, "just checking");
-  if (_should_stop && icms_enabled()) {
+  if (_should_stop && icms_is_enabled()) {
     MutexLockerEx x(iCMS_lock, Mutex::_no_safepoint_check_flag);
     trace_state("pause_icms");
     _collector->stats().stop_cms_timer();
-    while(!_should_run && icms_enabled()) {
+    while(!_should_run && icms_is_enabled()) {
       iCMS_lock->wait(Mutex::_no_safepoint_check_flag);
     }
     _collector->stats().start_cms_timer();
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
 class ConcurrentMarkSweepGeneration;
 class CMSCollector;
 
-// The Concurrent Mark Sweep GC Thread (could be several in the future).
+// The Concurrent Mark Sweep GC Thread
 class ConcurrentMarkSweepThread: public ConcurrentGCThread {
   friend class VMStructs;
   friend class ConcurrentMarkSweepGeneration;   // XXX should remove friendship
@@ -55,8 +55,6 @@
   static SurrogateLockerThread::SLT_msg_type _sltBuffer;
   static Monitor*                       _sltMonitor;
 
-  ConcurrentMarkSweepThread*            _next;
-
   static bool _should_terminate;
 
   enum CMS_flag_type {
@@ -84,7 +82,7 @@
   // Tracing messages, enabled by CMSTraceThreadState.
   static inline void trace_state(const char* desc);
 
-  static volatile bool _icms_enabled;   // iCMS enabled?
+  static volatile int _icms_disabled;   // a counter to track #iCMS disable & enable
   static volatile bool _should_run;     // iCMS may run
   static volatile bool _should_stop;    // iCMS should stop
 
@@ -214,10 +212,25 @@
 
   // Incremental mode is enabled globally by the flag CMSIncrementalMode.  It
   // must also be enabled/disabled dynamically to allow foreground collections.
-  static inline void enable_icms()              { _icms_enabled = true; }
-  static inline void disable_icms()             { _icms_enabled = false; }
-  static inline void set_icms_enabled(bool val) { _icms_enabled = val; }
-  static inline bool icms_enabled()             { return _icms_enabled; }
+#define ICMS_ENABLING_ASSERT                                                      \
+          assert((CMSIncrementalMode  && _icms_disabled >= 0) ||                  \
+                 (!CMSIncrementalMode && _icms_disabled <= 0), "Error")
+
+  static inline void enable_icms() {
+    ICMS_ENABLING_ASSERT;
+    Atomic::dec(&_icms_disabled);
+  }
+  static inline void disable_icms() {
+   ICMS_ENABLING_ASSERT;
+   Atomic::inc(&_icms_disabled);
+  }
+  static inline bool icms_is_disabled() {
+   ICMS_ENABLING_ASSERT;
+   return _icms_disabled > 0;
+  }
+  static inline bool icms_is_enabled() {
+   return !icms_is_disabled();
+  }
 };
 
 inline void ConcurrentMarkSweepThread::trace_state(const char* desc) {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -192,14 +192,18 @@
          "total_collections() should be monotonically increasing");
 
   MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
+  assert(_full_gc_count_before <= gch->total_full_collections(), "Error");
   if (gch->total_full_collections() == _full_gc_count_before) {
-    // Disable iCMS until the full collection is done.
+    // Disable iCMS until the full collection is done, and
+    // remember that we did so.
     CMSCollector::disable_icms();
+    _disabled_icms = true;
     // In case CMS thread was in icms_wait(), wake it up.
     CMSCollector::start_icms();
     // Nudge the CMS thread to start a concurrent collection.
     CMSCollector::request_full_gc(_full_gc_count_before);
   } else {
+    assert(_full_gc_count_before < gch->total_full_collections(), "Error");
     FullGCCount_lock->notify_all();  // Inform the Java thread its work is done
   }
 }
@@ -259,6 +263,8 @@
       FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
     }
   }
-  // Enable iCMS back.
-  CMSCollector::enable_icms();
+  // Enable iCMS back if we disabled it earlier.
+  if (_disabled_icms) {
+    CMSCollector::enable_icms();
+  }
 }
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -128,11 +128,14 @@
 // VM operation to invoke a concurrent collection of the heap as a
 // GenCollectedHeap heap.
 class VM_GenCollectFullConcurrent: public VM_GC_Operation {
+  bool _disabled_icms;
  public:
   VM_GenCollectFullConcurrent(unsigned int gc_count_before,
                               unsigned int full_gc_count_before,
                               GCCause::Cause gc_cause)
-    : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */) {
+    : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */),
+      _disabled_icms(false)
+  {
     assert(FullGCCount_lock != NULL, "Error");
     assert(UseAsyncConcMarkSweepGC, "Else will hang caller");
   }
--- a/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -373,7 +373,7 @@
             // RSet updating while within an evacuation pause.
             // In this case worker_i should be the id of a GC worker thread
             assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
-            assert(worker_i < (int) DirtyCardQueueSet::num_par_ids(), "incorrect worker id");
+            assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "incorrect worker id");
             into_cset_dcq->enqueue(entry);
           }
         }
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1828,7 +1828,7 @@
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   _cleanup_list.verify_optional();
-  FreeRegionList local_free_list("Local Cleanup List");
+  FreeRegionList tmp_free_list("Tmp Free List");
 
   if (G1ConcRegionFreeingVerbose) {
     gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
@@ -1842,7 +1842,7 @@
     HeapRegion* hr = _cleanup_list.remove_head();
     assert(hr != NULL, "the list was not empty");
     hr->rem_set()->clear();
-    local_free_list.add_as_tail(hr);
+    tmp_free_list.add_as_tail(hr);
 
     // Instead of adding one region at a time to the secondary_free_list,
     // we accumulate them in the local list and move them a few at a
@@ -1850,20 +1850,20 @@
     // we do during this process. We'll also append the local list when
     // _cleanup_list is empty (which means we just removed the last
     // region from the _cleanup_list).
-    if ((local_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
+    if ((tmp_free_list.length() % G1SecondaryFreeListAppendLength == 0) ||
         _cleanup_list.is_empty()) {
       if (G1ConcRegionFreeingVerbose) {
         gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
                                "appending "SIZE_FORMAT" entries to the "
                                "secondary_free_list, clean list still has "
                                SIZE_FORMAT" entries",
-                               local_free_list.length(),
+                               tmp_free_list.length(),
                                _cleanup_list.length());
       }
 
       {
         MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
-        g1h->secondary_free_list_add_as_tail(&local_free_list);
+        g1h->secondary_free_list_add_as_tail(&tmp_free_list);
         SecondaryFreeList_lock->notify_all();
       }
 
@@ -1874,7 +1874,7 @@
       }
     }
   }
-  assert(local_free_list.is_empty(), "post-condition");
+  assert(tmp_free_list.is_empty(), "post-condition");
 }
 
 // Support closures for reference procssing in G1
@@ -2141,21 +2141,22 @@
   G1CMKeepAliveClosure g1_keep_alive(g1h, this, nextMarkBitMap());
   G1CMDrainMarkingStackClosure
     g1_drain_mark_stack(nextMarkBitMap(), &_markStack, &g1_keep_alive);
-
   // We use the work gang from the G1CollectedHeap and we utilize all
   // the worker threads.
-  int active_workers = MAX2(MIN2(g1h->workers()->total_workers(), (int)_max_task_num), 1);
+  int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1;
+  active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1);
 
   G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(),
                                           g1h->workers(), active_workers);
 
+
   if (rp->processing_is_mt()) {
     // Set the degree of MT here.  If the discovery is done MT, there
     // may have been a different number of threads doing the discovery
     // and a different number of discovered lists may have Ref objects.
     // That is OK as long as the Reference lists are balanced (see
     // balance_all_queues() and balance_queues()).
-    rp->set_mt_degree(active_workers);
+    rp->set_active_mt_degree(active_workers);
 
     rp->process_discovered_references(&g1_is_alive,
                                       &g1_keep_alive,
@@ -3182,7 +3183,7 @@
 
   template <class T> void do_oop_work(T* p) {
     assert( _g1h->is_in_g1_reserved((HeapWord*) p), "invariant");
-    assert(!_g1h->is_on_free_list(
+    assert(!_g1h->is_on_master_free_list(
                     _g1h->heap_region_containing((HeapWord*) p)), "invariant");
 
     oop obj = oopDesc::load_decode_heap_oop(p);
@@ -3403,7 +3404,7 @@
 void CMTask::push(oop obj) {
   HeapWord* objAddr = (HeapWord*) obj;
   assert(_g1h->is_in_g1_reserved(objAddr), "invariant");
-  assert(!_g1h->is_on_free_list(
+  assert(!_g1h->is_on_master_free_list(
               _g1h->heap_region_containing((HeapWord*) objAddr)), "invariant");
   assert(!_g1h->is_obj_ill(obj), "invariant");
   assert(_nextMarkBitMap->isMarked(objAddr), "invariant");
@@ -3649,7 +3650,7 @@
                                (void*) obj);
 
       assert(_g1h->is_in_g1_reserved((HeapWord*) obj), "invariant" );
-      assert(!_g1h->is_on_free_list(
+      assert(!_g1h->is_on_master_free_list(
                   _g1h->heap_region_containing((HeapWord*) obj)), "invariant");
 
       scan_object(obj);
--- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -237,9 +237,9 @@
         // The following will finish freeing up any regions that we
         // found to be empty during cleanup. We'll do this part
         // without joining the suspendible set. If an evacuation pause
-        // takes places, then we would carry on freeing regions in
+        // takes place, then we would carry on freeing regions in
         // case they are needed by the pause. If a Full GC takes
-        // places, it would wait for us to process the regions
+        // place, it would wait for us to process the regions
         // reclaimed by cleanup.
 
         double cleanup_start_sec = os::elapsedTime();
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -479,7 +479,7 @@
 // Private methods.
 
 HeapRegion*
-G1CollectedHeap::new_region_try_secondary_free_list(size_t word_size) {
+G1CollectedHeap::new_region_try_secondary_free_list() {
   MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
   while (!_secondary_free_list.is_empty() || free_regions_coming()) {
     if (!_secondary_free_list.is_empty()) {
@@ -531,7 +531,7 @@
         gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
                                "forced to look at the secondary_free_list");
       }
-      res = new_region_try_secondary_free_list(word_size);
+      res = new_region_try_secondary_free_list();
       if (res != NULL) {
         return res;
       }
@@ -543,7 +543,7 @@
       gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
                              "res == NULL, trying the secondary_free_list");
     }
-    res = new_region_try_secondary_free_list(word_size);
+    res = new_region_try_secondary_free_list();
   }
   if (res == NULL && do_expand) {
     if (expand(word_size * HeapWordSize)) {
@@ -579,6 +579,9 @@
 
 int G1CollectedHeap::humongous_obj_allocate_find_first(size_t num_regions,
                                                        size_t word_size) {
+  assert(isHumongous(word_size), "word_size should be humongous");
+  assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
+
   int first = -1;
   if (num_regions == 1) {
     // Only one region to allocate, no need to go through the slower
@@ -600,7 +603,7 @@
     // request. If we are only allocating one region we use the common
     // region allocation code (see above).
     wait_while_free_regions_coming();
-    append_secondary_free_list_if_not_empty();
+    append_secondary_free_list_if_not_empty_with_lock();
 
     if (free_regions() >= num_regions) {
       first = _hrs->find_contiguous(num_regions);
@@ -608,7 +611,7 @@
         for (int i = first; i < first + (int) num_regions; ++i) {
           HeapRegion* hr = _hrs->at(i);
           assert(hr->is_empty(), "sanity");
-          assert(is_on_free_list(hr), "sanity");
+          assert(is_on_master_free_list(hr), "sanity");
           hr->set_pending_removal(true);
         }
         _free_list.remove_all_pending(num_regions);
@@ -618,6 +621,126 @@
   return first;
 }
 
+HeapWord*
+G1CollectedHeap::humongous_obj_allocate_initialize_regions(int first,
+                                                           size_t num_regions,
+                                                           size_t word_size) {
+  assert(first != -1, "pre-condition");
+  assert(isHumongous(word_size), "word_size should be humongous");
+  assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
+
+  // Index of last region in the series + 1.
+  int last = first + (int) num_regions;
+
+  // We need to initialize the region(s) we just discovered. This is
+  // a bit tricky given that it can happen concurrently with
+  // refinement threads refining cards on these regions and
+  // potentially wanting to refine the BOT as they are scanning
+  // those cards (this can happen shortly after a cleanup; see CR
+  // 6991377). So we have to set up the region(s) carefully and in
+  // a specific order.
+
+  // The word size sum of all the regions we will allocate.
+  size_t word_size_sum = num_regions * HeapRegion::GrainWords;
+  assert(word_size <= word_size_sum, "sanity");
+
+  // This will be the "starts humongous" region.
+  HeapRegion* first_hr = _hrs->at(first);
+  // The header of the new object will be placed at the bottom of
+  // the first region.
+  HeapWord* new_obj = first_hr->bottom();
+  // This will be the new end of the first region in the series that
+  // should also match the end of the last region in the seriers.
+  HeapWord* new_end = new_obj + word_size_sum;
+  // This will be the new top of the first region that will reflect
+  // this allocation.
+  HeapWord* new_top = new_obj + word_size;
+
+  // First, we need to zero the header of the space that we will be
+  // allocating. When we update top further down, some refinement
+  // threads might try to scan the region. By zeroing the header we
+  // ensure that any thread that will try to scan the region will
+  // come across the zero klass word and bail out.
+  //
+  // NOTE: It would not have been correct to have used
+  // CollectedHeap::fill_with_object() and make the space look like
+  // an int array. The thread that is doing the allocation will
+  // later update the object header to a potentially different array
+  // type and, for a very short period of time, the klass and length
+  // fields will be inconsistent. This could cause a refinement
+  // thread to calculate the object size incorrectly.
+  Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
+
+  // We will set up the first region as "starts humongous". This
+  // will also update the BOT covering all the regions to reflect
+  // that there is a single object that starts at the bottom of the
+  // first region.
+  first_hr->set_startsHumongous(new_top, new_end);
+
+  // Then, if there are any, we will set up the "continues
+  // humongous" regions.
+  HeapRegion* hr = NULL;
+  for (int i = first + 1; i < last; ++i) {
+    hr = _hrs->at(i);
+    hr->set_continuesHumongous(first_hr);
+  }
+  // If we have "continues humongous" regions (hr != NULL), then the
+  // end of the last one should match new_end.
+  assert(hr == NULL || hr->end() == new_end, "sanity");
+
+  // Up to this point no concurrent thread would have been able to
+  // do any scanning on any region in this series. All the top
+  // fields still point to bottom, so the intersection between
+  // [bottom,top] and [card_start,card_end] will be empty. Before we
+  // update the top fields, we'll do a storestore to make sure that
+  // no thread sees the update to top before the zeroing of the
+  // object header and the BOT initialization.
+  OrderAccess::storestore();
+
+  // Now that the BOT and the object header have been initialized,
+  // we can update top of the "starts humongous" region.
+  assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
+         "new_top should be in this region");
+  first_hr->set_top(new_top);
+
+  // Now, we will update the top fields of the "continues humongous"
+  // regions. The reason we need to do this is that, otherwise,
+  // these regions would look empty and this will confuse parts of
+  // G1. For example, the code that looks for a consecutive number
+  // of empty regions will consider them empty and try to
+  // re-allocate them. We can extend is_empty() to also include
+  // !continuesHumongous(), but it is easier to just update the top
+  // fields here. The way we set top for all regions (i.e., top ==
+  // end for all regions but the last one, top == new_top for the
+  // last one) is actually used when we will free up the humongous
+  // region in free_humongous_region().
+  hr = NULL;
+  for (int i = first + 1; i < last; ++i) {
+    hr = _hrs->at(i);
+    if ((i + 1) == last) {
+      // last continues humongous region
+      assert(hr->bottom() < new_top && new_top <= hr->end(),
+             "new_top should fall on this region");
+      hr->set_top(new_top);
+    } else {
+      // not last one
+      assert(new_top > hr->end(), "new_top should be above this region");
+      hr->set_top(hr->end());
+    }
+  }
+  // If we have continues humongous regions (hr != NULL), then the
+  // end of the last one should match new_end and its top should
+  // match new_top.
+  assert(hr == NULL ||
+         (hr->end() == new_end && hr->top() == new_top), "sanity");
+
+  assert(first_hr->used() == word_size * HeapWordSize, "invariant");
+  _summary_bytes_used += first_hr->used();
+  _humongous_set.add(first_hr);
+
+  return new_obj;
+}
+
 // If could fit into free regions w/o expansion, try.
 // Otherwise, if can expand, do so.
 // Otherwise, if using ex regions might help, try with ex given back.
@@ -653,121 +776,16 @@
     }
   }
 
+  HeapWord* result = NULL;
   if (first != -1) {
-    // Index of last region in the series + 1.
-    int last = first + (int) num_regions;
-
-    // We need to initialize the region(s) we just discovered. This is
-    // a bit tricky given that it can happen concurrently with
-    // refinement threads refining cards on these regions and
-    // potentially wanting to refine the BOT as they are scanning
-    // those cards (this can happen shortly after a cleanup; see CR
-    // 6991377). So we have to set up the region(s) carefully and in
-    // a specific order.
-
-    // The word size sum of all the regions we will allocate.
-    size_t word_size_sum = num_regions * HeapRegion::GrainWords;
-    assert(word_size <= word_size_sum, "sanity");
-
-    // This will be the "starts humongous" region.
-    HeapRegion* first_hr = _hrs->at(first);
-    // The header of the new object will be placed at the bottom of
-    // the first region.
-    HeapWord* new_obj = first_hr->bottom();
-    // This will be the new end of the first region in the series that
-    // should also match the end of the last region in the seriers.
-    HeapWord* new_end = new_obj + word_size_sum;
-    // This will be the new top of the first region that will reflect
-    // this allocation.
-    HeapWord* new_top = new_obj + word_size;
-
-    // First, we need to zero the header of the space that we will be
-    // allocating. When we update top further down, some refinement
-    // threads might try to scan the region. By zeroing the header we
-    // ensure that any thread that will try to scan the region will
-    // come across the zero klass word and bail out.
-    //
-    // NOTE: It would not have been correct to have used
-    // CollectedHeap::fill_with_object() and make the space look like
-    // an int array. The thread that is doing the allocation will
-    // later update the object header to a potentially different array
-    // type and, for a very short period of time, the klass and length
-    // fields will be inconsistent. This could cause a refinement
-    // thread to calculate the object size incorrectly.
-    Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
-
-    // We will set up the first region as "starts humongous". This
-    // will also update the BOT covering all the regions to reflect
-    // that there is a single object that starts at the bottom of the
-    // first region.
-    first_hr->set_startsHumongous(new_top, new_end);
-
-    // Then, if there are any, we will set up the "continues
-    // humongous" regions.
-    HeapRegion* hr = NULL;
-    for (int i = first + 1; i < last; ++i) {
-      hr = _hrs->at(i);
-      hr->set_continuesHumongous(first_hr);
-    }
-    // If we have "continues humongous" regions (hr != NULL), then the
-    // end of the last one should match new_end.
-    assert(hr == NULL || hr->end() == new_end, "sanity");
-
-    // Up to this point no concurrent thread would have been able to
-    // do any scanning on any region in this series. All the top
-    // fields still point to bottom, so the intersection between
-    // [bottom,top] and [card_start,card_end] will be empty. Before we
-    // update the top fields, we'll do a storestore to make sure that
-    // no thread sees the update to top before the zeroing of the
-    // object header and the BOT initialization.
-    OrderAccess::storestore();
-
-    // Now that the BOT and the object header have been initialized,
-    // we can update top of the "starts humongous" region.
-    assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
-           "new_top should be in this region");
-    first_hr->set_top(new_top);
-
-    // Now, we will update the top fields of the "continues humongous"
-    // regions. The reason we need to do this is that, otherwise,
-    // these regions would look empty and this will confuse parts of
-    // G1. For example, the code that looks for a consecutive number
-    // of empty regions will consider them empty and try to
-    // re-allocate them. We can extend is_empty() to also include
-    // !continuesHumongous(), but it is easier to just update the top
-    // fields here. The way we set top for all regions (i.e., top ==
-    // end for all regions but the last one, top == new_top for the
-    // last one) is actually used when we will free up the humongous
-    // region in free_humongous_region().
-    hr = NULL;
-    for (int i = first + 1; i < last; ++i) {
-      hr = _hrs->at(i);
-      if ((i + 1) == last) {
-        // last continues humongous region
-        assert(hr->bottom() < new_top && new_top <= hr->end(),
-               "new_top should fall on this region");
-        hr->set_top(new_top);
-      } else {
-        // not last one
-        assert(new_top > hr->end(), "new_top should be above this region");
-        hr->set_top(hr->end());
-      }
-    }
-    // If we have continues humongous regions (hr != NULL), then the
-    // end of the last one should match new_end and its top should
-    // match new_top.
-    assert(hr == NULL ||
-           (hr->end() == new_end && hr->top() == new_top), "sanity");
-
-    assert(first_hr->used() == word_size * HeapWordSize, "invariant");
-    _summary_bytes_used += first_hr->used();
-    _humongous_set.add(first_hr);
-
-    return new_obj;
+    result =
+      humongous_obj_allocate_initialize_regions(first, num_regions, word_size);
+    assert(result != NULL, "it should always return a valid result");
   }
 
   verify_region_sets_optional();
-  return NULL;
+
+  return result;
 }
 
 void
@@ -1389,7 +1407,7 @@
     g1_policy()->record_full_collection_start();
 
     wait_while_free_regions_coming();
-    append_secondary_free_list_if_not_empty();
+    append_secondary_free_list_if_not_empty_with_lock();
 
     gc_prologue(true);
     increment_total_collections(true /* full gc */);
@@ -1444,7 +1462,7 @@
     // how reference processing currently works in G1.
 
     // Temporarily make reference _discovery_ single threaded (non-MT).
-    ReferenceProcessorMTMutator rp_disc_ser(ref_processor(), false);
+    ReferenceProcessorMTDiscoveryMutator rp_disc_ser(ref_processor(), false);
 
     // Temporarily make refs discovery atomic
     ReferenceProcessorAtomicMutator rp_disc_atomic(ref_processor(), true);
@@ -2201,16 +2219,16 @@
 
   SharedHeap::ref_processing_init();
   MemRegion mr = reserved_region();
-  _ref_processor = ReferenceProcessor::create_ref_processor(
-                                         mr,    // span
-                                         false, // Reference discovery is not atomic
-                                         true,  // mt_discovery
-                                         &_is_alive_closure, // is alive closure
-                                                             // for efficiency
-                                         ParallelGCThreads,
-                                         ParallelRefProcEnabled,
-                                         true); // Setting next fields of discovered
-                                                // lists requires a barrier.
+  _ref_processor =
+    new ReferenceProcessor(mr,    // span
+                           ParallelRefProcEnabled && (ParallelGCThreads > 1),    // mt processing
+                           (int) ParallelGCThreads,   // degree of mt processing
+                           ParallelGCThreads > 1 || ConcGCThreads > 1,  // mt discovery
+                           (int) MAX2(ParallelGCThreads, ConcGCThreads), // degree of mt discovery
+                           false,                     // Reference discovery is not atomic
+                           &_is_alive_closure,        // is alive closure for efficiency
+                           true);                     // Setting next fields of discovered
+                                                      // lists requires a barrier.
 }
 
 size_t G1CollectedHeap::capacity() const {
@@ -3377,15 +3395,14 @@
 
     TraceMemoryManagerStats tms(false /* fullGC */);
 
-    // If there are any free regions available on the secondary_free_list
-    // make sure we append them to the free_list. However, we don't
-    // have to wait for the rest of the cleanup operation to
-    // finish. If it's still going on that's OK. If we run out of
-    // regions, the region allocation code will check the
-    // secondary_free_list and potentially wait if more free regions
-    // are coming (see new_region_try_secondary_free_list()).
+    // If the secondary_free_list is not empty, append it to the
+    // free_list. No need to wait for the cleanup operation to finish;
+    // the region allocation code will check the secondary_free_list
+    // and wait if necessary. If the G1StressConcRegionFreeing flag is
+    // set, skip this step so that the region allocation code has to
+    // get entries from the secondary_free_list.
     if (!G1StressConcRegionFreeing) {
-      append_secondary_free_list_if_not_empty();
+      append_secondary_free_list_if_not_empty_with_lock();
     }
 
     increment_gc_time_stamp();
@@ -5199,7 +5216,7 @@
   size_t rs_lengths = 0;
 
   while (cur != NULL) {
-    assert(!is_on_free_list(cur), "sanity");
+    assert(!is_on_master_free_list(cur), "sanity");
 
     if (non_young) {
       if (cur->is_young()) {
@@ -5543,13 +5560,10 @@
     return;
   }
 
-  {
-    MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
-    // Make sure we append the secondary_free_list on the free_list so
-    // that all free regions we will come across can be safely
-    // attributed to the free_list.
-    append_secondary_free_list();
-  }
+  // Make sure we append the secondary_free_list on the free_list so
+  // that all free regions we will come across can be safely
+  // attributed to the free_list.
+  append_secondary_free_list_if_not_empty_with_lock();
 
   // Finally, make sure that the region accounting in the lists is
   // consistent with what we see in the heap.
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -56,7 +56,6 @@
 class ConcurrentMark;
 class ConcurrentMarkThread;
 class ConcurrentG1Refine;
-class ConcurrentZFThread;
 
 typedef OverflowTaskQueue<StarTask>         RefToScanQueue;
 typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet;
@@ -64,12 +63,6 @@
 typedef int RegionIdx_t;   // needs to hold [ 0..max_regions() )
 typedef int CardIdx_t;     // needs to hold [ 0..CardsPerRegion )
 
-enum G1GCThreadGroups {
-  G1CRGroup = 0,
-  G1ZFGroup = 1,
-  G1CMGroup = 2
-};
-
 enum GCAllocPurpose {
   GCAllocForTenured,
   GCAllocForSurvived,
@@ -294,9 +287,9 @@
   // These are macros so that, if the assert fires, we get the correct
   // line number, file, etc.
 
-#define heap_locking_asserts_err_msg(__extra_message)                         \
+#define heap_locking_asserts_err_msg(_extra_message_)                         \
   err_msg("%s : Heap_lock locked: %s, at safepoint: %s, is VM thread: %s",    \
-          (__extra_message),                                                  \
+          (_extra_message_),                                                  \
           BOOL_TO_STR(Heap_lock->owned_by_self()),                            \
           BOOL_TO_STR(SafepointSynchronize::is_at_safepoint()),               \
           BOOL_TO_STR(Thread::current()->is_VM_thread()))
@@ -307,11 +300,11 @@
            heap_locking_asserts_err_msg("should be holding the Heap_lock"));  \
   } while (0)
 
-#define assert_heap_locked_or_at_safepoint(__should_be_vm_thread)             \
+#define assert_heap_locked_or_at_safepoint(_should_be_vm_thread_)             \
   do {                                                                        \
     assert(Heap_lock->owned_by_self() ||                                      \
            (SafepointSynchronize::is_at_safepoint() &&                        \
-             ((__should_be_vm_thread) == Thread::current()->is_VM_thread())), \
+             ((_should_be_vm_thread_) == Thread::current()->is_VM_thread())), \
            heap_locking_asserts_err_msg("should be holding the Heap_lock or " \
                                         "should be at a safepoint"));         \
   } while (0)
@@ -338,10 +331,10 @@
                                    "should not be at a safepoint"));          \
   } while (0)
 
-#define assert_at_safepoint(__should_be_vm_thread)                            \
+#define assert_at_safepoint(_should_be_vm_thread_)                            \
   do {                                                                        \
     assert(SafepointSynchronize::is_at_safepoint() &&                         \
-              ((__should_be_vm_thread) == Thread::current()->is_VM_thread()), \
+              ((_should_be_vm_thread_) == Thread::current()->is_VM_thread()), \
            heap_locking_asserts_err_msg("should be at a safepoint"));         \
   } while (0)
 
@@ -371,35 +364,40 @@
   // will check whether there's anything available in the
   // secondary_free_list and/or wait for more regions to appear in that
   // list, if _free_regions_coming is set.
-  HeapRegion* new_region_try_secondary_free_list(size_t word_size);
+  HeapRegion* new_region_try_secondary_free_list();
 
-  // It will try to allocate a single non-humongous HeapRegion
-  // sufficient for an allocation of the given word_size.  If
-  // do_expand is true, it will attempt to expand the heap if
-  // necessary to satisfy the allocation request. Note that word_size
-  // is only used to make sure that we expand sufficiently but, given
-  // that the allocation request is assumed not to be humongous,
-  // having word_size is not strictly necessary (expanding by a single
-  // region will always be sufficient). But let's keep that parameter
-  // in case we need it in the future.
+  // Try to allocate a single non-humongous HeapRegion sufficient for
+  // an allocation of the given word_size. If do_expand is true,
+  // attempt to expand the heap if necessary to satisfy the allocation
+  // request.
   HeapRegion* new_region_work(size_t word_size, bool do_expand);
 
-  // It will try to allocate a new region to be used for allocation by
-  // mutator threads. It will not try to expand the heap if not region
-  // is available.
+  // Try to allocate a new region to be used for allocation by a
+  // mutator thread. Attempt to expand the heap if no region is
+  // available.
   HeapRegion* new_alloc_region(size_t word_size) {
     return new_region_work(word_size, false /* do_expand */);
   }
 
-  // It will try to allocate a new region to be used for allocation by
-  // a GC thread. It will try to expand the heap if no region is
-  // available.
+  // Try to allocate a new region to be used for allocation by a GC
+  // thread. Attempt to expand the heap if no region is available.
   HeapRegion* new_gc_alloc_region(int purpose, size_t word_size);
 
+  // Attempt to satisfy a humongous allocation request of the given
+  // size by finding a contiguous set of free regions of num_regions
+  // length and remove them from the master free list. Return the
+  // index of the first region or -1 if the search was unsuccessful.
   int humongous_obj_allocate_find_first(size_t num_regions, size_t word_size);
 
-  // Attempt to allocate an object of the given (very large) "word_size".
-  // Returns "NULL" on failure.
+  // Initialize a contiguous set of free regions of length num_regions
+  // and starting at index first so that they appear as a single
+  // humongous region.
+  HeapWord* humongous_obj_allocate_initialize_regions(int first,
+                                                      size_t num_regions,
+                                                      size_t word_size);
+
+  // Attempt to allocate a humongous object of the given size. Return
+  // NULL if unsuccessful.
   HeapWord* humongous_obj_allocate(size_t word_size);
 
   // The following two methods, allocate_new_tlab() and
@@ -776,7 +774,7 @@
   // Invoke "save_marks" on all heap regions.
   void save_marks();
 
-  // It frees a non-humongous region by initializing its contents and
+  // Frees a non-humongous region by initializing its contents and
   // adding it to the free list that's passed as a parameter (this is
   // usually a local list which will be appended to the master free
   // list later). The used bytes of freed regions are accumulated in
@@ -787,13 +785,13 @@
                    FreeRegionList* free_list,
                    bool par);
 
-  // It frees a humongous region by collapsing it into individual
-  // regions and calling free_region() for each of them. The freed
-  // regions will be added to the free list that's passed as a parameter
-  // (this is usually a local list which will be appended to the
-  // master free list later). The used bytes of freed regions are
-  // accumulated in pre_used. If par is true, the region's RSet will
-  // not be freed up. The assumption is that this will be done later.
+  // Frees a humongous region by collapsing it into individual regions
+  // and calling free_region() for each of them. The freed regions
+  // will be added to the free list that's passed as a parameter (this
+  // is usually a local list which will be appended to the master free
+  // list later). The used bytes of freed regions are accumulated in
+  // pre_used. If par is true, the region's RSet will not be freed
+  // up. The assumption is that this will be done later.
   void free_humongous_region(HeapRegion* hr,
                              size_t* pre_used,
                              FreeRegionList* free_list,
@@ -1046,13 +1044,13 @@
 #endif // HEAP_REGION_SET_FORCE_VERIFY
 
 #ifdef ASSERT
-  bool is_on_free_list(HeapRegion* hr) {
+  bool is_on_master_free_list(HeapRegion* hr) {
     return hr->containing_set() == &_free_list;
   }
 
-  bool is_on_humongous_set(HeapRegion* hr) {
+  bool is_in_humongous_set(HeapRegion* hr) {
     return hr->containing_set() == &_humongous_set;
-}
+  }
 #endif // ASSERT
 
   // Wrapper for the region list operations that can be called from
@@ -1066,7 +1064,9 @@
     _free_list.add_as_tail(&_secondary_free_list);
   }
 
-  void append_secondary_free_list_if_not_empty() {
+  void append_secondary_free_list_if_not_empty_with_lock() {
+    // If the secondary free list looks empty there's no reason to
+    // take the lock and then try to append it.
     if (!_secondary_free_list.is_empty()) {
       MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag);
       append_secondary_free_list();
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -81,6 +81,57 @@
 
 // </NEW PREDICTION>
 
+// Help class for avoiding interleaved logging
+class LineBuffer: public StackObj {
+
+private:
+  static const int BUFFER_LEN = 1024;
+  static const int INDENT_CHARS = 3;
+  char _buffer[BUFFER_LEN];
+  int _indent_level;
+  int _cur;
+
+  void vappend(const char* format, va_list ap) {
+    int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
+    if (res != -1) {
+      _cur += res;
+    } else {
+      DEBUG_ONLY(warning("buffer too small in LineBuffer");)
+      _buffer[BUFFER_LEN -1] = 0;
+      _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
+    }
+  }
+
+public:
+  explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
+    for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
+      _buffer[_cur] = ' ';
+    }
+  }
+
+#ifndef PRODUCT
+  ~LineBuffer() {
+    assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
+  }
+#endif
+
+  void append(const char* format, ...) {
+    va_list ap;
+    va_start(ap, format);
+    vappend(format, ap);
+    va_end(ap);
+  }
+
+  void append_and_print_cr(const char* format, ...) {
+    va_list ap;
+    va_start(ap, format);
+    vappend(format, ap);
+    va_end(ap);
+    gclog_or_tty->print_cr("%s", _buffer);
+    _cur = _indent_level * INDENT_CHARS;
+  }
+};
+
 G1CollectorPolicy::G1CollectorPolicy() :
   _parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads()
     ? ParallelGCThreads : 1),
@@ -1016,10 +1067,8 @@
                                          bool summary) {
   double min = data[0], max = data[0];
   double total = 0.0;
-  int j;
-  for (j = 0; j < level; ++j)
-    gclog_or_tty->print("   ");
-  gclog_or_tty->print("[%s (ms):", str);
+  LineBuffer buf(level);
+  buf.append("[%s (ms):", str);
   for (uint i = 0; i < ParallelGCThreads; ++i) {
     double val = data[i];
     if (val < min)
@@ -1027,18 +1076,16 @@
     if (val > max)
       max = val;
     total += val;
-    gclog_or_tty->print("  %3.1lf", val);
+    buf.append("  %3.1lf", val);
   }
   if (summary) {
-    gclog_or_tty->print_cr("");
+    buf.append_and_print_cr("");
     double avg = total / (double) ParallelGCThreads;
-    gclog_or_tty->print(" ");
-    for (j = 0; j < level; ++j)
-      gclog_or_tty->print("   ");
-    gclog_or_tty->print("Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf",
+    buf.append(" ");
+    buf.append("Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf",
                         avg, min, max);
   }
-  gclog_or_tty->print_cr("]");
+  buf.append_and_print_cr("]");
 }
 
 void G1CollectorPolicy::print_par_sizes(int level,
@@ -1047,10 +1094,8 @@
                                         bool summary) {
   double min = data[0], max = data[0];
   double total = 0.0;
-  int j;
-  for (j = 0; j < level; ++j)
-    gclog_or_tty->print("   ");
-  gclog_or_tty->print("[%s :", str);
+  LineBuffer buf(level);
+  buf.append("[%s :", str);
   for (uint i = 0; i < ParallelGCThreads; ++i) {
     double val = data[i];
     if (val < min)
@@ -1058,34 +1103,28 @@
     if (val > max)
       max = val;
     total += val;
-    gclog_or_tty->print(" %d", (int) val);
+    buf.append(" %d", (int) val);
   }
   if (summary) {
-    gclog_or_tty->print_cr("");
+    buf.append_and_print_cr("");
     double avg = total / (double) ParallelGCThreads;
-    gclog_or_tty->print(" ");
-    for (j = 0; j < level; ++j)
-      gclog_or_tty->print("   ");
-    gclog_or_tty->print("Sum: %d, Avg: %d, Min: %d, Max: %d",
+    buf.append(" ");
+    buf.append("Sum: %d, Avg: %d, Min: %d, Max: %d",
                (int)total, (int)avg, (int)min, (int)max);
   }
-  gclog_or_tty->print_cr("]");
+  buf.append_and_print_cr("]");
 }
 
 void G1CollectorPolicy::print_stats (int level,
                                      const char* str,
                                      double value) {
-  for (int j = 0; j < level; ++j)
-    gclog_or_tty->print("   ");
-  gclog_or_tty->print_cr("[%s: %5.1lf ms]", str, value);
+  LineBuffer(level).append_and_print_cr("[%s: %5.1lf ms]", str, value);
 }
 
 void G1CollectorPolicy::print_stats (int level,
                                      const char* str,
                                      int value) {
-  for (int j = 0; j < level; ++j)
-    gclog_or_tty->print("   ");
-  gclog_or_tty->print_cr("[%s: %d]", str, value);
+  LineBuffer(level).append_and_print_cr("[%s: %d]", str, value);
 }
 
 double G1CollectorPolicy::avg_value (double* data) {
@@ -2060,17 +2099,11 @@
   _g1->collection_set_iterate(&cs_closure);
 }
 
-static void print_indent(int level) {
-  for (int j = 0; j < level+1; ++j)
-    gclog_or_tty->print("   ");
-}
-
 void G1CollectorPolicy::print_summary (int level,
                                        const char* str,
                                        NumberSeq* seq) const {
   double sum = seq->sum();
-  print_indent(level);
-  gclog_or_tty->print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
+  LineBuffer(level + 1).append_and_print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
                 str, sum / 1000.0, seq->avg());
 }
 
@@ -2078,8 +2111,7 @@
                                           const char* str,
                                           NumberSeq* seq) const {
   print_summary(level, str, seq);
-  print_indent(level + 5);
-  gclog_or_tty->print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+  LineBuffer(level + 6).append_and_print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
                 seq->num(), seq->sd(), seq->maximum());
 }
 
@@ -2087,6 +2119,7 @@
                                         NumberSeq* other_times_ms,
                                         NumberSeq* calc_other_times_ms) const {
   bool should_print = false;
+  LineBuffer buf(level + 2);
 
   double max_sum = MAX2(fabs(other_times_ms->sum()),
                         fabs(calc_other_times_ms->sum()));
@@ -2095,8 +2128,7 @@
   double sum_ratio = max_sum / min_sum;
   if (sum_ratio > 1.1) {
     should_print = true;
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
+    buf.append_and_print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
   }
 
   double max_avg = MAX2(fabs(other_times_ms->avg()),
@@ -2106,30 +2138,25 @@
   double avg_ratio = max_avg / min_avg;
   if (avg_ratio > 1.1) {
     should_print = true;
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
+    buf.append_and_print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
   }
 
   if (other_times_ms->sum() < -0.01) {
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
+    buf.append_and_print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
   }
 
   if (other_times_ms->avg() < -0.01) {
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
+    buf.append_and_print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
   }
 
   if (calc_other_times_ms->sum() < -0.01) {
     should_print = true;
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
+    buf.append_and_print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
   }
 
   if (calc_other_times_ms->avg() < -0.01) {
     should_print = true;
-    print_indent(level + 1);
-    gclog_or_tty->print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
+    buf.append_and_print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
   }
 
   if (should_print)
@@ -2210,10 +2237,9 @@
       }
     }
   } else {
-    print_indent(0);
-    gclog_or_tty->print_cr("none");
+    LineBuffer(1).append_and_print_cr("none");
   }
-  gclog_or_tty->print_cr("");
+  LineBuffer(0).append_and_print_cr("");
 }
 
 void G1CollectorPolicy::print_tracing_info() const {
@@ -2532,7 +2558,7 @@
     jint regions_added = parKnownGarbageCl.marked_regions_added();
     _hrSorted->incNumMarkedHeapRegions(regions_added);
     if (G1PrintParCleanupStats) {
-      gclog_or_tty->print("     Thread %d called %d times, added %d regions to list.\n",
+      gclog_or_tty->print_cr("     Thread %d called %d times, added %d regions to list.",
                  i, parKnownGarbageCl.invokes(), regions_added);
     }
   }
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -185,22 +185,22 @@
   G1CollectedHeap* _g1h;
   ModRefBarrierSet* _mrbs;
   CompactPoint _cp;
-  size_t _pre_used;
-  FreeRegionList _free_list;
   HumongousRegionSet _humongous_proxy_set;
 
   void free_humongous_region(HeapRegion* hr) {
     HeapWord* end = hr->end();
+    size_t dummy_pre_used;
+    FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
+
     assert(hr->startsHumongous(),
            "Only the start of a humongous region should be freed.");
-    _g1h->free_humongous_region(hr, &_pre_used, &_free_list,
+    _g1h->free_humongous_region(hr, &dummy_pre_used, &dummy_free_list,
                                 &_humongous_proxy_set, false /* par */);
-    // Do we also need to do this for the continues humongous regions
-    // we just collapsed?
     hr->prepare_for_compaction(&_cp);
     // Also clear the part of the card table that will be unused after
     // compaction.
     _mrbs->clear(MemRegion(hr->compaction_top(), end));
+    dummy_free_list.remove_all();
   }
 
 public:
@@ -208,8 +208,6 @@
   : _g1h(G1CollectedHeap::heap()),
     _mrbs(G1CollectedHeap::heap()->mr_bs()),
     _cp(NULL, cs, cs->initialize_threshold()),
-    _pre_used(0),
-    _free_list("Local Free List for G1MarkSweep"),
     _humongous_proxy_set("G1MarkSweep Humongous Proxy Set") { }
 
   void update_sets() {
@@ -219,7 +217,6 @@
                                             NULL, /* free_list */
                                             &_humongous_proxy_set,
                                             false /* par */);
-    _free_list.remove_all();
   }
 
   bool doHeapRegion(HeapRegion* hr) {
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -86,28 +86,6 @@
   bool idempotent() { return true; }
 };
 
-class IntoCSRegionClosure: public HeapRegionClosure {
-  IntoCSOopClosure _blk;
-  G1CollectedHeap* _g1;
-public:
-  IntoCSRegionClosure(G1CollectedHeap* g1, OopsInHeapRegionClosure* blk) :
-    _g1(g1), _blk(g1, blk) {}
-  bool doHeapRegion(HeapRegion* r) {
-    if (!r->in_collection_set()) {
-      _blk.set_region(r);
-      if (r->isHumongous()) {
-        if (r->startsHumongous()) {
-          oop obj = oop(r->bottom());
-          obj->oop_iterate(&_blk);
-        }
-      } else {
-        r->oop_before_save_marks_iterate(&_blk);
-      }
-    }
-    return false;
-  }
-};
-
 class VerifyRSCleanCardOopClosure: public OopClosure {
   G1CollectedHeap* _g1;
 public:
@@ -329,7 +307,7 @@
     // is during RSet updating within an evacuation pause.
     // In this case worker_i should be the id of a GC worker thread.
     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
-    assert(worker_i < (int) DirtyCardQueueSet::num_par_ids(), "should be a GC worker");
+    assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
 
     if (_g1rs->concurrentRefineOneCard(card_ptr, worker_i, true)) {
       // 'card_ptr' contains references that point into the collection
--- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -53,8 +53,8 @@
 class HeapRegionSetBase;
 
 #define HR_FORMAT "%d:["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
-#define HR_FORMAT_PARAMS(__hr) (__hr)->hrs_index(), (__hr)->bottom(), \
-                               (__hr)->top(), (__hr)->end()
+#define HR_FORMAT_PARAMS(_hr_) (_hr_)->hrs_index(), (_hr_)->bottom(), \
+                               (_hr_)->top(), (_hr_)->end()
 
 // A dirty card to oop closure for heap regions. It
 // knows how to get the G1 heap and how to use the bitmap
@@ -518,13 +518,13 @@
                    containing_set, _containing_set));
 
     _containing_set = containing_set;
-}
+  }
 
   HeapRegionSetBase* containing_set() { return _containing_set; }
 #else // ASSERT
   void set_containing_set(HeapRegionSetBase* containing_set) { }
 
-  // containing_set() is only used in asserts so there's not reason
+  // containing_set() is only used in asserts so there's no reason
   // to provide a dummy version of it.
 #endif // ASSERT
 
@@ -535,14 +535,15 @@
   bool pending_removal() { return _pending_removal; }
 
   void set_pending_removal(bool pending_removal) {
-    // We can only set pending_removal to true, if it's false and the
-    // region belongs to a set.
-    assert(!pending_removal ||
-           (!_pending_removal && containing_set() != NULL), "pre-condition");
-    // We can only set pending_removal to false, if it's true and the
-    // region does not belong to a set.
-    assert( pending_removal ||
-           ( _pending_removal && containing_set() == NULL), "pre-condition");
+    if (pending_removal) {
+      assert(!_pending_removal && containing_set() != NULL,
+             "can only set pending removal to true if it's false and "
+             "the region belongs to a region set");
+    } else {
+      assert( _pending_removal && containing_set() == NULL,
+              "can only set pending removal to false if it's true and "
+              "the region does not belong to a region set");
+    }
 
     _pending_removal = pending_removal;
   }
--- a/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -165,7 +165,7 @@
 
   assert(num_so_far <= num, "post-condition");
   if (num_so_far == num) {
-    // we find enough space for the humongous object
+    // we found enough space for the humongous object
     assert(from <= first && first < _regions.length(), "post-condition");
     assert(first < curr && (curr - first) == (int) num, "post-condition");
     for (int i = first; i < first + (int) num; ++i) {
--- a/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -76,7 +76,8 @@
   // that are available for allocation.
   size_t free_suffix();
 
-  // Finds a contiguous set of empty regions of length num.
+  // Find a contiguous set of empty regions of length num and return
+  // the index of the first region or -1 if the search was unsuccessful.
   int find_contiguous(size_t num);
 
   // Apply the "doHeapRegion" method of "blk" to all regions in "this",
--- a/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -42,7 +42,7 @@
   return region_num;
 }
 
-void HeapRegionSetBase::fill_in_ext_msg(hrl_ext_msg* msg, const char* message) {
+void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
   msg->append("[%s] %s "
               "ln: "SIZE_FORMAT" rn: "SIZE_FORMAT" "
               "cy: "SIZE_FORMAT" ud: "SIZE_FORMAT,
@@ -109,30 +109,30 @@
   // for the verification calls. If we do verification without the
   // appropriate locks and the set changes underneath our feet
   // verification might fail and send us on a wild goose chase.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
 
   guarantee(( is_empty() && length() == 0 && region_num() == 0 &&
               total_used_bytes() == 0 && total_capacity_bytes() == 0) ||
             (!is_empty() && length() >= 0 && region_num() >= 0 &&
               total_used_bytes() >= 0 && total_capacity_bytes() >= 0),
-            hrl_ext_msg(this, "invariant"));
+            hrs_ext_msg(this, "invariant"));
 
   guarantee((!regions_humongous() && region_num() == length()) ||
             ( regions_humongous() && region_num() >= length()),
-            hrl_ext_msg(this, "invariant"));
+            hrs_ext_msg(this, "invariant"));
 
   guarantee(!regions_empty() || total_used_bytes() == 0,
-            hrl_ext_msg(this, "invariant"));
+            hrs_ext_msg(this, "invariant"));
 
   guarantee(total_used_bytes() <= total_capacity_bytes(),
-            hrl_ext_msg(this, "invariant"));
+            hrs_ext_msg(this, "invariant"));
 }
 
 void HeapRegionSetBase::verify_start() {
   // See comment in verify() about MT safety and verification.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   assert(!_verify_in_progress,
-         hrl_ext_msg(this, "verification should not be in progress"));
+         hrs_ext_msg(this, "verification should not be in progress"));
 
   // Do the basic verification first before we do the checks over the regions.
   HeapRegionSetBase::verify();
@@ -146,11 +146,11 @@
 
 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) {
   // See comment in verify() about MT safety and verification.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   assert(_verify_in_progress,
-         hrl_ext_msg(this, "verification should be in progress"));
+         hrs_ext_msg(this, "verification should be in progress"));
 
-  guarantee(verify_region(hr, this), hrl_ext_msg(this, "region verification"));
+  guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification"));
 
   _calc_length               += 1;
   if (!hr->isHumongous()) {
@@ -164,28 +164,28 @@
 
 void HeapRegionSetBase::verify_end() {
   // See comment in verify() about MT safety and verification.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   assert(_verify_in_progress,
-         hrl_ext_msg(this, "verification should be in progress"));
+         hrs_ext_msg(this, "verification should be in progress"));
 
   guarantee(length() == _calc_length,
-            hrl_err_msg("[%s] length: "SIZE_FORMAT" should be == "
+            hrs_err_msg("[%s] length: "SIZE_FORMAT" should be == "
                         "calc length: "SIZE_FORMAT,
                         name(), length(), _calc_length));
 
   guarantee(region_num() == _calc_region_num,
-            hrl_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
+            hrs_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
                         "calc region num: "SIZE_FORMAT,
                         name(), region_num(), _calc_region_num));
 
   guarantee(total_capacity_bytes() == _calc_total_capacity_bytes,
-            hrl_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
+            hrs_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
                         "calc capacity bytes: "SIZE_FORMAT,
                         name(),
                         total_capacity_bytes(), _calc_total_capacity_bytes));
 
   guarantee(total_used_bytes() == _calc_total_used_bytes,
-            hrl_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
+            hrs_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
                         "calc used bytes: "SIZE_FORMAT,
                         name(), total_used_bytes(), _calc_total_used_bytes));
 
@@ -221,9 +221,9 @@
 //////////////////// HeapRegionSet ////////////////////
 
 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) {
-  hrl_assert_mt_safety_ok(this);
-  hrl_assert_mt_safety_ok(proxy_set);
-  hrl_assert_sets_match(this, proxy_set);
+  hrs_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(proxy_set);
+  hrs_assert_sets_match(this, proxy_set);
 
   verify_optional();
   proxy_set->verify_optional();
@@ -231,19 +231,19 @@
   if (proxy_set->is_empty()) return;
 
   assert(proxy_set->length() <= _length,
-         hrl_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
                      "should be <= length: "SIZE_FORMAT,
                      name(), proxy_set->length(), _length));
   _length -= proxy_set->length();
 
   assert(proxy_set->region_num() <= _region_num,
-         hrl_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
                      "should be <= region num: "SIZE_FORMAT,
                      name(), proxy_set->region_num(), _region_num));
   _region_num -= proxy_set->region_num();
 
   assert(proxy_set->total_used_bytes() <= _total_used_bytes,
-         hrl_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
                      "should be <= used bytes: "SIZE_FORMAT,
                      name(), proxy_set->total_used_bytes(),
                      _total_used_bytes));
@@ -257,13 +257,13 @@
 
 //////////////////// HeapRegionLinkedList ////////////////////
 
-void HeapRegionLinkedList::fill_in_ext_msg_extra(hrl_ext_msg* msg) {
+void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
   msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
 }
 
 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) {
-  hrl_assert_mt_safety_ok(this);
-  hrl_assert_mt_safety_ok(from_list);
+  hrs_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(from_list);
 
   verify_optional();
   from_list->verify_optional();
@@ -283,10 +283,10 @@
 #endif // ASSERT
 
   if (_tail != NULL) {
-    assert(length() >  0 && _head != NULL, hrl_ext_msg(this, "invariant"));
+    assert(length() >  0 && _head != NULL, hrs_ext_msg(this, "invariant"));
     _tail->set_next(from_list->_head);
   } else {
-    assert(length() == 0 && _head == NULL, hrl_ext_msg(this, "invariant"));
+    assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
     _head = from_list->_head;
   }
   _tail = from_list->_tail;
@@ -301,12 +301,12 @@
 }
 
 void HeapRegionLinkedList::remove_all() {
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   verify_optional();
 
   HeapRegion* curr = _head;
   while (curr != NULL) {
-    hrl_assert_region_ok(this, curr, this);
+    hrs_assert_region_ok(this, curr, this);
 
     HeapRegion* next = curr->next();
     curr->set_next(NULL);
@@ -319,9 +319,9 @@
 }
 
 void HeapRegionLinkedList::remove_all_pending(size_t target_count) {
-  hrl_assert_mt_safety_ok(this);
-  assert(target_count > 1, hrl_ext_msg(this, "pre-condition"));
-  assert(!is_empty(), hrl_ext_msg(this, "pre-condition"));
+  hrs_assert_mt_safety_ok(this);
+  assert(target_count > 1, hrs_ext_msg(this, "pre-condition"));
+  assert(!is_empty(), hrs_ext_msg(this, "pre-condition"));
 
   verify_optional();
   DEBUG_ONLY(size_t old_length = length();)
@@ -330,27 +330,27 @@
   HeapRegion* prev = NULL;
   size_t count = 0;
   while (curr != NULL) {
-    hrl_assert_region_ok(this, curr, this);
+    hrs_assert_region_ok(this, curr, this);
     HeapRegion* next = curr->next();
 
     if (curr->pending_removal()) {
       assert(count < target_count,
-             hrl_err_msg("[%s] should not come across more regions "
+             hrs_err_msg("[%s] should not come across more regions "
                          "pending for removal than target_count: "SIZE_FORMAT,
                          name(), target_count));
 
       if (prev == NULL) {
-        assert(_head == curr, hrl_ext_msg(this, "invariant"));
+        assert(_head == curr, hrs_ext_msg(this, "invariant"));
         _head = next;
       } else {
-        assert(_head != curr, hrl_ext_msg(this, "invariant"));
+        assert(_head != curr, hrs_ext_msg(this, "invariant"));
         prev->set_next(next);
       }
       if (next == NULL) {
-        assert(_tail == curr, hrl_ext_msg(this, "invariant"));
+        assert(_tail == curr, hrs_ext_msg(this, "invariant"));
         _tail = prev;
       } else {
-        assert(_tail != curr, hrl_ext_msg(this, "invariant"));
+        assert(_tail != curr, hrs_ext_msg(this, "invariant"));
       }
 
       curr->set_next(NULL);
@@ -371,10 +371,10 @@
   }
 
   assert(count == target_count,
-         hrl_err_msg("[%s] count: "SIZE_FORMAT" should be == "
+         hrs_err_msg("[%s] count: "SIZE_FORMAT" should be == "
                      "target_count: "SIZE_FORMAT, name(), count, target_count));
   assert(length() + target_count == old_length,
-         hrl_err_msg("[%s] new length should be consistent "
+         hrs_err_msg("[%s] new length should be consistent "
                      "new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" "
                      "target_count: "SIZE_FORMAT,
                      name(), length(), old_length, target_count));
@@ -385,7 +385,7 @@
 void HeapRegionLinkedList::verify() {
   // See comment in HeapRegionSetBase::verify() about MT safety and
   // verification.
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
 
   // This will also do the basic verification too.
   verify_start();
@@ -399,7 +399,7 @@
 
     count += 1;
     guarantee(count < _unrealistically_long_length,
-              hrl_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
+              hrs_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
                           "seems very long, is there maybe a cycle? "
                           "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" "
                           "prev1: "PTR_FORMAT" length: "SIZE_FORMAT,
@@ -410,7 +410,7 @@
     curr  = curr->next();
   }
 
-  guarantee(_tail == prev0, hrl_ext_msg(this, "post-condition"));
+  guarantee(_tail == prev0, hrs_ext_msg(this, "post-condition"));
 
   verify_end();
 }
--- a/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -28,8 +28,8 @@
 #include "gc_implementation/g1/heapRegion.hpp"
 
 // Large buffer for some cases where the output might be larger than normal.
-#define HRL_ERR_MSG_BUFSZ 512
-typedef FormatBuffer<HRL_ERR_MSG_BUFSZ> hrl_err_msg;
+#define HRS_ERR_MSG_BUFSZ 512
+typedef FormatBuffer<HRS_ERR_MSG_BUFSZ> hrs_err_msg;
 
 // Set verification will be forced either if someone defines
 // HEAP_REGION_SET_FORCE_VERIFY to be 1, or in builds in which
@@ -45,10 +45,10 @@
 // (e.g., length, region num, used bytes sum) plus any shared
 // functionality (e.g., verification).
 
-class hrl_ext_msg;
+class hrs_ext_msg;
 
 class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC {
-  friend class hrl_ext_msg;
+  friend class hrs_ext_msg;
 
 protected:
   static size_t calculate_region_num(HeapRegion* hr);
@@ -104,10 +104,10 @@
   virtual bool check_mt_safety() { return true; }
 
   // fill_in_ext_msg() writes the the values of the set's attributes
-  // in the custom err_msg (hrl_ext_msg). fill_in_ext_msg_extra()
+  // in the custom err_msg (hrs_ext_msg). fill_in_ext_msg_extra()
   // allows subclasses to append further information.
-  virtual void fill_in_ext_msg_extra(hrl_ext_msg* msg) { }
-  void fill_in_ext_msg(hrl_ext_msg* msg, const char* message);
+  virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { }
+  void fill_in_ext_msg(hrs_ext_msg* msg, const char* message);
 
   // It updates the fields of the set to reflect hr being added to
   // the set.
@@ -170,9 +170,9 @@
 // the fields of the associated set. This can be very helpful in
 // diagnosing failures.
 
-class hrl_ext_msg : public hrl_err_msg {
+class hrs_ext_msg : public hrs_err_msg {
 public:
-  hrl_ext_msg(HeapRegionSetBase* set, const char* message) : hrl_err_msg("") {
+  hrs_ext_msg(HeapRegionSetBase* set, const char* message) : hrs_err_msg("") {
     set->fill_in_ext_msg(this, message);
   }
 };
@@ -180,25 +180,25 @@
 // These two macros are provided for convenience, to keep the uses of
 // these two asserts a bit more concise.
 
-#define hrl_assert_mt_safety_ok(_set_)                                        \
+#define hrs_assert_mt_safety_ok(_set_)                                        \
   do {                                                                        \
-    assert((_set_)->check_mt_safety(), hrl_ext_msg((_set_), "MT safety"));    \
+    assert((_set_)->check_mt_safety(), hrs_ext_msg((_set_), "MT safety"));    \
   } while (0)
 
-#define hrl_assert_region_ok(_set_, _hr_, _expected_)                         \
+#define hrs_assert_region_ok(_set_, _hr_, _expected_)                         \
   do {                                                                        \
     assert((_set_)->verify_region((_hr_), (_expected_)),                      \
-           hrl_ext_msg((_set_), "region verification"));                      \
+           hrs_ext_msg((_set_), "region verification"));                      \
   } while (0)
 
 //////////////////// HeapRegionSet ////////////////////
 
-#define hrl_assert_sets_match(_set1_, _set2_)                                 \
+#define hrs_assert_sets_match(_set1_, _set2_)                                 \
   do {                                                                        \
     assert(((_set1_)->regions_humongous() ==                                  \
                                             (_set2_)->regions_humongous()) && \
            ((_set1_)->regions_empty() == (_set2_)->regions_empty()),          \
-           hrl_err_msg("the contents of set %s and set %s should match",      \
+           hrs_err_msg("the contents of set %s and set %s should match",      \
                        (_set1_)->name(), (_set2_)->name()));                  \
   } while (0)
 
@@ -267,7 +267,7 @@
   HeapRegion* tail() { return _tail; }
 
 protected:
-  virtual void fill_in_ext_msg_extra(hrl_ext_msg* msg);
+  virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg);
 
   // See the comment for HeapRegionSetBase::clear()
   virtual void clear();
@@ -309,10 +309,10 @@
   virtual void print_on(outputStream* out, bool print_contents = false);
 };
 
-//////////////////// HeapRegionLinkedList ////////////////////
+//////////////////// HeapRegionLinkedListIterator ////////////////////
 
-// Iterator class that provides a convenient way to iterator over the
-// regions in a HeapRegionLinkedList instance.
+// Iterator class that provides a convenient way to iterate over the
+// regions of a HeapRegionLinkedList instance.
 
 class HeapRegionLinkedListIterator : public StackObj {
 private:
--- a/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -42,8 +42,8 @@
 }
 
 inline void HeapRegionSetBase::add_internal(HeapRegion* hr) {
-  hrl_assert_region_ok(this, hr, NULL);
-  assert(hr->next() == NULL, hrl_ext_msg(this, "should not already be linked"));
+  hrs_assert_region_ok(this, hr, NULL);
+  assert(hr->next() == NULL, hrs_ext_msg(this, "should not already be linked"));
 
   update_for_addition(hr);
   hr->set_containing_set(this);
@@ -51,7 +51,7 @@
 
 inline void HeapRegionSetBase::update_for_removal(HeapRegion* hr) {
   // Assumes the caller has already verified the region.
-  assert(_length > 0, hrl_ext_msg(this, "pre-condition"));
+  assert(_length > 0, hrs_ext_msg(this, "pre-condition"));
   _length -= 1;
 
   size_t region_num_diff;
@@ -61,22 +61,22 @@
     region_num_diff = calculate_region_num(hr);
   }
   assert(region_num_diff <= _region_num,
-         hrl_err_msg("[%s] region's region num: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] region's region num: "SIZE_FORMAT" "
                      "should be <= region num: "SIZE_FORMAT,
                      name(), region_num_diff, _region_num));
   _region_num -= region_num_diff;
 
   size_t used_bytes = hr->used();
   assert(used_bytes <= _total_used_bytes,
-         hrl_err_msg("[%s] region's used bytes: "SIZE_FORMAT" "
+         hrs_err_msg("[%s] region's used bytes: "SIZE_FORMAT" "
                      "should be <= used bytes: "SIZE_FORMAT,
                      name(), used_bytes, _total_used_bytes));
   _total_used_bytes -= used_bytes;
 }
 
 inline void HeapRegionSetBase::remove_internal(HeapRegion* hr) {
-  hrl_assert_region_ok(this, hr, this);
-  assert(hr->next() == NULL, hrl_ext_msg(this, "should already be unlinked"));
+  hrs_assert_region_ok(this, hr, this);
+  assert(hr->next() == NULL, hrs_ext_msg(this, "should already be unlinked"));
 
   hr->set_containing_set(NULL);
   update_for_removal(hr);
@@ -85,13 +85,13 @@
 //////////////////// HeapRegionSet ////////////////////
 
 inline void HeapRegionSet::add(HeapRegion* hr) {
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   // add_internal() will verify the region.
   add_internal(hr);
 }
 
 inline void HeapRegionSet::remove(HeapRegion* hr) {
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   // remove_internal() will verify the region.
   remove_internal(hr);
 }
@@ -101,8 +101,8 @@
   // No need to fo the MT safety check here given that this method
   // does not update the contents of the set but instead accumulates
   // the changes in proxy_set which is assumed to be thread-local.
-  hrl_assert_sets_match(this, proxy_set);
-  hrl_assert_region_ok(this, hr, this);
+  hrs_assert_sets_match(this, proxy_set);
+  hrs_assert_region_ok(this, hr, this);
 
   hr->set_containing_set(NULL);
   proxy_set->update_for_addition(hr);
@@ -111,10 +111,10 @@
 //////////////////// HeapRegionLinkedList ////////////////////
 
 inline void HeapRegionLinkedList::add_as_tail(HeapRegion* hr) {
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
   assert((length() == 0 && _head == NULL && _tail == NULL) ||
          (length() >  0 && _head != NULL && _tail != NULL),
-         hrl_ext_msg(this, "invariant"));
+         hrs_ext_msg(this, "invariant"));
   // add_internal() will verify the region.
   add_internal(hr);
 
@@ -128,10 +128,10 @@
 }
 
 inline HeapRegion* HeapRegionLinkedList::remove_head() {
-  hrl_assert_mt_safety_ok(this);
-  assert(!is_empty(), hrl_ext_msg(this, "the list should not be empty"));
+  hrs_assert_mt_safety_ok(this);
+  assert(!is_empty(), hrs_ext_msg(this, "the list should not be empty"));
   assert(length() > 0 && _head != NULL && _tail != NULL,
-         hrl_ext_msg(this, "invariant"));
+         hrs_ext_msg(this, "invariant"));
 
   // We need to unlink it first.
   HeapRegion* hr = _head;
@@ -147,7 +147,7 @@
 }
 
 inline HeapRegion* HeapRegionLinkedList::remove_head_or_null() {
-  hrl_assert_mt_safety_ok(this);
+  hrs_assert_mt_safety_ok(this);
 
   if (!is_empty()) {
     return remove_head();
--- a/src/share/vm/gc_implementation/g1/heapRegionSets.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/g1/heapRegionSets.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -52,7 +52,7 @@
                                             FreeList_lock->owned_by_self())) ||
             (!SafepointSynchronize::is_at_safepoint() &&
                                                 Heap_lock->owned_by_self()),
-            hrl_ext_msg(this, "master free list MT safety protocol"));
+            hrs_ext_msg(this, "master free list MT safety protocol"));
 
   return FreeRegionList::check_mt_safety();
 }
@@ -65,7 +65,7 @@
   // while holding the SecondaryFreeList_lock.
 
   guarantee(SecondaryFreeList_lock->owned_by_self(),
-            hrl_ext_msg(this, "secondary free list MT safety protocol"));
+            hrs_ext_msg(this, "secondary free list MT safety protocol"));
 
   return FreeRegionList::check_mt_safety();
 }
@@ -81,7 +81,7 @@
   return HeapRegionSet::verify_region_extra(hr);
 }
 
-//////////////////// HumongousRegionSet ////////////////////
+//////////////////// MasterHumongousRegionSet ////////////////////
 
 bool MasterHumongousRegionSet::check_mt_safety() {
   // Master Humongous Set MT safety protocol:
@@ -97,6 +97,6 @@
                                              OldSets_lock->owned_by_self())) ||
             (!SafepointSynchronize::is_at_safepoint() &&
                                                  Heap_lock->owned_by_self()),
-            hrl_ext_msg(this, "master humongous set MT safety protocol"));
+            hrs_ext_msg(this, "master humongous set MT safety protocol"));
   return HumongousRegionSet::check_mt_safety();
 }
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1530,13 +1530,15 @@
 {
   if (_ref_processor == NULL) {
     // Allocate and initialize a reference processor
-    _ref_processor = ReferenceProcessor::create_ref_processor(
-        _reserved,                  // span
-        refs_discovery_is_atomic(), // atomic_discovery
-        refs_discovery_is_mt(),     // mt_discovery
-        NULL,                       // is_alive_non_header
-        ParallelGCThreads,
-        ParallelRefProcEnabled);
+    _ref_processor =
+      new ReferenceProcessor(_reserved,                  // span
+                             ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing
+                             (int) ParallelGCThreads,    // mt processing degree
+                             refs_discovery_is_mt(),     // mt discovery
+                             (int) ParallelGCThreads,    // mt discovery degree
+                             refs_discovery_is_atomic(), // atomic_discovery
+                             NULL,                       // is_alive_non_header
+                             false);                     // write barrier for next field updates
   }
 }
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,9 +58,7 @@
 
 void PSMarkSweep::initialize() {
   MemRegion mr = Universe::heap()->reserved_region();
-  _ref_processor = new ReferenceProcessor(mr,
-                                          true,    // atomic_discovery
-                                          false);  // mt_discovery
+  _ref_processor = new ReferenceProcessor(mr);     // a vanilla ref proc
   _counters = new CollectorCounters("PSMarkSweep", 1);
 }
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -827,13 +827,15 @@
   assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
 
   MemRegion mr = heap->reserved_region();
-  _ref_processor = ReferenceProcessor::create_ref_processor(
-    mr,                         // span
-    true,                       // atomic_discovery
-    true,                       // mt_discovery
-    &_is_alive_closure,
-    ParallelGCThreads,
-    ParallelRefProcEnabled);
+  _ref_processor =
+    new ReferenceProcessor(mr,            // span
+                           ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing
+                           (int) ParallelGCThreads, // mt processing degree
+                           true,          // mt discovery
+                           (int) ParallelGCThreads, // mt discovery degree
+                           true,          // atomic_discovery
+                           &_is_alive_closure, // non-header is alive closure
+                           false);        // write barrier for next field updates
   _counters = new CollectorCounters("PSParallelCompact", 1);
 
   // Initialize static fields in ParCompactionManager.
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -411,7 +411,7 @@
 template <class T> void PSPromotionManager::process_array_chunk_work(
                                                  oop obj,
                                                  int start, int end) {
-  assert(start < end, "invariant");
+  assert(start <= end, "invariant");
   T* const base      = (T*)objArrayOop(obj)->base();
   T* p               = base + start;
   T* const chunk_end = base + end;
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/symbolTable.hpp"
 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
 #include "gc_implementation/parallelScavenge/generationSizer.hpp"
@@ -439,6 +440,14 @@
       reference_processor()->enqueue_discovered_references(NULL);
     }
 
+    if (!JavaObjectsInPerm) {
+      // Unlink any dead interned Strings
+      StringTable::unlink(&_is_alive_closure);
+      // Process the remaining live ones
+      PSScavengeRootsClosure root_closure(promotion_manager);
+      StringTable::oops_do(&root_closure);
+    }
+
     // Finally, flush the promotion_manager's labs, and deallocate its stacks.
     PSPromotionManager::post_scavenge();
 
@@ -796,13 +805,15 @@
 
   // Initialize ref handling object for scavenging.
   MemRegion mr = young_gen->reserved();
-  _ref_processor = ReferenceProcessor::create_ref_processor(
-    mr,                         // span
-    true,                       // atomic_discovery
-    true,                       // mt_discovery
-    NULL,                       // is_alive_non_header
-    ParallelGCThreads,
-    ParallelRefProcEnabled);
+  _ref_processor =
+    new ReferenceProcessor(mr,                         // span
+                           ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing
+                           (int) ParallelGCThreads,    // mt processing degree
+                           true,                       // mt discovery
+                           (int) ParallelGCThreads,    // mt discovery degree
+                           true,                       // atomic_discovery
+                           NULL,                       // header provides liveness info
+                           false);                     // next field updates do not need write barrier
 
   // Cache the cardtable
   BarrierSet* bs = Universe::heap()->barrier_set();
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -86,4 +86,21 @@
   }
 }
 
+class PSScavengeRootsClosure: public OopClosure {
+ private:
+  PSPromotionManager* _promotion_manager;
+
+ protected:
+  template <class T> void do_oop_work(T *p) {
+    if (PSScavenge::should_scavenge(p)) {
+      // We never card mark roots, maybe call a func without test?
+      PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
+    }
+  }
+ public:
+  PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
+  void do_oop(oop* p)       { PSScavengeRootsClosure::do_oop_work(p); }
+  void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); }
+};
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSSCAVENGE_INLINE_HPP
--- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -30,7 +30,7 @@
 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.hpp"
+#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
 #include "gc_implementation/parallelScavenge/psTasks.hpp"
 #include "memory/iterator.hpp"
 #include "memory/universe.hpp"
@@ -46,24 +46,6 @@
 // ScavengeRootsTask
 //
 
-// Define before use
-class PSScavengeRootsClosure: public OopClosure {
- private:
-  PSPromotionManager* _promotion_manager;
-
- protected:
-  template <class T> void do_oop_work(T *p) {
-    if (PSScavenge::should_scavenge(p)) {
-      // We never card mark roots, maybe call a func without test?
-      PSScavenge::copy_and_push_safe_barrier(_promotion_manager, p);
-    }
-  }
- public:
-  PSScavengeRootsClosure(PSPromotionManager* pm) : _promotion_manager(pm) { }
-  void do_oop(oop* p)       { PSScavengeRootsClosure::do_oop_work(p); }
-  void do_oop(narrowOop* p) { PSScavengeRootsClosure::do_oop_work(p); }
-};
-
 void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
   assert(Universe::heap()->is_gc_active(), "called outside gc");
 
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -656,7 +656,7 @@
           // oop rcvr = locals[0].j.r;
           oop rcvr;
           if (METHOD->is_static()) {
-            rcvr = METHOD->constants()->pool_holder()->klass_part()->java_mirror();
+            rcvr = METHOD->constants()->pool_holder()->java_mirror();
           } else {
             rcvr = LOCALS_OBJECT(0);
             VERIFY_OOP(rcvr);
@@ -2111,8 +2111,8 @@
             break;
 
           case JVM_CONSTANT_Class:
-            VERIFY_OOP(constants->resolved_klass_at(index)->klass_part()->java_mirror());
-            SET_STACK_OBJECT(constants->resolved_klass_at(index)->klass_part()->java_mirror(), 0);
+            VERIFY_OOP(constants->resolved_klass_at(index)->java_mirror());
+            SET_STACK_OBJECT(constants->resolved_klass_at(index)->java_mirror(), 0);
             break;
 
           case JVM_CONSTANT_UnresolvedString:
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -118,7 +118,7 @@
 
   if (tag.is_unresolved_klass() || tag.is_klass()) {
     klassOop klass = pool->klass_at(index, CHECK);
-    oop java_class = klass->klass_part()->java_mirror();
+    oop java_class = klass->java_mirror();
     thread->set_vm_result(java_class);
   } else {
 #ifdef ASSERT
@@ -983,7 +983,8 @@
 ConstantPoolCacheEntry *cp_entry))
 
   // check the access_flags for the field in the klass
-  instanceKlass* ik = instanceKlass::cast((klassOop)cp_entry->f1());
+
+  instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1()));
   typeArrayOop fields = ik->fields();
   int index = cp_entry->field_index();
   assert(index < fields->length(), "holders field index is out of range");
@@ -1009,7 +1010,7 @@
     // non-static field accessors have an object, but we need a handle
     h_obj = Handle(thread, obj);
   }
-  instanceKlassHandle h_cp_entry_f1(thread, (klassOop)cp_entry->f1());
+  instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1()));
   jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2(), is_static);
   JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid);
 IRT_END
@@ -1017,7 +1018,7 @@
 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
   oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value))
 
-  klassOop k = (klassOop)cp_entry->f1();
+  klassOop k = java_lang_Class::as_klassOop(cp_entry->f1());
 
   // check the access_flags for the field in the klass
   instanceKlass* ik = instanceKlass::cast(k);
--- a/src/share/vm/memory/collectorPolicy.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/collectorPolicy.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -293,10 +293,11 @@
   // Determine maximum size of gen0
 
   size_t max_new_size = 0;
-  if (FLAG_IS_CMDLINE(MaxNewSize)) {
+  if (FLAG_IS_CMDLINE(MaxNewSize) || FLAG_IS_ERGO(MaxNewSize)) {
     if (MaxNewSize < min_alignment()) {
       max_new_size = min_alignment();
-    } else if (MaxNewSize >= max_heap_byte_size()) {
+    }
+    if (MaxNewSize >= max_heap_byte_size()) {
       max_new_size = align_size_down(max_heap_byte_size() - min_alignment(),
                                      min_alignment());
       warning("MaxNewSize (" SIZE_FORMAT "k) is equal to or "
@@ -333,7 +334,7 @@
   assert(max_new_size > 0, "All paths should set max_new_size");
 
   // Given the maximum gen0 size, determine the initial and
-  // minimum sizes.
+  // minimum gen0 sizes.
 
   if (max_heap_byte_size() == min_heap_byte_size()) {
     // The maximum and minimum heap sizes are the same so
@@ -396,7 +397,7 @@
   }
 
   if (PrintGCDetails && Verbose) {
-    gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
+    gclog_or_tty->print_cr("1: Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
       SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
       min_gen0_size(), initial_gen0_size(), max_gen0_size());
   }
@@ -448,7 +449,7 @@
   // At this point the minimum, initial and maximum sizes
   // of the overall heap and of gen0 have been determined.
   // The maximum gen1 size can be determined from the maximum gen0
-  // and maximum heap size since not explicit flags exits
+  // and maximum heap size since no explicit flags exits
   // for setting the gen1 maximum.
   _max_gen1_size = max_heap_byte_size() - _max_gen0_size;
   _max_gen1_size =
@@ -494,13 +495,13 @@
           "generation sizes: using maximum heap = " SIZE_FORMAT
           " -XX:OldSize flag is being ignored",
           max_heap_byte_size());
-  }
+    }
     // If there is an inconsistency between the OldSize and the minimum and/or
     // initial size of gen0, since OldSize was explicitly set, OldSize wins.
     if (adjust_gen0_sizes(&_min_gen0_size, &_min_gen1_size,
                           min_heap_byte_size(), OldSize)) {
       if (PrintGCDetails && Verbose) {
-        gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
+        gclog_or_tty->print_cr("2: Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
               SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
               min_gen0_size(), initial_gen0_size(), max_gen0_size());
       }
@@ -509,7 +510,7 @@
     if (adjust_gen0_sizes(&_initial_gen0_size, &_initial_gen1_size,
                          initial_heap_byte_size(), OldSize)) {
       if (PrintGCDetails && Verbose) {
-        gclog_or_tty->print_cr("Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
+        gclog_or_tty->print_cr("3: Minimum gen0 " SIZE_FORMAT "  Initial gen0 "
           SIZE_FORMAT "  Maximum gen0 " SIZE_FORMAT,
           min_gen0_size(), initial_gen0_size(), max_gen0_size());
       }
--- a/src/share/vm/memory/compactingPermGenGen.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/compactingPermGenGen.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -105,7 +105,7 @@
 public:
 
   enum {
-    vtbl_list_size = 16, // number of entries in the shared space vtable list.
+    vtbl_list_size = 17, // number of entries in the shared space vtable list.
     num_virtuals = 200   // number of virtual methods in Klass (or
                          // subclass) objects, or greater.
   };
--- a/src/share/vm/memory/dump.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/dump.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1561,6 +1561,7 @@
     // thread because it requires object allocation.
     LinkClassesClosure lcc(Thread::current());
     object_iterate(&lcc);
+    ensure_parsability(false); // arg is actually don't care
     tty->print_cr("done. ");
 
     // Create and dump the shared spaces.
--- a/src/share/vm/memory/generation.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/generation.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -83,14 +83,11 @@
 }
 
 // By default we get a single threaded default reference processor;
-// generations needing multi-threaded refs discovery override this method.
+// generations needing multi-threaded refs processing or discovery override this method.
 void Generation::ref_processor_init() {
   assert(_ref_processor == NULL, "a reference processor already exists");
   assert(!_reserved.is_empty(), "empty generation?");
-  _ref_processor =
-    new ReferenceProcessor(_reserved,                  // span
-                           refs_discovery_is_atomic(), // atomic_discovery
-                           refs_discovery_is_mt());    // mt_discovery
+  _ref_processor = new ReferenceProcessor(_reserved);    // a vanilla reference processor
   if (_ref_processor == NULL) {
     vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
   }
--- a/src/share/vm/memory/oopFactory.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/oopFactory.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -117,12 +117,12 @@
 }
 
 
-klassOop oopFactory::new_instanceKlass(int vtable_len, int itable_len,
+klassOop oopFactory::new_instanceKlass(Symbol* name, int vtable_len, int itable_len,
                                        int static_field_size,
                                        unsigned int nonstatic_oop_map_count,
                                        ReferenceType rt, TRAPS) {
   instanceKlassKlass* ikk = instanceKlassKlass::cast(Universe::instanceKlassKlassObj());
-  return ikk->allocate_instance_klass(vtable_len, itable_len, static_field_size, nonstatic_oop_map_count, rt, CHECK_NULL);
+  return ikk->allocate_instance_klass(name, vtable_len, itable_len, static_field_size, nonstatic_oop_map_count, rt, CHECK_NULL);
 }
 
 
--- a/src/share/vm/memory/oopFactory.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/oopFactory.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -72,7 +72,8 @@
                                                     TRAPS);
 
   // Instance classes
-  static klassOop        new_instanceKlass(int vtable_len, int itable_len,
+  static klassOop        new_instanceKlass(Symbol* name,
+                                           int vtable_len, int itable_len,
                                            int static_field_size,
                                            unsigned int nonstatic_oop_map_count,
                                            ReferenceType rt, TRAPS);
--- a/src/share/vm/memory/referenceProcessor.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/referenceProcessor.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -102,40 +102,17 @@
             "Unrecongnized RefDiscoveryPolicy");
 }
 
-ReferenceProcessor*
-ReferenceProcessor::create_ref_processor(MemRegion          span,
-                                         bool               atomic_discovery,
-                                         bool               mt_discovery,
-                                         BoolObjectClosure* is_alive_non_header,
-                                         int                parallel_gc_threads,
-                                         bool               mt_processing,
-                                         bool               dl_needs_barrier) {
-  int mt_degree = 1;
-  if (parallel_gc_threads > 1) {
-    mt_degree = parallel_gc_threads;
-  }
-  ReferenceProcessor* rp =
-    new ReferenceProcessor(span, atomic_discovery,
-                           mt_discovery, mt_degree,
-                           mt_processing && (parallel_gc_threads > 0),
-                           dl_needs_barrier);
-  if (rp == NULL) {
-    vm_exit_during_initialization("Could not allocate ReferenceProcessor object");
-  }
-  rp->set_is_alive_non_header(is_alive_non_header);
-  rp->setup_policy(false /* default soft ref policy */);
-  return rp;
-}
-
 ReferenceProcessor::ReferenceProcessor(MemRegion span,
+                                       bool      mt_processing,
+                                       int       mt_processing_degree,
+                                       bool      mt_discovery,
+                                       int       mt_discovery_degree,
                                        bool      atomic_discovery,
-                                       bool      mt_discovery,
-                                       int       mt_degree,
-                                       bool      mt_processing,
+                                       BoolObjectClosure* is_alive_non_header,
                                        bool      discovered_list_needs_barrier)  :
   _discovering_refs(false),
   _enqueuing_is_done(false),
-  _is_alive_non_header(NULL),
+  _is_alive_non_header(is_alive_non_header),
   _discovered_list_needs_barrier(discovered_list_needs_barrier),
   _bs(NULL),
   _processing_is_mt(mt_processing),
@@ -144,8 +121,8 @@
   _span = span;
   _discovery_is_atomic = atomic_discovery;
   _discovery_is_mt     = mt_discovery;
-  _num_q               = mt_degree;
-  _max_num_q           = mt_degree;
+  _num_q               = MAX2(1, mt_processing_degree);
+  _max_num_q           = MAX2(_num_q, mt_discovery_degree);
   _discoveredSoftRefs  = NEW_C_HEAP_ARRAY(DiscoveredList, _max_num_q * subclasses_of_ref);
   if (_discoveredSoftRefs == NULL) {
     vm_exit_during_initialization("Could not allocated RefProc Array");
@@ -163,6 +140,7 @@
   if (discovered_list_needs_barrier) {
     _bs = Universe::heap()->barrier_set();
   }
+  setup_policy(false /* default soft ref policy */);
 }
 
 #ifndef PRODUCT
@@ -405,15 +383,14 @@
   { }
 
   virtual void work(unsigned int work_id) {
-    assert(work_id < (unsigned int)_ref_processor.num_q(), "Index out-of-bounds");
+    assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
     // Simplest first cut: static partitioning.
     int index = work_id;
     // The increment on "index" must correspond to the maximum number of queues
     // (n_queues) with which that ReferenceProcessor was created.  That
     // is because of the "clever" way the discovered references lists were
-    // allocated and are indexed into.  That number is ParallelGCThreads
-    // currently.  Assert that.
-    assert(_n_queues == (int) ParallelGCThreads, "Different number not expected");
+    // allocated and are indexed into.
+    assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
     for (int j = 0;
          j < subclasses_of_ref;
          j++, index += _n_queues) {
@@ -672,7 +649,7 @@
     }
   }
   NOT_PRODUCT(
-    if (PrintGCDetails && TraceReferenceGC) {
+    if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
       gclog_or_tty->print_cr(" Dropped %d active Refs out of %d "
         "Refs in discovered list " INTPTR_FORMAT,
         iter.removed(), iter.processed(), (address)refs_list.head());
@@ -711,7 +688,7 @@
   // Now close the newly reachable set
   complete_gc->do_void();
   NOT_PRODUCT(
-    if (PrintGCDetails && TraceReferenceGC) {
+    if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
       gclog_or_tty->print_cr(" Dropped %d active Refs out of %d "
         "Refs in discovered list " INTPTR_FORMAT,
         iter.removed(), iter.processed(), (address)refs_list.head());
@@ -951,7 +928,7 @@
   }
   if (PrintReferenceGC && PrintGCDetails) {
     size_t total = 0;
-    for (int i = 0; i < _num_q; ++i) {
+    for (int i = 0; i < _max_num_q; ++i) {
       total += refs_lists[i].length();
     }
     gclog_or_tty->print(", %u refs", total);
@@ -967,7 +944,7 @@
       RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);
       task_executor->execute(phase1);
     } else {
-      for (int i = 0; i < _num_q; i++) {
+      for (int i = 0; i < _max_num_q; i++) {
         process_phase1(refs_lists[i], policy,
                        is_alive, keep_alive, complete_gc);
       }
@@ -983,7 +960,7 @@
     RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);
     task_executor->execute(phase2);
   } else {
-    for (int i = 0; i < _num_q; i++) {
+    for (int i = 0; i < _max_num_q; i++) {
       process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
     }
   }
@@ -994,7 +971,7 @@
     RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
     task_executor->execute(phase3);
   } else {
-    for (int i = 0; i < _num_q; i++) {
+    for (int i = 0; i < _max_num_q; i++) {
       process_phase3(refs_lists[i], clear_referent,
                      is_alive, keep_alive, complete_gc);
     }
@@ -1008,7 +985,7 @@
   //   for (int j = 0; j < _num_q; j++) {
   //     int index = i * _max_num_q + j;
   for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
-    if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) {
+    if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
       gclog_or_tty->print_cr(
         "\nScrubbing %s discovered list of Null referents",
         list_name(i));
@@ -1350,7 +1327,7 @@
   {
     TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
               false, gclog_or_tty);
-    for (int i = 0; i < _num_q; i++) {
+    for (int i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
       }
@@ -1363,7 +1340,7 @@
   {
     TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
               false, gclog_or_tty);
-    for (int i = 0; i < _num_q; i++) {
+    for (int i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
       }
@@ -1376,7 +1353,7 @@
   {
     TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
               false, gclog_or_tty);
-    for (int i = 0; i < _num_q; i++) {
+    for (int i = 0; i < _max_num_q; i++) {
       if (yield->should_return()) {
         return;
       }
@@ -1433,7 +1410,7 @@
   complete_gc->do_void();
 
   NOT_PRODUCT(
-    if (PrintGCDetails && PrintReferenceGC) {
+    if (PrintGCDetails && PrintReferenceGC && (iter.processed() > 0)) {
       gclog_or_tty->print_cr(" Dropped %d Refs out of %d "
         "Refs in discovered list " INTPTR_FORMAT,
         iter.removed(), iter.processed(), (address)refs_list.head());
--- a/src/share/vm/memory/referenceProcessor.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/referenceProcessor.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -71,7 +71,7 @@
   bool        _enqueuing_is_done;     // true if all weak references enqueued
   bool        _processing_is_mt;      // true during phases when
                                       // reference processing is MT.
-  int         _next_id;               // round-robin counter in
+  int         _next_id;               // round-robin mod _num_q counter in
                                       // support of work distribution
 
   // For collectors that do not keep GC marking information
@@ -103,7 +103,8 @@
 
  public:
   int num_q()                            { return _num_q; }
-  void set_mt_degree(int v)              { _num_q = v; }
+  int max_num_q()                        { return _max_num_q; }
+  void set_active_mt_degree(int v)       { _num_q = v; }
   DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; }
   static oop  sentinel_ref()             { return _sentinelRef; }
   static oop* adr_sentinel_ref()         { return &_sentinelRef; }
@@ -216,6 +217,7 @@
                                    VoidClosure*       complete_gc,
                                    YieldClosure*      yield);
 
+  // round-robin mod _num_q (not: _not_ mode _max_num_q)
   int next_id() {
     int id = _next_id;
     if (++_next_id == _num_q) {
@@ -256,24 +258,16 @@
     _max_num_q(0),
     _processing_is_mt(false),
     _next_id(0)
-  {}
+  { }
 
-  ReferenceProcessor(MemRegion span, bool atomic_discovery,
-                     bool mt_discovery,
-                     int mt_degree = 1,
-                     bool mt_processing = false,
+  // Default parameters give you a vanilla reference processor.
+  ReferenceProcessor(MemRegion span,
+                     bool mt_processing = false, int mt_processing_degree = 1,
+                     bool mt_discovery  = false, int mt_discovery_degree  = 1,
+                     bool atomic_discovery = true,
+                     BoolObjectClosure* is_alive_non_header = NULL,
                      bool discovered_list_needs_barrier = false);
 
-  // Allocates and initializes a reference processor.
-  static ReferenceProcessor* create_ref_processor(
-    MemRegion          span,
-    bool               atomic_discovery,
-    bool               mt_discovery,
-    BoolObjectClosure* is_alive_non_header = NULL,
-    int                parallel_gc_threads = 1,
-    bool               mt_processing = false,
-    bool               discovered_list_needs_barrier = false);
-
   // RefDiscoveryPolicy values
   enum DiscoveryPolicy {
     ReferenceBasedDiscovery = 0,
@@ -397,20 +391,20 @@
 // A utility class to temporarily change the MT'ness of
 // reference discovery for the given ReferenceProcessor
 // in the scope that contains it.
-class ReferenceProcessorMTMutator: StackObj {
+class ReferenceProcessorMTDiscoveryMutator: StackObj {
  private:
   ReferenceProcessor* _rp;
   bool                _saved_mt;
 
  public:
-  ReferenceProcessorMTMutator(ReferenceProcessor* rp,
-                              bool mt):
+  ReferenceProcessorMTDiscoveryMutator(ReferenceProcessor* rp,
+                                       bool mt):
     _rp(rp) {
     _saved_mt = _rp->discovery_is_mt();
     _rp->set_mt_discovery(mt);
   }
 
-  ~ReferenceProcessorMTMutator() {
+  ~ReferenceProcessorMTDiscoveryMutator() {
     _rp->set_mt_discovery(_saved_mt);
   }
 };
--- a/src/share/vm/memory/sharedHeap.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/sharedHeap.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -171,11 +171,13 @@
   }
 
   if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
-     if (so & SO_Strings) {
-       StringTable::oops_do(roots);
-     }
-    // Verify if the string table contents are in the perm gen
-    NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
+    if (so & SO_Strings || (!collecting_perm_gen && !JavaObjectsInPerm)) {
+      StringTable::oops_do(roots);
+    }
+    if (JavaObjectsInPerm) {
+      // Verify the string table contents are in the perm gen
+      NOT_PRODUCT(StringTable::oops_do(&assert_is_perm_closure));
+    }
   }
 
   if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {
--- a/src/share/vm/memory/universe.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/memory/universe.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -51,6 +51,7 @@
 #include "oops/cpCacheKlass.hpp"
 #include "oops/cpCacheOop.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceKlassKlass.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "oops/klassKlass.hpp"
@@ -521,6 +522,7 @@
   { objArrayKlassKlass o;     add_vtable(list, &n, &o, count); }
   { instanceKlassKlass o;     add_vtable(list, &n, &o, count); }
   { instanceKlass o;          add_vtable(list, &n, &o, count); }
+  { instanceMirrorKlass o;    add_vtable(list, &n, &o, count); }
   { instanceRefKlass o;       add_vtable(list, &n, &o, count); }
   { typeArrayKlassKlass o;    add_vtable(list, &n, &o, count); }
   { typeArrayKlass o;         add_vtable(list, &n, &o, count); }
@@ -547,7 +549,7 @@
       KlassHandle k(THREAD, klassOop(obj));
       // We will never reach the CATCH below since Exceptions::_throw will cause
       // the VM to exit if an exception is thrown during initialization
-      java_lang_Class::create_mirror(k, CATCH);
+      java_lang_Class::fixup_mirror(k, CATCH);
       // This call unconditionally creates a new mirror for k,
       // and links in k's component_mirror field if k is an array.
       // If k is an objArray, k's element type must already have
@@ -605,6 +607,10 @@
   // walk over permanent objects created so far (mostly classes) and fixup their mirrors. Note
   // that the number of objects allocated at this point is very small.
   assert(SystemDictionary::Class_klass_loaded(), "java.lang.Class should be loaded");
+
+  // Cache the start of the static fields
+  instanceMirrorKlass::init_offset_of_static_fields();
+
   FixupMirrorClosure blk;
   Universe::heap()->permanent_object_iterate(&blk);
 }
@@ -1313,6 +1319,8 @@
   JNIHandles::verify();
   if (!silent) gclog_or_tty->print("C-heap ");
   os::check_heap();
+  if (!silent) gclog_or_tty->print("code cache ");
+  CodeCache::verify_oops();
   if (!silent) gclog_or_tty->print_cr("]");
 
   _verify_in_progress = false;
--- a/src/share/vm/oops/arrayKlassKlass.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/arrayKlassKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -28,6 +28,13 @@
 #include "oops/arrayKlassKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
+#ifndef SERIALGC
+#include "gc_implementation/parNew/parOopClosures.inline.hpp"
+#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
+#include "memory/cardTableRS.hpp"
+#include "oops/oop.pcgc.inline.hpp"
+#endif
 
 
 klassOop arrayKlassKlass::create_klass(TRAPS) {
@@ -104,9 +111,12 @@
 int arrayKlassKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
   assert(obj->is_klass(), "must be klass");
   arrayKlass* ak = arrayKlass::cast(klassOop(obj));
-  blk->do_oop(ak->adr_component_mirror());
-  blk->do_oop(ak->adr_lower_dimension());
-  blk->do_oop(ak->adr_higher_dimension());
+  oop* addr = ak->adr_component_mirror();
+  if (mr.contains(addr)) blk->do_oop(addr);
+  addr = ak->adr_lower_dimension();
+  if (mr.contains(addr)) blk->do_oop(addr);
+  addr = ak->adr_higher_dimension();
+  if (mr.contains(addr)) blk->do_oop(addr);
   ak->vtable()->oop_oop_iterate_m(blk, mr);
   return klassKlass::oop_oop_iterate_m(obj, blk, mr);
 }
@@ -114,6 +124,12 @@
 #ifndef SERIALGC
 void arrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   assert(obj->blueprint()->oop_is_arrayKlass(),"must be an array klass");
+  arrayKlass* ak = arrayKlass::cast(klassOop(obj));
+  oop* p = ak->adr_component_mirror();
+  if (PSScavenge::should_scavenge(p)) {
+    pm->claim_or_forward_depth(p);
+  }
+  klassKlass::oop_push_contents(pm, obj);
 }
 
 int arrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
--- a/src/share/vm/oops/constantPoolKlass.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/constantPoolKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -285,10 +285,11 @@
 void constantPoolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   assert(obj->is_constantPool(), "should be constant pool");
   constantPoolOop cp = (constantPoolOop) obj;
-  if (AnonymousClasses && cp->has_pseudo_string() && cp->tags() != NULL) {
-    oop* base = (oop*)cp->base();
-    for (int i = 0; i < cp->length(); ++i, ++base) {
+  if (cp->tags() != NULL &&
+      (!JavaObjectsInPerm || (AnonymousClasses && cp->has_pseudo_string()))) {
+    for (int i = 1; i < cp->length(); ++i) {
       if (cp->tag_at(i).is_string()) {
+        oop* base = cp->obj_at_addr_raw(i);
         if (PSScavenge::should_scavenge(base)) {
           pm->claim_or_forward_depth(base);
         }
@@ -460,7 +461,8 @@
       if (cp->tag_at(i).is_string()) {
         if (!cp->has_pseudo_string()) {
           if (entry.is_oop()) {
-            guarantee(entry.get_oop()->is_perm(),   "should be in permspace");
+            guarantee(!JavaObjectsInPerm || entry.get_oop()->is_perm(),
+                      "should be in permspace");
             guarantee(entry.get_oop()->is_instance(), "should be instance");
           }
         } else {
--- a/src/share/vm/oops/constantPoolOop.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/constantPoolOop.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -481,7 +481,7 @@
     {
       klassOop resolved = klass_at_impl(this_oop, index, CHECK_NULL);
       // ldc wants the java mirror.
-      result_oop = resolved->klass_part()->java_mirror();
+      result_oop = resolved->java_mirror();
       break;
     }
 
--- a/src/share/vm/oops/cpCacheKlass.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/cpCacheKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -168,22 +168,18 @@
 void constantPoolCacheKlass::oop_push_contents(PSPromotionManager* pm,
                                                oop obj) {
   assert(obj->is_constantPoolCache(), "should be constant pool");
-  if (EnableInvokeDynamic) {
+  if (ScavengeRootsInCode) {
     constantPoolCacheOop cache = (constantPoolCacheOop)obj;
     // during a scavenge, it is safe to inspect my pool, since it is perm
     constantPoolOop pool = cache->constant_pool();
     assert(pool->is_constantPool(), "should be constant pool");
-    if (pool->has_invokedynamic()) {
-      for (int i = 0; i < cache->length(); i++) {
-        ConstantPoolCacheEntry* e = cache->entry_at(i);
-        oop* p = (oop*)&e->_f1;
-        if (e->is_secondary_entry()) {
-          if (PSScavenge::should_scavenge(p))
-            pm->claim_or_forward_depth(p);
-          assert(!(e->is_vfinal() && PSScavenge::should_scavenge((oop*)&e->_f2)),
-                 "no live oops here");
-        }
-      }
+    for (int i = 0; i < cache->length(); i++) {
+      ConstantPoolCacheEntry* e = cache->entry_at(i);
+      oop* p = (oop*)&e->_f1;
+      if (PSScavenge::should_scavenge(p))
+        pm->claim_or_forward_depth(p);
+      assert(!(e->is_vfinal() && PSScavenge::should_scavenge((oop*)&e->_f2)),
+             "no live oops here");
     }
   }
 }
--- a/src/share/vm/oops/cpCacheOop.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/cpCacheOop.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -133,7 +133,7 @@
                                        TosState field_type,
                                        bool is_final,
                                        bool is_volatile) {
-  set_f1(field_holder());
+  set_f1(field_holder()->java_mirror());
   set_f2(field_offset);
   // The field index is used by jvm/ti and is the index into fields() array
   // in holder instanceKlass.  This is scaled by instanceKlass::next_offset.
--- a/src/share/vm/oops/instanceKlass.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/instanceKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -37,6 +37,7 @@
 #include "memory/oopFactory.hpp"
 #include "memory/permGen.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/methodOop.hpp"
 #include "oops/objArrayKlassKlass.hpp"
@@ -649,6 +650,7 @@
 }
 
 instanceOop instanceKlass::allocate_instance(TRAPS) {
+  assert(!oop_is_instanceMirror(), "wrong allocation path");
   bool has_finalizer_flag = has_finalizer(); // Query before possible GC
   int size = size_helper();  // Query before forming handle.
 
@@ -669,6 +671,7 @@
   // instances so simply disallow finalizable perm objects.  This can
   // be relaxed if a need for it is found.
   assert(!has_finalizer(), "perm objects not allowed to have finalizers");
+  assert(!oop_is_instanceMirror(), "wrong allocation path");
   int size = size_helper();  // Query before forming handle.
   KlassHandle h_k(THREAD, as_klassOop());
   instanceOop i = (instanceOop)
@@ -898,6 +901,7 @@
   }
 }
 
+
 void instanceKlass::do_local_static_fields(FieldClosure* cl) {
   fieldDescriptor fd;
   int length = fields()->length();
@@ -1609,36 +1613,6 @@
 // The following macros call specialized macros, passing either oop or
 // narrowOop as the specialization type.  These test the UseCompressedOops
 // flag.
-#define InstanceKlass_OOP_ITERATE(start_p, count,    \
-                                  do_oop, assert_fn) \
-{                                                    \
-  if (UseCompressedOops) {                           \
-    InstanceKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
-      start_p, count,                                \
-      do_oop, assert_fn)                             \
-  } else {                                           \
-    InstanceKlass_SPECIALIZED_OOP_ITERATE(oop,       \
-      start_p, count,                                \
-      do_oop, assert_fn)                             \
-  }                                                  \
-}
-
-#define InstanceKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high,    \
-                                          do_oop, assert_fn) \
-{                                                            \
-  if (UseCompressedOops) {                                   \
-    InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop, \
-      start_p, count,                                        \
-      low, high,                                             \
-      do_oop, assert_fn)                                     \
-  } else {                                                   \
-    InstanceKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,       \
-      start_p, count,                                        \
-      low, high,                                             \
-      do_oop, assert_fn)                                     \
-  }                                                          \
-}
-
 #define InstanceKlass_OOP_MAP_ITERATE(obj, do_oop, assert_fn)            \
 {                                                                        \
   /* Compute oopmap block range. The common case                         \
@@ -1711,38 +1685,6 @@
   }                                                                      \
 }
 
-void instanceKlass::follow_static_fields() {
-  InstanceKlass_OOP_ITERATE( \
-    start_of_static_fields(), static_oop_field_size(), \
-    MarkSweep::mark_and_push(p), \
-    assert_is_in_closed_subset)
-}
-
-#ifndef SERIALGC
-void instanceKlass::follow_static_fields(ParCompactionManager* cm) {
-  InstanceKlass_OOP_ITERATE( \
-    start_of_static_fields(), static_oop_field_size(), \
-    PSParallelCompact::mark_and_push(cm, p), \
-    assert_is_in)
-}
-#endif // SERIALGC
-
-void instanceKlass::adjust_static_fields() {
-  InstanceKlass_OOP_ITERATE( \
-    start_of_static_fields(), static_oop_field_size(), \
-    MarkSweep::adjust_pointer(p), \
-    assert_nothing)
-}
-
-#ifndef SERIALGC
-void instanceKlass::update_static_fields() {
-  InstanceKlass_OOP_ITERATE( \
-    start_of_static_fields(), static_oop_field_size(), \
-    PSParallelCompact::adjust_pointer(p), \
-    assert_nothing)
-}
-#endif // SERIALGC
-
 void instanceKlass::oop_follow_contents(oop obj) {
   assert(obj != NULL, "can't follow the content of NULL object");
   obj->follow_header();
@@ -1829,22 +1771,6 @@
 ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
 #endif // !SERIALGC
 
-void instanceKlass::iterate_static_fields(OopClosure* closure) {
-    InstanceKlass_OOP_ITERATE( \
-      start_of_static_fields(), static_oop_field_size(), \
-      closure->do_oop(p), \
-      assert_is_in_reserved)
-}
-
-void instanceKlass::iterate_static_fields(OopClosure* closure,
-                                          MemRegion mr) {
-  InstanceKlass_BOUNDED_OOP_ITERATE( \
-    start_of_static_fields(), static_oop_field_size(), \
-    mr.start(), mr.end(), \
-    (closure)->do_oop_v(p), \
-    assert_is_in_closed_subset)
-}
-
 int instanceKlass::oop_adjust_pointers(oop obj) {
   int size = size_helper();
   InstanceKlass_OOP_MAP_ITERATE( \
@@ -1873,21 +1799,6 @@
   return size_helper();
 }
 
-void instanceKlass::push_static_fields(PSPromotionManager* pm) {
-  InstanceKlass_OOP_ITERATE( \
-    start_of_static_fields(), static_oop_field_size(), \
-    if (PSScavenge::should_scavenge(p)) { \
-      pm->claim_or_forward_depth(p); \
-    }, \
-    assert_nothing )
-}
-
-void instanceKlass::copy_static_fields(ParCompactionManager* cm) {
-  InstanceKlass_OOP_ITERATE( \
-    start_of_static_fields(), static_oop_field_size(), \
-    PSParallelCompact::adjust_pointer(p), \
-    assert_is_in)
-}
 #endif // SERIALGC
 
 // This klass is alive but the implementor link is not followed/updated.
@@ -2002,6 +1913,11 @@
   if (_source_debug_extension != NULL) _source_debug_extension->increment_refcount();
 }
 
+address instanceKlass::static_field_addr(int offset) {
+  return (address)(offset + instanceMirrorKlass::offset_of_static_fields() + (intptr_t)java_mirror());
+}
+
+
 const char* instanceKlass::signature_name() const {
   const char* src = (const char*) (name()->as_C_string());
   const int src_length = (int)strlen(src);
@@ -2369,7 +2285,7 @@
 
 void FieldPrinter::do_field(fieldDescriptor* fd) {
   _st->print(BULLET);
-   if (fd->is_static() || (_obj == NULL)) {
+   if (_obj == NULL) {
      fd->print_on(_st);
      _st->cr();
    } else {
@@ -2399,8 +2315,8 @@
   }
 
   st->print_cr(BULLET"---- fields (total size %d words):", oop_size(obj));
-  FieldPrinter print_nonstatic_field(st, obj);
-  do_nonstatic_fields(&print_nonstatic_field);
+  FieldPrinter print_field(st, obj);
+  do_nonstatic_fields(&print_field);
 
   if (as_klassOop() == SystemDictionary::Class_klass()) {
     st->print(BULLET"signature: ");
@@ -2418,6 +2334,12 @@
     st->print(BULLET"fake entry for array: ");
     array_klass->print_value_on(st);
     st->cr();
+    st->print_cr(BULLET"fake entry for oop_size: %d", java_lang_Class::oop_size(obj));
+    st->print_cr(BULLET"fake entry for static_oop_field_count: %d", java_lang_Class::static_oop_field_count(obj));
+    klassOop real_klass = java_lang_Class::as_klassOop(obj);
+    if (real_klass && real_klass->klass_part()->oop_is_instance()) {
+      instanceKlass::cast(real_klass)->do_local_static_fields(&print_field);
+    }
   } else if (as_klassOop() == SystemDictionary::MethodType_klass()) {
     st->print(BULLET"signature: ");
     java_lang_invoke_MethodType::print_signature(obj, st);
@@ -2560,7 +2482,7 @@
 
 
 void JNIid::verify(klassOop holder) {
-  int first_field_offset  = instanceKlass::cast(holder)->offset_of_static_fields();
+  int first_field_offset  = instanceMirrorKlass::offset_of_static_fields();
   int end_field_offset;
   end_field_offset = first_field_offset + (instanceKlass::cast(holder)->static_field_size() * wordSize);
 
--- a/src/share/vm/oops/instanceKlass.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/instanceKlass.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -75,8 +75,6 @@
 //    [Java vtable length         ]
 //    [oop map cache (stack maps) ]
 //    [EMBEDDED Java vtable             ] size in words = vtable_len
-//    [EMBEDDED static oop fields       ] size in words = static_oop_fields_size
-//    [         static non-oop fields   ] size in words = static_field_size - static_oop_fields_size
 //    [EMBEDDED nonstatic oop-map blocks] size in words = nonstatic_oop_map_size
 //
 //    The embedded nonstatic oop-map blocks are short pairs (offset, length) indicating
@@ -230,7 +228,7 @@
   // (including inherited fields but after header_size()).
   int             _nonstatic_field_size;
   int             _static_field_size;    // number words used by static fields (oop and non-oop) in this klass
-  int             _static_oop_field_size;// number of static oop fields in this klass
+  int             _static_oop_field_count;// number of static oop fields in this klass
   int             _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
   bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
   bool            _rewritten;            // methods rewritten.
@@ -281,8 +279,8 @@
   int static_field_size() const            { return _static_field_size; }
   void set_static_field_size(int size)     { _static_field_size = size; }
 
-  int static_oop_field_size() const        { return _static_oop_field_size; }
-  void set_static_oop_field_size(int size) { _static_oop_field_size = size; }
+  int static_oop_field_count() const        { return _static_oop_field_count; }
+  void set_static_oop_field_count(int size) { _static_oop_field_count = size; }
 
   // Java vtable
   int  vtable_length() const               { return _vtable_len; }
@@ -660,6 +658,7 @@
 
   // Casting from klassOop
   static instanceKlass* cast(klassOop k) {
+    assert(k->is_klass(), "must be");
     Klass* kp = k->klass_part();
     assert(kp->null_vtbl() || kp->oop_is_instance_slow(), "cast to instanceKlass");
     return (instanceKlass*) kp;
@@ -667,7 +666,7 @@
 
   // Sizing (in words)
   static int header_size()            { return align_object_offset(oopDesc::header_size() + sizeof(instanceKlass)/HeapWordSize); }
-  int object_size() const             { return object_size(align_object_offset(vtable_length()) + align_object_offset(itable_length()) + static_field_size() + nonstatic_oop_map_size()); }
+  int object_size() const             { return object_size(align_object_offset(vtable_length()) + align_object_offset(itable_length()) + nonstatic_oop_map_size()); }
   static int vtable_start_offset()    { return header_size(); }
   static int vtable_length_offset()   { return oopDesc::header_size() + offset_of(instanceKlass, _vtable_len) / HeapWordSize; }
   static int object_size(int extra)   { return align_object_size(header_size() + extra); }
@@ -676,20 +675,12 @@
   intptr_t* start_of_itable() const        { return start_of_vtable() + align_object_offset(vtable_length()); }
   int  itable_offset_in_words() const { return start_of_itable() - (intptr_t*)as_klassOop(); }
 
-  // Static field offset is an offset into the Heap, should be converted by
-  // based on UseCompressedOop for traversal
-  HeapWord* start_of_static_fields() const {
-    return (HeapWord*)(start_of_itable() + align_object_offset(itable_length()));
-  }
-
   intptr_t* end_of_itable() const          { return start_of_itable() + itable_length(); }
 
-  int offset_of_static_fields() const {
-    return (intptr_t)start_of_static_fields() - (intptr_t)as_klassOop();
-  }
+  address static_field_addr(int offset);
 
   OopMapBlock* start_of_nonstatic_oop_maps() const {
-    return (OopMapBlock*) (start_of_static_fields() + static_field_size());
+    return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length()));
   }
 
   // Allocation profiling support
@@ -719,8 +710,6 @@
 
   // Garbage collection
   void oop_follow_contents(oop obj);
-  void follow_static_fields();
-  void adjust_static_fields();
   int  oop_adjust_pointers(oop obj);
   bool object_is_parsable() const { return _init_state != unparsable_by_gc; }
        // Value of _init_state must be zero (unparsable_by_gc) when klass field is set.
@@ -732,16 +721,6 @@
   // Parallel Scavenge and Parallel Old
   PARALLEL_GC_DECLS
 
-#ifndef SERIALGC
-  // Parallel Scavenge
-  void push_static_fields(PSPromotionManager* pm);
-
-  // Parallel Old
-  void follow_static_fields(ParCompactionManager* cm);
-  void copy_static_fields(ParCompactionManager* cm);
-  void update_static_fields();
-#endif // SERIALGC
-
   // Naming
   const char* signature_name() const;
 
@@ -770,9 +749,6 @@
   ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
 #endif // !SERIALGC
 
-  void iterate_static_fields(OopClosure* closure);
-  void iterate_static_fields(OopClosure* closure, MemRegion mr);
-
 private:
   // initialization state
 #ifdef ASSERT
@@ -926,6 +902,10 @@
   // Identifier lookup
   JNIid* find(int offset);
 
+  bool find_local_field(fieldDescriptor* fd) {
+    return instanceKlass::cast(holder())->find_local_field_from_offset(offset(), true, fd);
+  }
+
   // Garbage collection support
   oop* holder_addr() { return (oop*)&_holder; }
   void oops_do(OopClosure* f);
--- a/src/share/vm/oops/instanceKlassKlass.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/instanceKlassKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -31,6 +31,7 @@
 #include "memory/gcLocker.hpp"
 #include "oops/constantPoolOop.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceKlassKlass.hpp"
 #include "oops/instanceRefKlass.hpp"
 #include "oops/objArrayKlassKlass.hpp"
@@ -86,7 +87,6 @@
   assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass");
 
   instanceKlass* ik = instanceKlass::cast(klassOop(obj));
-  ik->follow_static_fields();
   {
     HandleMark hm;
     ik->vtable()->oop_follow_contents();
@@ -127,7 +127,6 @@
   assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass");
 
   instanceKlass* ik = instanceKlass::cast(klassOop(obj));
-  ik->follow_static_fields(cm);
   ik->vtable()->oop_follow_contents(cm);
   ik->itable()->oop_follow_contents(cm);
 
@@ -168,7 +167,6 @@
   // Don't call size() or oop_size() since that is a virtual call.
   int size = ik->object_size();
 
-  ik->iterate_static_fields(blk);
   ik->vtable()->oop_oop_iterate(blk);
   ik->itable()->oop_oop_iterate(blk);
 
@@ -209,7 +207,6 @@
   // Don't call size() or oop_size() since that is a virtual call.
   int size = ik->object_size();
 
-  ik->iterate_static_fields(blk, mr);
   ik->vtable()->oop_oop_iterate_m(blk, mr);
   ik->itable()->oop_oop_iterate_m(blk, mr);
 
@@ -266,7 +263,6 @@
   assert(klassOop(obj)->klass_part()->oop_is_instance_slow(), "must be instance klass");
 
   instanceKlass* ik = instanceKlass::cast(klassOop(obj));
-  ik->adjust_static_fields();
   ik->vtable()->oop_adjust_pointers();
   ik->itable()->oop_adjust_pointers();
 
@@ -300,7 +296,6 @@
 #ifndef SERIALGC
 void instanceKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   instanceKlass* ik = instanceKlass::cast(klassOop(obj));
-  ik->push_static_fields(pm);
 
   oop* loader_addr = ik->adr_class_loader();
   if (PSScavenge::should_scavenge(loader_addr)) {
@@ -336,7 +331,6 @@
          "must be instance klass");
 
   instanceKlass* ik = instanceKlass::cast(klassOop(obj));
-  ik->update_static_fields();
   ik->vtable()->oop_update_pointers(cm);
   ik->itable()->oop_update_pointers(cm);
 
@@ -356,22 +350,28 @@
 #endif // SERIALGC
 
 klassOop
-instanceKlassKlass::allocate_instance_klass(int vtable_len, int itable_len,
+instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int itable_len,
                                             int static_field_size,
                                             unsigned nonstatic_oop_map_count,
                                             ReferenceType rt, TRAPS) {
 
   const int nonstatic_oop_map_size =
     instanceKlass::nonstatic_oop_map_size(nonstatic_oop_map_count);
-  int size = instanceKlass::object_size(align_object_offset(vtable_len) + align_object_offset(itable_len) + static_field_size + nonstatic_oop_map_size);
+  int size = instanceKlass::object_size(align_object_offset(vtable_len) + align_object_offset(itable_len) + nonstatic_oop_map_size);
 
   // Allocation
   KlassHandle h_this_klass(THREAD, as_klassOop());
   KlassHandle k;
   if (rt == REF_NONE) {
-    // regular klass
-    instanceKlass o;
-    k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL);
+    if (name != vmSymbols::java_lang_Class()) {
+      // regular klass
+      instanceKlass o;
+      k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL);
+    } else {
+      // Class
+      instanceMirrorKlass o;
+      k = base_create_klass(h_this_klass, size, o.vtbl_value(), CHECK_NULL);
+    }
   } else {
     // reference klass
     instanceRefKlass o;
@@ -408,7 +408,7 @@
     ik->set_source_debug_extension(NULL);
     ik->set_array_name(NULL);
     ik->set_inner_classes(NULL);
-    ik->set_static_oop_field_size(0);
+    ik->set_static_oop_field_count(0);
     ik->set_nonstatic_field_size(0);
     ik->set_is_marked_dependent(false);
     ik->set_init_state(instanceKlass::allocated);
@@ -442,9 +442,6 @@
     // To get verify to work - must be set to partial loaded before first GC point.
     k()->set_partially_loaded();
   }
-
-  // GC can happen here
-  java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror
   return k();
 }
 
@@ -566,13 +563,6 @@
   FieldPrinter print_nonstatic_field(st);
   ik->do_nonstatic_fields(&print_nonstatic_field);
 
-  st->print(BULLET"static oop maps:     ");
-  if (ik->static_oop_field_size() > 0) {
-    int first_offset = ik->offset_of_static_fields();
-    st->print("%d-%d", first_offset, first_offset + ik->static_oop_field_size() - 1);
-  }
-  st->cr();
-
   st->print(BULLET"non-static oop maps: ");
   OopMapBlock* map     = ik->start_of_nonstatic_oop_maps();
   OopMapBlock* end_map = map + ik->nonstatic_oop_map_count();
@@ -630,7 +620,6 @@
 
     // Verify static fields
     VerifyFieldClosure blk;
-    ik->iterate_static_fields(&blk);
 
     // Verify vtables
     if (ik->is_linked()) {
--- a/src/share/vm/oops/instanceKlassKlass.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/instanceKlassKlass.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -41,7 +41,8 @@
   // Allocation
   DEFINE_ALLOCATE_PERMANENT(instanceKlassKlass);
   static klassOop create_klass(TRAPS);
-  klassOop allocate_instance_klass(int vtable_len,
+  klassOop allocate_instance_klass(Symbol* name,
+                                   int vtable_len,
                                    int itable_len,
                                    int static_field_size,
                                    unsigned int nonstatic_oop_map_count,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/oops/instanceMirrorKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/javaClasses.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "gc_implementation/shared/markSweep.inline.hpp"
+#include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/genOopClosures.inline.hpp"
+#include "memory/oopFactory.hpp"
+#include "memory/permGen.hpp"
+#include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
+#include "oops/instanceOop.hpp"
+#include "oops/oop.inline.hpp"
+#include "oops/symbol.hpp"
+#include "runtime/handles.inline.hpp"
+#ifndef SERIALGC
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1OopClosures.inline.hpp"
+#include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/parNew/parOopClosures.inline.hpp"
+#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
+#include "oops/oop.pcgc.inline.hpp"
+#endif
+
+int instanceMirrorKlass::_offset_of_static_fields = 0;
+
+#ifdef ASSERT
+template <class T> void assert_is_in(T *p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(Universe::heap()->is_in(o), "should be in heap");
+  }
+}
+template <class T> void assert_is_in_closed_subset(T *p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(Universe::heap()->is_in_closed_subset(o), "should be in closed");
+  }
+}
+template <class T> void assert_is_in_reserved(T *p) {
+  T heap_oop = oopDesc::load_heap_oop(p);
+  if (!oopDesc::is_null(heap_oop)) {
+    oop o = oopDesc::decode_heap_oop_not_null(heap_oop);
+    assert(Universe::heap()->is_in_reserved(o), "should be in reserved");
+  }
+}
+template <class T> void assert_nothing(T *p) {}
+
+#else
+template <class T> void assert_is_in(T *p) {}
+template <class T> void assert_is_in_closed_subset(T *p) {}
+template <class T> void assert_is_in_reserved(T *p) {}
+template <class T> void assert_nothing(T *p) {}
+#endif // ASSERT
+
+#define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE( \
+  T, start_p, count, do_oop,                         \
+  assert_fn)                                         \
+{                                                    \
+  T* p         = (T*)(start_p);                      \
+  T* const end = p + (count);                        \
+  while (p < end) {                                  \
+    (assert_fn)(p);                                  \
+    do_oop;                                          \
+    ++p;                                             \
+  }                                                  \
+}
+
+#define InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE( \
+  T, start_p, count, low, high,                              \
+  do_oop, assert_fn)                                         \
+{                                                            \
+  T* const l = (T*)(low);                                    \
+  T* const h = (T*)(high);                                   \
+  assert(mask_bits((intptr_t)l, sizeof(T)-1) == 0 &&         \
+         mask_bits((intptr_t)h, sizeof(T)-1) == 0,           \
+         "bounded region must be properly aligned");         \
+  T* p       = (T*)(start_p);                                \
+  T* end     = p + (count);                                  \
+  if (p < l) p = l;                                          \
+  if (end > h) end = h;                                      \
+  while (p < end) {                                          \
+    (assert_fn)(p);                                          \
+    do_oop;                                                  \
+    ++p;                                                     \
+  }                                                          \
+}
+
+
+#define InstanceMirrorKlass_OOP_ITERATE(start_p, count,    \
+                                  do_oop, assert_fn)       \
+{                                                          \
+  if (UseCompressedOops) {                                 \
+    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(narrowOop, \
+      start_p, count,                                      \
+      do_oop, assert_fn)                                   \
+  } else {                                                 \
+    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE(oop,       \
+      start_p, count,                                      \
+      do_oop, assert_fn)                                   \
+  }                                                        \
+}
+
+// The following macros call specialized macros, passing either oop or
+// narrowOop as the specialization type.  These test the UseCompressedOops
+// flag.
+#define InstanceMirrorKlass_BOUNDED_OOP_ITERATE(start_p, count, low, high, \
+                                          do_oop, assert_fn)               \
+{                                                                          \
+  if (UseCompressedOops) {                                                 \
+    InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(narrowOop,         \
+      start_p, count,                                                      \
+      low, high,                                                           \
+      do_oop, assert_fn)                                                   \
+  } else {                                                                 \
+    InstanceMirrorKlass_SPECIALIZED_BOUNDED_OOP_ITERATE(oop,               \
+      start_p, count,                                                      \
+      low, high,                                                           \
+      do_oop, assert_fn)                                                   \
+  }                                                                        \
+}
+
+
+void instanceMirrorKlass::oop_follow_contents(oop obj) {
+  instanceKlass::oop_follow_contents(obj);
+  InstanceMirrorKlass_OOP_ITERATE(                                                    \
+    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
+    MarkSweep::mark_and_push(p),                                                      \
+    assert_is_in_closed_subset)
+}
+
+#ifndef SERIALGC
+void instanceMirrorKlass::oop_follow_contents(ParCompactionManager* cm,
+                                              oop obj) {
+  instanceKlass::oop_follow_contents(cm, obj);
+  InstanceMirrorKlass_OOP_ITERATE(                                                    \
+    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
+    PSParallelCompact::mark_and_push(cm, p),                                          \
+    assert_is_in)
+}
+#endif // SERIALGC
+
+int instanceMirrorKlass::oop_adjust_pointers(oop obj) {
+  int size = oop_size(obj);
+  instanceKlass::oop_adjust_pointers(obj);
+  InstanceMirrorKlass_OOP_ITERATE(                                                    \
+    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
+    MarkSweep::adjust_pointer(p),                                                     \
+    assert_nothing)
+  return size;
+}
+
+#define InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(T, nv_suffix)                \
+  InstanceMirrorKlass_OOP_ITERATE(                                                    \
+    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
+      (closure)->do_oop##nv_suffix(p),                                                \
+    assert_is_in_closed_subset)                                                       \
+  return oop_size(obj);                                                               \
+
+#define InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(T, nv_suffix, mr)         \
+  InstanceMirrorKlass_BOUNDED_OOP_ITERATE(                                            \
+    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),        \
+    mr.start(), mr.end(),                                                             \
+      (closure)->do_oop##nv_suffix(p),                                                \
+    assert_is_in_closed_subset)                                                       \
+  return oop_size(obj);                                                               \
+
+
+// Macro to define instanceMirrorKlass::oop_oop_iterate for virtual/nonvirtual for
+// all closures.  Macros calling macros above for each oop size.
+
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)           \
+                                                                                      \
+int instanceMirrorKlass::                                                             \
+oop_oop_iterate##nv_suffix(oop obj, OopClosureType* closure) {                        \
+  /* Get size before changing pointers */                                             \
+  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
+                                                                                      \
+  instanceKlass::oop_oop_iterate##nv_suffix(obj, closure);                            \
+                                                                                      \
+  if (UseCompressedOops) {                                                            \
+    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix);           \
+  } else {                                                                            \
+    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix);                 \
+  }                                                                                   \
+}
+
+#ifndef SERIALGC
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN(OopClosureType, nv_suffix) \
+                                                                                      \
+int instanceMirrorKlass::                                                             \
+oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* closure) {              \
+  /* Get size before changing pointers */                                             \
+  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
+                                                                                      \
+  instanceKlass::oop_oop_iterate_backwards##nv_suffix(obj, closure);                  \
+                                                                                      \
+  if (UseCompressedOops) {                                                            \
+    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(narrowOop, nv_suffix);           \
+  } else {                                                                            \
+    InstanceMirrorKlass_SPECIALIZED_OOP_ITERATE_DEFN(oop, nv_suffix);                 \
+  }                                                                                   \
+}
+#endif // !SERIALGC
+
+
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m(OopClosureType, nv_suffix)         \
+                                                                                      \
+int instanceMirrorKlass::                                                             \
+oop_oop_iterate##nv_suffix##_m(oop obj,                                               \
+                               OopClosureType* closure,                               \
+                               MemRegion mr) {                                        \
+  SpecializationStats::record_iterate_call##nv_suffix(SpecializationStats::irk);      \
+                                                                                      \
+  instanceKlass::oop_oop_iterate##nv_suffix##_m(obj, closure, mr);                    \
+  if (UseCompressedOops) {                                                            \
+    InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(narrowOop, nv_suffix, mr);    \
+  } else {                                                                            \
+    InstanceMirrorKlass_BOUNDED_SPECIALIZED_OOP_ITERATE(oop, nv_suffix, mr);          \
+  }                                                                                   \
+}
+
+ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
+ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN)
+#ifndef SERIALGC
+ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
+ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DEFN)
+#endif // SERIALGC
+ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
+ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DEFN_m)
+
+#ifndef SERIALGC
+void instanceMirrorKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
+  instanceKlass::oop_push_contents(pm, obj);
+  InstanceMirrorKlass_OOP_ITERATE(                                            \
+    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
+    if (PSScavenge::should_scavenge(p)) {                                     \
+      pm->claim_or_forward_depth(p);                                          \
+    },                                                                        \
+    assert_nothing )
+}
+
+int instanceMirrorKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
+  instanceKlass::oop_update_pointers(cm, obj);
+  InstanceMirrorKlass_OOP_ITERATE(                                            \
+    start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj),\
+    PSParallelCompact::adjust_pointer(p),                                     \
+    assert_nothing)
+  return oop_size(obj);
+}
+#endif // SERIALGC
+
+int instanceMirrorKlass::instance_size(KlassHandle k) {
+  if (k() != NULL && k->oop_is_instance()) {
+    return align_object_size(size_helper() + instanceKlass::cast(k())->static_field_size());
+  }
+  return size_helper();
+}
+
+instanceOop instanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
+  // Query before forming handle.
+  int size = instance_size(k);
+  KlassHandle h_k(THREAD, as_klassOop());
+  instanceOop i;
+
+  if (JavaObjectsInPerm) {
+    i = (instanceOop) CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
+  } else {
+    assert(ScavengeRootsInCode > 0, "must be");
+    i = (instanceOop) CollectedHeap::obj_allocate(h_k, size, CHECK_NULL);
+  }
+
+  return i;
+}
+
+int instanceMirrorKlass::oop_size(oop obj) const {
+  return java_lang_Class::oop_size(obj);
+}
+
+int instanceMirrorKlass::compute_static_oop_field_count(oop obj) {
+  klassOop k = java_lang_Class::as_klassOop(obj);
+  if (k != NULL && k->klass_part()->oop_is_instance()) {
+    return instanceKlass::cast(k)->static_oop_field_count();
+  }
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/oops/instanceMirrorKlass.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
+#define SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
+
+#include "oops/instanceKlass.hpp"
+
+// An instanceMirrorKlass is a specialized instanceKlass for
+// java.lang.Class instances.  These instances are special because
+// they contain the static fields of the class in addition to the
+// normal fields of Class.  This means they are variable sized
+// instances and need special logic for computing their size and for
+// iteration of their oops.
+
+
+class instanceMirrorKlass: public instanceKlass {
+ private:
+  static int _offset_of_static_fields;
+
+ public:
+  // Type testing
+  bool oop_is_instanceMirror() const             { return true; }
+
+  // Casting from klassOop
+  static instanceMirrorKlass* cast(klassOop k) {
+    assert(k->klass_part()->oop_is_instanceMirror(), "cast to instanceMirrorKlass");
+    return (instanceMirrorKlass*) k->klass_part();
+  }
+
+  // Returns the size of the instance including the extra static fields.
+  virtual int oop_size(oop obj) const;
+
+  // Static field offset is an offset into the Heap, should be converted by
+  // based on UseCompressedOop for traversal
+  static HeapWord* start_of_static_fields(oop obj) {
+    return (HeapWord*)((intptr_t)obj + offset_of_static_fields());
+  }
+
+  static void init_offset_of_static_fields() {
+    // Cache the offset of the static fields in the Class instance
+    assert(_offset_of_static_fields == 0, "once");
+    _offset_of_static_fields = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->size_helper() << LogHeapWordSize;
+  }
+
+  static int offset_of_static_fields() {
+    return _offset_of_static_fields;
+  }
+
+  int compute_static_oop_field_count(oop obj);
+
+  // Given a Klass return the size of the instance
+  int instance_size(KlassHandle k);
+
+  // allocation
+  DEFINE_ALLOCATE_PERMANENT(instanceMirrorKlass);
+  instanceOop allocate_instance(KlassHandle k, TRAPS);
+
+  // Garbage collection
+  int  oop_adjust_pointers(oop obj);
+  void oop_follow_contents(oop obj);
+
+  // Parallel Scavenge and Parallel Old
+  PARALLEL_GC_DECLS
+
+  int oop_oop_iterate(oop obj, OopClosure* blk) {
+    return oop_oop_iterate_v(obj, blk);
+  }
+  int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
+    return oop_oop_iterate_v_m(obj, blk, mr);
+  }
+
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_DECL(OopClosureType, nv_suffix)           \
+  int oop_oop_iterate##nv_suffix(oop obj, OopClosureType* blk);                       \
+  int oop_oop_iterate##nv_suffix##_m(oop obj, OopClosureType* blk, MemRegion mr);
+
+  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL)
+  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_DECL)
+
+#ifndef SERIALGC
+#define InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL(OopClosureType, nv_suffix) \
+  int oop_oop_iterate_backwards##nv_suffix(oop obj, OopClosureType* blk);
+
+  ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
+  ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceMirrorKlass_OOP_OOP_ITERATE_BACKWARDS_DECL)
+#endif // !SERIALGC
+};
+
+#endif // SHARE_VM_OOPS_INSTANCEMIRRORKLASS_HPP
--- a/src/share/vm/oops/klass.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/klass.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -577,6 +577,7 @@
  public:
   // type testing operations
   virtual bool oop_is_instance_slow()       const { return false; }
+  virtual bool oop_is_instanceMirror()      const { return false; }
   virtual bool oop_is_instanceRef()         const { return false; }
   virtual bool oop_is_array()               const { return false; }
   virtual bool oop_is_objArray_slow()       const { return false; }
@@ -811,4 +812,8 @@
 #endif
 };
 
+
+inline oop klassOopDesc::java_mirror() const                        { return klass_part()->java_mirror(); }
+
+
 #endif // SHARE_VM_OOPS_KLASS_HPP
--- a/src/share/vm/oops/klassKlass.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/klassKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -41,6 +41,10 @@
 #include "oops/typeArrayKlass.hpp"
 #include "runtime/handles.inline.hpp"
 #ifndef SERIALGC
+#include "gc_implementation/parNew/parOopClosures.inline.hpp"
+#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
+#include "memory/cardTableRS.hpp"
 #include "oops/oop.pcgc.inline.hpp"
 #endif
 
@@ -175,6 +179,12 @@
 
 #ifndef SERIALGC
 void klassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
+  Klass* k = Klass::cast(klassOop(obj));
+
+  oop* p = k->adr_java_mirror();
+  if (PSScavenge::should_scavenge(p)) {
+    pm->claim_or_forward_depth(p);
+  }
 }
 
 int klassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
@@ -233,7 +243,7 @@
 
   if (k->java_mirror() != NULL || (k->oop_is_instance() && instanceKlass::cast(klassOop(obj))->is_loaded())) {
     guarantee(k->java_mirror() != NULL,          "should be allocated");
-    guarantee(k->java_mirror()->is_perm(),       "should be in permspace");
+    guarantee(k->java_mirror()->is_perm() || !JavaObjectsInPerm,       "should be in permspace");
     guarantee(k->java_mirror()->is_instance(),   "should be instance");
   }
 }
--- a/src/share/vm/oops/klassOop.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/klassOop.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -45,7 +45,73 @@
   static int klass_part_offset_in_bytes()        { return sizeof(klassOopDesc); }
 
   // returns the Klass part containing dispatching behavior
-  Klass* klass_part()                            { return (Klass*)((address)this + klass_part_offset_in_bytes()); }
+  Klass* klass_part() const                      { return (Klass*)((address)this + klass_part_offset_in_bytes()); }
+
+  // Convenience wrapper
+  inline oop java_mirror() const;
+
+ private:
+  // These have no implementation since klassOop should never be accessed in this fashion
+  oop obj_field(int offset) const;
+  void obj_field_put(int offset, oop value);
+  void obj_field_raw_put(int offset, oop value);
+
+  jbyte byte_field(int offset) const;
+  void byte_field_put(int offset, jbyte contents);
+
+  jchar char_field(int offset) const;
+  void char_field_put(int offset, jchar contents);
+
+  jboolean bool_field(int offset) const;
+  void bool_field_put(int offset, jboolean contents);
+
+  jint int_field(int offset) const;
+  void int_field_put(int offset, jint contents);
+
+  jshort short_field(int offset) const;
+  void short_field_put(int offset, jshort contents);
+
+  jlong long_field(int offset) const;
+  void long_field_put(int offset, jlong contents);
+
+  jfloat float_field(int offset) const;
+  void float_field_put(int offset, jfloat contents);
+
+  jdouble double_field(int offset) const;
+  void double_field_put(int offset, jdouble contents);
+
+  address address_field(int offset) const;
+  void address_field_put(int offset, address contents);
+
+  oop obj_field_acquire(int offset) const;
+  void release_obj_field_put(int offset, oop value);
+
+  jbyte byte_field_acquire(int offset) const;
+  void release_byte_field_put(int offset, jbyte contents);
+
+  jchar char_field_acquire(int offset) const;
+  void release_char_field_put(int offset, jchar contents);
+
+  jboolean bool_field_acquire(int offset) const;
+  void release_bool_field_put(int offset, jboolean contents);
+
+  jint int_field_acquire(int offset) const;
+  void release_int_field_put(int offset, jint contents);
+
+  jshort short_field_acquire(int offset) const;
+  void release_short_field_put(int offset, jshort contents);
+
+  jlong long_field_acquire(int offset) const;
+  void release_long_field_put(int offset, jlong contents);
+
+  jfloat float_field_acquire(int offset) const;
+  void release_float_field_put(int offset, jfloat contents);
+
+  jdouble double_field_acquire(int offset) const;
+  void release_double_field_put(int offset, jdouble contents);
+
+  address address_field_acquire(int offset) const;
+  void release_address_field_put(int offset, address contents);
 };
 
 #endif // SHARE_VM_OOPS_KLASSOOP_HPP
--- a/src/share/vm/oops/klassVtable.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/klassVtable.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1095,7 +1095,7 @@
   itableOffsetEntry* ioe = (itableOffsetEntry*)klass->start_of_itable();
   itableMethodEntry* ime = (itableMethodEntry*)(ioe + nof_interfaces);
   intptr_t* end               = klass->end_of_itable();
-  assert((oop*)(ime + nof_methods) <= (oop*)klass->start_of_static_fields(), "wrong offset calculation (1)");
+  assert((oop*)(ime + nof_methods) <= (oop*)klass->start_of_nonstatic_oop_maps(), "wrong offset calculation (1)");
   assert((oop*)(end) == (oop*)(ime + nof_methods),                      "wrong offset calculation (2)");
 
   // Visit all interfaces and initialize itable offset table
--- a/src/share/vm/oops/objArrayKlassKlass.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/objArrayKlassKlass.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -31,6 +31,13 @@
 #include "oops/objArrayKlassKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/oop.inline2.hpp"
+#ifndef SERIALGC
+#include "gc_implementation/parNew/parOopClosures.inline.hpp"
+#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
+#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
+#include "memory/cardTableRS.hpp"
+#include "oops/oop.pcgc.inline.hpp"
+#endif
 
 klassOop objArrayKlassKlass::create_klass(TRAPS) {
   objArrayKlassKlass o;
@@ -236,12 +243,23 @@
   addr = oak->bottom_klass_addr();
   if (mr.contains(addr)) blk->do_oop(addr);
 
-  return arrayKlassKlass::oop_oop_iterate(obj, blk);
+  return arrayKlassKlass::oop_oop_iterate_m(obj, blk, mr);
 }
 
 #ifndef SERIALGC
 void objArrayKlassKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   assert(obj->blueprint()->oop_is_objArrayKlass(),"must be an obj array klass");
+  objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
+  oop* p = oak->element_klass_addr();
+  if (PSScavenge::should_scavenge(p)) {
+    pm->claim_or_forward_depth(p);
+  }
+  p = oak->bottom_klass_addr();
+  if (PSScavenge::should_scavenge(p)) {
+    pm->claim_or_forward_depth(p);
+  }
+
+  arrayKlassKlass::oop_push_contents(pm, obj);
 }
 
 int objArrayKlassKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
@@ -287,7 +305,7 @@
 // Verification
 
 void objArrayKlassKlass::oop_verify_on(oop obj, outputStream* st) {
-  klassKlass::oop_verify_on(obj, st);
+  arrayKlassKlass::oop_verify_on(obj, st);
   objArrayKlass* oak = objArrayKlass::cast((klassOop)obj);
   guarantee(oak->element_klass()->is_perm(),  "should be in permspace");
   guarantee(oak->element_klass()->is_klass(), "should be klass");
--- a/src/share/vm/oops/oop.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/oop.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -129,6 +129,7 @@
 
   // type test operations (inlined in oop.inline.h)
   bool is_instance()           const;
+  bool is_instanceMirror()     const;
   bool is_instanceRef()        const;
   bool is_array()              const;
   bool is_objArray()           const;
--- a/src/share/vm/oops/oop.inline.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/oop.inline.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -141,6 +141,7 @@
 inline bool oopDesc::is_a(klassOop k)        const { return blueprint()->is_subtype_of(k); }
 
 inline bool oopDesc::is_instance()           const { return blueprint()->oop_is_instance(); }
+inline bool oopDesc::is_instanceMirror()     const { return blueprint()->oop_is_instanceMirror(); }
 inline bool oopDesc::is_instanceRef()        const { return blueprint()->oop_is_instanceRef(); }
 inline bool oopDesc::is_array()              const { return blueprint()->oop_is_array(); }
 inline bool oopDesc::is_objArray()           const { return blueprint()->oop_is_objArray(); }
@@ -399,7 +400,7 @@
 
 inline int oopDesc::size_given_klass(Klass* klass)  {
   int lh = klass->layout_helper();
-  int s  = lh >> LogHeapWordSize;  // deliver size scaled by wordSize
+  int s;
 
   // lh is now a value computed at class initialization that may hint
   // at the size.  For instances, this is positive and equal to the
@@ -412,7 +413,13 @@
   // alive or dead.  So the speed here is equal in importance to the
   // speed of allocation.
 
-  if (lh <= Klass::_lh_neutral_value) {
+  if (lh > Klass::_lh_neutral_value) {
+    if (!Klass::layout_helper_needs_slow_path(lh)) {
+      s = lh >> LogHeapWordSize;  // deliver size scaled by wordSize
+    } else {
+      s = klass->oop_size(this);
+    }
+  } else if (lh <= Klass::_lh_neutral_value) {
     // The most common case is instances; fall through if so.
     if (lh < Klass::_lh_neutral_value) {
       // Second most common case is arrays.  We have to fetch the
--- a/src/share/vm/oops/oopsHierarchy.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/oops/oopsHierarchy.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -174,6 +174,7 @@
 
 class Klass;
 class   instanceKlass;
+class     instanceMirrorKlass;
 class     instanceRefKlass;
 class   methodKlass;
 class   constMethodKlass;
--- a/src/share/vm/opto/compile.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/compile.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -1202,11 +1202,15 @@
   // Oop pointers need some flattening
   const TypeInstPtr *to = tj->isa_instptr();
   if( to && _AliasLevel >= 2 && to != TypeOopPtr::BOTTOM ) {
+    ciInstanceKlass *k = to->klass()->as_instance_klass();
     if( ptr == TypePtr::Constant ) {
-      // No constant oop pointers (such as Strings); they alias with
-      // unknown strings.
-      assert(!is_known_inst, "not scalarizable allocation");
-      tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
+      if (to->klass() != ciEnv::current()->Class_klass() ||
+          offset < k->size_helper() * wordSize) {
+        // No constant oop pointers (such as Strings); they alias with
+        // unknown strings.
+        assert(!is_known_inst, "not scalarizable allocation");
+        tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
+      }
     } else if( is_known_inst ) {
       tj = to; // Keep NotNull and klass_is_exact for instance type
     } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
@@ -1216,7 +1220,6 @@
       tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
     }
     // Canonicalize the holder of this field
-    ciInstanceKlass *k = to->klass()->as_instance_klass();
     if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
       // First handle header references such as a LoadKlassNode, even if the
       // object's klass is unloaded at compile time (4965979).
@@ -1224,9 +1227,13 @@
         tj = to = TypeInstPtr::make(TypePtr::BotPTR, env()->Object_klass(), false, NULL, offset);
       }
     } else if (offset < 0 || offset >= k->size_helper() * wordSize) {
-      to = NULL;
-      tj = TypeOopPtr::BOTTOM;
-      offset = tj->offset();
+      // Static fields are in the space above the normal instance
+      // fields in the java.lang.Class instance.
+      if (to->klass() != ciEnv::current()->Class_klass()) {
+        to = NULL;
+        tj = TypeOopPtr::BOTTOM;
+        offset = tj->offset();
+      }
     } else {
       ciInstanceKlass *canonical_holder = k->get_canonical_holder(offset);
       if (!k->equals(canonical_holder) || tj->offset() != offset) {
@@ -1399,7 +1406,7 @@
 
 
 //--------------------------------find_alias_type------------------------------
-Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_create) {
+Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_create, ciField* original_field) {
   if (_AliasLevel == 0)
     return alias_type(AliasIdxBot);
 
@@ -1464,22 +1471,28 @@
     // but the base pointer type is not distinctive enough to identify
     // references into JavaThread.)
 
-    // Check for final instance fields.
+    // Check for final fields.
     const TypeInstPtr* tinst = flat->isa_instptr();
     if (tinst && tinst->offset() >= instanceOopDesc::base_offset_in_bytes()) {
-      ciInstanceKlass *k = tinst->klass()->as_instance_klass();
-      ciField* field = k->get_field_by_offset(tinst->offset(), false);
+      ciField* field;
+      if (tinst->const_oop() != NULL &&
+          tinst->klass() == ciEnv::current()->Class_klass() &&
+          tinst->offset() >= (tinst->klass()->as_instance_klass()->size_helper() * wordSize)) {
+        // static field
+        ciInstanceKlass* k = tinst->const_oop()->as_instance()->java_lang_Class_klass()->as_instance_klass();
+        field = k->get_field_by_offset(tinst->offset(), true);
+      } else {
+        ciInstanceKlass *k = tinst->klass()->as_instance_klass();
+        field = k->get_field_by_offset(tinst->offset(), false);
+      }
+      assert(field == NULL ||
+             original_field == NULL ||
+             (field->holder() == original_field->holder() &&
+              field->offset() == original_field->offset() &&
+              field->is_static() == original_field->is_static()), "wrong field?");
       // Set field() and is_rewritable() attributes.
       if (field != NULL)  alias_type(idx)->set_field(field);
     }
-    const TypeKlassPtr* tklass = flat->isa_klassptr();
-    // Check for final static fields.
-    if (tklass && tklass->klass()->is_instance_klass()) {
-      ciInstanceKlass *k = tklass->klass()->as_instance_klass();
-      ciField* field = k->get_field_by_offset(tklass->offset(), true);
-      // Set field() and is_rewritable() attributes.
-      if (field != NULL)   alias_type(idx)->set_field(field);
-    }
   }
 
   // Fill the cache for next time.
@@ -1502,10 +1515,10 @@
 Compile::AliasType* Compile::alias_type(ciField* field) {
   const TypeOopPtr* t;
   if (field->is_static())
-    t = TypeKlassPtr::make(field->holder());
+    t = TypeInstPtr::make(field->holder()->java_mirror());
   else
     t = TypeOopPtr::make_from_klass_raw(field->holder());
-  AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes()));
+  AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes()), field);
   assert(field->is_final() == !atp->is_rewritable(), "must get the rewritable bits correct");
   return atp;
 }
@@ -1522,7 +1535,7 @@
   if (adr_type == NULL)             return true;
   if (adr_type == TypePtr::BOTTOM)  return true;
 
-  return find_alias_type(adr_type, true) != NULL;
+  return find_alias_type(adr_type, true, NULL) != NULL;
 }
 
 //-----------------------------must_alias--------------------------------------
--- a/src/share/vm/opto/compile.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/compile.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -596,7 +596,7 @@
   }
 
   AliasType*        alias_type(int                idx)  { assert(idx < num_alias_types(), "oob"); return _alias_types[idx]; }
-  AliasType*        alias_type(const TypePtr* adr_type) { return find_alias_type(adr_type, false); }
+  AliasType*        alias_type(const TypePtr* adr_type, ciField* field = NULL) { return find_alias_type(adr_type, false, field); }
   bool         have_alias_type(const TypePtr* adr_type);
   AliasType*        alias_type(ciField*         field);
 
@@ -835,7 +835,7 @@
   void grow_alias_types();
   AliasCacheEntry* probe_alias_cache(const TypePtr* adr_type);
   const TypePtr *flatten_alias_type(const TypePtr* adr_type) const;
-  AliasType* find_alias_type(const TypePtr* adr_type, bool no_create);
+  AliasType* find_alias_type(const TypePtr* adr_type, bool no_create, ciField* field);
 
   void verify_top(Node*) const PRODUCT_RETURN;
 
--- a/src/share/vm/opto/library_call.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/library_call.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1118,7 +1118,7 @@
   Node* sourcea       = basic_plus_adr(string_object, string_object, value_offset);
   Node* source        = make_load(no_ctrl, sourcea, source_type, T_OBJECT, string_type->add_offset(value_offset));
 
-  Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array)) );
+  Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)) );
   jint target_length = target_array->length();
   const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
   const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
--- a/src/share/vm/opto/memnode.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/memnode.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1573,9 +1573,9 @@
             return TypeInt::make(constant.as_int());
           } else if (constant.basic_type() == T_ARRAY) {
             if (adr->bottom_type()->is_ptr_to_narrowoop()) {
-              return TypeNarrowOop::make_from_constant(constant.as_object());
+              return TypeNarrowOop::make_from_constant(constant.as_object(), true);
             } else {
-              return TypeOopPtr::make_from_constant(constant.as_object());
+              return TypeOopPtr::make_from_constant(constant.as_object(), true);
             }
           }
         }
--- a/src/share/vm/opto/parse.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/parse.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -491,8 +491,8 @@
   bool static_field_ok_in_clinit(ciField *field, ciMethod *method);
 
   // common code for actually performing the load or store
-  void do_get_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field);
-  void do_put_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field);
+  void do_get_xxx(Node* obj, ciField* field, bool is_field);
+  void do_put_xxx(Node* obj, ciField* field, bool is_field);
 
   // loading from a constant field or the constant pool
   // returns false if push failed (non-perm field constants only, not ldcs)
--- a/src/share/vm/opto/parse3.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/parse3.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -112,29 +112,31 @@
     // Compile-time detect of null-exception?
     if (stopped())  return;
 
+#ifdef ASSERT
     const TypeInstPtr *tjp = TypeInstPtr::make(TypePtr::NotNull, iter().get_declared_field_holder());
     assert(_gvn.type(obj)->higher_equal(tjp), "cast_up is no longer needed");
+#endif
 
     if (is_get) {
       --_sp;  // pop receiver before getting
-      do_get_xxx(tjp, obj, field, is_field);
+      do_get_xxx(obj, field, is_field);
     } else {
-      do_put_xxx(tjp, obj, field, is_field);
+      do_put_xxx(obj, field, is_field);
       --_sp;  // pop receiver after putting
     }
   } else {
-    const TypeKlassPtr* tkp = TypeKlassPtr::make(field_holder);
-    obj = _gvn.makecon(tkp);
+    const TypeInstPtr* tip = TypeInstPtr::make(field_holder->java_mirror());
+    obj = _gvn.makecon(tip);
     if (is_get) {
-      do_get_xxx(tkp, obj, field, is_field);
+      do_get_xxx(obj, field, is_field);
     } else {
-      do_put_xxx(tkp, obj, field, is_field);
+      do_put_xxx(obj, field, is_field);
     }
   }
 }
 
 
-void Parse::do_get_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field) {
+void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
   // Does this field have a constant value?  If so, just push the value.
   if (field->is_constant()) {
     if (field->is_static()) {
@@ -231,7 +233,7 @@
   }
 }
 
-void Parse::do_put_xxx(const TypePtr* obj_type, Node* obj, ciField* field, bool is_field) {
+void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) {
   bool is_vol = field->is_volatile();
   // If reference is volatile, prevent following memory ops from
   // floating down past the volatile write.  Also prevents commoning
--- a/src/share/vm/opto/stringopts.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/stringopts.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -910,7 +910,7 @@
       ciObject* con = field->constant_value().as_object();
       // Do not "join" in the previous type; it doesn't add value,
       // and may yield a vacuous result if the field is of interface type.
-      type = TypeOopPtr::make_from_constant(con)->isa_oopptr();
+      type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr();
       assert(type != NULL, "field singleton type must be consistent");
     } else {
       type = TypeOopPtr::make_from_klass(field_klass->as_klass());
--- a/src/share/vm/opto/type.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/type.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -32,6 +32,7 @@
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/klassKlass.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/typeArrayKlass.hpp"
@@ -2241,43 +2242,49 @@
     } else if (this->isa_aryptr()) {
       _is_ptr_to_narrowoop = (klass()->is_obj_array_klass() &&
                              _offset != arrayOopDesc::length_offset_in_bytes());
-    } else if (klass() == ciEnv::current()->Class_klass() &&
-               (_offset == java_lang_Class::klass_offset_in_bytes() ||
-                _offset == java_lang_Class::array_klass_offset_in_bytes())) {
-      // Special hidden fields from the Class.
-      assert(this->isa_instptr(), "must be an instance ptr.");
-      _is_ptr_to_narrowoop = true;
     } else if (klass()->is_instance_klass()) {
       ciInstanceKlass* ik = klass()->as_instance_klass();
       ciField* field = NULL;
       if (this->isa_klassptr()) {
-        // Perm objects don't use compressed references, except for
-        // static fields which are currently compressed.
-        field = ik->get_field_by_offset(_offset, true);
-        if (field != NULL) {
-          BasicType basic_elem_type = field->layout_type();
-          _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
-                                  basic_elem_type == T_ARRAY);
-        }
+        // Perm objects don't use compressed references
       } else if (_offset == OffsetBot || _offset == OffsetTop) {
         // unsafe access
         _is_ptr_to_narrowoop = true;
       } else { // exclude unsafe ops
         assert(this->isa_instptr(), "must be an instance ptr.");
-        // Field which contains a compressed oop references.
-        field = ik->get_field_by_offset(_offset, false);
-        if (field != NULL) {
+
+        if (klass() == ciEnv::current()->Class_klass() &&
+            (_offset == java_lang_Class::klass_offset_in_bytes() ||
+             _offset == java_lang_Class::array_klass_offset_in_bytes())) {
+          // Special hidden fields from the Class.
+          assert(this->isa_instptr(), "must be an instance ptr.");
+          _is_ptr_to_narrowoop = true;
+        } else if (klass() == ciEnv::current()->Class_klass() &&
+                   _offset >= instanceMirrorKlass::offset_of_static_fields()) {
+          // Static fields
+          assert(o != NULL, "must be constant");
+          ciInstanceKlass* k = o->as_instance()->java_lang_Class_klass()->as_instance_klass();
+          ciField* field = k->get_field_by_offset(_offset, true);
+          assert(field != NULL, "missing field");
           BasicType basic_elem_type = field->layout_type();
           _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
                                   basic_elem_type == T_ARRAY);
-        } else if (klass()->equals(ciEnv::current()->Object_klass())) {
-          // Compile::find_alias_type() cast exactness on all types to verify
-          // that it does not affect alias type.
-          _is_ptr_to_narrowoop = true;
         } else {
-          // Type for the copy start in LibraryCallKit::inline_native_clone().
-          assert(!klass_is_exact(), "only non-exact klass");
-          _is_ptr_to_narrowoop = true;
+          // Instance fields which contains a compressed oop references.
+          field = ik->get_field_by_offset(_offset, false);
+          if (field != NULL) {
+            BasicType basic_elem_type = field->layout_type();
+            _is_ptr_to_narrowoop = (basic_elem_type == T_OBJECT ||
+                                    basic_elem_type == T_ARRAY);
+          } else if (klass()->equals(ciEnv::current()->Object_klass())) {
+            // Compile::find_alias_type() cast exactness on all types to verify
+            // that it does not affect alias type.
+            _is_ptr_to_narrowoop = true;
+          } else {
+            // Type for the copy start in LibraryCallKit::inline_native_clone().
+            assert(!klass_is_exact(), "only non-exact klass");
+            _is_ptr_to_narrowoop = true;
+          }
         }
       }
     }
--- a/src/share/vm/opto/type.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/opto/type.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -988,8 +988,8 @@
 
   static const TypeNarrowOop *make( const TypePtr* type);
 
-  static const TypeNarrowOop* make_from_constant(ciObject* con) {
-    return make(TypeOopPtr::make_from_constant(con));
+  static const TypeNarrowOop* make_from_constant(ciObject* con, bool require_constant = false) {
+    return make(TypeOopPtr::make_from_constant(con, require_constant));
   }
 
   // returns the equivalent ptr type for this compressed pointer
--- a/src/share/vm/prims/jni.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/prims/jni.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -1858,7 +1858,7 @@
     // Static field. The fieldID a JNIid specifying the field holder and the offset within the klassOop.
     JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
     assert(id->is_static_field_id(), "invalid static field id");
-    found = instanceKlass::cast(id->holder())->find_local_field_from_offset(id->offset(), true, &fd);
+    found = id->find_local_field(&fd);
   } else {
     // Non-static field. The fieldID is really the offset of the field within the instanceOop.
     int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
@@ -1906,9 +1906,7 @@
   JNIid* id = instanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset());
   debug_only(id->set_is_static_field_id();)
 
-  debug_only(int first_offset = instanceKlass::cast(fd.field_holder())->offset_of_static_fields();)
-  debug_only(int end_offset = first_offset + (instanceKlass::cast(fd.field_holder())->static_field_size() * wordSize);)
-  assert(id->offset() >= first_offset && id->offset() < end_offset, "invalid static field offset");
+  debug_only(id->verify(fd.field_holder()));
 
   ret = jfieldIDWorkaround::to_static_jfieldID(id);
   return ret;
@@ -1928,7 +1926,7 @@
   if (JvmtiExport::should_post_field_access()) {
     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
   }
-  jobject ret = JNIHandles::make_local(id->holder()->obj_field(id->offset()));
+  jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
   DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);
   return ret;
 JNI_END
@@ -1950,7 +1948,7 @@
   if (JvmtiExport::should_post_field_access()) { \
     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
   } \
-  ret = id->holder()-> Fieldname##_field (id->offset()); \
+  ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \
   return ret;\
 JNI_END
 
@@ -1976,7 +1974,7 @@
     field_value.l = value;
     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value);
   }
-  id->holder()->obj_field_put(id->offset(), JNIHandles::resolve(value));
+  id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value));
   DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return);
 JNI_END
 
@@ -1999,7 +1997,7 @@
     field_value.unionType = value; \
     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
   } \
-  id->holder()-> Fieldname##_field_put (id->offset(), value); \
+  id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
   DTRACE_PROBE(hotspot_jni, SetStatic##Result##Field__return);\
 JNI_END
 
--- a/src/share/vm/prims/jniCheck.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/prims/jniCheck.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -224,8 +224,7 @@
     ReportJNIFatalError(thr, fatal_wrong_static_field);
 
   /* check for proper field type */
-  if (!instanceKlass::cast(f_oop)->find_local_field_from_offset(
-          id->offset(), true, &fd))
+  if (!id->find_local_field(&fd))
     ReportJNIFatalError(thr, fatal_static_field_not_found);
   if ((fd.field_type() != ftype) &&
       !(fd.field_type() == T_ARRAY && ftype == T_OBJECT)) {
--- a/src/share/vm/prims/jvm.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/prims/jvm.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1808,7 +1808,7 @@
     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
   }
   klassOop k = cp->klass_at(index, CHECK_NULL);
-  return (jclass) JNIHandles::make_local(k->klass_part()->java_mirror());
+  return (jclass) JNIHandles::make_local(k->java_mirror());
 }
 JVM_END
 
@@ -1824,7 +1824,7 @@
   }
   klassOop k = constantPoolOopDesc::klass_at_if_loaded(cp, index);
   if (k == NULL) return NULL;
-  return (jclass) JNIHandles::make_local(k->klass_part()->java_mirror());
+  return (jclass) JNIHandles::make_local(k->java_mirror());
 }
 JVM_END
 
--- a/src/share/vm/prims/jvmtiEnvBase.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/prims/jvmtiEnvBase.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -616,9 +616,7 @@
   bool found = false;
   if (jfieldIDWorkaround::is_static_jfieldID(field)) {
     JNIid* id = jfieldIDWorkaround::from_static_jfieldID(field);
-    int offset = id->offset();
-    klassOop holder = id->holder();
-    found = instanceKlass::cast(holder)->find_local_field_from_offset(offset, true, fd);
+    found = id->find_local_field(fd);
   } else {
     // Non-static field. The fieldID is really the offset of the field within the object.
     int offset = jfieldIDWorkaround::from_instance_jfieldID(k, field);
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -3350,11 +3350,12 @@
 
   for (Klass *subk = ik->subklass(); subk != NULL;
        subk = subk->next_sibling()) {
-    klassOop sub = subk->as_klassOop();
-    instanceKlass *subik = (instanceKlass *)sub->klass_part();
-
-    // recursively do subclasses of the current subclass
-    increment_class_counter(subik, THREAD);
+    if (subk->oop_is_instance()) {
+      // Only update instanceKlasses
+      instanceKlass *subik = (instanceKlass*)subk;
+      // recursively do subclasses of the current subclass
+      increment_class_counter(subik, THREAD);
+    }
   }
 }
 
--- a/src/share/vm/prims/jvmtiTagMap.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/prims/jvmtiTagMap.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -27,6 +27,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "jvmtifiles/jvmtiEnv.hpp"
+#include "oops/instanceMirrorKlass.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/oop.inline2.hpp"
 #include "prims/jvmtiEventController.hpp"
@@ -2594,6 +2595,11 @@
     if (o->is_klass()) {
       klassOop k = (klassOop)o;
       o = Klass::cast(k)->java_mirror();
+      if (o == NULL) {
+        // Classes without mirrors don't correspond to real Java
+        // classes so just ignore them.
+        return;
+      }
     } else {
 
       // SystemDictionary::always_strong_oops_do reports the application
@@ -2834,10 +2840,10 @@
 
 // verify that a static oop field is in range
 static inline bool verify_static_oop(instanceKlass* ik,
-                                     klassOop k, int offset) {
-  address obj_p = (address)k + offset;
-  address start = (address)ik->start_of_static_fields();
-  address end = start + (ik->static_oop_field_size() * heapOopSize);
+                                     oop mirror, int offset) {
+  address obj_p = (address)mirror + offset;
+  address start = (address)instanceMirrorKlass::start_of_static_fields(mirror);
+  address end = start + (java_lang_Class::static_oop_field_count(mirror) * heapOopSize);
   assert(end >= start, "sanity check");
 
   if (obj_p >= start && obj_p < end) {
@@ -2938,8 +2944,8 @@
       ClassFieldDescriptor* field = field_map->field_at(i);
       char type = field->field_type();
       if (!is_primitive_field_type(type)) {
-        oop fld_o = k->obj_field(field->field_offset());
-        assert(verify_static_oop(ik, k, field->field_offset()), "sanity check");
+        oop fld_o = mirror->obj_field(field->field_offset());
+        assert(verify_static_oop(ik, mirror, field->field_offset()), "sanity check");
         if (fld_o != NULL) {
           int slot = field->field_index();
           if (!CallbackInvoker::report_static_field_reference(mirror, fld_o, slot)) {
@@ -2949,7 +2955,7 @@
         }
       } else {
          if (is_reporting_primitive_fields()) {
-           address addr = (address)k + field->field_offset();
+           address addr = (address)mirror + field->field_offset();
            int slot = field->field_index();
            if (!CallbackInvoker::report_primitive_static_field(mirror, slot, addr, type)) {
              delete field_map;
--- a/src/share/vm/prims/unsafe.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/prims/unsafe.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -688,7 +688,7 @@
     THROW_0(vmSymbols::java_lang_IllegalArgumentException());
   }
 
-  return JNIHandles::make_local(env, java_lang_Class::as_klassOop(mirror));
+  return JNIHandles::make_local(env, mirror);
 UNSAFE_END
 
 //@deprecated
@@ -706,7 +706,7 @@
   if (clazz == NULL) {
     THROW_0(vmSymbols::java_lang_NullPointerException());
   }
-  return JNIHandles::make_local(env, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
+  return JNIHandles::make_local(env, JNIHandles::resolve_non_null(clazz));
 UNSAFE_END
 
 UNSAFE_ENTRY(void, Unsafe_EnsureClassInitialized(JNIEnv *env, jobject unsafe, jobject clazz))
--- a/src/share/vm/runtime/arguments.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/runtime/arguments.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -242,6 +242,7 @@
                            JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) },
   { "MaxLiveObjectEvacuationRatio",
                            JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) },
+  { "ForceSharedSpaces",   JDK_Version::jdk_update(6,25), JDK_Version::jdk(8) },
   { NULL, JDK_Version(0), JDK_Version(0) }
 };
 
@@ -1003,28 +1004,6 @@
   }
 }
 
-void Arguments::check_compressed_oops_compat() {
-#ifdef _LP64
-  assert(UseCompressedOops, "Precondition");
-  // Is it on by default or set on ergonomically
-  bool is_on_by_default = FLAG_IS_DEFAULT(UseCompressedOops) || FLAG_IS_ERGO(UseCompressedOops);
-
-  // If dumping an archive or forcing its use, disable compressed oops if possible
-  if (DumpSharedSpaces || RequireSharedSpaces) {
-    if (is_on_by_default) {
-      FLAG_SET_DEFAULT(UseCompressedOops, false);
-      return;
-    } else {
-      vm_exit_during_initialization(
-        "Class Data Sharing is not supported with compressed oops yet", NULL);
-    }
-  } else if (UseSharedSpaces) {
-    // UseSharedSpaces is on by default. With compressed oops, we turn it off.
-    FLAG_SET_DEFAULT(UseSharedSpaces, false);
-  }
-#endif
-}
-
 void Arguments::set_tiered_flags() {
   // With tiered, set default policy to AdvancedThresholdPolicy, which is 3.
   if (FLAG_IS_DEFAULT(CompilationPolicyChoice)) {
@@ -1123,40 +1102,28 @@
     set_parnew_gc_flags();
   }
 
+  // MaxHeapSize is aligned down in collectorPolicy
+  size_t max_heap = align_size_down(MaxHeapSize,
+                                    CardTableRS::ct_max_alignment_constraint());
+
   // Now make adjustments for CMS
-  size_t young_gen_per_worker;
-  intx new_ratio;
-  size_t min_new_default;
-  intx tenuring_default;
-  if (CMSUseOldDefaults) {  // old defaults: "old" as of 6.0
-    if FLAG_IS_DEFAULT(CMSYoungGenPerWorker) {
-      FLAG_SET_ERGO(intx, CMSYoungGenPerWorker, 4*M);
-    }
-    young_gen_per_worker = 4*M;
-    new_ratio = (intx)15;
-    min_new_default = 4*M;
-    tenuring_default = (intx)0;
-  } else { // new defaults: "new" as of 6.0
-    young_gen_per_worker = CMSYoungGenPerWorker;
-    new_ratio = (intx)7;
-    min_new_default = 16*M;
-    tenuring_default = (intx)4;
-  }
-
-  // Preferred young gen size for "short" pauses
+  intx   tenuring_default = (intx)6;
+  size_t young_gen_per_worker = CMSYoungGenPerWorker;
+
+  // Preferred young gen size for "short" pauses:
+  // upper bound depends on # of threads and NewRatio.
   const uintx parallel_gc_threads =
     (ParallelGCThreads == 0 ? 1 : ParallelGCThreads);
   const size_t preferred_max_new_size_unaligned =
-    ScaleForWordSize(young_gen_per_worker * parallel_gc_threads);
-  const size_t preferred_max_new_size =
+    MIN2(max_heap/(NewRatio+1), ScaleForWordSize(young_gen_per_worker * parallel_gc_threads));
+  size_t preferred_max_new_size =
     align_size_up(preferred_max_new_size_unaligned, os::vm_page_size());
 
   // Unless explicitly requested otherwise, size young gen
-  // for "short" pauses ~ 4M*ParallelGCThreads
+  // for "short" pauses ~ CMSYoungGenPerWorker*ParallelGCThreads
 
   // If either MaxNewSize or NewRatio is set on the command line,
   // assume the user is trying to set the size of the young gen.
-
   if (FLAG_IS_DEFAULT(MaxNewSize) && FLAG_IS_DEFAULT(NewRatio)) {
 
     // Set MaxNewSize to our calculated preferred_max_new_size unless
@@ -1169,49 +1136,13 @@
     }
     if (PrintGCDetails && Verbose) {
       // Too early to use gclog_or_tty
-      tty->print_cr("Ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
+      tty->print_cr("CMS ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize);
     }
 
-    // Unless explicitly requested otherwise, prefer a large
-    // Old to Young gen size so as to shift the collection load
-    // to the old generation concurrent collector
-
-    // If this is only guarded by FLAG_IS_DEFAULT(NewRatio)
-    // then NewSize and OldSize may be calculated.  That would
-    // generally lead to some differences with ParNewGC for which
-    // there was no obvious reason.  Also limit to the case where
-    // MaxNewSize has not been set.
-
-    FLAG_SET_ERGO(intx, NewRatio, MAX2(NewRatio, new_ratio));
-
     // Code along this path potentially sets NewSize and OldSize
 
-    // Calculate the desired minimum size of the young gen but if
-    // NewSize has been set on the command line, use it here since
-    // it should be the final value.
-    size_t min_new;
-    if (FLAG_IS_DEFAULT(NewSize)) {
-      min_new = align_size_up(ScaleForWordSize(min_new_default),
-                              os::vm_page_size());
-    } else {
-      min_new = NewSize;
-    }
-    size_t prev_initial_size = InitialHeapSize;
-    if (prev_initial_size != 0 && prev_initial_size < min_new + OldSize) {
-      FLAG_SET_ERGO(uintx, InitialHeapSize, min_new + OldSize);
-      // Currently minimum size and the initial heap sizes are the same.
-      set_min_heap_size(InitialHeapSize);
-      if (PrintGCDetails && Verbose) {
-        warning("Initial heap size increased to " SIZE_FORMAT " M from "
-                SIZE_FORMAT " M; use -XX:NewSize=... for finer control.",
-                InitialHeapSize/M, prev_initial_size/M);
-      }
-    }
-
-    // MaxHeapSize is aligned down in collectorPolicy
-    size_t max_heap =
-      align_size_down(MaxHeapSize,
-                      CardTableRS::ct_max_alignment_constraint());
+    assert(max_heap >= InitialHeapSize, "Error");
+    assert(max_heap >= NewSize, "Error");
 
     if (PrintGCDetails && Verbose) {
       // Too early to use gclog_or_tty
@@ -1220,7 +1151,11 @@
            " max_heap: " SIZE_FORMAT,
            min_heap_size(), InitialHeapSize, max_heap);
     }
-    if (max_heap > min_new) {
+    size_t min_new = preferred_max_new_size;
+    if (FLAG_IS_CMDLINE(NewSize)) {
+      min_new = NewSize;
+    }
+    if (max_heap > min_new && min_heap_size() > min_new) {
       // Unless explicitly requested otherwise, make young gen
       // at least min_new, and at most preferred_max_new_size.
       if (FLAG_IS_DEFAULT(NewSize)) {
@@ -1228,18 +1163,17 @@
         FLAG_SET_ERGO(uintx, NewSize, MIN2(preferred_max_new_size, NewSize));
         if (PrintGCDetails && Verbose) {
           // Too early to use gclog_or_tty
-          tty->print_cr("Ergo set NewSize: " SIZE_FORMAT, NewSize);
+          tty->print_cr("CMS ergo set NewSize: " SIZE_FORMAT, NewSize);
         }
       }
       // Unless explicitly requested otherwise, size old gen
-      // so that it's at least 3X of NewSize to begin with;
-      // later NewRatio will decide how it grows; see above.
+      // so it's NewRatio x of NewSize.
       if (FLAG_IS_DEFAULT(OldSize)) {
         if (max_heap > NewSize) {
-          FLAG_SET_ERGO(uintx, OldSize, MIN2(3*NewSize, max_heap - NewSize));
+          FLAG_SET_ERGO(uintx, OldSize, MIN2(NewRatio*NewSize, max_heap - NewSize));
           if (PrintGCDetails && Verbose) {
             // Too early to use gclog_or_tty
-            tty->print_cr("Ergo set OldSize: " SIZE_FORMAT, OldSize);
+            tty->print_cr("CMS ergo set OldSize: " SIZE_FORMAT, OldSize);
           }
         }
       }
@@ -1383,7 +1317,7 @@
 void Arguments::set_ergonomics_flags() {
   // Parallel GC is not compatible with sharing. If one specifies
   // that they want sharing explicitly, do not set ergonomics flags.
-  if (DumpSharedSpaces || ForceSharedSpaces) {
+  if (DumpSharedSpaces || RequireSharedSpaces) {
     return;
   }
 
@@ -1690,13 +1624,13 @@
 }
 
 bool Arguments::verify_min_value(intx val, intx min, const char* name) {
-  // Returns true if given value is greater than specified min threshold
+  // Returns true if given value is at least specified min threshold
   // false, otherwise.
   if (val >= min ) {
       return true;
   }
   jio_fprintf(defaultStream::error_stream(),
-              "%s of " INTX_FORMAT " is invalid; must be greater than " INTX_FORMAT "\n",
+              "%s of " INTX_FORMAT " is invalid; must be at least " INTX_FORMAT "\n",
               name, val, min);
   return false;
 }
@@ -1846,33 +1780,6 @@
 
   status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
 
-  // Check whether user-specified sharing option conflicts with GC or page size.
-  // Both sharing and large pages are enabled by default on some platforms;
-  // large pages override sharing only if explicitly set on the command line.
-  const bool cannot_share = UseConcMarkSweepGC || CMSIncrementalMode ||
-          UseG1GC || UseParNewGC || UseParallelGC || UseParallelOldGC ||
-          UseLargePages && FLAG_IS_CMDLINE(UseLargePages);
-  if (cannot_share) {
-    // Either force sharing on by forcing the other options off, or
-    // force sharing off.
-    if (DumpSharedSpaces || ForceSharedSpaces) {
-      jio_fprintf(defaultStream::error_stream(),
-                  "Using Serial GC and default page size because of %s\n",
-                  ForceSharedSpaces ? "-Xshare:on" : "-Xshare:dump");
-      force_serial_gc();
-      FLAG_SET_DEFAULT(UseLargePages, false);
-    } else {
-      if (UseSharedSpaces && Verbose) {
-        jio_fprintf(defaultStream::error_stream(),
-                    "Turning off use of shared archive because of "
-                    "choice of garbage collector or large pages\n");
-      }
-      no_shared_spaces();
-    }
-  } else if (UseLargePages && (UseSharedSpaces || DumpSharedSpaces)) {
-    FLAG_SET_DEFAULT(UseLargePages, false);
-  }
-
   status = status && check_gc_consistency();
   status = status && check_stack_pages();
 
@@ -1950,6 +1857,8 @@
     status = false;
   }
 
+  status = status && verify_min_value(ParGCArrayScanChunk, 1, "ParGCArrayScanChunk");
+
 #ifndef SERIALGC
   if (UseG1GC) {
     status = status && verify_percentage(InitiatingHeapOccupancyPercent,
@@ -2413,9 +2322,6 @@
     } else if (match_option(option, "-Xshare:on", &tail)) {
       FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
       FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
-#ifdef TIERED
-      FLAG_SET_CMDLINE(bool, ForceSharedSpaces, true);
-#endif // TIERED
     // -Xshare:auto
     } else if (match_option(option, "-Xshare:auto", &tail)) {
       FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
@@ -2912,6 +2818,52 @@
   return JNI_OK;
 }
 
+void Arguments::set_shared_spaces_flags() {
+  const bool must_share = DumpSharedSpaces || RequireSharedSpaces;
+  const bool might_share = must_share || UseSharedSpaces;
+
+  // The string table is part of the shared archive so the size must match.
+  if (!FLAG_IS_DEFAULT(StringTableSize)) {
+    // Disable sharing.
+    if (must_share) {
+      warning("disabling shared archive %s because of non-default "
+              "StringTableSize", DumpSharedSpaces ? "creation" : "use");
+    }
+    if (might_share) {
+      FLAG_SET_DEFAULT(DumpSharedSpaces, false);
+      FLAG_SET_DEFAULT(RequireSharedSpaces, false);
+      FLAG_SET_DEFAULT(UseSharedSpaces, false);
+    }
+    return;
+  }
+
+  // Check whether class data sharing settings conflict with GC, compressed oops
+  // or page size, and fix them up.  Explicit sharing options override other
+  // settings.
+  const bool cannot_share = UseConcMarkSweepGC || CMSIncrementalMode ||
+    UseG1GC || UseParNewGC || UseParallelGC || UseParallelOldGC ||
+    UseCompressedOops || UseLargePages && FLAG_IS_CMDLINE(UseLargePages);
+  if (cannot_share) {
+    if (must_share) {
+        warning("selecting serial gc and disabling large pages %s"
+                "because of %s", "" LP64_ONLY("and compressed oops "),
+                DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on");
+        force_serial_gc();
+        FLAG_SET_CMDLINE(bool, UseLargePages, false);
+        LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedOops, false));
+    } else {
+      if (UseSharedSpaces && Verbose) {
+        warning("turning off use of shared archive because of "
+                "choice of garbage collector or large pages");
+      }
+      no_shared_spaces();
+    }
+  } else if (UseLargePages && might_share) {
+    // Disable large pages to allow shared spaces.  This is sub-optimal, since
+    // there may not even be a shared archive to use.
+    FLAG_SET_DEFAULT(UseLargePages, false);
+  }
+}
 
 // Parse entry point called from JNI_CreateJavaVM
 
@@ -3040,6 +2992,12 @@
     }
     ScavengeRootsInCode = 1;
   }
+  if (!JavaObjectsInPerm && ScavengeRootsInCode == 0) {
+    if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) {
+      warning("forcing ScavengeRootsInCode non-zero because JavaObjectsInPerm is false");
+    }
+    ScavengeRootsInCode = 1;
+  }
 
   if (PrintGCDetails) {
     // Turn on -verbose:gc options as well
@@ -3059,9 +3017,7 @@
   // Set flags based on ergonomics.
   set_ergonomics_flags();
 
-  if (UseCompressedOops) {
-    check_compressed_oops_compat();
-  }
+  set_shared_spaces_flags();
 
   // Check the GC selections again.
   if (!check_gc_consistency()) {
@@ -3079,22 +3035,17 @@
   }
 
 #ifndef KERNEL
-  if (UseConcMarkSweepGC) {
-    // Set flags for CMS and ParNew.  Check UseConcMarkSweep first
-    // to ensure that when both UseConcMarkSweepGC and UseParNewGC
-    // are true, we don't call set_parnew_gc_flags() as well.
+  // Set heap size based on available physical memory
+  set_heap_size();
+  // Set per-collector flags
+  if (UseParallelGC || UseParallelOldGC) {
+    set_parallel_gc_flags();
+  } else if (UseConcMarkSweepGC) { // should be done before ParNew check below
     set_cms_and_parnew_gc_flags();
-  } else {
-    // Set heap size based on available physical memory
-    set_heap_size();
-    // Set per-collector flags
-    if (UseParallelGC || UseParallelOldGC) {
-      set_parallel_gc_flags();
-    } else if (UseParNewGC) {
-      set_parnew_gc_flags();
-    } else if (UseG1GC) {
-      set_g1_gc_flags();
-    }
+  } else if (UseParNewGC) {  // skipped if CMS is set above
+    set_parnew_gc_flags();
+  } else if (UseG1GC) {
+    set_g1_gc_flags();
   }
 #endif // KERNEL
 
--- a/src/share/vm/runtime/arguments.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/runtime/arguments.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -301,8 +301,6 @@
 
   // Tiered
   static void set_tiered_flags();
-  // Check compressed oops compatibility with other flags
-  static void check_compressed_oops_compat();
   // CMS/ParNew garbage collectors
   static void set_parnew_gc_flags();
   static void set_cms_and_parnew_gc_flags();
@@ -312,6 +310,7 @@
   static void set_g1_gc_flags();
   // GC ergonomics
   static void set_ergonomics_flags();
+  static void set_shared_spaces_flags();
   // Setup heap size
   static void set_heap_size();
   // Based on automatic selection criteria, should the
--- a/src/share/vm/runtime/globals.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/runtime/globals.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -851,7 +851,7 @@
   diagnostic(bool, TraceNMethodInstalls, false,                             \
              "Trace nmethod intallation")                                   \
                                                                             \
-  diagnostic(intx, ScavengeRootsInCode, 0,                                  \
+  diagnostic(intx, ScavengeRootsInCode, 1,                                  \
              "0: do not allow scavengable oops in the code cache; "         \
              "1: allow scavenging from the code cache; "                    \
              "2: emit as many constants as the compiler can see")           \
@@ -1221,6 +1221,11 @@
           "Decay time (in milliseconds) to re-enable bulk rebiasing of a "  \
           "type after previous bulk rebias")                                \
                                                                             \
+  develop(bool, JavaObjectsInPerm, false,                                   \
+          "controls whether Classes and interned Strings are allocated"     \
+          "in perm.  This purely intended to allow debugging issues"        \
+          "in production.")                                                 \
+                                                                            \
   /* tracing */                                                             \
                                                                             \
   notproduct(bool, TraceRuntimeCalls, false,                                \
@@ -1540,12 +1545,8 @@
   product(bool, AlwaysPreTouch, false,                                      \
           "It forces all freshly committed pages to be pre-touched.")       \
                                                                             \
-  product(bool, CMSUseOldDefaults, false,                                   \
-          "A flag temporarily introduced to allow reverting to some "       \
-          "older default settings; older as of 6.0")                        \
-                                                                            \
-  product(intx, CMSYoungGenPerWorker, 16*M,                                 \
-          "The amount of young gen chosen by default per GC worker "        \
+  product_pd(intx, CMSYoungGenPerWorker,                                    \
+          "The maximum size of young gen chosen by default per GC worker "  \
           "thread available")                                               \
                                                                             \
   product(bool, GCOverheadReporting, false,                                 \
@@ -3653,9 +3654,6 @@
   product(bool, RequireSharedSpaces, false,                                 \
           "Require shared spaces in the permanent generation")              \
                                                                             \
-  product(bool, ForceSharedSpaces, false,                                   \
-          "Require shared spaces in the permanent generation")              \
-                                                                            \
   product(bool, DumpSharedSpaces, false,                                    \
            "Special mode: JVM reads a class list, loads classes, builds "   \
             "shared spaces, and dumps the shared spaces to a file to be "   \
@@ -3758,6 +3756,9 @@
   diagnostic(bool, PrintDTraceDOF, false,                                   \
              "Print the DTrace DOF passed to the system for JSDT probes")   \
                                                                             \
+  product(uintx, StringTableSize, 1009,                                     \
+          "Number of buckets in the interned String table")                 \
+                                                                            \
   product(bool, UseVMInterruptibleIO, false,                                \
           "(Unstable, Solaris-specific) Thread interrupt before or with "   \
           "EINTR for I/O operations results in OS_INTRPT. The default value"\
--- a/src/share/vm/runtime/os.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/runtime/os.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1079,11 +1079,6 @@
         "%/lib/jsse.jar:"
         "%/lib/jce.jar:"
         "%/lib/charsets.jar:"
-
-        // ## TEMPORARY hack to keep the legacy launcher working when
-        // ## only the boot module is installed (cf. j.l.ClassLoader)
-        "%/lib/modules/jdk.boot.jar:"
-
         "%/classes";
     char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep);
     if (sysclasspath == NULL) return false;
--- a/src/share/vm/runtime/osThread.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/runtime/osThread.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -65,7 +65,7 @@
   OSThreadStartFunc _start_proc;  // Thread start routine
   void* _start_parm;              // Thread start routine parameter
   volatile ThreadState _state;    // Thread state *hint*
-  jint _interrupted;              // Thread.isInterrupted state
+  volatile jint _interrupted;     // Thread.isInterrupted state
 
   // Note:  _interrupted must be jint, so that Java intrinsics can access it.
   // The value stored there must be either 0 or 1.  It must be possible
@@ -89,7 +89,7 @@
   void* start_parm() const                          { return _start_parm; }
   void set_start_parm(void* start_parm)             { _start_parm = start_parm; }
 
-  bool interrupted() const                          { return _interrupted != 0; }
+  volatile bool interrupted() const                 { return _interrupted != 0; }
   void set_interrupted(bool z)                      { _interrupted = z ? 1 : 0; }
 
   // Printing
--- a/src/share/vm/runtime/reflection.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/runtime/reflection.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -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
@@ -649,7 +649,7 @@
       if (TraceClassResolution) {
         trace_class_resolution(k);
       }
-      return k->klass_part()->java_mirror();
+      return k->java_mirror();
   };
 }
 
--- a/src/share/vm/runtime/thread.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/runtime/thread.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -3166,7 +3166,7 @@
         fieldDescriptor fd;
         // Possible we might not find this field; if so, don't break
         if (ik->find_local_field(vmSymbols::frontCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
-          k()->bool_field_put(fd.offset(), true);
+          k()->java_mirror()->bool_field_put(fd.offset(), true);
         }
       }
 
@@ -3182,7 +3182,7 @@
           fieldDescriptor fd;
           // Possible we might not find this field: if so, silently don't break
           if (ik->find_local_field(vmSymbols::stringCacheEnabled_name(), vmSymbols::bool_signature(), &fd)) {
-            k()->bool_field_put(fd.offset(), true);
+            k()->java_mirror()->bool_field_put(fd.offset(), true);
           }
         }
       }
--- a/src/share/vm/runtime/vmStructs.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -269,7 +269,7 @@
   nonstatic_field(instanceKlass,               _inner_classes,                                typeArrayOop)                          \
   nonstatic_field(instanceKlass,               _nonstatic_field_size,                         int)                                   \
   nonstatic_field(instanceKlass,               _static_field_size,                            int)                                   \
-  nonstatic_field(instanceKlass,               _static_oop_field_size,                        int)                                   \
+  nonstatic_field(instanceKlass,               _static_oop_field_count,                       int)                                   \
   nonstatic_field(instanceKlass,               _nonstatic_oop_map_size,                       int)                                   \
   nonstatic_field(instanceKlass,               _is_marked_dependent,                          bool)                                  \
   nonstatic_field(instanceKlass,               _minor_version,                                u2)                                    \
@@ -840,7 +840,7 @@
   /* OSThread */                                                                                                                     \
   /************/                                                                                                                     \
                                                                                                                                      \
-  nonstatic_field(OSThread,                    _interrupted,                                  jint)                                  \
+  volatile_nonstatic_field(OSThread,           _interrupted,                                  jint)                                  \
                                                                                                                                      \
   /************************/                                                                                                         \
   /* OopMap and OopMapSet */                                                                                                         \
@@ -945,6 +945,15 @@
   static_field(Arguments,                      _num_jvm_args,                                 int)                                   \
   static_field(Arguments,                      _java_command,                                 char*)                                 \
                                                                                                                                      \
+  /*********************************/                                                                                                \
+  /* java_lang_Class fields        */                                                                                                \
+  /*********************************/                                                                                                \
+                                                                                                                                     \
+  static_field(java_lang_Class,                klass_offset,                                  int)                                   \
+  static_field(java_lang_Class,                resolved_constructor_offset,                   int)                                   \
+  static_field(java_lang_Class,                array_klass_offset,                            int)                                   \
+  static_field(java_lang_Class,                oop_size_offset,                               int)                                   \
+  static_field(java_lang_Class,                static_oop_field_count_offset,                 int)                                   \
                                                                                                                                      \
   /************************/                                                                                                         \
   /* Miscellaneous fields */                                                                                                         \
@@ -1414,6 +1423,7 @@
   declare_toplevel_type(intptr_t*)                                        \
    declare_unsigned_integer_type(InvocationCounter) /* FIXME: wrong type (not integer) */ \
   declare_toplevel_type(JavaThread*)                                      \
+  declare_toplevel_type(java_lang_Class)                                  \
   declare_toplevel_type(jbyte*)                                           \
   declare_toplevel_type(jbyte**)                                          \
   declare_toplevel_type(jint*)                                            \
@@ -1543,12 +1553,6 @@
                                                                           \
   declare_constant(SymbolTable::symbol_table_size)                        \
                                                                           \
-  /***************/                                                       \
-  /* StringTable */                                                       \
-  /***************/                                                       \
-                                                                          \
-  declare_constant(StringTable::string_table_size)                        \
-                                                                          \
   /********************/                                                  \
   /* SystemDictionary */                                                  \
   /********************/                                                  \
@@ -1700,15 +1704,6 @@
                                                                           \
   declare_constant(ConstantPoolCacheEntry::tosBits)                       \
                                                                           \
-  /*********************************/                                     \
-  /* java_lang_Class field offsets */                                     \
-  /*********************************/                                     \
-                                                                          \
-  declare_constant(java_lang_Class::hc_klass_offset)                      \
-  declare_constant(java_lang_Class::hc_array_klass_offset)                \
-  declare_constant(java_lang_Class::hc_resolved_constructor_offset)       \
-  declare_constant(java_lang_Class::hc_number_of_fake_oop_fields)         \
-                                                                          \
   /***************************************/                               \
   /* java_lang_Thread::ThreadStatus enum */                               \
   /***************************************/                               \
--- a/src/share/vm/services/heapDumper.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/services/heapDumper.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -832,7 +832,7 @@
 
       // value
       int offset = fld.offset();
-      address addr = (address)k + offset;
+      address addr = (address)ikh->java_mirror() + offset;
 
       dump_field_value(writer, sig->byte_at(0), addr);
     }
--- a/src/share/vm/shark/sharkNativeWrapper.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/shark/sharkNativeWrapper.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -101,7 +101,7 @@
     builder()->CreateStore(
       builder()->CreateInlineOop(
         JNIHandles::make_local(
-          target()->method_holder()->klass_part()->java_mirror())),
+          target()->method_holder()->java_mirror())),
       oop_tmp_slot());
 
     param_types.push_back(box_type);
--- a/src/share/vm/utilities/debug.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/utilities/debug.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_UTILITIES_DEBUG_HPP
 #define SHARE_VM_UTILITIES_DEBUG_HPP
 
+#include "prims/jvm.h"
 #include "utilities/globalDefinitions.hpp"
 
 #include <stdarg.h>
@@ -48,7 +49,7 @@
 FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) {
   va_list argp;
   va_start(argp, format);
-  vsnprintf(_buf, bufsz, format, argp);
+  jio_vsnprintf(_buf, bufsz, format, argp);
   va_end(argp);
 }
 
@@ -61,7 +62,7 @@
 
   va_list argp;
   va_start(argp, format);
-  vsnprintf(buf_end, bufsz - len, format, argp);
+  jio_vsnprintf(buf_end, bufsz - len, format, argp);
   va_end(argp);
 }
 
--- a/src/share/vm/utilities/globalDefinitions.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1185,7 +1185,7 @@
 // '%d' formats to indicate a 64-bit quantity; commonly "l" (in LP64) or "ll"
 // (in ILP32).
 
-#define BOOL_TO_STR(__b) (__b) ? "true" : "false"
+#define BOOL_TO_STR(_b_) ((_b_) ? "true" : "false")
 
 // Format 32-bit quantities.
 #define INT32_FORMAT  "%d"
--- a/src/share/vm/utilities/workgroup.cpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/utilities/workgroup.cpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,7 +156,7 @@
     tty->print_cr("/nFinished work gang %s: %d/%d sequence %d",
                   name(), finished_workers(), total_workers(),
                   _sequence_number);
-    }
+  }
 }
 
 void AbstractWorkGang::stop() {
--- a/src/share/vm/utilities/workgroup.hpp	Fri Mar 25 11:29:30 2011 -0700
+++ b/src/share/vm/utilities/workgroup.hpp	Fri Mar 25 18:19:22 2011 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,20 @@
 # include "thread_windows.inline.hpp"
 #endif
 
+// Task class hierarchy:
+//   AbstractGangTask
+//     AbstractGangTaskWOopQueues
+//
+// Gang/Group class hierarchy:
+//   AbstractWorkGang
+//     WorkGang
+//       FlexibleWorkGang
+//         YieldingFlexibleWorkGang (defined in another file)
+//
+// Worker class hierarchy:
+//   GangWorker (subclass of WorkerThread)
+//     YieldingFlexibleGangWorker   (defined in another file)
+
 // Forward declarations of classes defined here
 
 class WorkGang;