Merge

Mon, 28 Jun 2010 12:03:05 -0400

author
coleenp
date
Mon, 28 Jun 2010 12:03:05 -0400
changeset 1982
c5f1ea9e15e8
parent 1981
1a11430e0326
parent 1974
5a297ea605c7
child 1983
a00567c82f02
child 1995
bfc89697cccb

Merge

src/share/vm/runtime/arguments.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeDisassembler.java	Thu Jun 24 15:38:42 2010 -0700
     1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeDisassembler.java	Mon Jun 28 12:03:05 2010 -0400
     1.3 @@ -72,6 +72,7 @@
     1.4        addBytecodeClass(Bytecodes._invokestatic, BytecodeInvoke.class);
     1.5        addBytecodeClass(Bytecodes._invokespecial, BytecodeInvoke.class);
     1.6        addBytecodeClass(Bytecodes._invokeinterface, BytecodeInvoke.class);
     1.7 +      addBytecodeClass(Bytecodes._invokedynamic, BytecodeInvoke.class);
     1.8        addBytecodeClass(Bytecodes._jsr, BytecodeJsr.class);
     1.9        addBytecodeClass(Bytecodes._jsr_w, BytecodeJsrW.class);
    1.10        addBytecodeClass(Bytecodes._iload, BytecodeLoad.class);
     2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeInvoke.java	Thu Jun 24 15:38:42 2010 -0700
     2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeInvoke.java	Mon Jun 28 12:03:05 2010 -0400
     2.3 @@ -54,15 +54,31 @@
     2.4    // returns the name of the invoked method
     2.5    public Symbol name() {
     2.6      ConstantPool cp = method().getConstants();
     2.7 +    if (isInvokedynamic()) {
     2.8 +       int[] nt = cp.getNameAndTypeAt(indexForFieldOrMethod());
     2.9 +       return cp.getSymbolAt(nt[0]);
    2.10 +    }
    2.11      return cp.getNameRefAt(index());
    2.12    }
    2.13  
    2.14    // returns the signature of the invoked method
    2.15    public Symbol signature() {
    2.16      ConstantPool cp = method().getConstants();
    2.17 +    if (isInvokedynamic()) {
    2.18 +       int[] nt = cp.getNameAndTypeAt(indexForFieldOrMethod());
    2.19 +       return cp.getSymbolAt(nt[1]);
    2.20 +    }
    2.21      return cp.getSignatureRefAt(index());
    2.22    }
    2.23  
    2.24 +  public int getSecondaryIndex() {
    2.25 +    if (isInvokedynamic()) {
    2.26 +      // change byte-ordering of 4-byte integer
    2.27 +      return VM.getVM().getBytes().swapInt(javaSignedWordAt(1));
    2.28 +    }
    2.29 +    return super.getSecondaryIndex();  // throw an error
    2.30 +  }
    2.31 +
    2.32    public Method getInvokedMethod() {
    2.33      return method().getConstants().getMethodRefAt(index());
    2.34    }
    2.35 @@ -87,6 +103,7 @@
    2.36    public boolean isInvokevirtual()   { return adjustedInvokeCode() == Bytecodes._invokevirtual;   }
    2.37    public boolean isInvokestatic()    { return adjustedInvokeCode() == Bytecodes._invokestatic;    }
    2.38    public boolean isInvokespecial()   { return adjustedInvokeCode() == Bytecodes._invokespecial;   }
    2.39 +  public boolean isInvokedynamic()   { return adjustedInvokeCode() == Bytecodes._invokedynamic; }
    2.40  
    2.41    public boolean isValid()           { return isInvokeinterface() ||
    2.42                                                isInvokevirtual()   ||
    2.43 @@ -104,6 +121,11 @@
    2.44      buf.append(spaces);
    2.45      buf.append('#');
    2.46      buf.append(Integer.toString(indexForFieldOrMethod()));
    2.47 +    if (isInvokedynamic()) {
    2.48 +       buf.append('(');
    2.49 +       buf.append(Integer.toString(getSecondaryIndex()));
    2.50 +       buf.append(')');
    2.51 +    }
    2.52      buf.append(" [Method ");
    2.53      StringBuffer sigBuf = new StringBuffer();
    2.54      new SignatureConverter(signature(), sigBuf).iterateReturntype();
     3.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Thu Jun 24 15:38:42 2010 -0700
     3.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Mon Jun 28 12:03:05 2010 -0400
     3.3 @@ -25,6 +25,7 @@
     3.4  package sun.jvm.hotspot.interpreter;
     3.5  
     3.6  import sun.jvm.hotspot.oops.*;
     3.7 +import sun.jvm.hotspot.runtime.*;
     3.8  import sun.jvm.hotspot.utilities.*;
     3.9  
    3.10  public class BytecodeLoadConstant extends BytecodeWithCPIndex {
    3.11 @@ -32,10 +33,47 @@
    3.12      super(method, bci);
    3.13    }
    3.14  
    3.15 +  public boolean hasCacheIndex() {
    3.16 +    // normal ldc uses CP index, but fast_aldc uses swapped CP cache index
    3.17 +    return javaCode() != code();
    3.18 +  }
    3.19 +
    3.20    public int index() {
    3.21 -    return javaCode() == Bytecodes._ldc ?
    3.22 +    int i = javaCode() == Bytecodes._ldc ?
    3.23                   (int) (0xFF & javaByteAt(1))
    3.24                 : (int) (0xFFFF & javaShortAt(1));
    3.25 +    if (hasCacheIndex()) {
    3.26 +      return (0xFFFF & VM.getVM().getBytes().swapShort((short) i));
    3.27 +    } else {
    3.28 +      return i;
    3.29 +    }
    3.30 +  }
    3.31 +
    3.32 +  public int poolIndex() {
    3.33 +    int i = index();
    3.34 +    if (hasCacheIndex()) {
    3.35 +      ConstantPoolCache cpCache = method().getConstants().getCache();
    3.36 +      return cpCache.getEntryAt(i).getConstantPoolIndex();
    3.37 +    } else {
    3.38 +      return i;
    3.39 +    }
    3.40 +  }
    3.41 +
    3.42 +  public int cacheIndex() {
    3.43 +    if (hasCacheIndex()) {
    3.44 +      return index();
    3.45 +    } else {
    3.46 +      return -1;  // no cache index
    3.47 +    }
    3.48 +  }
    3.49 +
    3.50 +  private Oop getCachedConstant() {
    3.51 +    int i = cacheIndex();
    3.52 +    if (i >= 0) {
    3.53 +      ConstantPoolCache cpCache = method().getConstants().getCache();
    3.54 +      return cpCache.getEntryAt(i).getF1();
    3.55 +    }
    3.56 +    return null;
    3.57    }
    3.58  
    3.59    public void verify() {
    3.60 @@ -58,6 +96,7 @@
    3.61         // has to be int or float or String or Klass
    3.62         return (ctag.isUnresolvedString() || ctag.isString()
    3.63                 || ctag.isUnresolvedKlass() || ctag.isKlass()
    3.64 +               || ctag.isMethodHandle() || ctag.isMethodType()
    3.65                 || ctag.isInt() || ctag.isFloat())? true: false;
    3.66      }
    3.67    }
    3.68 @@ -112,7 +151,7 @@
    3.69  
    3.70    public String getConstantValue() {
    3.71      ConstantPool cpool = method().getConstants();
    3.72 -    int cpIndex = index();
    3.73 +    int cpIndex = poolIndex();
    3.74      ConstantTag ctag = cpool.getTagAt(cpIndex);
    3.75      if (ctag.isInt()) {
    3.76         return "<int " + Integer.toString(cpool.getIntAt(cpIndex)) +">";
    3.77 @@ -149,6 +188,18 @@
    3.78         } else {
    3.79            throw new RuntimeException("should not reach here");
    3.80         }
    3.81 +    } else if (ctag.isMethodHandle() || ctag.isMethodType()) {
    3.82 +       Oop x = getCachedConstant();
    3.83 +       int refidx = cpool.getMethodHandleIndexAt(cpIndex);
    3.84 +       int refkind = cpool.getMethodHandleRefKindAt(cpIndex);
    3.85 +       return "<MethodHandle kind=" + Integer.toString(refkind) +
    3.86 +           " ref=" + Integer.toString(refidx)
    3.87 +           + (x == null ? "" : " @" + x.getHandle()) + ">";
    3.88 +    } else if (ctag.isMethodType()) {
    3.89 +       Oop x = getCachedConstant();
    3.90 +       int refidx = cpool.getMethodTypeIndexAt(cpIndex);
    3.91 +       return "<MethodType " + cpool.getSymbolAt(refidx).asString()
    3.92 +           + (x == null ? "" : " @" + x.getHandle()) + ">";
    3.93      } else {
    3.94         if (Assert.ASSERTS_ENABLED) {
    3.95           Assert.that(false, "invalid load constant type");
    3.96 @@ -162,7 +213,12 @@
    3.97      buf.append(getJavaBytecodeName());
    3.98      buf.append(spaces);
    3.99      buf.append('#');
   3.100 -    buf.append(Integer.toString(index()));
   3.101 +    buf.append(Integer.toString(poolIndex()));
   3.102 +    if (hasCacheIndex()) {
   3.103 +       buf.append('(');
   3.104 +       buf.append(Integer.toString(cacheIndex()));
   3.105 +       buf.append(')');
   3.106 +    }
   3.107      buf.append(spaces);
   3.108      buf.append(getConstantValue());
   3.109      if (code() != javaCode()) {
     4.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithCPIndex.java	Thu Jun 24 15:38:42 2010 -0700
     4.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeWithCPIndex.java	Mon Jun 28 12:03:05 2010 -0400
     4.3 @@ -37,12 +37,19 @@
     4.4    // the constant pool index for this bytecode
     4.5    public int index() { return 0xFFFF & javaShortAt(1); }
     4.6  
     4.7 +  public int getSecondaryIndex() {
     4.8 +     throw new IllegalArgumentException("must be invokedynamic");
     4.9 +  }
    4.10 +
    4.11    protected int indexForFieldOrMethod() {
    4.12       ConstantPoolCache cpCache = method().getConstants().getCache();
    4.13       // get ConstantPool index from ConstantPoolCacheIndex at given bci
    4.14       int cpCacheIndex = index();
    4.15       if (cpCache == null) {
    4.16          return cpCacheIndex;
    4.17 +     } else if (code() == Bytecodes._invokedynamic) {
    4.18 +        int secondaryIndex = getSecondaryIndex();
    4.19 +        return cpCache.getMainEntryAt(secondaryIndex).getConstantPoolIndex();
    4.20       } else {
    4.21          // change byte-ordering and go via cache
    4.22          return cpCache.getEntryAt((int) (0xFFFF & VM.getVM().getBytes().swapShort((short) cpCacheIndex))).getConstantPoolIndex();
     5.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java	Thu Jun 24 15:38:42 2010 -0700
     5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/Bytecodes.java	Mon Jun 28 12:03:05 2010 -0400
     5.3 @@ -222,7 +222,7 @@
     5.4    public static final int _invokespecial        = 183; // 0xb7
     5.5    public static final int _invokestatic         = 184; // 0xb8
     5.6    public static final int _invokeinterface      = 185; // 0xb9
     5.7 -  public static final int _xxxunusedxxx         = 186; // 0xba
     5.8 +  public static final int _invokedynamic        = 186; // 0xba
     5.9    public static final int _new                  = 187; // 0xbb
    5.10    public static final int _newarray             = 188; // 0xbc
    5.11    public static final int _anewarray            = 189; // 0xbd
    5.12 @@ -269,9 +269,12 @@
    5.13    public static final int _fast_invokevfinal    = 226;
    5.14    public static final int _fast_linearswitch    = 227;
    5.15    public static final int _fast_binaryswitch    = 228;
    5.16 -  public static final int _shouldnotreachhere   = 229; // For debugging
    5.17 +  public static final int _fast_aldc            = 229;
    5.18 +  public static final int _fast_aldc_w          = 230;
    5.19 +  public static final int _return_register_finalizer = 231;
    5.20 +  public static final int _shouldnotreachhere   = 232; // For debugging
    5.21  
    5.22 -  public static final int number_of_codes       = 230;
    5.23 +  public static final int number_of_codes       = 233;
    5.24  
    5.25    public static int specialLengthAt(Method method, int bci) {
    5.26      int code = codeAt(method, bci);
    5.27 @@ -458,9 +461,9 @@
    5.28      def(_dconst_1            , "dconst_1"            , "b"    , null    , BasicType.getTDouble() ,  2, false);
    5.29      def(_bipush              , "bipush"              , "bc"   , null    , BasicType.getTInt()    ,  1, false);
    5.30      def(_sipush              , "sipush"              , "bcc"  , null    , BasicType.getTInt()    ,  1, false);
    5.31 -    def(_ldc                 , "ldc"                 , "bi"   , null    , BasicType.getTIllegal(),  1, true );
    5.32 -    def(_ldc_w               , "ldc_w"               , "bii"  , null    , BasicType.getTIllegal(),  1, true );
    5.33 -    def(_ldc2_w              , "ldc2_w"              , "bii"  , null    , BasicType.getTIllegal(),  2, true );
    5.34 +    def(_ldc                 , "ldc"                 , "bk"   , null    , BasicType.getTIllegal(),  1, true );
    5.35 +    def(_ldc_w               , "ldc_w"               , "bkk"  , null    , BasicType.getTIllegal(),  1, true );
    5.36 +    def(_ldc2_w              , "ldc2_w"              , "bkk"  , null    , BasicType.getTIllegal(),  2, true );
    5.37      def(_iload               , "iload"               , "bi"   , "wbii"  , BasicType.getTInt()    ,  1, false);
    5.38      def(_lload               , "lload"               , "bi"   , "wbii"  , BasicType.getTLong()   ,  2, false);
    5.39      def(_fload               , "fload"               , "bi"   , "wbii"  , BasicType.getTFloat()  ,  1, false);
    5.40 @@ -618,26 +621,26 @@
    5.41      def(_dreturn             , "dreturn"             , "b"    , null    , BasicType.getTDouble() , -2, true );
    5.42      def(_areturn             , "areturn"             , "b"    , null    , BasicType.getTObject() , -1, true );
    5.43      def(_return              , "return"              , "b"    , null    , BasicType.getTVoid()   ,  0, true );
    5.44 -    def(_getstatic           , "getstatic"           , "bjj"  , null    , BasicType.getTIllegal(),  1, true );
    5.45 -    def(_putstatic           , "putstatic"           , "bjj"  , null    , BasicType.getTIllegal(), -1, true );
    5.46 -    def(_getfield            , "getfield"            , "bjj"  , null    , BasicType.getTIllegal(),  0, true );
    5.47 -    def(_putfield            , "putfield"            , "bjj"  , null    , BasicType.getTIllegal(), -2, true );
    5.48 -    def(_invokevirtual       , "invokevirtual"       , "bjj"  , null    , BasicType.getTIllegal(), -1, true );
    5.49 -    def(_invokespecial       , "invokespecial"       , "bjj"  , null    , BasicType.getTIllegal(), -1, true );
    5.50 -    def(_invokestatic        , "invokestatic"        , "bjj"  , null    , BasicType.getTIllegal(),  0, true );
    5.51 -    def(_invokeinterface     , "invokeinterface"     , "bjj__", null    , BasicType.getTIllegal(), -1, true );
    5.52 -    def(_xxxunusedxxx        , "xxxunusedxxx"        , null   , null    , BasicType.getTVoid()   ,  0, false);
    5.53 -    def(_new                 , "new"                 , "bii"  , null    , BasicType.getTObject() ,  1, true );
    5.54 +    def(_getstatic           , "getstatic"           , "bJJ"  , null    , BasicType.getTIllegal(),  1, true );
    5.55 +    def(_putstatic           , "putstatic"           , "bJJ"  , null    , BasicType.getTIllegal(), -1, true );
    5.56 +    def(_getfield            , "getfield"            , "bJJ"  , null    , BasicType.getTIllegal(),  0, true );
    5.57 +    def(_putfield            , "putfield"            , "bJJ"  , null    , BasicType.getTIllegal(), -2, true );
    5.58 +    def(_invokevirtual       , "invokevirtual"       , "bJJ"  , null    , BasicType.getTIllegal(), -1, true );
    5.59 +    def(_invokespecial       , "invokespecial"       , "bJJ"  , null    , BasicType.getTIllegal(), -1, true );
    5.60 +    def(_invokestatic        , "invokestatic"        , "bJJ"  , null    , BasicType.getTIllegal(),  0, true );
    5.61 +    def(_invokeinterface     , "invokeinterface"     , "bJJ__", null    , BasicType.getTIllegal(), -1, true );
    5.62 +    def(_invokedynamic       , "invokedynamic"       , "bJJJJ", null    , BasicType.getTIllegal(), -1, true );
    5.63 +    def(_new                 , "new"                 , "bkk"  , null    , BasicType.getTObject() ,  1, true );
    5.64      def(_newarray            , "newarray"            , "bc"   , null    , BasicType.getTObject() ,  0, true );
    5.65 -    def(_anewarray           , "anewarray"           , "bii"  , null    , BasicType.getTObject() ,  0, true );
    5.66 +    def(_anewarray           , "anewarray"           , "bkk"  , null    , BasicType.getTObject() ,  0, true );
    5.67      def(_arraylength         , "arraylength"         , "b"    , null    , BasicType.getTVoid()   ,  0, true );
    5.68      def(_athrow              , "athrow"              , "b"    , null    , BasicType.getTVoid()   , -1, true );
    5.69 -    def(_checkcast           , "checkcast"           , "bii"  , null    , BasicType.getTObject() ,  0, true );
    5.70 -    def(_instanceof          , "instanceof"          , "bii"  , null    , BasicType.getTInt()    ,  0, true );
    5.71 +    def(_checkcast           , "checkcast"           , "bkk"  , null    , BasicType.getTObject() ,  0, true );
    5.72 +    def(_instanceof          , "instanceof"          , "bkk"  , null    , BasicType.getTInt()    ,  0, true );
    5.73      def(_monitorenter        , "monitorenter"        , "b"    , null    , BasicType.getTVoid()   , -1, true );
    5.74      def(_monitorexit         , "monitorexit"         , "b"    , null    , BasicType.getTVoid()   , -1, true );
    5.75      def(_wide                , "wide"                , ""     , null    , BasicType.getTVoid()   ,  0, false);
    5.76 -    def(_multianewarray      , "multianewarray"      , "biic" , null    , BasicType.getTObject() ,  1, true );
    5.77 +    def(_multianewarray      , "multianewarray"      , "bkkc" , null    , BasicType.getTObject() ,  1, true );
    5.78      def(_ifnull              , "ifnull"              , "boo"  , null    , BasicType.getTVoid()   , -1, false);
    5.79      def(_ifnonnull           , "ifnonnull"           , "boo"  , null    , BasicType.getTVoid()   , -1, false);
    5.80      def(_goto_w              , "goto_w"              , "boooo", null    , BasicType.getTVoid()   ,  0, false);
    5.81 @@ -646,38 +649,44 @@
    5.82  
    5.83      //  JVM bytecodes
    5.84      //  bytecode               bytecode name           format   wide f.   result tp               stk traps  std code
    5.85 -    def(_fast_agetfield      , "fast_agetfield"      , "bjj"  , null    , BasicType.getTObject() ,  0, true , _getfield       );
    5.86 -    def(_fast_bgetfield      , "fast_bgetfield"      , "bjj"  , null    , BasicType.getTInt()    ,  0, true , _getfield       );
    5.87 -    def(_fast_cgetfield      , "fast_cgetfield"      , "bjj"  , null    , BasicType.getTChar()   ,  0, true , _getfield       );
    5.88 -    def(_fast_dgetfield      , "fast_dgetfield"      , "bjj"  , null    , BasicType.getTDouble() ,  0, true , _getfield       );
    5.89 -    def(_fast_fgetfield      , "fast_fgetfield"      , "bjj"  , null    , BasicType.getTFloat()  ,  0, true , _getfield       );
    5.90 -    def(_fast_igetfield      , "fast_igetfield"      , "bjj"  , null    , BasicType.getTInt()    ,  0, true , _getfield       );
    5.91 -    def(_fast_lgetfield      , "fast_lgetfield"      , "bjj"  , null    , BasicType.getTLong()   ,  0, true , _getfield       );
    5.92 -    def(_fast_sgetfield      , "fast_sgetfield"      , "bjj"  , null    , BasicType.getTShort()  ,  0, true , _getfield       );
    5.93 +    def(_fast_agetfield      , "fast_agetfield"      , "bJJ"  , null    , BasicType.getTObject() ,  0, true , _getfield       );
    5.94 +    def(_fast_bgetfield      , "fast_bgetfield"      , "bJJ"  , null    , BasicType.getTInt()    ,  0, true , _getfield       );
    5.95 +    def(_fast_cgetfield      , "fast_cgetfield"      , "bJJ"  , null    , BasicType.getTChar()   ,  0, true , _getfield       );
    5.96 +    def(_fast_dgetfield      , "fast_dgetfield"      , "bJJ"  , null    , BasicType.getTDouble() ,  0, true , _getfield       );
    5.97 +    def(_fast_fgetfield      , "fast_fgetfield"      , "bJJ"  , null    , BasicType.getTFloat()  ,  0, true , _getfield       );
    5.98 +    def(_fast_igetfield      , "fast_igetfield"      , "bJJ"  , null    , BasicType.getTInt()    ,  0, true , _getfield       );
    5.99 +    def(_fast_lgetfield      , "fast_lgetfield"      , "bJJ"  , null    , BasicType.getTLong()   ,  0, true , _getfield       );
   5.100 +    def(_fast_sgetfield      , "fast_sgetfield"      , "bJJ"  , null    , BasicType.getTShort()  ,  0, true , _getfield       );
   5.101  
   5.102 -    def(_fast_aputfield      , "fast_aputfield"      , "bjj"  , null    , BasicType.getTObject() ,  0, true , _putfield       );
   5.103 -    def(_fast_bputfield      , "fast_bputfield"      , "bjj"  , null    , BasicType.getTInt()    ,  0, true , _putfield       );
   5.104 -    def(_fast_cputfield      , "fast_cputfield"      , "bjj"  , null    , BasicType.getTChar()   ,  0, true , _putfield       );
   5.105 -    def(_fast_dputfield      , "fast_dputfield"      , "bjj"  , null    , BasicType.getTDouble() ,  0, true , _putfield       );
   5.106 -    def(_fast_fputfield      , "fast_fputfield"      , "bjj"  , null    , BasicType.getTFloat()  ,  0, true , _putfield       );
   5.107 -    def(_fast_iputfield      , "fast_iputfield"      , "bjj"  , null    , BasicType.getTInt()    ,  0, true , _putfield       );
   5.108 -    def(_fast_lputfield      , "fast_lputfield"      , "bjj"  , null    , BasicType.getTLong()   ,  0, true , _putfield       );
   5.109 -    def(_fast_sputfield      , "fast_sputfield"      , "bjj"  , null    , BasicType.getTShort()  ,  0, true , _putfield       );
   5.110 +    def(_fast_aputfield      , "fast_aputfield"      , "bJJ"  , null    , BasicType.getTObject() ,  0, true , _putfield       );
   5.111 +    def(_fast_bputfield      , "fast_bputfield"      , "bJJ"  , null    , BasicType.getTInt()    ,  0, true , _putfield       );
   5.112 +    def(_fast_cputfield      , "fast_cputfield"      , "bJJ"  , null    , BasicType.getTChar()   ,  0, true , _putfield       );
   5.113 +    def(_fast_dputfield      , "fast_dputfield"      , "bJJ"  , null    , BasicType.getTDouble() ,  0, true , _putfield       );
   5.114 +    def(_fast_fputfield      , "fast_fputfield"      , "bJJ"  , null    , BasicType.getTFloat()  ,  0, true , _putfield       );
   5.115 +    def(_fast_iputfield      , "fast_iputfield"      , "bJJ"  , null    , BasicType.getTInt()    ,  0, true , _putfield       );
   5.116 +    def(_fast_lputfield      , "fast_lputfield"      , "bJJ"  , null    , BasicType.getTLong()   ,  0, true , _putfield       );
   5.117 +    def(_fast_sputfield      , "fast_sputfield"      , "bJJ"  , null    , BasicType.getTShort()  ,  0, true , _putfield       );
   5.118  
   5.119      def(_fast_aload_0        , "fast_aload_0"        , "b"    , null    , BasicType.getTObject() ,  1, true , _aload_0        );
   5.120 -    def(_fast_iaccess_0      , "fast_iaccess_0"      , "b_jj" , null    , BasicType.getTInt()    ,  1, true , _aload_0        );
   5.121 -    def(_fast_aaccess_0      , "fast_aaccess_0"      , "b_jj" , null    , BasicType.getTObject() ,  1, true , _aload_0        );
   5.122 -    def(_fast_faccess_0      , "fast_faccess_0"      , "b_jj" , null    , BasicType.getTObject() ,  1, true , _aload_0        );
   5.123 +    def(_fast_iaccess_0      , "fast_iaccess_0"      , "b_JJ" , null    , BasicType.getTInt()    ,  1, true , _aload_0        );
   5.124 +    def(_fast_aaccess_0      , "fast_aaccess_0"      , "b_JJ" , null    , BasicType.getTObject() ,  1, true , _aload_0        );
   5.125 +    def(_fast_faccess_0      , "fast_faccess_0"      , "b_JJ" , null    , BasicType.getTObject() ,  1, true , _aload_0        );
   5.126  
   5.127      def(_fast_iload          , "fast_iload"          , "bi"   , null    , BasicType.getTInt()    ,  1, false, _iload);
   5.128      def(_fast_iload2         , "fast_iload2"         , "bi_i" , null    , BasicType.getTInt()    ,  2, false, _iload);
   5.129      def(_fast_icaload        , "fast_icaload"        , "bi_"  , null    , BasicType.getTInt()    ,  0, false, _iload);
   5.130  
   5.131      // Faster method invocation.
   5.132 -    def(_fast_invokevfinal   , "fast_invokevfinal"   , "bjj"  , null    , BasicType.getTIllegal(), -1, true, _invokevirtual);
   5.133 +    def(_fast_invokevfinal   , "fast_invokevfinal"   , "bJJ"  , null    , BasicType.getTIllegal(), -1, true, _invokevirtual);
   5.134  
   5.135      def(_fast_linearswitch   , "fast_linearswitch"   , ""     , null    , BasicType.getTVoid()   , -1, false, _lookupswitch   );
   5.136      def(_fast_binaryswitch   , "fast_binaryswitch"   , ""     , null    , BasicType.getTVoid()   , -1, false, _lookupswitch   );
   5.137 +
   5.138 +    def(_return_register_finalizer, "return_register_finalizer", "b"    , null    , BasicType.getTVoid()   , 0, true, _return );
   5.139 +
   5.140 +    def(_fast_aldc           , "fast_aldc"           , "bj"   , null    , BasicType.getTObject(),   1, true,  _ldc   );
   5.141 +    def(_fast_aldc_w         , "fast_aldc_w"         , "bJJ"  , null    , BasicType.getTObject(),   1, true,  _ldc_w );
   5.142 +
   5.143      def(_shouldnotreachhere  , "_shouldnotreachhere" , "b"    , null    , BasicType.getTVoid()   ,  0, false);
   5.144  
   5.145      if (Assert.ASSERTS_ENABLED) {
     6.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Thu Jun 24 15:38:42 2010 -0700
     6.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java	Mon Jun 28 12:03:05 2010 -0400
     6.3 @@ -152,7 +152,7 @@
     6.4      return res;
     6.5    }
     6.6  
     6.7 -  public int getNameAndTypeAt(int which) {
     6.8 +  public int[] getNameAndTypeAt(int which) {
     6.9      if (Assert.ASSERTS_ENABLED) {
    6.10        Assert.that(getTagAt(which).isNameAndType(), "Corrupted constant pool");
    6.11      }
    6.12 @@ -160,18 +160,16 @@
    6.13      if (DEBUG) {
    6.14        System.err.println("ConstantPool.getNameAndTypeAt(" + which + "): result = " + i);
    6.15      }
    6.16 -    return i;
    6.17 +    return new int[] { extractLowShortFromInt(i), extractHighShortFromInt(i) };
    6.18    }
    6.19  
    6.20    public Symbol getNameRefAt(int which) {
    6.21 -    int refIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which));
    6.22 -    int nameIndex = extractLowShortFromInt(refIndex);
    6.23 +    int nameIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[0];
    6.24      return getSymbolAt(nameIndex);
    6.25    }
    6.26  
    6.27    public Symbol getSignatureRefAt(int which) {
    6.28 -    int refIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which));
    6.29 -    int sigIndex = extractHighShortFromInt(refIndex);
    6.30 +    int sigIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[1];
    6.31      return getSymbolAt(sigIndex);
    6.32    }
    6.33  
    6.34 @@ -220,11 +218,11 @@
    6.35  
    6.36    /** Lookup for entries consisting of (name_index, signature_index) */
    6.37    public int getNameRefIndexAt(int index) {
    6.38 -    int refIndex = getNameAndTypeAt(index);
    6.39 +    int[] refIndex = getNameAndTypeAt(index);
    6.40      if (DEBUG) {
    6.41 -      System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): refIndex = " + refIndex);
    6.42 +      System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): refIndex = " + refIndex[0]+"/"+refIndex[1]);
    6.43      }
    6.44 -    int i = extractLowShortFromInt(refIndex);
    6.45 +    int i = refIndex[0];
    6.46      if (DEBUG) {
    6.47        System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): result = " + i);
    6.48      }
    6.49 @@ -233,17 +231,53 @@
    6.50  
    6.51    /** Lookup for entries consisting of (name_index, signature_index) */
    6.52    public int getSignatureRefIndexAt(int index) {
    6.53 -    int refIndex = getNameAndTypeAt(index);
    6.54 +    int[] refIndex = getNameAndTypeAt(index);
    6.55      if (DEBUG) {
    6.56 -      System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): refIndex = " + refIndex);
    6.57 +      System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): refIndex = " + refIndex[0]+"/"+refIndex[1]);
    6.58      }
    6.59 -    int i = extractHighShortFromInt(refIndex);
    6.60 +    int i = refIndex[1];
    6.61      if (DEBUG) {
    6.62        System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): result = " + i);
    6.63      }
    6.64      return i;
    6.65    }
    6.66  
    6.67 +  /** Lookup for MethodHandle entries. */
    6.68 +  public int getMethodHandleIndexAt(int i) {
    6.69 +    if (Assert.ASSERTS_ENABLED) {
    6.70 +      Assert.that(getTagAt(i).isMethodHandle(), "Corrupted constant pool");
    6.71 +    }
    6.72 +    int res = extractHighShortFromInt(getIntAt(i));
    6.73 +    if (DEBUG) {
    6.74 +      System.err.println("ConstantPool.getMethodHandleIndexAt(" + i + "): result = " + res);
    6.75 +    }
    6.76 +    return res;
    6.77 +  }
    6.78 +
    6.79 +  /** Lookup for MethodHandle entries. */
    6.80 +  public int getMethodHandleRefKindAt(int i) {
    6.81 +    if (Assert.ASSERTS_ENABLED) {
    6.82 +      Assert.that(getTagAt(i).isMethodHandle(), "Corrupted constant pool");
    6.83 +    }
    6.84 +    int res = extractLowShortFromInt(getIntAt(i));
    6.85 +    if (DEBUG) {
    6.86 +      System.err.println("ConstantPool.getMethodHandleRefKindAt(" + i + "): result = " + res);
    6.87 +    }
    6.88 +    return res;
    6.89 +  }
    6.90 +
    6.91 +  /** Lookup for MethodType entries. */
    6.92 +  public int getMethodTypeIndexAt(int i) {
    6.93 +    if (Assert.ASSERTS_ENABLED) {
    6.94 +      Assert.that(getTagAt(i).isMethodType(), "Corrupted constant pool");
    6.95 +    }
    6.96 +    int res = getIntAt(i);
    6.97 +    if (DEBUG) {
    6.98 +      System.err.println("ConstantPool.getMethodHandleTypeAt(" + i + "): result = " + res);
    6.99 +    }
   6.100 +    return res;
   6.101 +  }
   6.102 +
   6.103    final private static String[] nameForTag = new String[] {
   6.104    };
   6.105  
   6.106 @@ -261,6 +295,8 @@
   6.107      case JVM_CONSTANT_Methodref:          return "JVM_CONSTANT_Methodref";
   6.108      case JVM_CONSTANT_InterfaceMethodref: return "JVM_CONSTANT_InterfaceMethodref";
   6.109      case JVM_CONSTANT_NameAndType:        return "JVM_CONSTANT_NameAndType";
   6.110 +    case JVM_CONSTANT_MethodHandle:       return "JVM_CONSTANT_MethodHandle";
   6.111 +    case JVM_CONSTANT_MethodType:         return "JVM_CONSTANT_MethodType";
   6.112      case JVM_CONSTANT_Invalid:            return "JVM_CONSTANT_Invalid";
   6.113      case JVM_CONSTANT_UnresolvedClass:    return "JVM_CONSTANT_UnresolvedClass";
   6.114      case JVM_CONSTANT_UnresolvedClassInError:    return "JVM_CONSTANT_UnresolvedClassInError";
   6.115 @@ -317,6 +353,8 @@
   6.116          case JVM_CONSTANT_Methodref:
   6.117          case JVM_CONSTANT_InterfaceMethodref:
   6.118          case JVM_CONSTANT_NameAndType:
   6.119 +        case JVM_CONSTANT_MethodHandle:
   6.120 +        case JVM_CONSTANT_MethodType:
   6.121            visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
   6.122            break;
   6.123          }
   6.124 @@ -467,6 +505,18 @@
   6.125                                            + ", type = " + signatureIndex);
   6.126                    break;
   6.127                }
   6.128 +
   6.129 +              case JVM_CONSTANT_MethodHandle: {
   6.130 +                  dos.writeByte(cpConstType);
   6.131 +                  int value = getIntAt(ci);
   6.132 +                  short nameIndex = (short) extractLowShortFromInt(value);
   6.133 +                  short signatureIndex = (short) extractHighShortFromInt(value);
   6.134 +                  dos.writeShort(nameIndex);
   6.135 +                  dos.writeShort(signatureIndex);
   6.136 +                  if (DEBUG) debugMessage("CP[" + ci + "] = N&T name = " + nameIndex
   6.137 +                                          + ", type = " + signatureIndex);
   6.138 +                  break;
   6.139 +              }
   6.140                default:
   6.141                    throw new InternalError("unknown tag: " + cpConstType);
   6.142            } // switch
   6.143 @@ -488,10 +538,12 @@
   6.144    //
   6.145  
   6.146    private static int extractHighShortFromInt(int val) {
   6.147 +    // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc.
   6.148      return (val >> 16) & 0xFFFF;
   6.149    }
   6.150  
   6.151    private static int extractLowShortFromInt(int val) {
   6.152 +    // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc.
   6.153      return val & 0xFFFF;
   6.154    }
   6.155  }
     7.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java	Thu Jun 24 15:38:42 2010 -0700
     7.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java	Mon Jun 28 12:03:05 2010 -0400
     7.3 @@ -78,6 +78,31 @@
     7.4      return new ConstantPoolCacheEntry(this, i);
     7.5    }
     7.6  
     7.7 +  public static boolean isSecondaryIndex(int i)     { return (i < 0); }
     7.8 +  public static int     decodeSecondaryIndex(int i) { return  isSecondaryIndex(i) ? ~i : i; }
     7.9 +  public static int     encodeSecondaryIndex(int i) { return !isSecondaryIndex(i) ? ~i : i; }
    7.10 +
    7.11 +  // secondary entries hold invokedynamic call site bindings
    7.12 +  public ConstantPoolCacheEntry getSecondaryEntryAt(int i) {
    7.13 +    ConstantPoolCacheEntry e = new ConstantPoolCacheEntry(this, decodeSecondaryIndex(i));
    7.14 +    if (Assert.ASSERTS_ENABLED) {
    7.15 +      Assert.that(e.isSecondaryEntry(), "must be a secondary entry");
    7.16 +    }
    7.17 +    return e;
    7.18 +  }
    7.19 +
    7.20 +  public ConstantPoolCacheEntry getMainEntryAt(int i) {
    7.21 +    if (isSecondaryIndex(i)) {
    7.22 +      // run through an extra level of indirection:
    7.23 +      i = getSecondaryEntryAt(i).getMainEntryIndex();
    7.24 +    }
    7.25 +    ConstantPoolCacheEntry e = new ConstantPoolCacheEntry(this, i);
    7.26 +    if (Assert.ASSERTS_ENABLED) {
    7.27 +      Assert.that(!e.isSecondaryEntry(), "must not be a secondary entry");
    7.28 +    }
    7.29 +    return e;
    7.30 +  }
    7.31 +
    7.32    public int getIntAt(int entry, int fld) {
    7.33      //alignObjectSize ?
    7.34      long offset = baseOffset + /*alignObjectSize*/entry * elementSize + fld* getHeap().getIntSize();
     8.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCacheEntry.java	Thu Jun 24 15:38:42 2010 -0700
     8.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCacheEntry.java	Mon Jun 28 12:03:05 2010 -0400
     8.3 @@ -28,6 +28,7 @@
     8.4  import sun.jvm.hotspot.debugger.*;
     8.5  import sun.jvm.hotspot.runtime.*;
     8.6  import sun.jvm.hotspot.types.*;
     8.7 +import sun.jvm.hotspot.utilities.*;
     8.8  
     8.9  public class ConstantPoolCacheEntry {
    8.10    private static long          size;
    8.11 @@ -67,9 +68,23 @@
    8.12    }
    8.13  
    8.14    public int getConstantPoolIndex() {
    8.15 +    if (Assert.ASSERTS_ENABLED) {
    8.16 +      Assert.that(!isSecondaryEntry(), "must not be a secondary CP entry");
    8.17 +    }
    8.18      return (int) (getIndices() & 0xFFFF);
    8.19    }
    8.20  
    8.21 +  public boolean isSecondaryEntry() {
    8.22 +    return (getIndices() & 0xFFFF) == 0;
    8.23 +  }
    8.24 +
    8.25 +  public int getMainEntryIndex() {
    8.26 +    if (Assert.ASSERTS_ENABLED) {
    8.27 +      Assert.that(isSecondaryEntry(), "must be a secondary CP entry");
    8.28 +    }
    8.29 +    return (int) (getIndices() >>> 16);
    8.30 +  }
    8.31 +
    8.32    private long getIndices() {
    8.33        return cp.getHandle().getCIntegerAt(indices.getOffset() + offset, indices.getSize(), indices.isUnsigned());
    8.34    }
     9.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java	Thu Jun 24 15:38:42 2010 -0700
     9.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java	Mon Jun 28 12:03:05 2010 -0400
     9.3 @@ -566,6 +566,7 @@
     9.4        case Bytecodes._invokespecial:
     9.5        case Bytecodes._invokestatic:
     9.6        case Bytecodes._invokeinterface:
     9.7 +      case Bytecodes._invokedynamic:
     9.8          // FIXME: print signature of referenced method (need more
     9.9          // accessors in ConstantPool and ConstantPoolCache)
    9.10          int idx = currentBC.getIndexBig();
    9.11 @@ -605,6 +606,7 @@
    9.12        case Bytecodes._invokespecial:
    9.13        case Bytecodes._invokestatic:
    9.14        case Bytecodes._invokeinterface:
    9.15 +      case Bytecodes._invokedynamic:
    9.16          // FIXME: print signature of referenced method (need more
    9.17          // accessors in ConstantPool and ConstantPoolCache)
    9.18          int idx = currentBC.getIndexBig();
    9.19 @@ -1134,6 +1136,7 @@
    9.20        case Bytecodes._invokespecial:
    9.21        case Bytecodes._invokestatic:
    9.22        case Bytecodes._invokeinterface:
    9.23 +      case Bytecodes._invokedynamic:
    9.24          _itr_send = itr;
    9.25          _report_result_for_send = true;
    9.26          break;
    9.27 @@ -1379,6 +1382,7 @@
    9.28      case Bytecodes._invokevirtual:
    9.29      case Bytecodes._invokespecial:     doMethod(false, false, itr.getIndexBig(), itr.bci()); break;
    9.30      case Bytecodes._invokestatic:      doMethod(true,  false, itr.getIndexBig(), itr.bci()); break;
    9.31 +    case Bytecodes._invokedynamic:     doMethod(false, true,  itr.getIndexBig(), itr.bci()); break;
    9.32      case Bytecodes._invokeinterface:   doMethod(false, true,  itr.getIndexBig(), itr.bci()); break;
    9.33      case Bytecodes._newarray:
    9.34      case Bytecodes._anewarray:         ppNewRef(vCTS, itr.bci()); break;
    9.35 @@ -1725,7 +1729,7 @@
    9.36    void  doMethod                            (boolean is_static, boolean is_interface, int idx, int bci) {
    9.37      // Dig up signature for field in constant pool
    9.38      ConstantPool cp       = _method.getConstants();
    9.39 -    int nameAndTypeIdx    = cp.getNameAndTypeRefIndexAt(idx);
    9.40 +    int nameAndTypeIdx    = cp.getTagAt(idx).isNameAndType() ? idx : cp.getNameAndTypeRefIndexAt(idx);
    9.41      int signatureIdx      = cp.getSignatureRefIndexAt(nameAndTypeIdx);
    9.42      Symbol signature      = cp.getSymbolAt(signatureIdx);
    9.43  
    10.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java	Thu Jun 24 15:38:42 2010 -0700
    10.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java	Mon Jun 28 12:03:05 2010 -0400
    10.3 @@ -40,6 +40,19 @@
    10.4      public static final int JVM_CONSTANT_Methodref          = 10;
    10.5      public static final int JVM_CONSTANT_InterfaceMethodref = 11;
    10.6      public static final int JVM_CONSTANT_NameAndType        = 12;
    10.7 +    public static final int JVM_CONSTANT_MethodHandle       = 15;
    10.8 +    public static final int JVM_CONSTANT_MethodType         = 16;
    10.9 +
   10.10 +    // JVM_CONSTANT_MethodHandle subtypes
   10.11 +    public static final int JVM_REF_getField                = 1;
   10.12 +    public static final int JVM_REF_getStatic               = 2;
   10.13 +    public static final int JVM_REF_putField                = 3;
   10.14 +    public static final int JVM_REF_putStatic               = 4;
   10.15 +    public static final int JVM_REF_invokeVirtual           = 5;
   10.16 +    public static final int JVM_REF_invokeStatic            = 6;
   10.17 +    public static final int JVM_REF_invokeSpecial           = 7;
   10.18 +    public static final int JVM_REF_newInvokeSpecial        = 8;
   10.19 +    public static final int JVM_REF_invokeInterface         = 9;
   10.20  
   10.21      // HotSpot specific constant pool constant types.
   10.22  
    11.1 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java	Thu Jun 24 15:38:42 2010 -0700
    11.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java	Mon Jun 28 12:03:05 2010 -0400
    11.3 @@ -54,14 +54,34 @@
    11.4  
    11.5      }
    11.6  
    11.7 -    protected short getConstantPoolIndex(int bci) {
    11.8 +    protected short getConstantPoolIndex(int rawcode, int bci) {
    11.9         // get ConstantPool index from ConstantPoolCacheIndex at given bci
   11.10 -       short cpCacheIndex = method.getBytecodeShortArg(bci);
   11.11 +       String fmt = Bytecodes.format(rawcode);
   11.12 +       int cpCacheIndex;
   11.13 +       switch (fmt.length()) {
   11.14 +       case 2: cpCacheIndex = method.getBytecodeByteArg(bci); break;
   11.15 +       case 3: cpCacheIndex = method.getBytecodeShortArg(bci); break;
   11.16 +       case 5:
   11.17 +           if (fmt.indexOf("__") >= 0)
   11.18 +               cpCacheIndex = method.getBytecodeShortArg(bci);
   11.19 +           else
   11.20 +               cpCacheIndex = method.getBytecodeIntArg(bci);
   11.21 +           break;
   11.22 +       default: throw new IllegalArgumentException();
   11.23 +       }
   11.24         if (cpCache == null) {
   11.25 -          return cpCacheIndex;
   11.26 +          return (short) cpCacheIndex;
   11.27 +       } else if (fmt.indexOf("JJJJ") >= 0) {
   11.28 +          // change byte-ordering and go via secondary cache entry
   11.29 +          return (short) cpCache.getMainEntryAt(bytes.swapInt(cpCacheIndex)).getConstantPoolIndex();
   11.30 +       } else if (fmt.indexOf("JJ") >= 0) {
   11.31 +          // change byte-ordering and go via cache
   11.32 +          return (short) cpCache.getEntryAt((int) (0xFFFF & bytes.swapShort((short)cpCacheIndex))).getConstantPoolIndex();
   11.33 +       } else if (fmt.indexOf("j") >= 0) {
   11.34 +          // go via cache
   11.35 +          return (short) cpCache.getEntryAt((int) (0xFF & cpCacheIndex)).getConstantPoolIndex();
   11.36         } else {
   11.37 -          // change byte-ordering and go via cache
   11.38 -          return (short) cpCache.getEntryAt((int) (0xFFFF & bytes.swapShort(cpCacheIndex))).getConstantPoolIndex();
   11.39 +          return (short) cpCacheIndex;
   11.40         }
   11.41      }
   11.42  
   11.43 @@ -100,10 +120,31 @@
   11.44                  case Bytecodes._invokespecial:
   11.45                  case Bytecodes._invokestatic:
   11.46                  case Bytecodes._invokeinterface: {
   11.47 -                    cpoolIndex = getConstantPoolIndex(bci + 1);
   11.48 +                    cpoolIndex = getConstantPoolIndex(hotspotcode, bci + 1);
   11.49                      writeShort(code, bci + 1, cpoolIndex);
   11.50                      break;
   11.51                  }
   11.52 +
   11.53 +                case Bytecodes._invokedynamic:
   11.54 +                    cpoolIndex = getConstantPoolIndex(hotspotcode, bci + 1);
   11.55 +                    writeShort(code, bci + 1, cpoolIndex);
   11.56 +                    writeShort(code, bci + 3, (short)0);  // clear out trailing bytes
   11.57 +                    break;
   11.58 +
   11.59 +                case Bytecodes._ldc_w:
   11.60 +                    if (hotspotcode != bytecode) {
   11.61 +                        // fast_aldc_w puts constant in CP cache
   11.62 +                        cpoolIndex = getConstantPoolIndex(hotspotcode, bci + 1);
   11.63 +                        writeShort(code, bci + 1, cpoolIndex);
   11.64 +                    }
   11.65 +                    break;
   11.66 +                case Bytecodes._ldc:
   11.67 +                    if (hotspotcode != bytecode) {
   11.68 +                        // fast_aldc puts constant in CP cache
   11.69 +                        cpoolIndex = getConstantPoolIndex(hotspotcode, bci + 1);
   11.70 +                        code[bci + 1] = (byte)(cpoolIndex);
   11.71 +                    }
   11.72 +                    break;
   11.73              }
   11.74  
   11.75              len = Bytecodes.lengthFor(bytecode);
    12.1 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Thu Jun 24 15:38:42 2010 -0700
    12.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java	Mon Jun 28 12:03:05 2010 -0400
    12.3 @@ -61,10 +61,12 @@
    12.4      protected short  _signatureIndex;
    12.5  
    12.6      protected static int extractHighShortFromInt(int val) {
    12.7 +        // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc.
    12.8          return (val >> 16) & 0xFFFF;
    12.9      }
   12.10  
   12.11      protected static int extractLowShortFromInt(int val) {
   12.12 +        // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc.
   12.13          return val & 0xFFFF;
   12.14      }
   12.15  
   12.16 @@ -297,6 +299,28 @@
   12.17                                          + ", type = " + signatureIndex);
   12.18                       break;
   12.19                  }
   12.20 +
   12.21 +                case JVM_CONSTANT_MethodHandle: {
   12.22 +                     dos.writeByte(cpConstType);
   12.23 +                     int value = cpool.getIntAt(ci);
   12.24 +                     short refIndex = (short) extractHighShortFromInt(value);
   12.25 +                     byte  refKind  = (byte)  extractLowShortFromInt(value);
   12.26 +                     dos.writeByte(refKind);
   12.27 +                     dos.writeShort(refIndex);
   12.28 +                     if (DEBUG) debugMessage("CP[" + ci + "] = MH index = " + refIndex
   12.29 +                                        + ", kind = " + refKind);
   12.30 +                     break;
   12.31 +                }
   12.32 +
   12.33 +                case JVM_CONSTANT_MethodType: {
   12.34 +                     dos.writeByte(cpConstType);
   12.35 +                     int value = cpool.getIntAt(ci);
   12.36 +                     short refIndex = (short) value;
   12.37 +                     dos.writeShort(refIndex);
   12.38 +                     if (DEBUG) debugMessage("CP[" + ci + "] = MT index = " + refIndex);
   12.39 +                     break;
   12.40 +                }
   12.41 +
   12.42                  default:
   12.43                    throw new InternalError("Unknown tag: " + cpConstType);
   12.44              } // switch
    13.1 --- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Thu Jun 24 15:38:42 2010 -0700
    13.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Mon Jun 28 12:03:05 2010 -0400
    13.3 @@ -572,6 +572,16 @@
    13.4                 buf.cell(Integer.toString(cpool.getIntAt(index)));
    13.5                 break;
    13.6  
    13.7 +            case JVM_CONSTANT_MethodHandle:
    13.8 +               buf.cell("JVM_CONSTANT_MethodHandle");
    13.9 +               buf.cell(genLowHighShort(cpool.getIntAt(index)));
   13.10 +               break;
   13.11 +
   13.12 +            case JVM_CONSTANT_MethodType:
   13.13 +               buf.cell("JVM_CONSTANT_MethodType");
   13.14 +               buf.cell(Integer.toString(cpool.getIntAt(index)));
   13.15 +               break;
   13.16 +
   13.17              default:
   13.18                 throw new InternalError("unknown tag: " + ctag);
   13.19           }
    14.1 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java	Thu Jun 24 15:38:42 2010 -0700
    14.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java	Mon Jun 28 12:03:05 2010 -0400
    14.3 @@ -38,12 +38,26 @@
    14.4    private static int JVM_CONSTANT_Methodref               = 10;
    14.5    private static int JVM_CONSTANT_InterfaceMethodref      = 11;
    14.6    private static int JVM_CONSTANT_NameAndType             = 12;
    14.7 +  private static int JVM_CONSTANT_MethodHandle            = 15;  // JSR 292
    14.8 +  private static int JVM_CONSTANT_MethodType              = 16;  // JSR 292
    14.9    private static int JVM_CONSTANT_Invalid                 = 0;   // For bad value initialization
   14.10    private static int JVM_CONSTANT_UnresolvedClass         = 100; // Temporary tag until actual use
   14.11    private static int JVM_CONSTANT_ClassIndex              = 101; // Temporary tag while constructing constant pool
   14.12    private static int JVM_CONSTANT_UnresolvedString        = 102; // Temporary tag until actual use
   14.13    private static int JVM_CONSTANT_StringIndex             = 103; // Temporary tag while constructing constant pool
   14.14    private static int JVM_CONSTANT_UnresolvedClassInError  = 104; // Resolution failed
   14.15 +  private static int JVM_CONSTANT_Object                  = 105; // Required for BoundMethodHandle arguments.
   14.16 +
   14.17 +  // JVM_CONSTANT_MethodHandle subtypes //FIXME: connect these to data structure
   14.18 +  private static int JVM_REF_getField                = 1;
   14.19 +  private static int JVM_REF_getStatic               = 2;
   14.20 +  private static int JVM_REF_putField                = 3;
   14.21 +  private static int JVM_REF_putStatic               = 4;
   14.22 +  private static int JVM_REF_invokeVirtual           = 5;
   14.23 +  private static int JVM_REF_invokeStatic            = 6;
   14.24 +  private static int JVM_REF_invokeSpecial           = 7;
   14.25 +  private static int JVM_REF_newInvokeSpecial        = 8;
   14.26 +  private static int JVM_REF_invokeInterface         = 9;
   14.27  
   14.28    private byte tag;
   14.29  
   14.30 @@ -62,6 +76,8 @@
   14.31    public boolean isDouble()           { return tag == JVM_CONSTANT_Double; }
   14.32    public boolean isNameAndType()      { return tag == JVM_CONSTANT_NameAndType; }
   14.33    public boolean isUtf8()             { return tag == JVM_CONSTANT_Utf8; }
   14.34 +  public boolean isMethodHandle()     { return tag == JVM_CONSTANT_MethodHandle; }
   14.35 +  public boolean isMethodType()       { return tag == JVM_CONSTANT_MethodType; }
   14.36  
   14.37    public boolean isInvalid()          { return tag == JVM_CONSTANT_Invalid; }
   14.38  
   14.39 @@ -73,6 +89,8 @@
   14.40    public boolean isUnresolvedString()       { return tag == JVM_CONSTANT_UnresolvedString; }
   14.41    public boolean isStringIndex()            { return tag == JVM_CONSTANT_StringIndex; }
   14.42  
   14.43 +  public boolean isObject()                 { return tag == JVM_CONSTANT_Object; }
   14.44 +
   14.45    public boolean isKlassReference()   { return isKlassIndex() || isUnresolvedKlass(); }
   14.46    public boolean isFieldOrMethod()    { return isField() || isMethod() || isInterfaceMethod(); }
   14.47    public boolean isSymbol()           { return isUtf8(); }
    15.1 --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Thu Jun 24 15:38:42 2010 -0700
    15.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js	Mon Jun 28 12:03:05 2010 -0400
    15.3 @@ -825,6 +825,8 @@
    15.4     }
    15.5     writeln("");
    15.6     disAsm.decode(new sapkg.interpreter.BytecodeVisitor() {
    15.7 +                    prologue: function(method) { },
    15.8 +                    epilogue: function() { },
    15.9                      visit: function(bytecode) {
   15.10                         if (hasLines) {
   15.11                            var line = method.getLineNumberFromBCI(bci);
    16.1 --- a/make/linux/makefiles/adlc.make	Thu Jun 24 15:38:42 2010 -0700
    16.2 +++ b/make/linux/makefiles/adlc.make	Mon Jun 28 12:03:05 2010 -0400
    16.3 @@ -138,7 +138,11 @@
    16.4  
    16.5  # Normally, debugging is done directly on the ad_<arch>*.cpp files.
    16.6  # But -g will put #line directives in those files pointing back to <arch>.ad.
    16.7 +# Some builds of gcc 3.2 have a bug that gets tickled by the extra #line directives
    16.8 +# so skip it for 3.2 and ealier.
    16.9 +ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 3 \) \| \( \( $(CC_VER_MAJOR) = 3 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
   16.10  ADLCFLAGS += -g
   16.11 +endif
   16.12  
   16.13  ifdef LP64
   16.14  ADLCFLAGS += -D_LP64
    17.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Jun 24 15:38:42 2010 -0700
    17.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Mon Jun 28 12:03:05 2010 -0400
    17.3 @@ -318,6 +318,31 @@
    17.4    __ bind(exit);
    17.5  }
    17.6  
    17.7 +// Fast path for caching oop constants.
    17.8 +// %%% We should use this to handle Class and String constants also.
    17.9 +// %%% It will simplify the ldc/primitive path considerably.
   17.10 +void TemplateTable::fast_aldc(bool wide) {
   17.11 +  transition(vtos, atos);
   17.12 +
   17.13 +  if (!EnableMethodHandles) {
   17.14 +    // We should not encounter this bytecode if !EnableMethodHandles.
   17.15 +    // The verifier will stop it.  However, if we get past the verifier,
   17.16 +    // this will stop the thread in a reasonable way, without crashing the JVM.
   17.17 +    __ call_VM(noreg, CAST_FROM_FN_PTR(address,
   17.18 +                     InterpreterRuntime::throw_IncompatibleClassChangeError));
   17.19 +    // the call_VM checks for exception, so we should never return here.
   17.20 +    __ should_not_reach_here();
   17.21 +    return;
   17.22 +  }
   17.23 +
   17.24 +  Register Rcache = G3_scratch;
   17.25 +  Register Rscratch = G4_scratch;
   17.26 +
   17.27 +  resolve_cache_and_index(f1_oop, Otos_i, Rcache, Rscratch, wide ? sizeof(u2) : sizeof(u1));
   17.28 +
   17.29 +  __ verify_oop(Otos_i);
   17.30 +}
   17.31 +
   17.32  void TemplateTable::ldc2_w() {
   17.33    transition(vtos, vtos);
   17.34    Label retry, resolved, Long, exit;
   17.35 @@ -1994,6 +2019,8 @@
   17.36      case Bytecodes::_invokestatic   : // fall through
   17.37      case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;
   17.38      case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);  break;
   17.39 +    case Bytecodes::_fast_aldc      : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
   17.40 +    case Bytecodes::_fast_aldc_w    : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
   17.41      default                         : ShouldNotReachHere();                                 break;
   17.42    }
   17.43    // first time invocation - must resolve first
    18.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Thu Jun 24 15:38:42 2010 -0700
    18.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Mon Jun 28 12:03:05 2010 -0400
    18.3 @@ -375,6 +375,32 @@
    18.4    __ bind(Done);
    18.5  }
    18.6  
    18.7 +// Fast path for caching oop constants.
    18.8 +// %%% We should use this to handle Class and String constants also.
    18.9 +// %%% It will simplify the ldc/primitive path considerably.
   18.10 +void TemplateTable::fast_aldc(bool wide) {
   18.11 +  transition(vtos, atos);
   18.12 +
   18.13 +  if (!EnableMethodHandles) {
   18.14 +    // We should not encounter this bytecode if !EnableMethodHandles.
   18.15 +    // The verifier will stop it.  However, if we get past the verifier,
   18.16 +    // this will stop the thread in a reasonable way, without crashing the JVM.
   18.17 +    __ call_VM(noreg, CAST_FROM_FN_PTR(address,
   18.18 +                     InterpreterRuntime::throw_IncompatibleClassChangeError));
   18.19 +    // the call_VM checks for exception, so we should never return here.
   18.20 +    __ should_not_reach_here();
   18.21 +    return;
   18.22 +  }
   18.23 +
   18.24 +  const Register cache = rcx;
   18.25 +  const Register index = rdx;
   18.26 +
   18.27 +  resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1));
   18.28 +  if (VerifyOops) {
   18.29 +    __ verify_oop(rax);
   18.30 +  }
   18.31 +}
   18.32 +
   18.33  void TemplateTable::ldc2_w() {
   18.34    transition(vtos, vtos);
   18.35    Label Long, Done;
   18.36 @@ -2055,6 +2081,8 @@
   18.37      case Bytecodes::_invokestatic   : // fall through
   18.38      case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;
   18.39      case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
   18.40 +    case Bytecodes::_fast_aldc      : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
   18.41 +    case Bytecodes::_fast_aldc_w    : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
   18.42      default                         : ShouldNotReachHere();                                 break;
   18.43    }
   18.44    __ movl(temp, (int)bytecode());
    19.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Thu Jun 24 15:38:42 2010 -0700
    19.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Mon Jun 28 12:03:05 2010 -0400
    19.3 @@ -389,6 +389,32 @@
    19.4    __ bind(Done);
    19.5  }
    19.6  
    19.7 +// Fast path for caching oop constants.
    19.8 +// %%% We should use this to handle Class and String constants also.
    19.9 +// %%% It will simplify the ldc/primitive path considerably.
   19.10 +void TemplateTable::fast_aldc(bool wide) {
   19.11 +  transition(vtos, atos);
   19.12 +
   19.13 +  if (!EnableMethodHandles) {
   19.14 +    // We should not encounter this bytecode if !EnableMethodHandles.
   19.15 +    // The verifier will stop it.  However, if we get past the verifier,
   19.16 +    // this will stop the thread in a reasonable way, without crashing the JVM.
   19.17 +    __ call_VM(noreg, CAST_FROM_FN_PTR(address,
   19.18 +                     InterpreterRuntime::throw_IncompatibleClassChangeError));
   19.19 +    // the call_VM checks for exception, so we should never return here.
   19.20 +    __ should_not_reach_here();
   19.21 +    return;
   19.22 +  }
   19.23 +
   19.24 +  const Register cache = rcx;
   19.25 +  const Register index = rdx;
   19.26 +
   19.27 +  resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1));
   19.28 +  if (VerifyOops) {
   19.29 +    __ verify_oop(rax);
   19.30 +  }
   19.31 +}
   19.32 +
   19.33  void TemplateTable::ldc2_w() {
   19.34    transition(vtos, vtos);
   19.35    Label Long, Done;
   19.36 @@ -2063,6 +2089,12 @@
   19.37    case Bytecodes::_invokedynamic:
   19.38      entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
   19.39      break;
   19.40 +  case Bytecodes::_fast_aldc:
   19.41 +    entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
   19.42 +    break;
   19.43 +  case Bytecodes::_fast_aldc_w:
   19.44 +    entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
   19.45 +    break;
   19.46    default:
   19.47      ShouldNotReachHere();
   19.48      break;
    20.1 --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp	Thu Jun 24 15:38:42 2010 -0700
    20.2 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Mon Jun 28 12:03:05 2010 -0400
    20.3 @@ -820,7 +820,7 @@
    20.4                                             bool      is_top_frame) {
    20.5    assert(popframe_extra_args == 0, "what to do?");
    20.6    assert(!is_top_frame || (!callee_locals && !callee_param_count),
    20.7 -         "top frame should have no caller")
    20.8 +         "top frame should have no caller");
    20.9  
   20.10    // This code must exactly match what InterpreterFrame::build
   20.11    // does (the full InterpreterFrame::build, that is, not the
    21.1 --- a/src/os_cpu/linux_x86/vm/copy_linux_x86.inline.hpp	Thu Jun 24 15:38:42 2010 -0700
    21.2 +++ b/src/os_cpu/linux_x86/vm/copy_linux_x86.inline.hpp	Mon Jun 28 12:03:05 2010 -0400
    21.3 @@ -26,7 +26,7 @@
    21.4  #ifdef AMD64
    21.5    (void)memmove(to, from, count * HeapWordSize);
    21.6  #else
    21.7 -  // Same as pd_aligned_conjoint_words, except includes a zero-count check.
    21.8 +  // Includes a zero-count check.
    21.9    intx temp;
   21.10    __asm__ volatile("        testl   %6,%6         ;"
   21.11                     "        jz      7f            ;"
   21.12 @@ -84,7 +84,7 @@
   21.13      break;
   21.14    }
   21.15  #else
   21.16 -  // Same as pd_aligned_disjoint_words, except includes a zero-count check.
   21.17 +  // Includes a zero-count check.
   21.18    intx temp;
   21.19    __asm__ volatile("        testl   %6,%6       ;"
   21.20                     "        jz      3f          ;"
   21.21 @@ -130,75 +130,18 @@
   21.22  }
   21.23  
   21.24  static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
   21.25 -#ifdef AMD64
   21.26 -  (void)memmove(to, from, count * HeapWordSize);
   21.27 -#else
   21.28 -  // Same as pd_conjoint_words, except no zero-count check.
   21.29 -  intx temp;
   21.30 -  __asm__ volatile("        cmpl    %4,%5         ;"
   21.31 -                   "        leal    -4(%4,%6,4),%3;"
   21.32 -                   "        jbe     1f            ;"
   21.33 -                   "        cmpl    %7,%5         ;"
   21.34 -                   "        jbe     4f            ;"
   21.35 -                   "1:      cmpl    $32,%6        ;"
   21.36 -                   "        ja      3f            ;"
   21.37 -                   "        subl    %4,%1         ;"
   21.38 -                   "2:      movl    (%4),%3       ;"
   21.39 -                   "        movl    %7,(%5,%4,1)  ;"
   21.40 -                   "        addl    $4,%0         ;"
   21.41 -                   "        subl    $1,%2          ;"
   21.42 -                   "        jnz     2b            ;"
   21.43 -                   "        jmp     7f            ;"
   21.44 -                   "3:      rep;    smovl         ;"
   21.45 -                   "        jmp     7f            ;"
   21.46 -                   "4:      cmpl    $32,%2        ;"
   21.47 -                   "        movl    %7,%0         ;"
   21.48 -                   "        leal    -4(%5,%6,4),%1;"
   21.49 -                   "        ja      6f            ;"
   21.50 -                   "        subl    %4,%1         ;"
   21.51 -                   "5:      movl    (%4),%3       ;"
   21.52 -                   "        movl    %7,(%5,%4,1)  ;"
   21.53 -                   "        subl    $4,%0         ;"
   21.54 -                   "        subl    $1,%2          ;"
   21.55 -                   "        jnz     5b            ;"
   21.56 -                   "        jmp     7f            ;"
   21.57 -                   "6:      std                   ;"
   21.58 -                   "        rep;    smovl         ;"
   21.59 -                   "        cld                   ;"
   21.60 -                   "7:      nop                    "
   21.61 -                   : "=S" (from), "=D" (to), "=c" (count), "=r" (temp)
   21.62 -                   : "0"  (from), "1"  (to), "2"  (count), "3"  (temp)
   21.63 -                   : "memory", "flags");
   21.64 -#endif // AMD64
   21.65 +  pd_conjoint_words(from, to, count);
   21.66  }
   21.67  
   21.68  static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
   21.69 -#ifdef AMD64
   21.70    pd_disjoint_words(from, to, count);
   21.71 -#else
   21.72 -  // Same as pd_disjoint_words, except no zero-count check.
   21.73 -  intx temp;
   21.74 -  __asm__ volatile("        cmpl    $32,%6      ;"
   21.75 -                   "        ja      2f          ;"
   21.76 -                   "        subl    %4,%1       ;"
   21.77 -                   "1:      movl    (%4),%3     ;"
   21.78 -                   "        movl    %7,(%5,%4,1);"
   21.79 -                   "        addl    $4,%0       ;"
   21.80 -                   "        subl    $1,%2        ;"
   21.81 -                   "        jnz     1b          ;"
   21.82 -                   "        jmp     3f          ;"
   21.83 -                   "2:      rep;    smovl       ;"
   21.84 -                   "3:      nop                  "
   21.85 -                   : "=S" (from), "=D" (to), "=c" (count), "=r" (temp)
   21.86 -                   : "0"  (from), "1"  (to), "2"  (count), "3"  (temp)
   21.87 -                   : "memory", "cc");
   21.88 -#endif // AMD64
   21.89  }
   21.90  
   21.91  static void pd_conjoint_bytes(void* from, void* to, size_t count) {
   21.92  #ifdef AMD64
   21.93    (void)memmove(to, from, count);
   21.94  #else
   21.95 +  // Includes a zero-count check.
   21.96    intx temp;
   21.97    __asm__ volatile("        testl   %6,%6          ;"
   21.98                     "        jz      13f            ;"
    22.1 --- a/src/os_cpu/linux_x86/vm/linux_x86_32.s	Thu Jun 24 15:38:42 2010 -0700
    22.2 +++ b/src/os_cpu/linux_x86/vm/linux_x86_32.s	Mon Jun 28 12:03:05 2010 -0400
    22.3 @@ -121,10 +121,10 @@
    22.4          jnz      3b
    22.5          addl     %esi,%edi
    22.6  4:      movl     %eax,%ecx            # byte count less prefix
    22.7 -        andl     $3,%ecx              # suffix byte count
    22.8 +5:      andl     $3,%ecx              # suffix byte count
    22.9          jz       7f                   # no suffix
   22.10          # copy suffix
   22.11 -5:      xorl     %eax,%eax
   22.12 +        xorl     %eax,%eax
   22.13  6:      movb     (%esi,%eax,1),%dl
   22.14          movb     %dl,(%edi,%eax,1)
   22.15          addl     $1,%eax
   22.16 @@ -159,10 +159,10 @@
   22.17          # copy dwords, aligned or not
   22.18  3:      rep;     smovl
   22.19  4:      movl     %eax,%ecx            # byte count
   22.20 -        andl     $3,%ecx              # suffix byte count
   22.21 +5:      andl     $3,%ecx              # suffix byte count
   22.22          jz       7f                   # no suffix
   22.23          # copy suffix
   22.24 -5:      subl     %esi,%edi
   22.25 +        subl     %esi,%edi
   22.26          addl     $3,%esi
   22.27  6:      movb     (%esi),%dl
   22.28          movb     %dl,(%edi,%esi,1)
   22.29 @@ -214,10 +214,10 @@
   22.30          # copy aligned dwords
   22.31  3:      rep;     smovl
   22.32  4:      movl     %eax,%ecx
   22.33 -        andl     $3,%ecx
   22.34 +5:      andl     $3,%ecx
   22.35          jz       7f
   22.36          # copy suffix
   22.37 -5:      xorl     %eax,%eax
   22.38 +        xorl     %eax,%eax
   22.39  6:      movb     (%esi,%eax,1),%dl
   22.40          movb     %dl,(%edi,%eax,1)
   22.41          addl     $1,%eax
   22.42 @@ -250,9 +250,9 @@
   22.43          jnz      3b
   22.44          addl     %esi,%edi
   22.45  4:      movl     %eax,%ecx
   22.46 -        andl     $3,%ecx
   22.47 +5:      andl     $3,%ecx
   22.48          jz       7f
   22.49 -5:      subl     %esi,%edi
   22.50 +        subl     %esi,%edi
   22.51          addl     $3,%esi
   22.52  6:      movb     (%esi),%dl
   22.53          movb     %dl,(%edi,%esi,1)
   22.54 @@ -287,11 +287,12 @@
   22.55          andl     $3,%eax              # either 0 or 2
   22.56          jz       1f                   # no prefix
   22.57          # copy prefix
   22.58 +        subl     $1,%ecx
   22.59 +        jl       5f                   # zero count
   22.60          movw     (%esi),%dx
   22.61          movw     %dx,(%edi)
   22.62          addl     %eax,%esi            # %eax == 2
   22.63          addl     %eax,%edi
   22.64 -        subl     $1,%ecx
   22.65  1:      movl     %ecx,%eax            # word count less prefix
   22.66          sarl     %ecx                 # dword count
   22.67          jz       4f                   # no dwords to move
   22.68 @@ -454,12 +455,13 @@
   22.69          ret
   22.70          .=.+10
   22.71  2:      subl     %esi,%edi
   22.72 +        jmp      4f
   22.73          .p2align 4,,15
   22.74  3:      movl     (%esi),%edx
   22.75          movl     %edx,(%edi,%esi,1)
   22.76          addl     $4,%esi
   22.77 -        subl     $1,%ecx
   22.78 -        jnz      3b
   22.79 +4:      subl     $1,%ecx
   22.80 +        jge      3b
   22.81          popl     %edi
   22.82          popl     %esi
   22.83          ret
   22.84 @@ -467,19 +469,20 @@
   22.85          std
   22.86          leal     -4(%edi,%ecx,4),%edi # to + count*4 - 4
   22.87          cmpl     $32,%ecx
   22.88 -        ja       3f                   # > 32 dwords
   22.89 +        ja       4f                   # > 32 dwords
   22.90          subl     %eax,%edi            # eax == from + count*4 - 4
   22.91 +        jmp      3f
   22.92          .p2align 4,,15
   22.93  2:      movl     (%eax),%edx
   22.94          movl     %edx,(%edi,%eax,1)
   22.95          subl     $4,%eax
   22.96 -        subl     $1,%ecx
   22.97 -        jnz      2b
   22.98 +3:      subl     $1,%ecx
   22.99 +        jge      2b
  22.100          cld
  22.101          popl     %edi
  22.102          popl     %esi
  22.103          ret
  22.104 -3:      movl     %eax,%esi            # from + count*4 - 4
  22.105 +4:      movl     %eax,%esi            # from + count*4 - 4
  22.106          rep;     smovl
  22.107          cld
  22.108          popl     %edi
    23.1 --- a/src/os_cpu/solaris_x86/vm/solaris_x86_32.s	Thu Jun 24 15:38:42 2010 -0700
    23.2 +++ b/src/os_cpu/solaris_x86/vm/solaris_x86_32.s	Mon Jun 28 12:03:05 2010 -0400
    23.3 @@ -154,10 +154,10 @@
    23.4          jnz      3b
    23.5          addl     %esi,%edi
    23.6  4:      movl     %eax,%ecx            / byte count less prefix
    23.7 -        andl     $3,%ecx              / suffix byte count
    23.8 +5:      andl     $3,%ecx              / suffix byte count
    23.9          jz       7f                   / no suffix
   23.10          / copy suffix
   23.11 -5:      xorl     %eax,%eax
   23.12 +        xorl     %eax,%eax
   23.13  6:      movb     (%esi,%eax,1),%dl
   23.14          movb     %dl,(%edi,%eax,1)
   23.15          addl     $1,%eax
   23.16 @@ -192,10 +192,10 @@
   23.17          / copy dwords, aligned or not
   23.18  3:      rep;     smovl
   23.19  4:      movl     %eax,%ecx            / byte count
   23.20 -        andl     $3,%ecx              / suffix byte count
   23.21 +5:      andl     $3,%ecx              / suffix byte count
   23.22          jz       7f                   / no suffix
   23.23          / copy suffix
   23.24 -5:      subl     %esi,%edi
   23.25 +        subl     %esi,%edi
   23.26          addl     $3,%esi
   23.27  6:      movb     (%esi),%dl
   23.28          movb     %dl,(%edi,%esi,1)
   23.29 @@ -246,10 +246,10 @@
   23.30          / copy aligned dwords
   23.31  3:      rep;     smovl
   23.32  4:      movl     %eax,%ecx
   23.33 -        andl     $3,%ecx
   23.34 +5:      andl     $3,%ecx
   23.35          jz       7f
   23.36          / copy suffix
   23.37 -5:      xorl     %eax,%eax
   23.38 +        xorl     %eax,%eax
   23.39  6:      movb     (%esi,%eax,1),%dl
   23.40          movb     %dl,(%edi,%eax,1)
   23.41          addl     $1,%eax
   23.42 @@ -282,9 +282,9 @@
   23.43          jnz      3b
   23.44          addl     %esi,%edi
   23.45  4:      movl     %eax,%ecx
   23.46 -        andl     $3,%ecx
   23.47 +5:      andl     $3,%ecx
   23.48          jz       7f
   23.49 -5:      subl     %esi,%edi
   23.50 +        subl     %esi,%edi
   23.51          addl     $3,%esi
   23.52  6:      movb     (%esi),%dl
   23.53          movb     %dl,(%edi,%esi,1)
   23.54 @@ -318,11 +318,12 @@
   23.55          andl     $3,%eax              / either 0 or 2
   23.56          jz       1f                   / no prefix
   23.57          / copy prefix
   23.58 +        subl     $1,%ecx
   23.59 +        jl       5f                   / zero count
   23.60          movw     (%esi),%dx
   23.61          movw     %dx,(%edi)
   23.62          addl     %eax,%esi            / %eax == 2
   23.63          addl     %eax,%edi
   23.64 -        subl     $1,%ecx
   23.65  1:      movl     %ecx,%eax            / word count less prefix
   23.66          sarl     %ecx                 / dword count
   23.67          jz       4f                   / no dwords to move
   23.68 @@ -482,12 +483,13 @@
   23.69          ret
   23.70          .=.+10
   23.71  2:      subl     %esi,%edi
   23.72 +        jmp      4f
   23.73          .align   16
   23.74  3:      movl     (%esi),%edx
   23.75          movl     %edx,(%edi,%esi,1)
   23.76          addl     $4,%esi
   23.77 -        subl     $1,%ecx
   23.78 -        jnz      3b
   23.79 +4:      subl     $1,%ecx
   23.80 +        jge      3b
   23.81          popl     %edi
   23.82          popl     %esi
   23.83          ret
   23.84 @@ -495,19 +497,20 @@
   23.85          std
   23.86          leal     -4(%edi,%ecx,4),%edi / to + count*4 - 4
   23.87          cmpl     $32,%ecx
   23.88 -        ja       3f                   / > 32 dwords
   23.89 +        ja       4f                   / > 32 dwords
   23.90          subl     %eax,%edi            / eax == from + count*4 - 4
   23.91 +        jmp      3f
   23.92          .align   16
   23.93  2:      movl     (%eax),%edx
   23.94          movl     %edx,(%edi,%eax,1)
   23.95          subl     $4,%eax
   23.96 -        subl     $1,%ecx
   23.97 -        jnz      2b
   23.98 +3:      subl     $1,%ecx
   23.99 +        jge      2b
  23.100          cld
  23.101          popl     %edi
  23.102          popl     %esi
  23.103          ret
  23.104 -3:      movl     %eax,%esi            / from + count*4 - 4
  23.105 +4:      movl     %eax,%esi            / from + count*4 - 4
  23.106          rep;     smovl
  23.107          cld
  23.108          popl     %edi
    24.1 --- a/src/share/vm/asm/codeBuffer.cpp	Thu Jun 24 15:38:42 2010 -0700
    24.2 +++ b/src/share/vm/asm/codeBuffer.cpp	Mon Jun 28 12:03:05 2010 -0400
    24.3 @@ -404,7 +404,7 @@
    24.4        locs_start = REALLOC_RESOURCE_ARRAY(relocInfo, _locs_start, old_capacity, new_capacity);
    24.5      } else {
    24.6        locs_start = NEW_RESOURCE_ARRAY(relocInfo, new_capacity);
    24.7 -      Copy::conjoint_bytes(_locs_start, locs_start, old_capacity * sizeof(relocInfo));
    24.8 +      Copy::conjoint_jbytes(_locs_start, locs_start, old_capacity * sizeof(relocInfo));
    24.9        _locs_own = true;
   24.10      }
   24.11      _locs_start    = locs_start;
   24.12 @@ -581,7 +581,7 @@
   24.13                               (HeapWord*)(buf+buf_offset),
   24.14                               (lsize + HeapWordSize-1) / HeapWordSize);
   24.15        } else {
   24.16 -        Copy::conjoint_bytes(lstart, buf+buf_offset, lsize);
   24.17 +        Copy::conjoint_jbytes(lstart, buf+buf_offset, lsize);
   24.18        }
   24.19      }
   24.20      buf_offset += lsize;
    25.1 --- a/src/share/vm/c1/c1_Compilation.cpp	Thu Jun 24 15:38:42 2010 -0700
    25.2 +++ b/src/share/vm/c1/c1_Compilation.cpp	Mon Jun 28 12:03:05 2010 -0400
    25.3 @@ -242,10 +242,10 @@
    25.4    code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
    25.5                                          locs_buffer_size / sizeof(relocInfo));
    25.6    code->initialize_consts_size(Compilation::desired_max_constant_size());
    25.7 -  // Call stubs + deopt/exception handler
    25.8 +  // Call stubs + two deopt handlers (regular and MH) + exception handler
    25.9    code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) +
   25.10                                LIR_Assembler::exception_handler_size +
   25.11 -                              LIR_Assembler::deopt_handler_size);
   25.12 +                              2 * LIR_Assembler::deopt_handler_size);
   25.13  }
   25.14  
   25.15  
    26.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Jun 24 15:38:42 2010 -0700
    26.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Mon Jun 28 12:03:05 2010 -0400
    26.3 @@ -878,15 +878,12 @@
    26.4        case T_OBJECT :
    26.5         {
    26.6          ciObject* obj = con.as_object();
    26.7 -        if (obj->is_klass()) {
    26.8 -          ciKlass* klass = obj->as_klass();
    26.9 -          if (!klass->is_loaded() || PatchALot) {
   26.10 -            patch_state = state()->copy();
   26.11 -            t = new ObjectConstant(obj);
   26.12 -          } else {
   26.13 -            t = new InstanceConstant(klass->java_mirror());
   26.14 -          }
   26.15 +        if (!obj->is_loaded()
   26.16 +            || (PatchALot && obj->klass() != ciEnv::current()->String_klass())) {
   26.17 +          patch_state = state()->copy();
   26.18 +          t = new ObjectConstant(obj);
   26.19          } else {
   26.20 +          assert(!obj->is_klass(), "must be java_mirror of klass");
   26.21            t = new InstanceConstant(obj->as_instance());
   26.22          }
   26.23          break;
    27.1 --- a/src/share/vm/c1/c1_Runtime1.cpp	Thu Jun 24 15:38:42 2010 -0700
    27.2 +++ b/src/share/vm/c1/c1_Runtime1.cpp	Mon Jun 28 12:03:05 2010 -0400
    27.3 @@ -601,7 +601,7 @@
    27.4  
    27.5  
    27.6  static klassOop resolve_field_return_klass(methodHandle caller, int bci, TRAPS) {
    27.7 -  Bytecode_field* field_access = Bytecode_field_at(caller(), caller->bcp_from(bci));
    27.8 +  Bytecode_field* field_access = Bytecode_field_at(caller, bci);
    27.9    // This can be static or non-static field access
   27.10    Bytecodes::Code code       = field_access->code();
   27.11  
   27.12 @@ -721,7 +721,7 @@
   27.13    Handle load_klass(THREAD, NULL);                // oop needed by load_klass_patching code
   27.14    if (stub_id == Runtime1::access_field_patching_id) {
   27.15  
   27.16 -    Bytecode_field* field_access = Bytecode_field_at(caller_method(), caller_method->bcp_from(bci));
   27.17 +    Bytecode_field* field_access = Bytecode_field_at(caller_method, bci);
   27.18      FieldAccessInfo result; // initialize class if needed
   27.19      Bytecodes::Code code = field_access->code();
   27.20      constantPoolHandle constants(THREAD, caller_method->constants());
   27.21 @@ -781,11 +781,9 @@
   27.22        case Bytecodes::_ldc:
   27.23        case Bytecodes::_ldc_w:
   27.24          {
   27.25 -          Bytecode_loadconstant* cc = Bytecode_loadconstant_at(caller_method(),
   27.26 -                                                               caller_method->bcp_from(bci));
   27.27 -          klassOop resolved = caller_method->constants()->klass_at(cc->index(), CHECK);
   27.28 -          // ldc wants the java mirror.
   27.29 -          k = resolved->klass_part()->java_mirror();
   27.30 +          Bytecode_loadconstant* cc = Bytecode_loadconstant_at(caller_method, bci);
   27.31 +          k = cc->resolve_constant(CHECK);
   27.32 +          assert(k != NULL && !k->is_klass(), "must be class mirror or other Java constant");
   27.33          }
   27.34          break;
   27.35        default: Unimplemented();
   27.36 @@ -816,6 +814,15 @@
   27.37      // Return to the now deoptimized frame.
   27.38    }
   27.39  
   27.40 +  // If we are patching in a non-perm oop, make sure the nmethod
   27.41 +  // is on the right list.
   27.42 +  if (ScavengeRootsInCode && load_klass.not_null() && load_klass->is_scavengable()) {
   27.43 +    MutexLockerEx ml_code (CodeCache_lock, Mutex::_no_safepoint_check_flag);
   27.44 +    nmethod* nm = CodeCache::find_nmethod(caller_frame.pc());
   27.45 +    guarantee(nm != NULL, "only nmethods can contain non-perm oops");
   27.46 +    if (!nm->on_scavenge_root_list())
   27.47 +      CodeCache::add_scavenge_root_nmethod(nm);
   27.48 +  }
   27.49  
   27.50    // Now copy code back
   27.51  
   27.52 @@ -1115,7 +1122,7 @@
   27.53    if (length == 0) return;
   27.54    // Not guaranteed to be word atomic, but that doesn't matter
   27.55    // for anything but an oop array, which is covered by oop_arraycopy.
   27.56 -  Copy::conjoint_bytes(src, dst, length);
   27.57 +  Copy::conjoint_jbytes(src, dst, length);
   27.58  JRT_END
   27.59  
   27.60  JRT_LEAF(void, Runtime1::oop_arraycopy(HeapWord* src, HeapWord* dst, int num))
    28.1 --- a/src/share/vm/ci/ciCPCache.cpp	Thu Jun 24 15:38:42 2010 -0700
    28.2 +++ b/src/share/vm/ci/ciCPCache.cpp	Mon Jun 28 12:03:05 2010 -0400
    28.3 @@ -44,13 +44,23 @@
    28.4  // ciCPCache::is_f1_null_at
    28.5  bool ciCPCache::is_f1_null_at(int index) {
    28.6    VM_ENTRY_MARK;
    28.7 -  constantPoolCacheOop cpcache = (constantPoolCacheOop) get_oop();
    28.8 -  oop f1 = cpcache->secondary_entry_at(index)->f1();
    28.9 +  oop f1 = entry_at(index)->f1();
   28.10    return (f1 == NULL);
   28.11  }
   28.12  
   28.13  
   28.14  // ------------------------------------------------------------------
   28.15 +// ciCPCache::get_pool_index
   28.16 +int ciCPCache::get_pool_index(int index) {
   28.17 +  VM_ENTRY_MARK;
   28.18 +  ConstantPoolCacheEntry* e = entry_at(index);
   28.19 +  if (e->is_secondary_entry())
   28.20 +    e = entry_at(e->main_entry_index());
   28.21 +  return e->constant_pool_index();
   28.22 +}
   28.23 +
   28.24 +
   28.25 +// ------------------------------------------------------------------
   28.26  // ciCPCache::print
   28.27  //
   28.28  // Print debugging information about the cache.
    29.1 --- a/src/share/vm/ci/ciCPCache.hpp	Thu Jun 24 15:38:42 2010 -0700
    29.2 +++ b/src/share/vm/ci/ciCPCache.hpp	Mon Jun 28 12:03:05 2010 -0400
    29.3 @@ -29,6 +29,18 @@
    29.4  // Note: This class is called ciCPCache as ciConstantPoolCache is used
    29.5  // for something different.
    29.6  class ciCPCache : public ciObject {
    29.7 +private:
    29.8 +  constantPoolCacheOop get_cpCacheOop() {   // must be called inside a VM_ENTRY_MARK
    29.9 +    return (constantPoolCacheOop) get_oop();
   29.10 +  }
   29.11 +
   29.12 +  ConstantPoolCacheEntry* entry_at(int i) {
   29.13 +    int raw_index = i;
   29.14 +    if (constantPoolCacheOopDesc::is_secondary_index(i))
   29.15 +      raw_index = constantPoolCacheOopDesc::decode_secondary_index(i);
   29.16 +    return get_cpCacheOop()->entry_at(raw_index);
   29.17 +  }
   29.18 +
   29.19  public:
   29.20    ciCPCache(constantPoolCacheHandle cpcache) : ciObject(cpcache) {}
   29.21  
   29.22 @@ -41,5 +53,7 @@
   29.23  
   29.24    bool is_f1_null_at(int index);
   29.25  
   29.26 +  int get_pool_index(int index);
   29.27 +
   29.28    void print();
   29.29  };
    30.1 --- a/src/share/vm/ci/ciClassList.hpp	Thu Jun 24 15:38:42 2010 -0700
    30.2 +++ b/src/share/vm/ci/ciClassList.hpp	Mon Jun 28 12:03:05 2010 -0400
    30.3 @@ -85,6 +85,7 @@
    30.4  friend class ciConstantPoolCache;      \
    30.5  friend class ciField;                  \
    30.6  friend class ciConstant;               \
    30.7 +friend class ciCPCache;                \
    30.8  friend class ciFlags;                  \
    30.9  friend class ciExceptionHandler;       \
   30.10  friend class ciCallProfile;            \
    31.1 --- a/src/share/vm/ci/ciEnv.cpp	Thu Jun 24 15:38:42 2010 -0700
    31.2 +++ b/src/share/vm/ci/ciEnv.cpp	Mon Jun 28 12:03:05 2010 -0400
    31.3 @@ -511,9 +511,22 @@
    31.4  //
    31.5  // Implementation of get_constant_by_index().
    31.6  ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,
    31.7 -                                             int index,
    31.8 +                                             int pool_index, int cache_index,
    31.9                                               ciInstanceKlass* accessor) {
   31.10 +  bool ignore_will_link;
   31.11    EXCEPTION_CONTEXT;
   31.12 +  int index = pool_index;
   31.13 +  if (cache_index >= 0) {
   31.14 +    assert(index < 0, "only one kind of index at a time");
   31.15 +    ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index);
   31.16 +    index = cpc_entry->constant_pool_index();
   31.17 +    oop obj = cpc_entry->f1();
   31.18 +    if (obj != NULL) {
   31.19 +      assert(obj->is_instance(), "must be an instance");
   31.20 +      ciObject* ciobj = get_object(obj);
   31.21 +      return ciConstant(T_OBJECT, ciobj);
   31.22 +    }
   31.23 +  }
   31.24    constantTag tag = cpool->tag_at(index);
   31.25    if (tag.is_int()) {
   31.26      return ciConstant(T_INT, (jint)cpool->int_at(index));
   31.27 @@ -540,8 +553,7 @@
   31.28      return ciConstant(T_OBJECT, constant);
   31.29    } else if (tag.is_klass() || tag.is_unresolved_klass()) {
   31.30      // 4881222: allow ldc to take a class type
   31.31 -    bool ignore;
   31.32 -    ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore, accessor);
   31.33 +    ciKlass* klass = get_klass_by_index_impl(cpool, index, ignore_will_link, accessor);
   31.34      if (HAS_PENDING_EXCEPTION) {
   31.35        CLEAR_PENDING_EXCEPTION;
   31.36        record_out_of_memory_failure();
   31.37 @@ -549,12 +561,26 @@
   31.38      }
   31.39      assert (klass->is_instance_klass() || klass->is_array_klass(),
   31.40              "must be an instance or array klass ");
   31.41 -    return ciConstant(T_OBJECT, klass);
   31.42 +    return ciConstant(T_OBJECT, klass->java_mirror());
   31.43    } else if (tag.is_object()) {
   31.44      oop obj = cpool->object_at(index);
   31.45      assert(obj->is_instance(), "must be an instance");
   31.46      ciObject* ciobj = get_object(obj);
   31.47      return ciConstant(T_OBJECT, ciobj);
   31.48 +  } else if (tag.is_method_type()) {
   31.49 +    // must execute Java code to link this CP entry into cache[i].f1
   31.50 +    ciSymbol* signature = get_object(cpool->method_type_signature_at(index))->as_symbol();
   31.51 +    ciObject* ciobj = get_unloaded_method_type_constant(signature);
   31.52 +    return ciConstant(T_OBJECT, ciobj);
   31.53 +  } else if (tag.is_method_handle()) {
   31.54 +    // must execute Java code to link this CP entry into cache[i].f1
   31.55 +    int ref_kind        = cpool->method_handle_ref_kind_at(index);
   31.56 +    int callee_index    = cpool->method_handle_klass_index_at(index);
   31.57 +    ciKlass* callee     = get_klass_by_index_impl(cpool, callee_index, ignore_will_link, accessor);
   31.58 +    ciSymbol* name      = get_object(cpool->method_handle_name_ref_at(index))->as_symbol();
   31.59 +    ciSymbol* signature = get_object(cpool->method_handle_signature_ref_at(index))->as_symbol();
   31.60 +    ciObject* ciobj     = get_unloaded_method_handle_constant(callee, name, signature, ref_kind);
   31.61 +    return ciConstant(T_OBJECT, ciobj);
   31.62    } else {
   31.63      ShouldNotReachHere();
   31.64      return ciConstant();
   31.65 @@ -562,61 +588,15 @@
   31.66  }
   31.67  
   31.68  // ------------------------------------------------------------------
   31.69 -// ciEnv::is_unresolved_string_impl
   31.70 -//
   31.71 -// Implementation of is_unresolved_string().
   31.72 -bool ciEnv::is_unresolved_string_impl(instanceKlass* accessor, int index) const {
   31.73 -  EXCEPTION_CONTEXT;
   31.74 -  assert(accessor->is_linked(), "must be linked before accessing constant pool");
   31.75 -  constantPoolOop cpool = accessor->constants();
   31.76 -  constantTag tag = cpool->tag_at(index);
   31.77 -  return tag.is_unresolved_string();
   31.78 -}
   31.79 -
   31.80 -// ------------------------------------------------------------------
   31.81 -// ciEnv::is_unresolved_klass_impl
   31.82 -//
   31.83 -// Implementation of is_unresolved_klass().
   31.84 -bool ciEnv::is_unresolved_klass_impl(instanceKlass* accessor, int index) const {
   31.85 -  EXCEPTION_CONTEXT;
   31.86 -  assert(accessor->is_linked(), "must be linked before accessing constant pool");
   31.87 -  constantPoolOop cpool = accessor->constants();
   31.88 -  constantTag tag = cpool->tag_at(index);
   31.89 -  return tag.is_unresolved_klass();
   31.90 -}
   31.91 -
   31.92 -// ------------------------------------------------------------------
   31.93  // ciEnv::get_constant_by_index
   31.94  //
   31.95  // Pull a constant out of the constant pool.  How appropriate.
   31.96  //
   31.97  // Implementation note: this query is currently in no way cached.
   31.98  ciConstant ciEnv::get_constant_by_index(constantPoolHandle cpool,
   31.99 -                                        int index,
  31.100 +                                        int pool_index, int cache_index,
  31.101                                          ciInstanceKlass* accessor) {
  31.102 -  GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, index, accessor);)
  31.103 -}
  31.104 -
  31.105 -// ------------------------------------------------------------------
  31.106 -// ciEnv::is_unresolved_string
  31.107 -//
  31.108 -// Check constant pool
  31.109 -//
  31.110 -// Implementation note: this query is currently in no way cached.
  31.111 -bool ciEnv::is_unresolved_string(ciInstanceKlass* accessor,
  31.112 -                                 int index) const {
  31.113 -  GUARDED_VM_ENTRY(return is_unresolved_string_impl(accessor->get_instanceKlass(), index); )
  31.114 -}
  31.115 -
  31.116 -// ------------------------------------------------------------------
  31.117 -// ciEnv::is_unresolved_klass
  31.118 -//
  31.119 -// Check constant pool
  31.120 -//
  31.121 -// Implementation note: this query is currently in no way cached.
  31.122 -bool ciEnv::is_unresolved_klass(ciInstanceKlass* accessor,
  31.123 -                                int index) const {
  31.124 -  GUARDED_VM_ENTRY(return is_unresolved_klass_impl(accessor->get_instanceKlass(), index); )
  31.125 +  GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, pool_index, cache_index, accessor);)
  31.126  }
  31.127  
  31.128  // ------------------------------------------------------------------
    32.1 --- a/src/share/vm/ci/ciEnv.hpp	Thu Jun 24 15:38:42 2010 -0700
    32.2 +++ b/src/share/vm/ci/ciEnv.hpp	Mon Jun 28 12:03:05 2010 -0400
    32.3 @@ -116,12 +116,8 @@
    32.4                                  bool& is_accessible,
    32.5                                  ciInstanceKlass* loading_klass);
    32.6    ciConstant get_constant_by_index(constantPoolHandle cpool,
    32.7 -                                   int constant_index,
    32.8 +                                   int pool_index, int cache_index,
    32.9                                     ciInstanceKlass* accessor);
   32.10 -  bool       is_unresolved_string(ciInstanceKlass* loading_klass,
   32.11 -                                   int constant_index) const;
   32.12 -  bool       is_unresolved_klass(ciInstanceKlass* loading_klass,
   32.13 -                                   int constant_index) const;
   32.14    ciField*   get_field_by_index(ciInstanceKlass* loading_klass,
   32.15                                  int field_index);
   32.16    ciMethod*  get_method_by_index(constantPoolHandle cpool,
   32.17 @@ -137,12 +133,8 @@
   32.18                                       bool& is_accessible,
   32.19                                       ciInstanceKlass* loading_klass);
   32.20    ciConstant get_constant_by_index_impl(constantPoolHandle cpool,
   32.21 -                                        int constant_index,
   32.22 +                                        int pool_index, int cache_index,
   32.23                                          ciInstanceKlass* loading_klass);
   32.24 -  bool       is_unresolved_string_impl (instanceKlass* loading_klass,
   32.25 -                                        int constant_index) const;
   32.26 -  bool       is_unresolved_klass_impl (instanceKlass* loading_klass,
   32.27 -                                        int constant_index) const;
   32.28    ciField*   get_field_by_index_impl(ciInstanceKlass* loading_klass,
   32.29                                       int field_index);
   32.30    ciMethod*  get_method_by_index_impl(constantPoolHandle cpool,
   32.31 @@ -190,6 +182,25 @@
   32.32      return _factory->get_unloaded_klass(accessing_klass, name, true);
   32.33    }
   32.34  
   32.35 +  // Get a ciKlass representing an unloaded klass mirror.
   32.36 +  // Result is not necessarily unique, but will be unloaded.
   32.37 +  ciInstance* get_unloaded_klass_mirror(ciKlass* type) {
   32.38 +    return _factory->get_unloaded_klass_mirror(type);
   32.39 +  }
   32.40 +
   32.41 +  // Get a ciInstance representing an unresolved method handle constant.
   32.42 +  ciInstance* get_unloaded_method_handle_constant(ciKlass*  holder,
   32.43 +                                                  ciSymbol* name,
   32.44 +                                                  ciSymbol* signature,
   32.45 +                                                  int       ref_kind) {
   32.46 +    return _factory->get_unloaded_method_handle_constant(holder, name, signature, ref_kind);
   32.47 +  }
   32.48 +
   32.49 +  // Get a ciInstance representing an unresolved method type constant.
   32.50 +  ciInstance* get_unloaded_method_type_constant(ciSymbol* signature) {
   32.51 +    return _factory->get_unloaded_method_type_constant(signature);
   32.52 +  }
   32.53 +
   32.54    // See if we already have an unloaded klass for the given name
   32.55    // or return NULL if not.
   32.56    ciKlass *check_get_unloaded_klass(ciKlass* accessing_klass, ciSymbol* name) {
    33.1 --- a/src/share/vm/ci/ciInstanceKlass.cpp	Thu Jun 24 15:38:42 2010 -0700
    33.2 +++ b/src/share/vm/ci/ciInstanceKlass.cpp	Mon Jun 28 12:03:05 2010 -0400
    33.3 @@ -323,8 +323,8 @@
    33.4  // ciInstanceKlass::java_mirror
    33.5  //
    33.6  // Get the instance of java.lang.Class corresponding to this klass.
    33.7 +// Cache it on this->_java_mirror.
    33.8  ciInstance* ciInstanceKlass::java_mirror() {
    33.9 -  assert(is_loaded(), "must be loaded");
   33.10    if (_java_mirror == NULL) {
   33.11      _java_mirror = ciKlass::java_mirror();
   33.12    }
    34.1 --- a/src/share/vm/ci/ciKlass.cpp	Thu Jun 24 15:38:42 2010 -0700
    34.2 +++ b/src/share/vm/ci/ciKlass.cpp	Mon Jun 28 12:03:05 2010 -0400
    34.3 @@ -192,8 +192,14 @@
    34.4  
    34.5  // ------------------------------------------------------------------
    34.6  // ciKlass::java_mirror
    34.7 +//
    34.8 +// Get the instance of java.lang.Class corresponding to this klass.
    34.9 +// If it is an unloaded instance or array klass, return an unloaded
   34.10 +// mirror object of type Class.
   34.11  ciInstance* ciKlass::java_mirror() {
   34.12    GUARDED_VM_ENTRY(
   34.13 +    if (!is_loaded())
   34.14 +      return ciEnv::current()->get_unloaded_klass_mirror(this);
   34.15      oop java_mirror = get_Klass()->java_mirror();
   34.16      return CURRENT_ENV->get_object(java_mirror)->as_instance();
   34.17    )
    35.1 --- a/src/share/vm/ci/ciObjectFactory.cpp	Thu Jun 24 15:38:42 2010 -0700
    35.2 +++ b/src/share/vm/ci/ciObjectFactory.cpp	Mon Jun 28 12:03:05 2010 -0400
    35.3 @@ -70,6 +70,7 @@
    35.4  
    35.5    _unloaded_methods = new (arena) GrowableArray<ciMethod*>(arena, 4, 0, NULL);
    35.6    _unloaded_klasses = new (arena) GrowableArray<ciKlass*>(arena, 8, 0, NULL);
    35.7 +  _unloaded_instances = new (arena) GrowableArray<ciInstance*>(arena, 4, 0, NULL);
    35.8    _return_addresses =
    35.9      new (arena) GrowableArray<ciReturnAddress*>(arena, 8, 0, NULL);
   35.10  }
   35.11 @@ -443,6 +444,74 @@
   35.12    return new_klass;
   35.13  }
   35.14  
   35.15 +
   35.16 +//------------------------------------------------------------------
   35.17 +// ciObjectFactory::get_unloaded_instance
   35.18 +//
   35.19 +// Get a ciInstance representing an as-yet undetermined instance of a given class.
   35.20 +//
   35.21 +ciInstance* ciObjectFactory::get_unloaded_instance(ciInstanceKlass* instance_klass) {
   35.22 +  for (int i=0; i<_unloaded_instances->length(); i++) {
   35.23 +    ciInstance* entry = _unloaded_instances->at(i);
   35.24 +    if (entry->klass()->equals(instance_klass)) {
   35.25 +      // We've found a match.
   35.26 +      return entry;
   35.27 +    }
   35.28 +  }
   35.29 +
   35.30 +  // This is a new unloaded instance.  Create it and stick it in
   35.31 +  // the cache.
   35.32 +  ciInstance* new_instance = new (arena()) ciInstance(instance_klass);
   35.33 +
   35.34 +  init_ident_of(new_instance);
   35.35 +  _unloaded_instances->append(new_instance);
   35.36 +
   35.37 +  // make sure it looks the way we want:
   35.38 +  assert(!new_instance->is_loaded(), "");
   35.39 +  assert(new_instance->klass() == instance_klass, "");
   35.40 +
   35.41 +  return new_instance;
   35.42 +}
   35.43 +
   35.44 +
   35.45 +//------------------------------------------------------------------
   35.46 +// ciObjectFactory::get_unloaded_klass_mirror
   35.47 +//
   35.48 +// Get a ciInstance representing an unresolved klass mirror.
   35.49 +//
   35.50 +// Currently, this ignores the parameters and returns a unique unloaded instance.
   35.51 +ciInstance* ciObjectFactory::get_unloaded_klass_mirror(ciKlass*  type) {
   35.52 +  assert(ciEnv::_Class_klass != NULL, "");
   35.53 +  return get_unloaded_instance(ciEnv::_Class_klass->as_instance_klass());
   35.54 +}
   35.55 +
   35.56 +//------------------------------------------------------------------
   35.57 +// ciObjectFactory::get_unloaded_method_handle_constant
   35.58 +//
   35.59 +// Get a ciInstance representing an unresolved method handle constant.
   35.60 +//
   35.61 +// Currently, this ignores the parameters and returns a unique unloaded instance.
   35.62 +ciInstance* ciObjectFactory::get_unloaded_method_handle_constant(ciKlass*  holder,
   35.63 +                                                                 ciSymbol* name,
   35.64 +                                                                 ciSymbol* signature,
   35.65 +                                                                 int       ref_kind) {
   35.66 +  if (ciEnv::_MethodHandle_klass == NULL)  return NULL;
   35.67 +  return get_unloaded_instance(ciEnv::_MethodHandle_klass->as_instance_klass());
   35.68 +}
   35.69 +
   35.70 +//------------------------------------------------------------------
   35.71 +// ciObjectFactory::get_unloaded_method_type_constant
   35.72 +//
   35.73 +// Get a ciInstance representing an unresolved method type constant.
   35.74 +//
   35.75 +// Currently, this ignores the parameters and returns a unique unloaded instance.
   35.76 +ciInstance* ciObjectFactory::get_unloaded_method_type_constant(ciSymbol* signature) {
   35.77 +  if (ciEnv::_MethodType_klass == NULL)  return NULL;
   35.78 +  return get_unloaded_instance(ciEnv::_MethodType_klass->as_instance_klass());
   35.79 +}
   35.80 +
   35.81 +
   35.82 +
   35.83  //------------------------------------------------------------------
   35.84  // ciObjectFactory::get_empty_methodData
   35.85  //
   35.86 @@ -637,7 +706,8 @@
   35.87  //
   35.88  // Print debugging information about the object factory
   35.89  void ciObjectFactory::print() {
   35.90 -  tty->print("<ciObjectFactory oops=%d unloaded_methods=%d unloaded_klasses=%d>",
   35.91 +  tty->print("<ciObjectFactory oops=%d unloaded_methods=%d unloaded_instances=%d unloaded_klasses=%d>",
   35.92               _ci_objects->length(), _unloaded_methods->length(),
   35.93 +             _unloaded_instances->length(),
   35.94               _unloaded_klasses->length());
   35.95  }
    36.1 --- a/src/share/vm/ci/ciObjectFactory.hpp	Thu Jun 24 15:38:42 2010 -0700
    36.2 +++ b/src/share/vm/ci/ciObjectFactory.hpp	Mon Jun 28 12:03:05 2010 -0400
    36.3 @@ -39,6 +39,7 @@
    36.4    GrowableArray<ciObject*>* _ci_objects;
    36.5    GrowableArray<ciMethod*>* _unloaded_methods;
    36.6    GrowableArray<ciKlass*>* _unloaded_klasses;
    36.7 +  GrowableArray<ciInstance*>* _unloaded_instances;
    36.8    GrowableArray<ciReturnAddress*>* _return_addresses;
    36.9    int                       _next_ident;
   36.10  
   36.11 @@ -73,6 +74,8 @@
   36.12  
   36.13    void print_contents_impl();
   36.14  
   36.15 +  ciInstance* get_unloaded_instance(ciInstanceKlass* klass);
   36.16 +
   36.17  public:
   36.18    static bool is_initialized() { return _initialized; }
   36.19  
   36.20 @@ -98,6 +101,18 @@
   36.21                                ciSymbol* name,
   36.22                                bool create_if_not_found);
   36.23  
   36.24 +  // Get a ciInstance representing an unresolved klass mirror.
   36.25 +  ciInstance* get_unloaded_klass_mirror(ciKlass* type);
   36.26 +
   36.27 +  // Get a ciInstance representing an unresolved method handle constant.
   36.28 +  ciInstance* get_unloaded_method_handle_constant(ciKlass*  holder,
   36.29 +                                                  ciSymbol* name,
   36.30 +                                                  ciSymbol* signature,
   36.31 +                                                  int       ref_kind);
   36.32 +
   36.33 +  // Get a ciInstance representing an unresolved method type constant.
   36.34 +  ciInstance* get_unloaded_method_type_constant(ciSymbol* signature);
   36.35 +
   36.36  
   36.37    // Get the ciMethodData representing the methodData for a method
   36.38    // with none.
    37.1 --- a/src/share/vm/ci/ciStreams.cpp	Thu Jun 24 15:38:42 2010 -0700
    37.2 +++ b/src/share/vm/ci/ciStreams.cpp	Mon Jun 28 12:03:05 2010 -0400
    37.3 @@ -186,12 +186,13 @@
    37.4  }
    37.5  
    37.6  // ------------------------------------------------------------------
    37.7 -// ciBytecodeStream::get_constant_index
    37.8 +// ciBytecodeStream::get_constant_raw_index
    37.9  //
   37.10  // If this bytecode is one of the ldc variants, get the index of the
   37.11  // referenced constant.
   37.12 -int ciBytecodeStream::get_constant_index() const {
   37.13 -  switch(cur_bc()) {
   37.14 +int ciBytecodeStream::get_constant_raw_index() const {
   37.15 +  // work-alike for Bytecode_loadconstant::raw_index()
   37.16 +  switch (cur_bc()) {
   37.17    case Bytecodes::_ldc:
   37.18      return get_index_u1();
   37.19    case Bytecodes::_ldc_w:
   37.20 @@ -202,25 +203,52 @@
   37.21      return 0;
   37.22    }
   37.23  }
   37.24 +
   37.25 +// ------------------------------------------------------------------
   37.26 +// ciBytecodeStream::get_constant_pool_index
   37.27 +// Decode any CP cache index into a regular pool index.
   37.28 +int ciBytecodeStream::get_constant_pool_index() const {
   37.29 +  // work-alike for Bytecode_loadconstant::pool_index()
   37.30 +  int index = get_constant_raw_index();
   37.31 +  if (has_cache_index()) {
   37.32 +    return get_cpcache()->get_pool_index(index);
   37.33 +  }
   37.34 +  return index;
   37.35 +}
   37.36 +
   37.37 +// ------------------------------------------------------------------
   37.38 +// ciBytecodeStream::get_constant_cache_index
   37.39 +// Return the CP cache index, or -1 if there isn't any.
   37.40 +int ciBytecodeStream::get_constant_cache_index() const {
   37.41 +  // work-alike for Bytecode_loadconstant::cache_index()
   37.42 +  return has_cache_index() ? get_constant_raw_index() : -1;
   37.43 +}
   37.44 +
   37.45  // ------------------------------------------------------------------
   37.46  // ciBytecodeStream::get_constant
   37.47  //
   37.48  // If this bytecode is one of the ldc variants, get the referenced
   37.49  // constant.
   37.50  ciConstant ciBytecodeStream::get_constant() {
   37.51 +  int pool_index = get_constant_raw_index();
   37.52 +  int cache_index = -1;
   37.53 +  if (has_cache_index()) {
   37.54 +    cache_index = pool_index;
   37.55 +    pool_index = -1;
   37.56 +  }
   37.57    VM_ENTRY_MARK;
   37.58    constantPoolHandle cpool(_method->get_methodOop()->constants());
   37.59 -  return CURRENT_ENV->get_constant_by_index(cpool, get_constant_index(), _holder);
   37.60 +  return CURRENT_ENV->get_constant_by_index(cpool, pool_index, cache_index, _holder);
   37.61  }
   37.62  
   37.63  // ------------------------------------------------------------------
   37.64 -bool ciBytecodeStream::is_unresolved_string() const {
   37.65 -  return CURRENT_ENV->is_unresolved_string(_holder, get_constant_index());
   37.66 -}
   37.67 -
   37.68 -// ------------------------------------------------------------------
   37.69 -bool ciBytecodeStream::is_unresolved_klass() const {
   37.70 -  return CURRENT_ENV->is_unresolved_klass(_holder, get_klass_index());
   37.71 +// ciBytecodeStream::get_constant_pool_tag
   37.72 +//
   37.73 +// If this bytecode is one of the ldc variants, get the referenced
   37.74 +// constant.
   37.75 +constantTag ciBytecodeStream::get_constant_pool_tag(int index) const {
   37.76 +  VM_ENTRY_MARK;
   37.77 +  return _method->get_methodOop()->constants()->tag_at(index);
   37.78  }
   37.79  
   37.80  // ------------------------------------------------------------------
   37.81 @@ -378,13 +406,16 @@
   37.82  
   37.83  // ------------------------------------------------------------------
   37.84  // ciBytecodeStream::get_cpcache
   37.85 -ciCPCache* ciBytecodeStream::get_cpcache() {
   37.86 -  VM_ENTRY_MARK;
   37.87 -  // Get the constant pool.
   37.88 -  constantPoolOop      cpool   = _holder->get_instanceKlass()->constants();
   37.89 -  constantPoolCacheOop cpcache = cpool->cache();
   37.90 +ciCPCache* ciBytecodeStream::get_cpcache() const {
   37.91 +  if (_cpcache == NULL) {
   37.92 +    VM_ENTRY_MARK;
   37.93 +    // Get the constant pool.
   37.94 +    constantPoolOop      cpool   = _holder->get_instanceKlass()->constants();
   37.95 +    constantPoolCacheOop cpcache = cpool->cache();
   37.96  
   37.97 -  return CURRENT_ENV->get_object(cpcache)->as_cpcache();
   37.98 +    *(ciCPCache**)&_cpcache = CURRENT_ENV->get_object(cpcache)->as_cpcache();
   37.99 +  }
  37.100 +  return _cpcache;
  37.101  }
  37.102  
  37.103  // ------------------------------------------------------------------
    38.1 --- a/src/share/vm/ci/ciStreams.hpp	Thu Jun 24 15:38:42 2010 -0700
    38.2 +++ b/src/share/vm/ci/ciStreams.hpp	Mon Jun 28 12:03:05 2010 -0400
    38.3 @@ -46,6 +46,7 @@
    38.4  
    38.5    ciMethod* _method;           // the method
    38.6    ciInstanceKlass* _holder;
    38.7 +  ciCPCache* _cpcache;
    38.8    address _bc_start;            // Start of current bytecode for table
    38.9    address _was_wide;            // Address past last wide bytecode
   38.10    jint* _table_base;            // Aligned start of last table or switch
   38.11 @@ -58,7 +59,9 @@
   38.12  
   38.13    void reset( address base, unsigned int size ) {
   38.14      _bc_start =_was_wide = 0;
   38.15 -    _start = _pc = base; _end = base + size; }
   38.16 +    _start = _pc = base; _end = base + size;
   38.17 +    _cpcache = NULL;
   38.18 +  }
   38.19  
   38.20    void assert_wide(bool require_wide) const {
   38.21      if (require_wide)
   38.22 @@ -136,15 +139,20 @@
   38.23    bool is_wide() const { return ( _pc == _was_wide ); }
   38.24  
   38.25    // Does this instruction contain an index which refes into the CP cache?
   38.26 -  bool uses_cp_cache() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); }
   38.27 +  bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); }
   38.28  
   38.29    int get_index_u1() const {
   38.30      return bytecode()->get_index_u1(cur_bc_raw());
   38.31    }
   38.32  
   38.33 +  int get_index_u1_cpcache() const {
   38.34 +    return bytecode()->get_index_u1_cpcache(cur_bc_raw());
   38.35 +  }
   38.36 +
   38.37    // Get a byte index following this bytecode.
   38.38    // If prefixed with a wide bytecode, get a wide index.
   38.39    int get_index() const {
   38.40 +    assert(!has_cache_index(), "else use cpcache variant");
   38.41      return (_pc == _was_wide)   // was widened?
   38.42        ? get_index_u2(true)      // yes, return wide index
   38.43        : get_index_u1();         // no, return narrow index
   38.44 @@ -207,7 +215,9 @@
   38.45      return cur_bci() + get_int_table(index); }
   38.46  
   38.47    // --- Constant pool access ---
   38.48 -  int get_constant_index() const;
   38.49 +  int get_constant_raw_index() const;
   38.50 +  int get_constant_pool_index() const;
   38.51 +  int get_constant_cache_index() const;
   38.52    int get_field_index();
   38.53    int get_method_index();
   38.54  
   38.55 @@ -217,12 +227,17 @@
   38.56    int get_klass_index() const;
   38.57  
   38.58    // If this bytecode is one of the ldc variants, get the referenced
   38.59 -  // constant
   38.60 +  // constant.  Do not attempt to resolve it, since that would require
   38.61 +  // execution of Java code.  If it is not resolved, return an unloaded
   38.62 +  // object (ciConstant.as_object()->is_loaded() == false).
   38.63    ciConstant get_constant();
   38.64 -  // True if the ldc variant points to an unresolved string
   38.65 -  bool is_unresolved_string() const;
   38.66 -  // True if the ldc variant points to an unresolved klass
   38.67 -  bool is_unresolved_klass() const;
   38.68 +  constantTag get_constant_pool_tag(int index) const;
   38.69 +
   38.70 +  // True if the klass-using bytecode points to an unresolved klass
   38.71 +  bool is_unresolved_klass() const {
   38.72 +    constantTag tag = get_constant_pool_tag(get_klass_index());
   38.73 +    return tag.is_unresolved_klass();
   38.74 +  }
   38.75  
   38.76    // If this bytecode is one of get_field, get_static, put_field,
   38.77    // or put_static, get the referenced field.
   38.78 @@ -238,7 +253,7 @@
   38.79    int       get_method_holder_index();
   38.80    int       get_method_signature_index();
   38.81  
   38.82 -  ciCPCache*  get_cpcache();
   38.83 +  ciCPCache*  get_cpcache() const;
   38.84    ciCallSite* get_call_site();
   38.85  };
   38.86  
    39.1 --- a/src/share/vm/ci/ciTypeFlow.cpp	Thu Jun 24 15:38:42 2010 -0700
    39.2 +++ b/src/share/vm/ci/ciTypeFlow.cpp	Mon Jun 28 12:03:05 2010 -0400
    39.3 @@ -712,10 +712,8 @@
    39.4      ciObject* obj = con.as_object();
    39.5      if (obj->is_null_object()) {
    39.6        push_null();
    39.7 -    } else if (obj->is_klass()) {
    39.8 -      // The type of ldc <class> is java.lang.Class
    39.9 -      push_object(outer()->env()->Class_klass());
   39.10      } else {
   39.11 +      assert(!obj->is_klass(), "must be java_mirror of klass");
   39.12        push_object(obj->klass());
   39.13      }
   39.14    } else {
    40.1 --- a/src/share/vm/classfile/classFileParser.cpp	Thu Jun 24 15:38:42 2010 -0700
    40.2 +++ b/src/share/vm/classfile/classFileParser.cpp	Mon Jun 28 12:03:05 2010 -0400
    40.3 @@ -117,6 +117,29 @@
    40.4            cp->string_index_at_put(index, string_index);
    40.5          }
    40.6          break;
    40.7 +      case JVM_CONSTANT_MethodHandle :
    40.8 +      case JVM_CONSTANT_MethodType :
    40.9 +        if (!EnableMethodHandles ||
   40.10 +            _major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
   40.11 +          classfile_parse_error(
   40.12 +            (!EnableInvokeDynamic ?
   40.13 +             "This JVM does not support constant tag %u in class file %s" :
   40.14 +             "Class file version does not support constant tag %u in class file %s"),
   40.15 +            tag, CHECK);
   40.16 +        }
   40.17 +        if (tag == JVM_CONSTANT_MethodHandle) {
   40.18 +          cfs->guarantee_more(4, CHECK);  // ref_kind, method_index, tag/access_flags
   40.19 +          u1 ref_kind = cfs->get_u1_fast();
   40.20 +          u2 method_index = cfs->get_u2_fast();
   40.21 +          cp->method_handle_index_at_put(index, ref_kind, method_index);
   40.22 +        } else if (tag == JVM_CONSTANT_MethodType) {
   40.23 +          cfs->guarantee_more(3, CHECK);  // signature_index, tag/access_flags
   40.24 +          u2 signature_index = cfs->get_u2_fast();
   40.25 +          cp->method_type_index_at_put(index, signature_index);
   40.26 +        } else {
   40.27 +          ShouldNotReachHere();
   40.28 +        }
   40.29 +        break;
   40.30        case JVM_CONSTANT_Integer :
   40.31          {
   40.32            cfs->guarantee_more(5, CHECK);  // bytes, tag/access_flags
   40.33 @@ -337,6 +360,60 @@
   40.34            cp->unresolved_string_at_put(index, sym);
   40.35          }
   40.36          break;
   40.37 +      case JVM_CONSTANT_MethodHandle :
   40.38 +        {
   40.39 +          int ref_index = cp->method_handle_index_at(index);
   40.40 +          check_property(
   40.41 +            valid_cp_range(ref_index, length) &&
   40.42 +                EnableMethodHandles,
   40.43 +              "Invalid constant pool index %u in class file %s",
   40.44 +              ref_index, CHECK_(nullHandle));
   40.45 +          constantTag tag = cp->tag_at(ref_index);
   40.46 +          int ref_kind  = cp->method_handle_ref_kind_at(index);
   40.47 +          switch (ref_kind) {
   40.48 +          case JVM_REF_getField:
   40.49 +          case JVM_REF_getStatic:
   40.50 +          case JVM_REF_putField:
   40.51 +          case JVM_REF_putStatic:
   40.52 +            check_property(
   40.53 +              tag.is_field(),
   40.54 +              "Invalid constant pool index %u in class file %s (not a field)",
   40.55 +              ref_index, CHECK_(nullHandle));
   40.56 +            break;
   40.57 +          case JVM_REF_invokeVirtual:
   40.58 +          case JVM_REF_invokeStatic:
   40.59 +          case JVM_REF_invokeSpecial:
   40.60 +          case JVM_REF_newInvokeSpecial:
   40.61 +            check_property(
   40.62 +              tag.is_method(),
   40.63 +              "Invalid constant pool index %u in class file %s (not a method)",
   40.64 +              ref_index, CHECK_(nullHandle));
   40.65 +            break;
   40.66 +          case JVM_REF_invokeInterface:
   40.67 +            check_property(
   40.68 +              tag.is_interface_method(),
   40.69 +              "Invalid constant pool index %u in class file %s (not an interface method)",
   40.70 +              ref_index, CHECK_(nullHandle));
   40.71 +            break;
   40.72 +          default:
   40.73 +            classfile_parse_error(
   40.74 +              "Bad method handle kind at constant pool index %u in class file %s",
   40.75 +              index, CHECK_(nullHandle));
   40.76 +          }
   40.77 +          // Keep the ref_index unchanged.  It will be indirected at link-time.
   40.78 +        }
   40.79 +        break;
   40.80 +      case JVM_CONSTANT_MethodType :
   40.81 +        {
   40.82 +          int ref_index = cp->method_type_index_at(index);
   40.83 +          check_property(
   40.84 +            valid_cp_range(ref_index, length) &&
   40.85 +                cp->tag_at(ref_index).is_utf8() &&
   40.86 +                EnableMethodHandles,
   40.87 +              "Invalid constant pool index %u in class file %s",
   40.88 +              ref_index, CHECK_(nullHandle));
   40.89 +        }
   40.90 +        break;
   40.91        default:
   40.92          fatal(err_msg("bad constant pool tag value %u",
   40.93                        cp->tag_at(index).value()));
   40.94 @@ -452,6 +529,43 @@
   40.95          }
   40.96          break;
   40.97        }
   40.98 +      case JVM_CONSTANT_MethodHandle: {
   40.99 +        int ref_index = cp->method_handle_index_at(index);
  40.100 +        int ref_kind  = cp->method_handle_ref_kind_at(index);
  40.101 +        switch (ref_kind) {
  40.102 +        case JVM_REF_invokeVirtual:
  40.103 +        case JVM_REF_invokeStatic:
  40.104 +        case JVM_REF_invokeSpecial:
  40.105 +        case JVM_REF_newInvokeSpecial:
  40.106 +          {
  40.107 +            int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index);
  40.108 +            int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index);
  40.109 +            symbolHandle name(THREAD, cp->symbol_at(name_ref_index));
  40.110 +            if (ref_kind == JVM_REF_newInvokeSpecial) {
  40.111 +              if (name() != vmSymbols::object_initializer_name()) {
  40.112 +                classfile_parse_error(
  40.113 +                  "Bad constructor name at constant pool index %u in class file %s",
  40.114 +                  name_ref_index, CHECK_(nullHandle));
  40.115 +              }
  40.116 +            } else {
  40.117 +              if (name() == vmSymbols::object_initializer_name()) {
  40.118 +                classfile_parse_error(
  40.119 +                  "Bad method name at constant pool index %u in class file %s",
  40.120 +                  name_ref_index, CHECK_(nullHandle));
  40.121 +              }
  40.122 +            }
  40.123 +          }
  40.124 +          break;
  40.125 +          // Other ref_kinds are already fully checked in previous pass.
  40.126 +        }
  40.127 +        break;
  40.128 +      }
  40.129 +      case JVM_CONSTANT_MethodType: {
  40.130 +        symbolHandle no_name = vmSymbolHandles::type_name(); // place holder
  40.131 +        symbolHandle signature(THREAD, cp->method_type_signature_at(index));
  40.132 +        verify_legal_method_signature(no_name, signature, CHECK_(nullHandle));
  40.133 +        break;
  40.134 +      }
  40.135      }  // end of switch
  40.136    }  // end of for
  40.137  
  40.138 @@ -467,7 +581,7 @@
  40.139    case JVM_CONSTANT_UnresolvedClass :
  40.140      // Patching a class means pre-resolving it.
  40.141      // The name in the constant pool is ignored.
  40.142 -    if (patch->klass() == SystemDictionary::Class_klass()) { // %%% java_lang_Class::is_instance
  40.143 +    if (java_lang_Class::is_instance(patch())) {
  40.144        guarantee_property(!java_lang_Class::is_primitive(patch()),
  40.145                           "Illegal class patch at %d in class file %s",
  40.146                           index, CHECK);
    41.1 --- a/src/share/vm/classfile/systemDictionary.cpp	Thu Jun 24 15:38:42 2010 -0700
    41.2 +++ b/src/share/vm/classfile/systemDictionary.cpp	Mon Jun 28 12:03:05 2010 -0400
    41.3 @@ -2454,6 +2454,48 @@
    41.4    return Handle(THREAD, (oop) result.get_jobject());
    41.5  }
    41.6  
    41.7 +// Ask Java code to find or construct a method handle constant.
    41.8 +Handle SystemDictionary::link_method_handle_constant(KlassHandle caller,
    41.9 +                                                     int ref_kind, //e.g., JVM_REF_invokeVirtual
   41.10 +                                                     KlassHandle callee,
   41.11 +                                                     symbolHandle name_sym,
   41.12 +                                                     symbolHandle signature,
   41.13 +                                                     TRAPS) {
   41.14 +  Handle empty;
   41.15 +  Handle name = java_lang_String::create_from_symbol(name_sym(), CHECK_(empty));
   41.16 +  Handle type;
   41.17 +  if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') {
   41.18 +    bool ignore_is_on_bcp = false;
   41.19 +    type = find_method_handle_type(signature, caller, ignore_is_on_bcp, CHECK_(empty));
   41.20 +  } else {
   41.21 +    SignatureStream ss(signature(), false);
   41.22 +    if (!ss.is_done()) {
   41.23 +      oop mirror = ss.as_java_mirror(caller->class_loader(), caller->protection_domain(),
   41.24 +                                     SignatureStream::NCDFError, CHECK_(empty));
   41.25 +      type = Handle(THREAD, mirror);
   41.26 +      ss.next();
   41.27 +      if (!ss.is_done())  type = Handle();  // error!
   41.28 +    }
   41.29 +  }
   41.30 +  if (type.is_null()) {
   41.31 +    THROW_MSG_(vmSymbols::java_lang_LinkageError(), "bad signature", empty);
   41.32 +  }
   41.33 +
   41.34 +  // call sun.dyn.MethodHandleNatives::linkMethodHandleConstant(Class caller, int refKind, Class callee, String name, Object type) -> MethodHandle
   41.35 +  JavaCallArguments args;
   41.36 +  args.push_oop(caller->java_mirror());  // the referring class
   41.37 +  args.push_int(ref_kind);
   41.38 +  args.push_oop(callee->java_mirror());  // the target class
   41.39 +  args.push_oop(name());
   41.40 +  args.push_oop(type());
   41.41 +  JavaValue result(T_OBJECT);
   41.42 +  JavaCalls::call_static(&result,
   41.43 +                         SystemDictionary::MethodHandleNatives_klass(),
   41.44 +                         vmSymbols::linkMethodHandleConstant_name(),
   41.45 +                         vmSymbols::linkMethodHandleConstant_signature(),
   41.46 +                         &args, CHECK_(empty));
   41.47 +  return Handle(THREAD, (oop) result.get_jobject());
   41.48 +}
   41.49  
   41.50  // Ask Java code to find or construct a java.dyn.CallSite for the given
   41.51  // name and signature, as interpreted relative to the given class loader.
    42.1 --- a/src/share/vm/classfile/systemDictionary.hpp	Thu Jun 24 15:38:42 2010 -0700
    42.2 +++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Jun 28 12:03:05 2010 -0400
    42.3 @@ -473,6 +473,13 @@
    42.4                                             KlassHandle accessing_klass,
    42.5                                             bool& return_bcp_flag,
    42.6                                             TRAPS);
    42.7 +  // ask Java to compute a java.dyn.MethodHandle object for a given CP entry
    42.8 +  static Handle    link_method_handle_constant(KlassHandle caller,
    42.9 +                                               int ref_kind, //e.g., JVM_REF_invokeVirtual
   42.10 +                                               KlassHandle callee,
   42.11 +                                               symbolHandle name,
   42.12 +                                               symbolHandle signature,
   42.13 +                                               TRAPS);
   42.14    // ask Java to create a dynamic call site, while linking an invokedynamic op
   42.15    static Handle    make_dynamic_call_site(Handle bootstrap_method,
   42.16                                            // Callee information:
    43.1 --- a/src/share/vm/classfile/verifier.cpp	Thu Jun 24 15:38:42 2010 -0700
    43.2 +++ b/src/share/vm/classfile/verifier.cpp	Mon Jun 28 12:03:05 2010 -0400
    43.3 @@ -1598,7 +1598,10 @@
    43.4    if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) {
    43.5      if (!tag.is_unresolved_string() && !tag.is_unresolved_klass()) {
    43.6        types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float)
    43.7 -            | (1 << JVM_CONSTANT_String)  | (1 << JVM_CONSTANT_Class);
    43.8 +            | (1 << JVM_CONSTANT_String)  | (1 << JVM_CONSTANT_Class)
    43.9 +            | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType);
   43.10 +      // Note:  The class file parser already verified the legality of
   43.11 +      // MethodHandle and MethodType constants.
   43.12        verify_cp_type(index, cp, types, CHECK_VERIFY(this));
   43.13      }
   43.14    } else {
   43.15 @@ -1632,6 +1635,14 @@
   43.16      current_frame->push_stack_2(
   43.17        VerificationType::long_type(),
   43.18        VerificationType::long2_type(), CHECK_VERIFY(this));
   43.19 +  } else if (tag.is_method_handle()) {
   43.20 +    current_frame->push_stack(
   43.21 +      VerificationType::reference_type(
   43.22 +        vmSymbols::java_dyn_MethodHandle()), CHECK_VERIFY(this));
   43.23 +  } else if (tag.is_method_type()) {
   43.24 +    current_frame->push_stack(
   43.25 +      VerificationType::reference_type(
   43.26 +        vmSymbols::java_dyn_MethodType()), CHECK_VERIFY(this));
   43.27    } else {
   43.28      verify_error(bci, "Invalid index in ldc");
   43.29      return;
   43.30 @@ -1920,9 +1931,12 @@
   43.31    // Get referenced class type
   43.32    VerificationType ref_class_type;
   43.33    if (opcode == Bytecodes::_invokedynamic) {
   43.34 -    if (!EnableInvokeDynamic) {
   43.35 +    if (!EnableInvokeDynamic ||
   43.36 +        _klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
   43.37        class_format_error(
   43.38 -        "invokedynamic instructions not enabled on this JVM",
   43.39 +        (!EnableInvokeDynamic ?
   43.40 +         "invokedynamic instructions not enabled in this JVM" :
   43.41 +         "invokedynamic instructions not supported by this class file version"),
   43.42          _klass->external_name());
   43.43        return;
   43.44      }
    44.1 --- a/src/share/vm/classfile/verifier.hpp	Thu Jun 24 15:38:42 2010 -0700
    44.2 +++ b/src/share/vm/classfile/verifier.hpp	Mon Jun 28 12:03:05 2010 -0400
    44.3 @@ -25,7 +25,10 @@
    44.4  // The verifier class
    44.5  class Verifier : AllStatic {
    44.6   public:
    44.7 -  enum { STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50 };
    44.8 +  enum {
    44.9 +    STACKMAP_ATTRIBUTE_MAJOR_VERSION    = 50,
   44.10 +    INVOKEDYNAMIC_MAJOR_VERSION         = 51
   44.11 +  };
   44.12    typedef enum { ThrowException, NoException } Mode;
   44.13  
   44.14    /**
    45.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Thu Jun 24 15:38:42 2010 -0700
    45.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Jun 28 12:03:05 2010 -0400
    45.3 @@ -246,6 +246,8 @@
    45.4    /* internal up-calls made only by the JVM, via class sun.dyn.MethodHandleNatives: */            \
    45.5    template(findMethodHandleType_name,                 "findMethodHandleType")                     \
    45.6    template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/dyn/MethodType;") \
    45.7 +  template(linkMethodHandleConstant_name,             "linkMethodHandleConstant")                 \
    45.8 +  template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/dyn/MethodHandle;") \
    45.9    template(makeDynamicCallSite_name,                  "makeDynamicCallSite")                      \
   45.10    template(makeDynamicCallSite_signature, "(Ljava/dyn/MethodHandle;Ljava/lang/String;Ljava/dyn/MethodType;Ljava/lang/Object;Lsun/dyn/MemberName;I)Ljava/dyn/CallSite;") \
   45.11    NOT_LP64(  do_alias(machine_word_signature,         int_signature)  )                           \
    46.1 --- a/src/share/vm/code/nmethod.cpp	Thu Jun 24 15:38:42 2010 -0700
    46.2 +++ b/src/share/vm/code/nmethod.cpp	Mon Jun 28 12:03:05 2010 -0400
    46.3 @@ -584,6 +584,7 @@
    46.4      _oops_do_mark_link       = NULL;
    46.5      _method                  = method;
    46.6      _entry_bci               = InvocationEntryBci;
    46.7 +    _jmethod_id              = NULL;
    46.8      _osr_link                = NULL;
    46.9      _scavenge_root_link      = NULL;
   46.10      _scavenge_root_state     = 0;
   46.11 @@ -677,6 +678,7 @@
   46.12      _oops_do_mark_link       = NULL;
   46.13      _method                  = method;
   46.14      _entry_bci               = InvocationEntryBci;
   46.15 +    _jmethod_id              = NULL;
   46.16      _osr_link                = NULL;
   46.17      _scavenge_root_link      = NULL;
   46.18      _scavenge_root_state     = 0;
   46.19 @@ -784,6 +786,7 @@
   46.20      NOT_PRODUCT(_has_debug_info = false);
   46.21      _oops_do_mark_link       = NULL;
   46.22      _method                  = method;
   46.23 +    _jmethod_id              = NULL;
   46.24      _compile_id              = compile_id;
   46.25      _comp_level              = comp_level;
   46.26      _entry_bci               = entry_bci;
   46.27 @@ -1488,11 +1491,25 @@
   46.28        moop->signature()->utf8_length(),
   46.29        code_begin(), code_size());
   46.30  
   46.31 +  if (JvmtiExport::should_post_compiled_method_load() ||
   46.32 +      JvmtiExport::should_post_compiled_method_unload()) {
   46.33 +    get_and_cache_jmethod_id();
   46.34 +  }
   46.35 +
   46.36    if (JvmtiExport::should_post_compiled_method_load()) {
   46.37      JvmtiExport::post_compiled_method_load(this);
   46.38    }
   46.39  }
   46.40  
   46.41 +jmethodID nmethod::get_and_cache_jmethod_id() {
   46.42 +  if (_jmethod_id == NULL) {
   46.43 +    // Cache the jmethod_id since it can no longer be looked up once the
   46.44 +    // method itself has been marked for unloading.
   46.45 +    _jmethod_id = method()->jmethod_id();
   46.46 +  }
   46.47 +  return _jmethod_id;
   46.48 +}
   46.49 +
   46.50  void nmethod::post_compiled_method_unload() {
   46.51    if (unload_reported()) {
   46.52      // During unloading we transition to unloaded and then to zombie
   46.53 @@ -1504,12 +1521,17 @@
   46.54    DTRACE_METHOD_UNLOAD_PROBE(method());
   46.55  
   46.56    // If a JVMTI agent has enabled the CompiledMethodUnload event then
   46.57 -  // post the event. Sometime later this nmethod will be made a zombie by
   46.58 -  // the sweeper but the methodOop will not be valid at that point.
   46.59 -  if (JvmtiExport::should_post_compiled_method_unload()) {
   46.60 +  // post the event. Sometime later this nmethod will be made a zombie
   46.61 +  // by the sweeper but the methodOop will not be valid at that point.
   46.62 +  // If the _jmethod_id is null then no load event was ever requested
   46.63 +  // so don't bother posting the unload.  The main reason for this is
   46.64 +  // that the jmethodID is a weak reference to the methodOop so if
   46.65 +  // it's being unloaded there's no way to look it up since the weak
   46.66 +  // ref will have been cleared.
   46.67 +  if (_jmethod_id != NULL && JvmtiExport::should_post_compiled_method_unload()) {
   46.68      assert(!unload_reported(), "already unloaded");
   46.69      HandleMark hm;
   46.70 -    JvmtiExport::post_compiled_method_unload(method()->jmethod_id(), code_begin());
   46.71 +    JvmtiExport::post_compiled_method_unload(_jmethod_id, code_begin());
   46.72    }
   46.73  
   46.74    // The JVMTI CompiledMethodUnload event can be enabled or disabled at
   46.75 @@ -2659,13 +2681,10 @@
   46.76          case Bytecodes::_getstatic:
   46.77          case Bytecodes::_putstatic:
   46.78            {
   46.79 -            methodHandle sdm = sd->method();
   46.80 -            Bytecode_field* field = Bytecode_field_at(sdm(), sdm->bcp_from(sd->bci()));
   46.81 -            constantPoolOop sdmc = sdm->constants();
   46.82 -            symbolOop name = sdmc->name_ref_at(field->index());
   46.83 +            Bytecode_field* field = Bytecode_field_at(sd->method(), sd->bci());
   46.84              st->print(" ");
   46.85 -            if (name != NULL)
   46.86 -              name->print_symbol_on(st);
   46.87 +            if (field->name() != NULL)
   46.88 +              field->name()->print_symbol_on(st);
   46.89              else
   46.90                st->print("<UNKNOWN>");
   46.91            }
    47.1 --- a/src/share/vm/code/nmethod.hpp	Thu Jun 24 15:38:42 2010 -0700
    47.2 +++ b/src/share/vm/code/nmethod.hpp	Mon Jun 28 12:03:05 2010 -0400
    47.3 @@ -135,6 +135,7 @@
    47.4  
    47.5    methodOop _method;
    47.6    int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
    47.7 +  jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
    47.8  
    47.9    // To support simple linked-list chaining of nmethods:
   47.10    nmethod*  _osr_link;         // from instanceKlass::osr_nmethods_head
   47.11 @@ -599,6 +600,7 @@
   47.12  
   47.13    // jvmti support:
   47.14    void post_compiled_method_load_event();
   47.15 +  jmethodID get_and_cache_jmethod_id();
   47.16  
   47.17    // verify operations
   47.18    void verify();
    48.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Jun 24 15:38:42 2010 -0700
    48.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Jun 28 12:03:05 2010 -0400
    48.3 @@ -3972,6 +3972,10 @@
    48.4  
    48.5    void work(int i) {
    48.6      if (i >= _n_workers) return;  // no work needed this round
    48.7 +
    48.8 +    double start_time_ms = os::elapsedTime() * 1000.0;
    48.9 +    _g1h->g1_policy()->record_gc_worker_start_time(i, start_time_ms);
   48.10 +
   48.11      ResourceMark rm;
   48.12      HandleMark   hm;
   48.13  
   48.14 @@ -4019,7 +4023,7 @@
   48.15        double elapsed_ms = (os::elapsedTime()-start)*1000.0;
   48.16        double term_ms = pss.term_time()*1000.0;
   48.17        _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms);
   48.18 -      _g1h->g1_policy()->record_termination_time(i, term_ms);
   48.19 +      _g1h->g1_policy()->record_termination(i, term_ms, pss.term_attempts());
   48.20      }
   48.21      _g1h->g1_policy()->record_thread_age_table(pss.age_table());
   48.22      _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
   48.23 @@ -4043,7 +4047,8 @@
   48.24        double term         = pss.term_time();
   48.25        gclog_or_tty->print("  Elapsed: %7.2f ms.\n"
   48.26                            "    Strong roots: %7.2f ms (%6.2f%%)\n"
   48.27 -                          "    Termination:  %7.2f ms (%6.2f%%) (in %d entries)\n",
   48.28 +                          "    Termination:  %7.2f ms (%6.2f%%) "
   48.29 +                                                 "(in "SIZE_FORMAT" entries)\n",
   48.30                            elapsed * 1000.0,
   48.31                            strong_roots * 1000.0, (strong_roots*100.0/elapsed),
   48.32                            term * 1000.0, (term*100.0/elapsed),
   48.33 @@ -4059,6 +4064,8 @@
   48.34  
   48.35      assert(pss.refs_to_scan() == 0, "Task queue should be empty");
   48.36      assert(pss.overflowed_refs_to_scan() == 0, "Overflow queue should be empty");
   48.37 +    double end_time_ms = os::elapsedTime() * 1000.0;
   48.38 +    _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms);
   48.39    }
   48.40  };
   48.41  
    49.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Jun 24 15:38:42 2010 -0700
    49.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Mon Jun 28 12:03:05 2010 -0400
    49.3 @@ -1549,7 +1549,7 @@
    49.4    int _hash_seed;
    49.5    int _queue_num;
    49.6  
    49.7 -  int _term_attempts;
    49.8 +  size_t _term_attempts;
    49.9  #if G1_DETAILED_STATS
   49.10    int _pushes, _pops, _steals, _steal_attempts;
   49.11    int _overflow_pushes;
   49.12 @@ -1727,8 +1727,8 @@
   49.13    int* hash_seed() { return &_hash_seed; }
   49.14    int  queue_num() { return _queue_num; }
   49.15  
   49.16 -  int term_attempts()   { return _term_attempts; }
   49.17 -  void note_term_attempt()  { _term_attempts++; }
   49.18 +  size_t term_attempts()   { return _term_attempts; }
   49.19 +  void note_term_attempt() { _term_attempts++; }
   49.20  
   49.21  #if G1_DETAILED_STATS
   49.22    int pushes()          { return _pushes; }
    50.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Jun 24 15:38:42 2010 -0700
    50.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Mon Jun 28 12:03:05 2010 -0400
    50.3 @@ -231,20 +231,21 @@
    50.4    _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
    50.5    _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
    50.6  
    50.7 +  _par_last_gc_worker_start_times_ms = new double[_parallel_gc_threads];
    50.8    _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads];
    50.9    _par_last_mark_stack_scan_times_ms = new double[_parallel_gc_threads];
   50.10  
   50.11 -  _par_last_update_rs_start_times_ms = new double[_parallel_gc_threads];
   50.12    _par_last_update_rs_times_ms = new double[_parallel_gc_threads];
   50.13    _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads];
   50.14  
   50.15 -  _par_last_scan_rs_start_times_ms = new double[_parallel_gc_threads];
   50.16    _par_last_scan_rs_times_ms = new double[_parallel_gc_threads];
   50.17    _par_last_scan_new_refs_times_ms = new double[_parallel_gc_threads];
   50.18  
   50.19    _par_last_obj_copy_times_ms = new double[_parallel_gc_threads];
   50.20  
   50.21    _par_last_termination_times_ms = new double[_parallel_gc_threads];
   50.22 +  _par_last_termination_attempts = new double[_parallel_gc_threads];
   50.23 +  _par_last_gc_worker_end_times_ms = new double[_parallel_gc_threads];
   50.24  
   50.25    // start conservatively
   50.26    _expensive_region_limit_ms = 0.5 * (double) MaxGCPauseMillis;
   50.27 @@ -274,10 +275,64 @@
   50.28  
   50.29    // </NEW PREDICTION>
   50.30  
   50.31 +  // Below, we might need to calculate the pause time target based on
   50.32 +  // the pause interval. When we do so we are going to give G1 maximum
   50.33 +  // flexibility and allow it to do pauses when it needs to. So, we'll
   50.34 +  // arrange that the pause interval to be pause time target + 1 to
   50.35 +  // ensure that a) the pause time target is maximized with respect to
   50.36 +  // the pause interval and b) we maintain the invariant that pause
   50.37 +  // time target < pause interval. If the user does not want this
   50.38 +  // maximum flexibility, they will have to set the pause interval
   50.39 +  // explicitly.
   50.40 +
   50.41 +  // First make sure that, if either parameter is set, its value is
   50.42 +  // reasonable.
   50.43 +  if (!FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
   50.44 +    if (MaxGCPauseMillis < 1) {
   50.45 +      vm_exit_during_initialization("MaxGCPauseMillis should be "
   50.46 +                                    "greater than 0");
   50.47 +    }
   50.48 +  }
   50.49 +  if (!FLAG_IS_DEFAULT(GCPauseIntervalMillis)) {
   50.50 +    if (GCPauseIntervalMillis < 1) {
   50.51 +      vm_exit_during_initialization("GCPauseIntervalMillis should be "
   50.52 +                                    "greater than 0");
   50.53 +    }
   50.54 +  }
   50.55 +
   50.56 +  // Then, if the pause time target parameter was not set, set it to
   50.57 +  // the default value.
   50.58 +  if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
   50.59 +    if (FLAG_IS_DEFAULT(GCPauseIntervalMillis)) {
   50.60 +      // The default pause time target in G1 is 200ms
   50.61 +      FLAG_SET_DEFAULT(MaxGCPauseMillis, 200);
   50.62 +    } else {
   50.63 +      // We do not allow the pause interval to be set without the
   50.64 +      // pause time target
   50.65 +      vm_exit_during_initialization("GCPauseIntervalMillis cannot be set "
   50.66 +                                    "without setting MaxGCPauseMillis");
   50.67 +    }
   50.68 +  }
   50.69 +
   50.70 +  // Then, if the interval parameter was not set, set it according to
   50.71 +  // the pause time target (this will also deal with the case when the
   50.72 +  // pause time target is the default value).
   50.73 +  if (FLAG_IS_DEFAULT(GCPauseIntervalMillis)) {
   50.74 +    FLAG_SET_DEFAULT(GCPauseIntervalMillis, MaxGCPauseMillis + 1);
   50.75 +  }
   50.76 +
   50.77 +  // Finally, make sure that the two parameters are consistent.
   50.78 +  if (MaxGCPauseMillis >= GCPauseIntervalMillis) {
   50.79 +    char buffer[256];
   50.80 +    jio_snprintf(buffer, 256,
   50.81 +                 "MaxGCPauseMillis (%u) should be less than "
   50.82 +                 "GCPauseIntervalMillis (%u)",
   50.83 +                 MaxGCPauseMillis, GCPauseIntervalMillis);
   50.84 +    vm_exit_during_initialization(buffer);
   50.85 +  }
   50.86 +
   50.87 +  double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
   50.88    double time_slice  = (double) GCPauseIntervalMillis / 1000.0;
   50.89 -  double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
   50.90 -  guarantee(max_gc_time < time_slice,
   50.91 -            "Max GC time should not be greater than the time slice");
   50.92    _mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
   50.93    _sigma = (double) G1ConfidencePercent / 100.0;
   50.94  
   50.95 @@ -782,16 +837,17 @@
   50.96    // if they are not set properly
   50.97  
   50.98    for (int i = 0; i < _parallel_gc_threads; ++i) {
   50.99 -    _par_last_ext_root_scan_times_ms[i] = -666.0;
  50.100 -    _par_last_mark_stack_scan_times_ms[i] = -666.0;
  50.101 -    _par_last_update_rs_start_times_ms[i] = -666.0;
  50.102 -    _par_last_update_rs_times_ms[i] = -666.0;
  50.103 -    _par_last_update_rs_processed_buffers[i] = -666.0;
  50.104 -    _par_last_scan_rs_start_times_ms[i] = -666.0;
  50.105 -    _par_last_scan_rs_times_ms[i] = -666.0;
  50.106 -    _par_last_scan_new_refs_times_ms[i] = -666.0;
  50.107 -    _par_last_obj_copy_times_ms[i] = -666.0;
  50.108 -    _par_last_termination_times_ms[i] = -666.0;
  50.109 +    _par_last_gc_worker_start_times_ms[i] = -1234.0;
  50.110 +    _par_last_ext_root_scan_times_ms[i] = -1234.0;
  50.111 +    _par_last_mark_stack_scan_times_ms[i] = -1234.0;
  50.112 +    _par_last_update_rs_times_ms[i] = -1234.0;
  50.113 +    _par_last_update_rs_processed_buffers[i] = -1234.0;
  50.114 +    _par_last_scan_rs_times_ms[i] = -1234.0;
  50.115 +    _par_last_scan_new_refs_times_ms[i] = -1234.0;
  50.116 +    _par_last_obj_copy_times_ms[i] = -1234.0;
  50.117 +    _par_last_termination_times_ms[i] = -1234.0;
  50.118 +    _par_last_termination_attempts[i] = -1234.0;
  50.119 +    _par_last_gc_worker_end_times_ms[i] = -1234.0;
  50.120    }
  50.121  #endif
  50.122  
  50.123 @@ -942,9 +998,9 @@
  50.124    return sum;
  50.125  }
  50.126  
  50.127 -void G1CollectorPolicy::print_par_stats (int level,
  50.128 -                                         const char* str,
  50.129 -                                         double* data,
  50.130 +void G1CollectorPolicy::print_par_stats(int level,
  50.131 +                                        const char* str,
  50.132 +                                        double* data,
  50.133                                           bool summary) {
  50.134    double min = data[0], max = data[0];
  50.135    double total = 0.0;
  50.136 @@ -973,10 +1029,10 @@
  50.137    gclog_or_tty->print_cr("]");
  50.138  }
  50.139  
  50.140 -void G1CollectorPolicy::print_par_buffers (int level,
  50.141 -                                         const char* str,
  50.142 -                                         double* data,
  50.143 -                                         bool summary) {
  50.144 +void G1CollectorPolicy::print_par_sizes(int level,
  50.145 +                                        const char* str,
  50.146 +                                        double* data,
  50.147 +                                        bool summary) {
  50.148    double min = data[0], max = data[0];
  50.149    double total = 0.0;
  50.150    int j;
  50.151 @@ -1321,15 +1377,22 @@
  50.152        }
  50.153        if (parallel) {
  50.154          print_stats(1, "Parallel Time", _cur_collection_par_time_ms);
  50.155 -        print_par_stats(2, "Update RS (Start)", _par_last_update_rs_start_times_ms, false);
  50.156 +        print_par_stats(2, "GC Worker Start Time",
  50.157 +                        _par_last_gc_worker_start_times_ms, false);
  50.158          print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
  50.159 -        print_par_buffers(3, "Processed Buffers",
  50.160 -                          _par_last_update_rs_processed_buffers, true);
  50.161 -        print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
  50.162 -        print_par_stats(2, "Mark Stack Scanning", _par_last_mark_stack_scan_times_ms);
  50.163 +        print_par_sizes(3, "Processed Buffers",
  50.164 +                        _par_last_update_rs_processed_buffers, true);
  50.165 +        print_par_stats(2, "Ext Root Scanning",
  50.166 +                        _par_last_ext_root_scan_times_ms);
  50.167 +        print_par_stats(2, "Mark Stack Scanning",
  50.168 +                        _par_last_mark_stack_scan_times_ms);
  50.169          print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms);
  50.170          print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms);
  50.171          print_par_stats(2, "Termination", _par_last_termination_times_ms);
  50.172 +        print_par_sizes(3, "Termination Attempts",
  50.173 +                        _par_last_termination_attempts, true);
  50.174 +        print_par_stats(2, "GC Worker End Time",
  50.175 +                        _par_last_gc_worker_end_times_ms, false);
  50.176          print_stats(2, "Other", parallel_other_time);
  50.177          print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
  50.178        } else {
    51.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Thu Jun 24 15:38:42 2010 -0700
    51.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Mon Jun 28 12:03:05 2010 -0400
    51.3 @@ -171,16 +171,17 @@
    51.4    double*    _cur_aux_times_ms;
    51.5    bool*      _cur_aux_times_set;
    51.6  
    51.7 +  double* _par_last_gc_worker_start_times_ms;
    51.8    double* _par_last_ext_root_scan_times_ms;
    51.9    double* _par_last_mark_stack_scan_times_ms;
   51.10 -  double* _par_last_update_rs_start_times_ms;
   51.11    double* _par_last_update_rs_times_ms;
   51.12    double* _par_last_update_rs_processed_buffers;
   51.13 -  double* _par_last_scan_rs_start_times_ms;
   51.14    double* _par_last_scan_rs_times_ms;
   51.15    double* _par_last_scan_new_refs_times_ms;
   51.16    double* _par_last_obj_copy_times_ms;
   51.17    double* _par_last_termination_times_ms;
   51.18 +  double* _par_last_termination_attempts;
   51.19 +  double* _par_last_gc_worker_end_times_ms;
   51.20  
   51.21    // indicates that we are in young GC mode
   51.22    bool _in_young_gc_mode;
   51.23 @@ -559,13 +560,14 @@
   51.24    }
   51.25  
   51.26  protected:
   51.27 -  void print_stats (int level, const char* str, double value);
   51.28 -  void print_stats (int level, const char* str, int value);
   51.29 -  void print_par_stats (int level, const char* str, double* data) {
   51.30 +  void print_stats(int level, const char* str, double value);
   51.31 +  void print_stats(int level, const char* str, int value);
   51.32 +
   51.33 +  void print_par_stats(int level, const char* str, double* data) {
   51.34      print_par_stats(level, str, data, true);
   51.35    }
   51.36 -  void print_par_stats (int level, const char* str, double* data, bool summary);
   51.37 -  void print_par_buffers (int level, const char* str, double* data, bool summary);
   51.38 +  void print_par_stats(int level, const char* str, double* data, bool summary);
   51.39 +  void print_par_sizes(int level, const char* str, double* data, bool summary);
   51.40  
   51.41    void check_other_times(int level,
   51.42                           NumberSeq* other_times_ms,
   51.43 @@ -891,6 +893,10 @@
   51.44    virtual void record_full_collection_start();
   51.45    virtual void record_full_collection_end();
   51.46  
   51.47 +  void record_gc_worker_start_time(int worker_i, double ms) {
   51.48 +    _par_last_gc_worker_start_times_ms[worker_i] = ms;
   51.49 +  }
   51.50 +
   51.51    void record_ext_root_scan_time(int worker_i, double ms) {
   51.52      _par_last_ext_root_scan_times_ms[worker_i] = ms;
   51.53    }
   51.54 @@ -912,10 +918,6 @@
   51.55      _all_mod_union_times_ms->add(ms);
   51.56    }
   51.57  
   51.58 -  void record_update_rs_start_time(int thread, double ms) {
   51.59 -    _par_last_update_rs_start_times_ms[thread] = ms;
   51.60 -  }
   51.61 -
   51.62    void record_update_rs_time(int thread, double ms) {
   51.63      _par_last_update_rs_times_ms[thread] = ms;
   51.64    }
   51.65 @@ -925,10 +927,6 @@
   51.66      _par_last_update_rs_processed_buffers[thread] = processed_buffers;
   51.67    }
   51.68  
   51.69 -  void record_scan_rs_start_time(int thread, double ms) {
   51.70 -    _par_last_scan_rs_start_times_ms[thread] = ms;
   51.71 -  }
   51.72 -
   51.73    void record_scan_rs_time(int thread, double ms) {
   51.74      _par_last_scan_rs_times_ms[thread] = ms;
   51.75    }
   51.76 @@ -953,16 +951,13 @@
   51.77      _par_last_obj_copy_times_ms[thread] += ms;
   51.78    }
   51.79  
   51.80 -  void record_obj_copy_time(double ms) {
   51.81 -    record_obj_copy_time(0, ms);
   51.82 +  void record_termination(int thread, double ms, size_t attempts) {
   51.83 +    _par_last_termination_times_ms[thread] = ms;
   51.84 +    _par_last_termination_attempts[thread] = (double) attempts;
   51.85    }
   51.86  
   51.87 -  void record_termination_time(int thread, double ms) {
   51.88 -    _par_last_termination_times_ms[thread] = ms;
   51.89 -  }
   51.90 -
   51.91 -  void record_termination_time(double ms) {
   51.92 -    record_termination_time(0, ms);
   51.93 +  void record_gc_worker_end_time(int worker_i, double ms) {
   51.94 +    _par_last_gc_worker_end_times_ms[worker_i] = ms;
   51.95    }
   51.96  
   51.97    void record_pause_time_ms(double ms) {
    52.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu Jun 24 15:38:42 2010 -0700
    52.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Mon Jun 28 12:03:05 2010 -0400
    52.3 @@ -303,7 +303,6 @@
    52.4    assert( _cards_scanned != NULL, "invariant" );
    52.5    _cards_scanned[worker_i] = scanRScl.cards_done();
    52.6  
    52.7 -  _g1p->record_scan_rs_start_time(worker_i, rs_time_start * 1000.0);
    52.8    _g1p->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
    52.9  }
   52.10  
   52.11 @@ -311,8 +310,6 @@
   52.12    ConcurrentG1Refine* cg1r = _g1->concurrent_g1_refine();
   52.13  
   52.14    double start = os::elapsedTime();
   52.15 -  _g1p->record_update_rs_start_time(worker_i, start * 1000.0);
   52.16 -
   52.17    // Apply the appropriate closure to all remaining log entries.
   52.18    _g1->iterate_dirty_card_closure(false, worker_i);
   52.19    // Now there should be no dirty cards.
   52.20 @@ -471,7 +468,6 @@
   52.21        updateRS(worker_i);
   52.22        scanNewRefsRS(oc, worker_i);
   52.23      } else {
   52.24 -      _g1p->record_update_rs_start_time(worker_i, os::elapsedTime() * 1000.0);
   52.25        _g1p->record_update_rs_processed_buffers(worker_i, 0.0);
   52.26        _g1p->record_update_rs_time(worker_i, 0.0);
   52.27        _g1p->record_scan_new_refs_time(worker_i, 0.0);
   52.28 @@ -479,7 +475,6 @@
   52.29      if (G1UseParallelRSetScanning || (worker_i == 0)) {
   52.30        scanRS(oc, worker_i);
   52.31      } else {
   52.32 -      _g1p->record_scan_rs_start_time(worker_i, os::elapsedTime() * 1000.0);
   52.33        _g1p->record_scan_rs_time(worker_i, 0.0);
   52.34      }
   52.35    } else {
    53.1 --- a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Thu Jun 24 15:38:42 2010 -0700
    53.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp	Mon Jun 28 12:03:05 2010 -0400
    53.3 @@ -1,5 +1,5 @@
    53.4  /*
    53.5 - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
    53.6 + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
    53.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    53.8   *
    53.9   * This code is free software; you can redistribute it and/or modify it
   53.10 @@ -566,14 +566,14 @@
   53.11  #endif
   53.12  
   53.13    // Commit new or uncommit old pages, if necessary.
   53.14 -  resize_commit_uncommit(changed_region, new_region);
   53.15 +  if (resize_commit_uncommit(changed_region, new_region)) {
   53.16 +    // Set the new start of the committed region
   53.17 +    resize_update_committed_table(changed_region, new_region);
   53.18 +  }
   53.19  
   53.20    // Update card table entries
   53.21    resize_update_card_table_entries(changed_region, new_region);
   53.22  
   53.23 -  // Set the new start of the committed region
   53.24 -  resize_update_committed_table(changed_region, new_region);
   53.25 -
   53.26    // Update the covered region
   53.27    resize_update_covered_table(changed_region, new_region);
   53.28  
   53.29 @@ -604,8 +604,9 @@
   53.30    debug_only(verify_guard();)
   53.31  }
   53.32  
   53.33 -void CardTableExtension::resize_commit_uncommit(int changed_region,
   53.34 +bool CardTableExtension::resize_commit_uncommit(int changed_region,
   53.35                                                  MemRegion new_region) {
   53.36 +  bool result = false;
   53.37    // Commit new or uncommit old pages, if necessary.
   53.38    MemRegion cur_committed = _committed[changed_region];
   53.39    assert(_covered[changed_region].end() == new_region.end(),
   53.40 @@ -675,20 +676,31 @@
   53.41                                "card table expansion");
   53.42        }
   53.43      }
   53.44 +    result = true;
   53.45    } else if (new_start_aligned > cur_committed.start()) {
   53.46      // Shrink the committed region
   53.47 +#if 0 // uncommitting space is currently unsafe because of the interactions
   53.48 +      // of growing and shrinking regions.  One region A can uncommit space
   53.49 +      // that it owns but which is being used by another region B (maybe).
   53.50 +      // Region B has not committed the space because it was already
   53.51 +      // committed by region A.
   53.52      MemRegion uncommit_region = committed_unique_to_self(changed_region,
   53.53        MemRegion(cur_committed.start(), new_start_aligned));
   53.54      if (!uncommit_region.is_empty()) {
   53.55        if (!os::uncommit_memory((char*)uncommit_region.start(),
   53.56                                 uncommit_region.byte_size())) {
   53.57 -        vm_exit_out_of_memory(uncommit_region.byte_size(),
   53.58 -          "card table contraction");
   53.59 +        // If the uncommit fails, ignore it.  Let the
   53.60 +        // committed table resizing go even though the committed
   53.61 +        // table will over state the committed space.
   53.62        }
   53.63      }
   53.64 +#else
   53.65 +    assert(!result, "Should be false with current workaround");
   53.66 +#endif
   53.67    }
   53.68    assert(_committed[changed_region].end() == cur_committed.end(),
   53.69      "end should not change");
   53.70 +  return result;
   53.71  }
   53.72  
   53.73  void CardTableExtension::resize_update_committed_table(int changed_region,
    54.1 --- a/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp	Thu Jun 24 15:38:42 2010 -0700
    54.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp	Mon Jun 28 12:03:05 2010 -0400
    54.3 @@ -1,5 +1,5 @@
    54.4  /*
    54.5 - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
    54.6 + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
    54.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    54.8   *
    54.9   * This code is free software; you can redistribute it and/or modify it
   54.10 @@ -30,7 +30,9 @@
   54.11  class CardTableExtension : public CardTableModRefBS {
   54.12   private:
   54.13    // Support methods for resizing the card table.
   54.14 -  void resize_commit_uncommit(int changed_region, MemRegion new_region);
   54.15 +  // resize_commit_uncommit() returns true if the pages were committed or
   54.16 +  // uncommitted
   54.17 +  bool resize_commit_uncommit(int changed_region, MemRegion new_region);
   54.18    void resize_update_card_table_entries(int changed_region,
   54.19                                          MemRegion new_region);
   54.20    void resize_update_committed_table(int changed_region, MemRegion new_region);
    55.1 --- a/src/share/vm/includeDB_core	Thu Jun 24 15:38:42 2010 -0700
    55.2 +++ b/src/share/vm/includeDB_core	Mon Jun 28 12:03:05 2010 -0400
    55.3 @@ -545,6 +545,7 @@
    55.4  
    55.5  ciCPCache.hpp                           ciClassList.hpp
    55.6  ciCPCache.hpp                           ciObject.hpp
    55.7 +ciCPCache.hpp                           cpCacheOop.hpp
    55.8  
    55.9  ciEnv.cpp                               allocation.inline.hpp
   55.10  ciEnv.cpp                               ciConstant.hpp
   55.11 @@ -823,6 +824,7 @@
   55.12  
   55.13  ciStreams.cpp                           ciCallSite.hpp
   55.14  ciStreams.cpp                           ciConstant.hpp
   55.15 +ciStreams.cpp                           ciCPCache.hpp
   55.16  ciStreams.cpp                           ciField.hpp
   55.17  ciStreams.cpp                           ciStreams.hpp
   55.18  ciStreams.cpp                           ciUtilities.hpp
    56.1 --- a/src/share/vm/interpreter/bytecode.cpp	Thu Jun 24 15:38:42 2010 -0700
    56.2 +++ b/src/share/vm/interpreter/bytecode.cpp	Mon Jun 28 12:03:05 2010 -0400
    56.3 @@ -136,25 +136,24 @@
    56.4  // Implementation of Bytecode_invoke
    56.5  
    56.6  void Bytecode_invoke::verify() const {
    56.7 -  Bytecodes::Code bc = adjusted_invoke_code();
    56.8    assert(is_valid(), "check invoke");
    56.9    assert(method()->constants()->cache() != NULL, "do not call this from verifier or rewriter");
   56.10  }
   56.11  
   56.12  
   56.13 -symbolOop Bytecode_invoke::signature() const {
   56.14 +symbolOop Bytecode_member_ref::signature() const {
   56.15    constantPoolOop constants = method()->constants();
   56.16    return constants->signature_ref_at(index());
   56.17  }
   56.18  
   56.19  
   56.20 -symbolOop Bytecode_invoke::name() const {
   56.21 +symbolOop Bytecode_member_ref::name() const {
   56.22    constantPoolOop constants = method()->constants();
   56.23    return constants->name_ref_at(index());
   56.24  }
   56.25  
   56.26  
   56.27 -BasicType Bytecode_invoke::result_type(Thread *thread) const {
   56.28 +BasicType Bytecode_member_ref::result_type(Thread *thread) const {
   56.29    symbolHandle sh(thread, signature());
   56.30    ResultTypeFinder rts(sh);
   56.31    rts.iterate();
   56.32 @@ -167,9 +166,9 @@
   56.33    KlassHandle resolved_klass;
   56.34    constantPoolHandle constants(THREAD, _method->constants());
   56.35  
   56.36 -  if (adjusted_invoke_code() == Bytecodes::_invokedynamic) {
   56.37 +  if (java_code() == Bytecodes::_invokedynamic) {
   56.38      LinkResolver::resolve_dynamic_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
   56.39 -  } else if (adjusted_invoke_code() != Bytecodes::_invokeinterface) {
   56.40 +  } else if (java_code() != Bytecodes::_invokeinterface) {
   56.41      LinkResolver::resolve_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
   56.42    } else {
   56.43      LinkResolver::resolve_interface_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
   56.44 @@ -178,51 +177,68 @@
   56.45  }
   56.46  
   56.47  
   56.48 -int Bytecode_invoke::index() const {
   56.49 +int Bytecode_member_ref::index() const {
   56.50    // Note:  Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4,
   56.51    // at the same time it allocates per-call-site CP cache entries.
   56.52 -  Bytecodes::Code stdc = Bytecodes::java_code(code());
   56.53 -  Bytecode* invoke = Bytecode_at(bcp());
   56.54 -  if (invoke->has_index_u4(stdc))
   56.55 -    return invoke->get_index_u4(stdc);
   56.56 +  Bytecodes::Code rawc = code();
   56.57 +  Bytecode* invoke = bytecode();
   56.58 +  if (invoke->has_index_u4(rawc))
   56.59 +    return invoke->get_index_u4(rawc);
   56.60    else
   56.61 -    return invoke->get_index_u2_cpcache(stdc);
   56.62 +    return invoke->get_index_u2_cpcache(rawc);
   56.63  }
   56.64  
   56.65 +int Bytecode_member_ref::pool_index() const {
   56.66 +  int index = this->index();
   56.67 +  DEBUG_ONLY({
   56.68 +      if (!bytecode()->has_index_u4(code()))
   56.69 +        index -= constantPoolOopDesc::CPCACHE_INDEX_TAG;
   56.70 +    });
   56.71 +  return _method->constants()->cache()->entry_at(index)->constant_pool_index();
   56.72 +}
   56.73  
   56.74  // Implementation of Bytecode_field
   56.75  
   56.76  void Bytecode_field::verify() const {
   56.77 -  Bytecodes::Code stdc = Bytecodes::java_code(code());
   56.78 -  assert(stdc == Bytecodes::_putstatic || stdc == Bytecodes::_getstatic ||
   56.79 -         stdc == Bytecodes::_putfield  || stdc == Bytecodes::_getfield, "check field");
   56.80 +  assert(is_valid(), "check field");
   56.81  }
   56.82  
   56.83  
   56.84 -bool Bytecode_field::is_static() const {
   56.85 -  Bytecodes::Code stdc = Bytecodes::java_code(code());
   56.86 -  return stdc == Bytecodes::_putstatic || stdc == Bytecodes::_getstatic;
   56.87 +// Implementation of Bytecode_loadconstant
   56.88 +
   56.89 +int Bytecode_loadconstant::raw_index() const {
   56.90 +  Bytecode* bcp = bytecode();
   56.91 +  Bytecodes::Code rawc = bcp->code();
   56.92 +  assert(rawc != Bytecodes::_wide, "verifier prevents this");
   56.93 +  if (Bytecodes::java_code(rawc) == Bytecodes::_ldc)
   56.94 +    return bcp->get_index_u1(rawc);
   56.95 +  else
   56.96 +    return bcp->get_index_u2(rawc, false);
   56.97  }
   56.98  
   56.99 -
  56.100 -int Bytecode_field::index() const {
  56.101 -  Bytecode* invoke = Bytecode_at(bcp());
  56.102 -  return invoke->get_index_u2_cpcache(Bytecodes::_getfield);
  56.103 +int Bytecode_loadconstant::pool_index() const {
  56.104 +  int index = raw_index();
  56.105 +  if (has_cache_index()) {
  56.106 +    return _method->constants()->cache()->entry_at(index)->constant_pool_index();
  56.107 +  }
  56.108 +  return index;
  56.109  }
  56.110  
  56.111 +BasicType Bytecode_loadconstant::result_type() const {
  56.112 +  int index = pool_index();
  56.113 +  constantTag tag = _method->constants()->tag_at(index);
  56.114 +  return tag.basic_type();
  56.115 +}
  56.116  
  56.117 -// Implementation of Bytecodes loac constant
  56.118 -
  56.119 -int Bytecode_loadconstant::index() const {
  56.120 -  Bytecodes::Code stdc = Bytecodes::java_code(code());
  56.121 -  if (stdc != Bytecodes::_wide) {
  56.122 -    if (Bytecodes::java_code(stdc) == Bytecodes::_ldc)
  56.123 -      return get_index_u1(stdc);
  56.124 -    else
  56.125 -      return get_index_u2(stdc, false);
  56.126 +oop Bytecode_loadconstant::resolve_constant(TRAPS) const {
  56.127 +  assert(_method.not_null(), "must supply method to resolve constant");
  56.128 +  int index = raw_index();
  56.129 +  constantPoolOop constants = _method->constants();
  56.130 +  if (has_cache_index()) {
  56.131 +    return constants->resolve_cached_constant_at(index, THREAD);
  56.132 +  } else {
  56.133 +    return constants->resolve_constant_at(index, THREAD);
  56.134    }
  56.135 -  stdc = Bytecodes::code_at(addr_at(1));
  56.136 -  return get_index_u2(stdc, true);
  56.137  }
  56.138  
  56.139  //------------------------------------------------------------------------------
    57.1 --- a/src/share/vm/interpreter/bytecode.hpp	Thu Jun 24 15:38:42 2010 -0700
    57.2 +++ b/src/share/vm/interpreter/bytecode.hpp	Mon Jun 28 12:03:05 2010 -0400
    57.3 @@ -76,9 +76,13 @@
    57.4            return Bytes::get_native_u2(p);
    57.5      else  return Bytes::get_Java_u2(p);
    57.6    }
    57.7 +  int get_index_u1_cpcache(Bytecodes::Code bc) const {
    57.8 +    assert_same_format_as(bc); assert_index_size(1, bc);
    57.9 +    return *(jubyte*)addr_at(1) + constantPoolOopDesc::CPCACHE_INDEX_TAG;
   57.10 +  }
   57.11    int get_index_u2_cpcache(Bytecodes::Code bc) const {
   57.12      assert_same_format_as(bc); assert_index_size(2, bc); assert_native_index(bc);
   57.13 -    return Bytes::get_native_u2(addr_at(1)) DEBUG_ONLY(+ constantPoolOopDesc::CPCACHE_INDEX_TAG);
   57.14 +    return Bytes::get_native_u2(addr_at(1)) + constantPoolOopDesc::CPCACHE_INDEX_TAG;
   57.15    }
   57.16    int get_index_u4(Bytecodes::Code bc) const {
   57.17      assert_same_format_as(bc); assert_index_size(4, bc);
   57.18 @@ -152,7 +156,7 @@
   57.19  
   57.20  inline Bytecode_lookupswitch* Bytecode_lookupswitch_at(address bcp) {
   57.21    Bytecode_lookupswitch* b = (Bytecode_lookupswitch*)bcp;
   57.22 -  debug_only(b->verify());
   57.23 +  DEBUG_ONLY(b->verify());
   57.24    return b;
   57.25  }
   57.26  
   57.27 @@ -174,44 +178,56 @@
   57.28  
   57.29  inline Bytecode_tableswitch* Bytecode_tableswitch_at(address bcp) {
   57.30    Bytecode_tableswitch* b = (Bytecode_tableswitch*)bcp;
   57.31 -  debug_only(b->verify());
   57.32 +  DEBUG_ONLY(b->verify());
   57.33    return b;
   57.34  }
   57.35  
   57.36  
   57.37 -// Abstraction for invoke_{virtual, static, interface, special}
   57.38 +// Common code for decoding invokes and field references.
   57.39  
   57.40 -class Bytecode_invoke: public ResourceObj {
   57.41 +class Bytecode_member_ref: public ResourceObj {
   57.42   protected:
   57.43    methodHandle _method;                          // method containing the bytecode
   57.44    int          _bci;                             // position of the bytecode
   57.45  
   57.46 -  Bytecode_invoke(methodHandle method, int bci)  : _method(method), _bci(bci) {}
   57.47 +  Bytecode_member_ref(methodHandle method, int bci)  : _method(method), _bci(bci) {}
   57.48 +
   57.49 + public:
   57.50 +  // Attributes
   57.51 +  methodHandle method() const                    { return _method; }
   57.52 +  int          bci() const                       { return _bci; }
   57.53 +  address      bcp() const                       { return _method->bcp_from(bci()); }
   57.54 +  Bytecode*    bytecode() const                  { return Bytecode_at(bcp()); }
   57.55 +
   57.56 +  int          index() const;                    // cache index (loaded from instruction)
   57.57 +  int          pool_index() const;               // constant pool index
   57.58 +  symbolOop    name() const;                     // returns the name of the method or field
   57.59 +  symbolOop    signature() const;                // returns the signature of the method or field
   57.60 +
   57.61 +  BasicType    result_type(Thread* thread) const; // returns the result type of the getfield or invoke
   57.62 +
   57.63 +  Bytecodes::Code code() const                   { return Bytecodes::code_at(bcp(), _method()); }
   57.64 +  Bytecodes::Code java_code() const              { return Bytecodes::java_code(code()); }
   57.65 +};
   57.66 +
   57.67 +// Abstraction for invoke_{virtual, static, interface, special}
   57.68 +
   57.69 +class Bytecode_invoke: public Bytecode_member_ref {
   57.70 + protected:
   57.71 +  Bytecode_invoke(methodHandle method, int bci)  : Bytecode_member_ref(method, bci) {}
   57.72  
   57.73   public:
   57.74    void verify() const;
   57.75  
   57.76    // Attributes
   57.77 -  methodHandle method() const                    { return _method; }
   57.78 -  int          bci() const                       { return _bci; }
   57.79 -  address      bcp() const                       { return _method->bcp_from(bci()); }
   57.80 -
   57.81 -  int          index() const;                    // the constant pool index for the invoke
   57.82 -  symbolOop    name() const;                     // returns the name of the invoked method
   57.83 -  symbolOop    signature() const;                // returns the signature of the invoked method
   57.84 -  BasicType    result_type(Thread *thread) const; // returns the result type of the invoke
   57.85 -
   57.86 -  Bytecodes::Code code() const                   { return Bytecodes::code_at(bcp(), _method()); }
   57.87 -  Bytecodes::Code adjusted_invoke_code() const   { return Bytecodes::java_code(code()); }
   57.88 -
   57.89    methodHandle static_target(TRAPS);             // "specified" method   (from constant pool)
   57.90  
   57.91    // Testers
   57.92 -  bool is_invokeinterface() const                { return adjusted_invoke_code() == Bytecodes::_invokeinterface; }
   57.93 -  bool is_invokevirtual() const                  { return adjusted_invoke_code() == Bytecodes::_invokevirtual; }
   57.94 -  bool is_invokestatic() const                   { return adjusted_invoke_code() == Bytecodes::_invokestatic; }
   57.95 -  bool is_invokespecial() const                  { return adjusted_invoke_code() == Bytecodes::_invokespecial; }
   57.96 -  bool is_invokedynamic() const                  { return adjusted_invoke_code() == Bytecodes::_invokedynamic; }
   57.97 +  bool is_invokeinterface() const                { return java_code() == Bytecodes::_invokeinterface; }
   57.98 +  bool is_invokevirtual() const                  { return java_code() == Bytecodes::_invokevirtual; }
   57.99 +  bool is_invokestatic() const                   { return java_code() == Bytecodes::_invokestatic; }
  57.100 +  bool is_invokespecial() const                  { return java_code() == Bytecodes::_invokespecial; }
  57.101 +  bool is_invokedynamic() const                  { return java_code() == Bytecodes::_invokedynamic; }
  57.102  
  57.103    bool has_receiver() const                      { return !is_invokestatic() && !is_invokedynamic(); }
  57.104  
  57.105 @@ -230,7 +246,7 @@
  57.106  
  57.107  inline Bytecode_invoke* Bytecode_invoke_at(methodHandle method, int bci) {
  57.108    Bytecode_invoke* b = new Bytecode_invoke(method, bci);
  57.109 -  debug_only(b->verify());
  57.110 +  DEBUG_ONLY(b->verify());
  57.111    return b;
  57.112  }
  57.113  
  57.114 @@ -240,21 +256,34 @@
  57.115  }
  57.116  
  57.117  
  57.118 -// Abstraction for all field accesses (put/get field/static_
  57.119 -class Bytecode_field: public Bytecode {
  57.120 -public:
  57.121 +// Abstraction for all field accesses (put/get field/static)
  57.122 +class Bytecode_field: public Bytecode_member_ref {
  57.123 + protected:
  57.124 +  Bytecode_field(methodHandle method, int bci)  : Bytecode_member_ref(method, bci) {}
  57.125 +
  57.126 + public:
  57.127 +  // Testers
  57.128 +  bool is_getfield() const                       { return java_code() == Bytecodes::_getfield; }
  57.129 +  bool is_putfield() const                       { return java_code() == Bytecodes::_putfield; }
  57.130 +  bool is_getstatic() const                      { return java_code() == Bytecodes::_getstatic; }
  57.131 +  bool is_putstatic() const                      { return java_code() == Bytecodes::_putstatic; }
  57.132 +
  57.133 +  bool is_getter() const                         { return is_getfield()  || is_getstatic(); }
  57.134 +  bool is_static() const                         { return is_getstatic() || is_putstatic(); }
  57.135 +
  57.136 +  bool is_valid() const                          { return is_getfield()   ||
  57.137 +                                                          is_putfield()   ||
  57.138 +                                                          is_getstatic()  ||
  57.139 +                                                          is_putstatic(); }
  57.140    void verify() const;
  57.141  
  57.142 -  int  index() const;
  57.143 -  bool is_static() const;
  57.144 -
  57.145    // Creation
  57.146 -  inline friend Bytecode_field* Bytecode_field_at(const methodOop method, address bcp);
  57.147 +  inline friend Bytecode_field* Bytecode_field_at(methodHandle method, int bci);
  57.148  };
  57.149  
  57.150 -inline Bytecode_field* Bytecode_field_at(const methodOop method, address bcp) {
  57.151 -  Bytecode_field* b = (Bytecode_field*)bcp;
  57.152 -  debug_only(b->verify());
  57.153 +inline Bytecode_field* Bytecode_field_at(methodHandle method, int bci) {
  57.154 +  Bytecode_field* b = new Bytecode_field(method, bci);
  57.155 +  DEBUG_ONLY(b->verify());
  57.156    return b;
  57.157  }
  57.158  
  57.159 @@ -274,7 +303,7 @@
  57.160  
  57.161  inline Bytecode_checkcast* Bytecode_checkcast_at(address bcp) {
  57.162    Bytecode_checkcast* b = (Bytecode_checkcast*)bcp;
  57.163 -  debug_only(b->verify());
  57.164 +  DEBUG_ONLY(b->verify());
  57.165    return b;
  57.166  }
  57.167  
  57.168 @@ -294,7 +323,7 @@
  57.169  
  57.170  inline Bytecode_instanceof* Bytecode_instanceof_at(address bcp) {
  57.171    Bytecode_instanceof* b = (Bytecode_instanceof*)bcp;
  57.172 -  debug_only(b->verify());
  57.173 +  DEBUG_ONLY(b->verify());
  57.174    return b;
  57.175  }
  57.176  
  57.177 @@ -312,7 +341,7 @@
  57.178  
  57.179  inline Bytecode_new* Bytecode_new_at(address bcp) {
  57.180    Bytecode_new* b = (Bytecode_new*)bcp;
  57.181 -  debug_only(b->verify());
  57.182 +  DEBUG_ONLY(b->verify());
  57.183    return b;
  57.184  }
  57.185  
  57.186 @@ -330,7 +359,7 @@
  57.187  
  57.188  inline Bytecode_multianewarray* Bytecode_multianewarray_at(address bcp) {
  57.189    Bytecode_multianewarray* b = (Bytecode_multianewarray*)bcp;
  57.190 -  debug_only(b->verify());
  57.191 +  DEBUG_ONLY(b->verify());
  57.192    return b;
  57.193  }
  57.194  
  57.195 @@ -348,29 +377,57 @@
  57.196  
  57.197  inline Bytecode_anewarray* Bytecode_anewarray_at(address bcp) {
  57.198    Bytecode_anewarray* b = (Bytecode_anewarray*)bcp;
  57.199 -  debug_only(b->verify());
  57.200 +  DEBUG_ONLY(b->verify());
  57.201    return b;
  57.202  }
  57.203  
  57.204  
  57.205  // Abstraction for ldc, ldc_w and ldc2_w
  57.206  
  57.207 -class Bytecode_loadconstant: public Bytecode {
  57.208 +class Bytecode_loadconstant: public ResourceObj {
  57.209 + private:
  57.210 +  int          _bci;
  57.211 +  methodHandle _method;
  57.212 +
  57.213 +  Bytecodes::Code code() const                   { return bytecode()->code(); }
  57.214 +
  57.215 +  int raw_index() const;
  57.216 +
  57.217 +  Bytecode_loadconstant(methodHandle method, int bci) : _method(method), _bci(bci) {}
  57.218 +
  57.219   public:
  57.220 +  // Attributes
  57.221 +  methodHandle method() const                    { return _method; }
  57.222 +  int          bci() const                       { return _bci; }
  57.223 +  address      bcp() const                       { return _method->bcp_from(bci()); }
  57.224 +  Bytecode*    bytecode() const                  { return Bytecode_at(bcp()); }
  57.225 +
  57.226    void verify() const {
  57.227 +    assert(_method.not_null(), "must supply method");
  57.228      Bytecodes::Code stdc = Bytecodes::java_code(code());
  57.229      assert(stdc == Bytecodes::_ldc ||
  57.230             stdc == Bytecodes::_ldc_w ||
  57.231             stdc == Bytecodes::_ldc2_w, "load constant");
  57.232    }
  57.233  
  57.234 -  int index() const;
  57.235 +  // Only non-standard bytecodes (fast_aldc) have CP cache indexes.
  57.236 +  bool has_cache_index() const { return code() >= Bytecodes::number_of_java_codes; }
  57.237  
  57.238 -  inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp);
  57.239 +  int pool_index() const;               // index into constant pool
  57.240 +  int cache_index() const {             // index into CP cache (or -1 if none)
  57.241 +    return has_cache_index() ? raw_index() : -1;
  57.242 +  }
  57.243 +
  57.244 +  BasicType result_type() const;        // returns the result type of the ldc
  57.245 +
  57.246 +  oop resolve_constant(TRAPS) const;
  57.247 +
  57.248 +  // Creation
  57.249 +  inline friend Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci);
  57.250  };
  57.251  
  57.252 -inline Bytecode_loadconstant* Bytecode_loadconstant_at(const methodOop method, address bcp) {
  57.253 -  Bytecode_loadconstant* b = (Bytecode_loadconstant*)bcp;
  57.254 -  debug_only(b->verify());
  57.255 +inline Bytecode_loadconstant* Bytecode_loadconstant_at(methodHandle method, int bci) {
  57.256 +  Bytecode_loadconstant* b = new Bytecode_loadconstant(method, bci);
  57.257 +  DEBUG_ONLY(b->verify());
  57.258    return b;
  57.259  }
    58.1 --- a/src/share/vm/interpreter/bytecodeTracer.cpp	Thu Jun 24 15:38:42 2010 -0700
    58.2 +++ b/src/share/vm/interpreter/bytecodeTracer.cpp	Mon Jun 28 12:03:05 2010 -0400
    58.3 @@ -49,6 +49,7 @@
    58.4  
    58.5    int       get_index_u1()           { return *(address)_next_pc++; }
    58.6    int       get_index_u2()           { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; }
    58.7 +  int       get_index_u1_cpcache()   { return get_index_u1() + constantPoolOopDesc::CPCACHE_INDEX_TAG; }
    58.8    int       get_index_u2_cpcache()   { int i=Bytes::get_native_u2(_next_pc); _next_pc+=2; return i + constantPoolOopDesc::CPCACHE_INDEX_TAG; }
    58.9    int       get_index_u4()           { int i=Bytes::get_native_u4(_next_pc); _next_pc+=4; return i; }
   58.10    int       get_index_special()      { return (is_wide()) ? get_index_u2() : get_index_u1(); }
   58.11 @@ -60,6 +61,7 @@
   58.12    bool      check_index(int i, int& cp_index, outputStream* st = tty);
   58.13    void      print_constant(int i, outputStream* st = tty);
   58.14    void      print_field_or_method(int i, outputStream* st = tty);
   58.15 +  void      print_field_or_method(int orig_i, int i, outputStream* st = tty);
   58.16    void      print_attributes(int bci, outputStream* st = tty);
   58.17    void      bytecode_epilog(int bci, outputStream* st = tty);
   58.18  
   58.19 @@ -177,18 +179,29 @@
   58.20    _closure->trace(method, bcp, st);
   58.21  }
   58.22  
   58.23 +void print_symbol(symbolOop sym, outputStream* st) {
   58.24 +  char buf[40];
   58.25 +  int len = sym->utf8_length();
   58.26 +  if (len >= (int)sizeof(buf)) {
   58.27 +    st->print_cr(" %s...[%d]", sym->as_C_string(buf, sizeof(buf)), len);
   58.28 +  } else {
   58.29 +    st->print(" ");
   58.30 +    sym->print_on(st); st->cr();
   58.31 +  }
   58.32 +}
   58.33 +
   58.34  void print_oop(oop value, outputStream* st) {
   58.35    if (value == NULL) {
   58.36      st->print_cr(" NULL");
   58.37 -  } else {
   58.38 +  } else if (java_lang_String::is_instance(value)) {
   58.39      EXCEPTION_MARK;
   58.40      Handle h_value (THREAD, value);
   58.41      symbolHandle sym = java_lang_String::as_symbol(h_value, CATCH);
   58.42 -    if (sym->utf8_length() > 32) {
   58.43 -      st->print_cr(" ....");
   58.44 -    } else {
   58.45 -      sym->print_on(st); st->cr();
   58.46 -    }
   58.47 +    print_symbol(sym(), st);
   58.48 +  } else if (value->is_symbol()) {
   58.49 +    print_symbol(symbolOop(value), st);
   58.50 +  } else {
   58.51 +    st->print_cr(" " PTR_FORMAT, (intptr_t) value);
   58.52    }
   58.53  }
   58.54  
   58.55 @@ -279,16 +292,27 @@
   58.56    } else if (tag.is_double()) {
   58.57      st->print_cr(" %f", constants->double_at(i));
   58.58    } else if (tag.is_string()) {
   58.59 -    oop string = constants->resolved_string_at(i);
   58.60 +    oop string = constants->pseudo_string_at(i);
   58.61      print_oop(string, st);
   58.62    } else if (tag.is_unresolved_string()) {
   58.63 -    st->print_cr(" <unresolved string at %d>", i);
   58.64 +    const char* string = constants->string_at_noresolve(i);
   58.65 +    st->print_cr(" %s", string);
   58.66    } else if (tag.is_klass()) {
   58.67      st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name());
   58.68    } else if (tag.is_unresolved_klass()) {
   58.69      st->print_cr(" <unresolved klass at %d>", i);
   58.70    } else if (tag.is_object()) {
   58.71 -    st->print_cr(" " PTR_FORMAT, constants->object_at(i));
   58.72 +    st->print(" <Object>");
   58.73 +    print_oop(constants->object_at(i), st);
   58.74 +  } else if (tag.is_method_type()) {
   58.75 +    int i2 = constants->method_type_index_at(i);
   58.76 +    st->print(" <MethodType> %d", i2);
   58.77 +    print_oop(constants->symbol_at(i2), st);
   58.78 +  } else if (tag.is_method_handle()) {
   58.79 +    int kind = constants->method_handle_ref_kind_at(i);
   58.80 +    int i2 = constants->method_handle_index_at(i);
   58.81 +    st->print(" <MethodHandle of kind %d>", kind, i2);
   58.82 +    print_field_or_method(-i, i2, st);
   58.83    } else {
   58.84      st->print_cr(" bad tag=%d at %d", tag.value(), i);
   58.85    }
   58.86 @@ -297,7 +321,10 @@
   58.87  void BytecodePrinter::print_field_or_method(int i, outputStream* st) {
   58.88    int orig_i = i;
   58.89    if (!check_index(orig_i, i, st))  return;
   58.90 +  print_field_or_method(orig_i, i, st);
   58.91 +}
   58.92  
   58.93 +void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st) {
   58.94    constantPoolOop constants = method()->constants();
   58.95    constantTag tag = constants->tag_at(i);
   58.96  
   58.97 @@ -314,9 +341,11 @@
   58.98      return;
   58.99    }
  58.100  
  58.101 +  symbolOop klass = constants->klass_name_at(constants->uncached_klass_ref_index_at(i));
  58.102    symbolOop name = constants->uncached_name_ref_at(i);
  58.103    symbolOop signature = constants->uncached_signature_ref_at(i);
  58.104 -  st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string());
  58.105 +  const char* sep = (tag.is_field() ? "/" : "");
  58.106 +  st->print_cr(" %d <%s.%s%s%s> ", i, klass->as_C_string(), name->as_C_string(), sep, signature->as_C_string());
  58.107  }
  58.108  
  58.109  
  58.110 @@ -340,12 +369,20 @@
  58.111        st->print_cr(" " INT32_FORMAT, get_short());
  58.112        break;
  58.113      case Bytecodes::_ldc:
  58.114 -      print_constant(get_index_u1(), st);
  58.115 +      if (Bytecodes::uses_cp_cache(raw_code())) {
  58.116 +        print_constant(get_index_u1_cpcache(), st);
  58.117 +      } else {
  58.118 +        print_constant(get_index_u1(), st);
  58.119 +      }
  58.120        break;
  58.121  
  58.122      case Bytecodes::_ldc_w:
  58.123      case Bytecodes::_ldc2_w:
  58.124 -      print_constant(get_index_u2(), st);
  58.125 +      if (Bytecodes::uses_cp_cache(raw_code())) {
  58.126 +        print_constant(get_index_u2_cpcache(), st);
  58.127 +      } else {
  58.128 +        print_constant(get_index_u2(), st);
  58.129 +      }
  58.130        break;
  58.131  
  58.132      case Bytecodes::_iload:
    59.1 --- a/src/share/vm/interpreter/bytecodes.cpp	Thu Jun 24 15:38:42 2010 -0700
    59.2 +++ b/src/share/vm/interpreter/bytecodes.cpp	Mon Jun 28 12:03:05 2010 -0400
    59.3 @@ -489,6 +489,9 @@
    59.4  
    59.5    def(_return_register_finalizer , "return_register_finalizer" , "b"    , NULL    , T_VOID   ,  0, true, _return);
    59.6  
    59.7 +  def(_fast_aldc           , "fast_aldc"           , "bj"   , NULL    , T_OBJECT,   1, true,  _ldc   );
    59.8 +  def(_fast_aldc_w         , "fast_aldc_w"         , "bJJ"  , NULL    , T_OBJECT,   1, true,  _ldc_w );
    59.9 +
   59.10    def(_shouldnotreachhere  , "_shouldnotreachhere" , "b"    , NULL    , T_VOID   ,  0, false);
   59.11  
   59.12    // platform specific JVM bytecodes
    60.1 --- a/src/share/vm/interpreter/bytecodes.hpp	Thu Jun 24 15:38:42 2010 -0700
    60.2 +++ b/src/share/vm/interpreter/bytecodes.hpp	Mon Jun 28 12:03:05 2010 -0400
    60.3 @@ -270,6 +270,10 @@
    60.4      _fast_linearswitch    ,
    60.5      _fast_binaryswitch    ,
    60.6  
    60.7 +    // special handling of oop constants:
    60.8 +    _fast_aldc            ,
    60.9 +    _fast_aldc_w          ,
   60.10 +
   60.11      _return_register_finalizer    ,
   60.12  
   60.13      _shouldnotreachhere,      // For debugging
    61.1 --- a/src/share/vm/interpreter/interpreter.cpp	Thu Jun 24 15:38:42 2010 -0700
    61.2 +++ b/src/share/vm/interpreter/interpreter.cpp	Mon Jun 28 12:03:05 2010 -0400
    61.3 @@ -267,20 +267,6 @@
    61.4  }
    61.5  #endif // PRODUCT
    61.6  
    61.7 -static BasicType constant_pool_type(methodOop method, int index) {
    61.8 -  constantTag tag = method->constants()->tag_at(index);
    61.9 -       if (tag.is_int              ()) return T_INT;
   61.10 -  else if (tag.is_float            ()) return T_FLOAT;
   61.11 -  else if (tag.is_long             ()) return T_LONG;
   61.12 -  else if (tag.is_double           ()) return T_DOUBLE;
   61.13 -  else if (tag.is_string           ()) return T_OBJECT;
   61.14 -  else if (tag.is_unresolved_string()) return T_OBJECT;
   61.15 -  else if (tag.is_klass            ()) return T_OBJECT;
   61.16 -  else if (tag.is_unresolved_klass ()) return T_OBJECT;
   61.17 -  ShouldNotReachHere();
   61.18 -  return T_ILLEGAL;
   61.19 -}
   61.20 -
   61.21  
   61.22  //------------------------------------------------------------------------------------------------------------------------
   61.23  // Deoptimization support
   61.24 @@ -330,13 +316,15 @@
   61.25      }
   61.26  
   61.27      case Bytecodes::_ldc   :
   61.28 -      type = constant_pool_type( method, *(bcp+1) );
   61.29 -      break;
   61.30 -
   61.31      case Bytecodes::_ldc_w : // fall through
   61.32      case Bytecodes::_ldc2_w:
   61.33 -      type = constant_pool_type( method, Bytes::get_Java_u2(bcp+1) );
   61.34 -      break;
   61.35 +      {
   61.36 +        Thread *thread = Thread::current();
   61.37 +        ResourceMark rm(thread);
   61.38 +        methodHandle mh(thread, method);
   61.39 +        type = Bytecode_loadconstant_at(mh, bci)->result_type();
   61.40 +        break;
   61.41 +      }
   61.42  
   61.43      default:
   61.44        type = Bytecodes::result_type(code);
    62.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Jun 24 15:38:42 2010 -0700
    62.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Mon Jun 28 12:03:05 2010 -0400
    62.3 @@ -83,6 +83,18 @@
    62.4    }
    62.5  IRT_END
    62.6  
    62.7 +IRT_ENTRY(void, InterpreterRuntime::resolve_ldc(JavaThread* thread, Bytecodes::Code bytecode)) {
    62.8 +  assert(bytecode == Bytecodes::_fast_aldc ||
    62.9 +         bytecode == Bytecodes::_fast_aldc_w, "wrong bc");
   62.10 +  ResourceMark rm(thread);
   62.11 +  methodHandle m (thread, method(thread));
   62.12 +  Bytecode_loadconstant* ldc = Bytecode_loadconstant_at(m, bci(thread));
   62.13 +  oop result = ldc->resolve_constant(THREAD);
   62.14 +  DEBUG_ONLY(ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc->cache_index()));
   62.15 +  assert(result == cpce->f1(), "expected result for assembly code");
   62.16 +}
   62.17 +IRT_END
   62.18 +
   62.19  
   62.20  //------------------------------------------------------------------------------------------------------------------------
   62.21  // Allocation
   62.22 @@ -328,7 +340,7 @@
   62.23    typeArrayHandle    h_extable  (thread, h_method->exception_table());
   62.24    bool               should_repeat;
   62.25    int                handler_bci;
   62.26 -  int                current_bci = bcp(thread) - h_method->code_base();
   62.27 +  int                current_bci = bci(thread);
   62.28  
   62.29    // Need to do this check first since when _do_not_unlock_if_synchronized
   62.30    // is set, we don't want to trigger any classloading which may make calls
   62.31 @@ -615,8 +627,7 @@
   62.32    if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
   62.33      ResourceMark rm(thread);
   62.34      methodHandle m (thread, method(thread));
   62.35 -    int bci = m->bci_from(bcp(thread));
   62.36 -    Bytecode_invoke* call = Bytecode_invoke_at(m, bci);
   62.37 +    Bytecode_invoke* call = Bytecode_invoke_at(m, bci(thread));
   62.38      symbolHandle signature (thread, call->signature());
   62.39      receiver = Handle(thread,
   62.40                    thread->last_frame().interpreter_callee_receiver(signature));
   62.41 @@ -1257,7 +1268,7 @@
   62.42    Bytecode_invoke* invoke = Bytecode_invoke_at(mh, bci);
   62.43    ArgumentSizeComputer asc(invoke->signature());
   62.44    int size_of_arguments = (asc.size() + (invoke->has_receiver() ? 1 : 0)); // receiver
   62.45 -  Copy::conjoint_bytes(src_address, dest_address,
   62.46 +  Copy::conjoint_jbytes(src_address, dest_address,
   62.47                         size_of_arguments * Interpreter::stackElementSize);
   62.48  IRT_END
   62.49  #endif
    63.1 --- a/src/share/vm/interpreter/interpreterRuntime.hpp	Thu Jun 24 15:38:42 2010 -0700
    63.2 +++ b/src/share/vm/interpreter/interpreterRuntime.hpp	Mon Jun 28 12:03:05 2010 -0400
    63.3 @@ -34,6 +34,7 @@
    63.4    static frame     last_frame(JavaThread *thread)    { return thread->last_frame(); }
    63.5    static methodOop method(JavaThread *thread)        { return last_frame(thread).interpreter_frame_method(); }
    63.6    static address   bcp(JavaThread *thread)           { return last_frame(thread).interpreter_frame_bcp(); }
    63.7 +  static int       bci(JavaThread *thread)           { return last_frame(thread).interpreter_frame_bci(); }
    63.8    static void      set_bcp_and_mdp(address bcp, JavaThread*thread);
    63.9    static Bytecodes::Code code(JavaThread *thread)    {
   63.10      // pass method to avoid calling unsafe bcp_to_method (partial fix 4926272)
   63.11 @@ -59,6 +60,7 @@
   63.12   public:
   63.13    // Constants
   63.14    static void    ldc           (JavaThread* thread, bool wide);
   63.15 +  static void    resolve_ldc   (JavaThread* thread, Bytecodes::Code bytecode);
   63.16  
   63.17    // Allocation
   63.18    static void    _new          (JavaThread* thread, constantPoolOopDesc* pool, int index);
    64.1 --- a/src/share/vm/interpreter/rewriter.cpp	Thu Jun 24 15:38:42 2010 -0700
    64.2 +++ b/src/share/vm/interpreter/rewriter.cpp	Mon Jun 28 12:03:05 2010 -0400
    64.3 @@ -38,6 +38,8 @@
    64.4        case JVM_CONSTANT_InterfaceMethodref:
    64.5        case JVM_CONSTANT_Fieldref          : // fall through
    64.6        case JVM_CONSTANT_Methodref         : // fall through
    64.7 +      case JVM_CONSTANT_MethodHandle      : // fall through
    64.8 +      case JVM_CONSTANT_MethodType        : // fall through
    64.9          add_cp_cache_entry(i);
   64.10          break;
   64.11      }
   64.12 @@ -131,6 +133,27 @@
   64.13  }
   64.14  
   64.15  
   64.16 +// Rewrite some ldc bytecodes to _fast_aldc
   64.17 +void Rewriter::maybe_rewrite_ldc(address bcp, int offset, bool is_wide) {
   64.18 +  assert((*bcp) == (is_wide ? Bytecodes::_ldc_w : Bytecodes::_ldc), "");
   64.19 +  address p = bcp + offset;
   64.20 +  int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p);
   64.21 +  constantTag tag = _pool->tag_at(cp_index).value();
   64.22 +  if (tag.is_method_handle() || tag.is_method_type()) {
   64.23 +    int cache_index = cp_entry_to_cp_cache(cp_index);
   64.24 +    if (is_wide) {
   64.25 +      (*bcp) = Bytecodes::_fast_aldc_w;
   64.26 +      assert(cache_index == (u2)cache_index, "");
   64.27 +      Bytes::put_native_u2(p, cache_index);
   64.28 +    } else {
   64.29 +      (*bcp) = Bytecodes::_fast_aldc;
   64.30 +      assert(cache_index == (u1)cache_index, "");
   64.31 +      (*p) = (u1)cache_index;
   64.32 +    }
   64.33 +  }
   64.34 +}
   64.35 +
   64.36 +
   64.37  // Rewrites a method given the index_map information
   64.38  void Rewriter::scan_method(methodOop method) {
   64.39  
   64.40 @@ -198,6 +221,12 @@
   64.41          case Bytecodes::_invokedynamic:
   64.42            rewrite_invokedynamic(bcp, prefix_length+1);
   64.43            break;
   64.44 +        case Bytecodes::_ldc:
   64.45 +          maybe_rewrite_ldc(bcp, prefix_length+1, false);
   64.46 +          break;
   64.47 +        case Bytecodes::_ldc_w:
   64.48 +          maybe_rewrite_ldc(bcp, prefix_length+1, true);
   64.49 +          break;
   64.50          case Bytecodes::_jsr            : // fall through
   64.51          case Bytecodes::_jsr_w          : nof_jsrs++;                   break;
   64.52          case Bytecodes::_monitorenter   : // fall through
    65.1 --- a/src/share/vm/interpreter/rewriter.hpp	Thu Jun 24 15:38:42 2010 -0700
    65.2 +++ b/src/share/vm/interpreter/rewriter.hpp	Mon Jun 28 12:03:05 2010 -0400
    65.3 @@ -66,6 +66,7 @@
    65.4    void rewrite_Object_init(methodHandle m, TRAPS);
    65.5    void rewrite_member_reference(address bcp, int offset);
    65.6    void rewrite_invokedynamic(address bcp, int offset);
    65.7 +  void maybe_rewrite_ldc(address bcp, int offset, bool is_wide);
    65.8  
    65.9   public:
   65.10    // Driver routine:
    66.1 --- a/src/share/vm/interpreter/templateTable.cpp	Thu Jun 24 15:38:42 2010 -0700
    66.2 +++ b/src/share/vm/interpreter/templateTable.cpp	Mon Jun 28 12:03:05 2010 -0400
    66.3 @@ -507,6 +507,9 @@
    66.4    def(Bytecodes::_fast_linearswitch   , ubcp|disp|____|____, itos, vtos, fast_linearswitch   ,  _           );
    66.5    def(Bytecodes::_fast_binaryswitch   , ubcp|disp|____|____, itos, vtos, fast_binaryswitch   ,  _           );
    66.6  
    66.7 +  def(Bytecodes::_fast_aldc           , ubcp|____|clvm|____, vtos, atos, fast_aldc           ,  false       );
    66.8 +  def(Bytecodes::_fast_aldc_w         , ubcp|____|clvm|____, vtos, atos, fast_aldc           ,  true        );
    66.9 +
   66.10    def(Bytecodes::_return_register_finalizer , ____|disp|clvm|____, vtos, vtos, _return       ,  vtos        );
   66.11  
   66.12    def(Bytecodes::_shouldnotreachhere   , ____|____|____|____, vtos, vtos, shouldnotreachhere ,  _           );
    67.1 --- a/src/share/vm/interpreter/templateTable.hpp	Thu Jun 24 15:38:42 2010 -0700
    67.2 +++ b/src/share/vm/interpreter/templateTable.hpp	Mon Jun 28 12:03:05 2010 -0400
    67.3 @@ -123,6 +123,7 @@
    67.4    static void sipush();
    67.5    static void ldc(bool wide);
    67.6    static void ldc2_w();
    67.7 +  static void fast_aldc(bool wide);
    67.8  
    67.9    static void locals_index(Register reg, int offset = 1);
   67.10    static void iload();
    68.1 --- a/src/share/vm/memory/cardTableModRefBS.cpp	Thu Jun 24 15:38:42 2010 -0700
    68.2 +++ b/src/share/vm/memory/cardTableModRefBS.cpp	Mon Jun 28 12:03:05 2010 -0400
    68.3 @@ -1,5 +1,5 @@
    68.4  /*
    68.5 - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
    68.6 + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
    68.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    68.8   *
    68.9   * This code is free software; you can redistribute it and/or modify it
   68.10 @@ -284,12 +284,19 @@
   68.11          committed_unique_to_self(ind, MemRegion(new_end_aligned,
   68.12                                                  cur_committed.end()));
   68.13        if (!uncommit_region.is_empty()) {
   68.14 -        if (!os::uncommit_memory((char*)uncommit_region.start(),
   68.15 -                                 uncommit_region.byte_size())) {
   68.16 -          assert(false, "Card table contraction failed");
   68.17 -          // The call failed so don't change the end of the
   68.18 -          // committed region.  This is better than taking the
   68.19 -          // VM down.
   68.20 +        // It is not safe to uncommit cards if the boundary between
   68.21 +        // the generations is moving.  A shrink can uncommit cards
   68.22 +        // owned by generation A but being used by generation B.
   68.23 +        if (!UseAdaptiveGCBoundary) {
   68.24 +          if (!os::uncommit_memory((char*)uncommit_region.start(),
   68.25 +                                   uncommit_region.byte_size())) {
   68.26 +            assert(false, "Card table contraction failed");
   68.27 +            // The call failed so don't change the end of the
   68.28 +            // committed region.  This is better than taking the
   68.29 +            // VM down.
   68.30 +            new_end_aligned = _committed[ind].end();
   68.31 +          }
   68.32 +        } else {
   68.33            new_end_aligned = _committed[ind].end();
   68.34          }
   68.35        }
   68.36 @@ -297,6 +304,19 @@
   68.37      // In any case, we can reset the end of the current committed entry.
   68.38      _committed[ind].set_end(new_end_aligned);
   68.39  
   68.40 +#ifdef ASSERT
   68.41 +    // Check that the last card in the new region is committed according
   68.42 +    // to the tables.
   68.43 +    bool covered = false;
   68.44 +    for (int cr = 0; cr < _cur_covered_regions; cr++) {
   68.45 +      if (_committed[cr].contains(new_end - 1)) {
   68.46 +        covered = true;
   68.47 +        break;
   68.48 +      }
   68.49 +    }
   68.50 +    assert(covered, "Card for end of new region not committed");
   68.51 +#endif
   68.52 +
   68.53      // The default of 0 is not necessarily clean cards.
   68.54      jbyte* entry;
   68.55      if (old_region.last() < _whole_heap.start()) {
   68.56 @@ -354,6 +374,9 @@
   68.57                    addr_for((jbyte*) _committed[ind].start()),
   68.58                    addr_for((jbyte*) _committed[ind].last()));
   68.59    }
   68.60 +  // Touch the last card of the covered region to show that it
   68.61 +  // is committed (or SEGV).
   68.62 +  debug_only(*byte_for(_covered[ind].last());)
   68.63    debug_only(verify_guard();)
   68.64  }
   68.65  
    69.1 --- a/src/share/vm/oops/constantPoolKlass.cpp	Thu Jun 24 15:38:42 2010 -0700
    69.2 +++ b/src/share/vm/oops/constantPoolKlass.cpp	Mon Jun 28 12:03:05 2010 -0400
    69.3 @@ -372,6 +372,13 @@
    69.4          entry->print_value_on(st);
    69.5          }
    69.6          break;
    69.7 +      case JVM_CONSTANT_MethodHandle :
    69.8 +        st->print("ref_kind=%d", cp->method_handle_ref_kind_at(index));
    69.9 +        st->print(" ref_index=%d", cp->method_handle_index_at(index));
   69.10 +        break;
   69.11 +      case JVM_CONSTANT_MethodType :
   69.12 +        st->print("signature_index=%d", cp->method_type_index_at(index));
   69.13 +        break;
   69.14        default:
   69.15          ShouldNotReachHere();
   69.16          break;
   69.17 @@ -437,6 +444,7 @@
   69.18            // can be non-perm, can be non-instance (array)
   69.19          }
   69.20        }
   69.21 +      // FIXME: verify JSR 292 tags JVM_CONSTANT_MethodHandle, etc.
   69.22        base++;
   69.23      }
   69.24      guarantee(cp->tags()->is_perm(),         "should be in permspace");
    70.1 --- a/src/share/vm/oops/constantPoolOop.cpp	Thu Jun 24 15:38:42 2010 -0700
    70.2 +++ b/src/share/vm/oops/constantPoolOop.cpp	Mon Jun 28 12:03:05 2010 -0400
    70.3 @@ -358,6 +358,11 @@
    70.4    return klass_at_noresolve(ref_index);
    70.5  }
    70.6  
    70.7 +symbolOop constantPoolOopDesc::uncached_klass_ref_at_noresolve(int which) {
    70.8 +  jint ref_index = uncached_klass_ref_index_at(which);
    70.9 +  return klass_at_noresolve(ref_index);
   70.10 +}
   70.11 +
   70.12  char* constantPoolOopDesc::string_at_noresolve(int which) {
   70.13    // Test entry type in case string is resolved while in here.
   70.14    oop entry = *(obj_at_addr(which));
   70.15 @@ -384,6 +389,119 @@
   70.16    }
   70.17  }
   70.18  
   70.19 +oop constantPoolOopDesc::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) {
   70.20 +  oop result_oop = NULL;
   70.21 +  if (cache_index >= 0) {
   70.22 +    assert(index < 0, "only one kind of index at a time");
   70.23 +    ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
   70.24 +    result_oop = cpc_entry->f1();
   70.25 +    if (result_oop != NULL) {
   70.26 +      return result_oop;  // that was easy...
   70.27 +    }
   70.28 +    index = cpc_entry->constant_pool_index();
   70.29 +  }
   70.30 +
   70.31 +  int tag_value = this_oop->tag_at(index).value();
   70.32 +  switch (tag_value) {
   70.33 +
   70.34 +  case JVM_CONSTANT_UnresolvedClass:
   70.35 +  case JVM_CONSTANT_UnresolvedClassInError:
   70.36 +  case JVM_CONSTANT_Class:
   70.37 +    {
   70.38 +      klassOop resolved = klass_at_impl(this_oop, index, CHECK_NULL);
   70.39 +      // ldc wants the java mirror.
   70.40 +      result_oop = resolved->klass_part()->java_mirror();
   70.41 +      break;
   70.42 +    }
   70.43 +
   70.44 +  case JVM_CONSTANT_String:
   70.45 +  case JVM_CONSTANT_UnresolvedString:
   70.46 +    if (this_oop->is_pseudo_string_at(index)) {
   70.47 +      result_oop = this_oop->pseudo_string_at(index);
   70.48 +      break;
   70.49 +    }
   70.50 +    result_oop = string_at_impl(this_oop, index, CHECK_NULL);
   70.51 +    break;
   70.52 +
   70.53 +  case JVM_CONSTANT_Object:
   70.54 +    result_oop = this_oop->object_at(index);
   70.55 +    break;
   70.56 +
   70.57 +  case JVM_CONSTANT_MethodHandle:
   70.58 +    {
   70.59 +      int ref_kind                 = this_oop->method_handle_ref_kind_at(index);
   70.60 +      int callee_index             = this_oop->method_handle_klass_index_at(index);
   70.61 +      symbolHandle name(THREAD,      this_oop->method_handle_name_ref_at(index));
   70.62 +      symbolHandle signature(THREAD, this_oop->method_handle_signature_ref_at(index));
   70.63 +      if (PrintMiscellaneous)
   70.64 +        tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
   70.65 +                      ref_kind, index, this_oop->method_handle_index_at(index),
   70.66 +                      callee_index, name->as_C_string(), signature->as_C_string());
   70.67 +      KlassHandle callee;
   70.68 +      { klassOop k = klass_at_impl(this_oop, callee_index, CHECK_NULL);
   70.69 +        callee = KlassHandle(THREAD, k);
   70.70 +      }
   70.71 +      KlassHandle klass(THREAD, this_oop->pool_holder());
   70.72 +      Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind,
   70.73 +                                                                   callee, name, signature,
   70.74 +                                                                   CHECK_NULL);
   70.75 +      result_oop = value();
   70.76 +      // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error.
   70.77 +      break;
   70.78 +    }
   70.79 +
   70.80 +  case JVM_CONSTANT_MethodType:
   70.81 +    {
   70.82 +      symbolHandle signature(THREAD, this_oop->method_type_signature_at(index));
   70.83 +      if (PrintMiscellaneous)
   70.84 +        tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
   70.85 +                      index, this_oop->method_type_index_at(index),
   70.86 +                      signature->as_C_string());
   70.87 +      KlassHandle klass(THREAD, this_oop->pool_holder());
   70.88 +      bool ignore_is_on_bcp = false;
   70.89 +      Handle value = SystemDictionary::find_method_handle_type(signature,
   70.90 +                                                               klass,
   70.91 +                                                               ignore_is_on_bcp,
   70.92 +                                                               CHECK_NULL);
   70.93 +      result_oop = value();
   70.94 +      // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error.
   70.95 +      break;
   70.96 +    }
   70.97 +
   70.98 +    /* maybe some day
   70.99 +  case JVM_CONSTANT_Integer:
  70.100 +  case JVM_CONSTANT_Float:
  70.101 +  case JVM_CONSTANT_Long:
  70.102 +  case JVM_CONSTANT_Double:
  70.103 +    result_oop = java_lang_boxing_object::create(...);
  70.104 +    break;
  70.105 +    */
  70.106 +
  70.107 +  default:
  70.108 +    DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d",
  70.109 +                              this_oop(), index, cache_index, tag_value) );
  70.110 +    assert(false, "unexpected constant tag");
  70.111 +    break;
  70.112 +  }
  70.113 +
  70.114 +  if (cache_index >= 0) {
  70.115 +    // Cache the oop here also.
  70.116 +    Handle result(THREAD, result_oop);
  70.117 +    result_oop = NULL;  // safety
  70.118 +    ObjectLocker ol(this_oop, THREAD);
  70.119 +    ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
  70.120 +    oop result_oop2 = cpc_entry->f1();
  70.121 +    if (result_oop2 != NULL) {
  70.122 +      // Race condition:  May already be filled in while we were trying to lock.
  70.123 +      return result_oop2;
  70.124 +    }
  70.125 +    cpc_entry->set_f1(result());
  70.126 +    return result();
  70.127 +  } else {
  70.128 +    return result_oop;
  70.129 +  }
  70.130 +}
  70.131 +
  70.132  oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
  70.133    oop entry = *(this_oop->obj_at_addr(which));
  70.134    if (entry->is_symbol()) {
  70.135 @@ -690,6 +808,28 @@
  70.136      }
  70.137    } break;
  70.138  
  70.139 +  case JVM_CONSTANT_MethodType:
  70.140 +  {
  70.141 +    int k1 = method_type_index_at(index1);
  70.142 +    int k2 = cp2->method_type_index_at(index2);
  70.143 +    if (k1 == k2) {
  70.144 +      return true;
  70.145 +    }
  70.146 +  } break;
  70.147 +
  70.148 +  case JVM_CONSTANT_MethodHandle:
  70.149 +  {
  70.150 +    int k1 = method_handle_ref_kind_at(index1);
  70.151 +    int k2 = cp2->method_handle_ref_kind_at(index2);
  70.152 +    if (k1 == k2) {
  70.153 +      int i1 = method_handle_index_at(index1);
  70.154 +      int i2 = cp2->method_handle_index_at(index2);
  70.155 +      if (i1 == i2) {
  70.156 +        return true;
  70.157 +      }
  70.158 +    }
  70.159 +  } break;
  70.160 +
  70.161    case JVM_CONSTANT_UnresolvedString:
  70.162    {
  70.163      symbolOop s1 = unresolved_string_at(index1);
  70.164 @@ -863,6 +1003,19 @@
  70.165      to_cp->symbol_at_put(to_i, s);
  70.166    } break;
  70.167  
  70.168 +  case JVM_CONSTANT_MethodType:
  70.169 +  {
  70.170 +    jint k = method_type_index_at(from_i);
  70.171 +    to_cp->method_type_index_at_put(to_i, k);
  70.172 +  } break;
  70.173 +
  70.174 +  case JVM_CONSTANT_MethodHandle:
  70.175 +  {
  70.176 +    int k1 = method_handle_ref_kind_at(from_i);
  70.177 +    int k2 = method_handle_index_at(from_i);
  70.178 +    to_cp->method_handle_index_at_put(to_i, k1, k2);
  70.179 +  } break;
  70.180 +
  70.181    // Invalid is used as the tag for the second constant pool entry
  70.182    // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should
  70.183    // not be seen by itself.
  70.184 @@ -1066,8 +1219,12 @@
  70.185      case JVM_CONSTANT_UnresolvedClassInError:
  70.186      case JVM_CONSTANT_StringIndex:
  70.187      case JVM_CONSTANT_UnresolvedString:
  70.188 +    case JVM_CONSTANT_MethodType:
  70.189        return 3;
  70.190  
  70.191 +    case JVM_CONSTANT_MethodHandle:
  70.192 +      return 4; //tag, ref_kind, ref_index
  70.193 +
  70.194      case JVM_CONSTANT_Integer:
  70.195      case JVM_CONSTANT_Float:
  70.196      case JVM_CONSTANT_Fieldref:
  70.197 @@ -1271,6 +1428,22 @@
  70.198          DBG(printf("JVM_CONSTANT_StringIndex: %hd", idx1));
  70.199          break;
  70.200        }
  70.201 +      case JVM_CONSTANT_MethodHandle: {
  70.202 +        *bytes = JVM_CONSTANT_MethodHandle;
  70.203 +        int kind = method_handle_ref_kind_at(idx);
  70.204 +        idx1 = method_handle_index_at(idx);
  70.205 +        *(bytes+1) = (unsigned char) kind;
  70.206 +        Bytes::put_Java_u2((address) (bytes+2), idx1);
  70.207 +        DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1));
  70.208 +        break;
  70.209 +      }
  70.210 +      case JVM_CONSTANT_MethodType: {
  70.211 +        *bytes = JVM_CONSTANT_MethodType;
  70.212 +        idx1 = method_type_index_at(idx);
  70.213 +        Bytes::put_Java_u2((address) (bytes+1), idx1);
  70.214 +        DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1));
  70.215 +        break;
  70.216 +      }
  70.217      }
  70.218      DBG(printf("\n"));
  70.219      bytes += ent_size;
    71.1 --- a/src/share/vm/oops/constantPoolOop.hpp	Thu Jun 24 15:38:42 2010 -0700
    71.2 +++ b/src/share/vm/oops/constantPoolOop.hpp	Mon Jun 28 12:03:05 2010 -0400
    71.3 @@ -146,6 +146,16 @@
    71.4      oop_store_without_check(obj_at_addr(which), oop(s));
    71.5    }
    71.6  
    71.7 +  void method_handle_index_at_put(int which, int ref_kind, int ref_index) {
    71.8 +    tag_at_put(which, JVM_CONSTANT_MethodHandle);
    71.9 +    *int_at_addr(which) = ((jint) ref_index<<16) | ref_kind;
   71.10 +  }
   71.11 +
   71.12 +  void method_type_index_at_put(int which, int ref_index) {
   71.13 +    tag_at_put(which, JVM_CONSTANT_MethodType);
   71.14 +    *int_at_addr(which) = ref_index;
   71.15 +  }
   71.16 +
   71.17    // Temporary until actual use
   71.18    void unresolved_string_at_put(int which, symbolOop s) {
   71.19      *obj_at_addr(which) = NULL;
   71.20 @@ -357,6 +367,36 @@
   71.21      return *int_at_addr(which);
   71.22    }
   71.23  
   71.24 +  int method_handle_ref_kind_at(int which) {
   71.25 +    assert(tag_at(which).is_method_handle(), "Corrupted constant pool");
   71.26 +    return extract_low_short_from_int(*int_at_addr(which));  // mask out unwanted ref_index bits
   71.27 +  }
   71.28 +  int method_handle_index_at(int which) {
   71.29 +    assert(tag_at(which).is_method_handle(), "Corrupted constant pool");
   71.30 +    return extract_high_short_from_int(*int_at_addr(which));  // shift out unwanted ref_kind bits
   71.31 +  }
   71.32 +  int method_type_index_at(int which) {
   71.33 +    assert(tag_at(which).is_method_type(), "Corrupted constant pool");
   71.34 +    return *int_at_addr(which);
   71.35 +  }
   71.36 +  // Derived queries:
   71.37 +  symbolOop method_handle_name_ref_at(int which) {
   71.38 +    int member = method_handle_index_at(which);
   71.39 +    return impl_name_ref_at(member, true);
   71.40 +  }
   71.41 +  symbolOop method_handle_signature_ref_at(int which) {
   71.42 +    int member = method_handle_index_at(which);
   71.43 +    return impl_signature_ref_at(member, true);
   71.44 +  }
   71.45 +  int method_handle_klass_index_at(int which) {
   71.46 +    int member = method_handle_index_at(which);
   71.47 +    return impl_klass_ref_index_at(member, true);
   71.48 +  }
   71.49 +  symbolOop method_type_signature_at(int which) {
   71.50 +    int sym = method_type_index_at(which);
   71.51 +    return symbol_at(sym);
   71.52 +  }
   71.53 +
   71.54    // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve,
   71.55    // name_and_type_ref_index_at) all expect to be passed indices obtained
   71.56    // directly from the bytecode, and extracted according to java byte order.
   71.57 @@ -388,6 +428,17 @@
   71.58      resolve_string_constants_impl(h_this, CHECK);
   71.59    }
   71.60  
   71.61 +  // Resolve late bound constants.
   71.62 +  oop resolve_constant_at(int index, TRAPS) {
   71.63 +    constantPoolHandle h_this(THREAD, this);
   71.64 +    return resolve_constant_at_impl(h_this, index, -1, THREAD);
   71.65 +  }
   71.66 +
   71.67 +  oop resolve_cached_constant_at(int cache_index, TRAPS) {
   71.68 +    constantPoolHandle h_this(THREAD, this);
   71.69 +    return resolve_constant_at_impl(h_this, -1, cache_index, THREAD);
   71.70 +  }
   71.71 +
   71.72    // Klass name matches name at offset
   71.73    bool klass_name_at_matches(instanceKlassHandle k, int which);
   71.74  
   71.75 @@ -420,6 +471,7 @@
   71.76    // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
   71.77    // future by other Java code. These take constant pool indices rather than possibly-byte-swapped
   71.78    // constant pool cache indices as do the peer methods above.
   71.79 +  symbolOop uncached_klass_ref_at_noresolve(int which);
   71.80    symbolOop uncached_name_ref_at(int which)                 { return impl_name_ref_at(which, true); }
   71.81    symbolOop uncached_signature_ref_at(int which)            { return impl_signature_ref_at(which, true); }
   71.82    int       uncached_klass_ref_index_at(int which)          { return impl_klass_ref_index_at(which, true); }
   71.83 @@ -436,6 +488,8 @@
   71.84  
   71.85  #ifdef ASSERT
   71.86    enum { CPCACHE_INDEX_TAG = 0x10000 };  // helps keep CP cache indices distinct from CP indices
   71.87 +#else
   71.88 +  enum { CPCACHE_INDEX_TAG = 0 };        // in product mode, this zero value is a no-op
   71.89  #endif //ASSERT
   71.90  
   71.91   private:
   71.92 @@ -469,6 +523,8 @@
   71.93    // Resolve string constants (to prevent allocation during compilation)
   71.94    static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS);
   71.95  
   71.96 +  static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS);
   71.97 +
   71.98   public:
   71.99    // Merging constantPoolOop support:
  71.100    bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
    72.1 --- a/src/share/vm/oops/cpCacheOop.hpp	Thu Jun 24 15:38:42 2010 -0700
    72.2 +++ b/src/share/vm/oops/cpCacheOop.hpp	Mon Jun 28 12:03:05 2010 -0400
    72.3 @@ -110,6 +110,7 @@
    72.4  class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
    72.5    friend class VMStructs;
    72.6    friend class constantPoolCacheKlass;
    72.7 +  friend class constantPoolOopDesc;  //resolve_constant_at_impl => set_f1
    72.8  
    72.9   private:
   72.10    volatile intx     _indices;  // constant pool index & rewrite bytecodes
    73.1 --- a/src/share/vm/opto/compile.cpp	Thu Jun 24 15:38:42 2010 -0700
    73.2 +++ b/src/share/vm/opto/compile.cpp	Mon Jun 28 12:03:05 2010 -0400
    73.3 @@ -2000,6 +2000,17 @@
    73.4      }
    73.5    }
    73.6  
    73.7 +#ifdef ASSERT
    73.8 +  if( n->is_Mem() ) {
    73.9 +    Compile* C = Compile::current();
   73.10 +    int alias_idx = C->get_alias_index(n->as_Mem()->adr_type());
   73.11 +    assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw ||
   73.12 +            // oop will be recorded in oop map if load crosses safepoint
   73.13 +            n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() ||
   73.14 +                             LoadNode::is_immutable_value(n->in(MemNode::Address))),
   73.15 +            "raw memory operations should have control edge");
   73.16 +  }
   73.17 +#endif
   73.18    // Count FPU ops and common calls, implements item (3)
   73.19    switch( nop ) {
   73.20    // Count all float operations that may use FPU
    74.1 --- a/src/share/vm/opto/graphKit.cpp	Thu Jun 24 15:38:42 2010 -0700
    74.2 +++ b/src/share/vm/opto/graphKit.cpp	Mon Jun 28 12:03:05 2010 -0400
    74.3 @@ -1789,9 +1789,10 @@
    74.4  
    74.5  void GraphKit::increment_counter(Node* counter_addr) {
    74.6    int adr_type = Compile::AliasIdxRaw;
    74.7 -  Node* cnt  = make_load(NULL, counter_addr, TypeInt::INT, T_INT, adr_type);
    74.8 +  Node* ctrl = control();
    74.9 +  Node* cnt  = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type);
   74.10    Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1)));
   74.11 -  store_to_memory( NULL, counter_addr, incr, T_INT, adr_type );
   74.12 +  store_to_memory( ctrl, counter_addr, incr, T_INT, adr_type );
   74.13  }
   74.14  
   74.15  
   74.16 @@ -2771,11 +2772,7 @@
   74.17      // Update the counter for this lock.  Don't bother using an atomic
   74.18      // operation since we don't require absolute accuracy.
   74.19      lock->create_lock_counter(map()->jvms());
   74.20 -    int adr_type = Compile::AliasIdxRaw;
   74.21 -    Node* counter_addr = makecon(TypeRawPtr::make(lock->counter()->addr()));
   74.22 -    Node* cnt  = make_load(NULL, counter_addr, TypeInt::INT, T_INT, adr_type);
   74.23 -    Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1)));
   74.24 -    store_to_memory(control(), counter_addr, incr, T_INT, adr_type);
   74.25 +    increment_counter(lock->counter()->addr());
   74.26    }
   74.27  #endif
   74.28  
    75.1 --- a/src/share/vm/opto/library_call.cpp	Thu Jun 24 15:38:42 2010 -0700
    75.2 +++ b/src/share/vm/opto/library_call.cpp	Mon Jun 28 12:03:05 2010 -0400
    75.3 @@ -3512,8 +3512,7 @@
    75.4  
    75.5    // Get the header out of the object, use LoadMarkNode when available
    75.6    Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
    75.7 -  Node* header = make_load(NULL, header_addr, TypeRawPtr::BOTTOM, T_ADDRESS);
    75.8 -  header = _gvn.transform( new (C, 2) CastP2XNode(NULL, header) );
    75.9 +  Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type());
   75.10  
   75.11    // Test the header to see if it is unlocked.
   75.12    Node *lock_mask      = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place);
   75.13 @@ -5202,7 +5201,7 @@
   75.14    // super_check_offset, for the desired klass.
   75.15    int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc);
   75.16    Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset);
   75.17 -  Node* n3 = new(C, 3) LoadINode(NULL, immutable_memory(), p3, TypeRawPtr::BOTTOM);
   75.18 +  Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr());
   75.19    Node* check_offset = _gvn.transform(n3);
   75.20    Node* check_value  = dest_elem_klass;
   75.21  
    76.1 --- a/src/share/vm/opto/macro.cpp	Thu Jun 24 15:38:42 2010 -0700
    76.2 +++ b/src/share/vm/opto/macro.cpp	Mon Jun 28 12:03:05 2010 -0400
    76.3 @@ -1431,7 +1431,7 @@
    76.4    Node* mark_node = NULL;
    76.5    // For now only enable fast locking for non-array types
    76.6    if (UseBiasedLocking && (length == NULL)) {
    76.7 -    mark_node = make_load(NULL, rawmem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeRawPtr::BOTTOM, T_ADDRESS);
    76.8 +    mark_node = make_load(control, rawmem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeRawPtr::BOTTOM, T_ADDRESS);
    76.9    } else {
   76.10      mark_node = makecon(TypeRawPtr::make((address)markOopDesc::prototype()));
   76.11    }
    77.1 --- a/src/share/vm/opto/memnode.cpp	Thu Jun 24 15:38:42 2010 -0700
    77.2 +++ b/src/share/vm/opto/memnode.cpp	Mon Jun 28 12:03:05 2010 -0400
    77.3 @@ -815,6 +815,16 @@
    77.4  }
    77.5  #endif
    77.6  
    77.7 +#ifdef ASSERT
    77.8 +//----------------------------is_immutable_value-------------------------------
    77.9 +// Helper function to allow a raw load without control edge for some cases
   77.10 +bool LoadNode::is_immutable_value(Node* adr) {
   77.11 +  return (adr->is_AddP() && adr->in(AddPNode::Base)->is_top() &&
   77.12 +          adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
   77.13 +          (adr->in(AddPNode::Offset)->find_intptr_t_con(-1) ==
   77.14 +           in_bytes(JavaThread::osthread_offset())));
   77.15 +}
   77.16 +#endif
   77.17  
   77.18  //----------------------------LoadNode::make-----------------------------------
   77.19  // Polymorphic factory method:
   77.20 @@ -828,6 +838,11 @@
   77.21    assert(!(adr_type->isa_aryptr() &&
   77.22             adr_type->offset() == arrayOopDesc::length_offset_in_bytes()),
   77.23           "use LoadRangeNode instead");
   77.24 +  // Check control edge of raw loads
   77.25 +  assert( ctl != NULL || C->get_alias_index(adr_type) != Compile::AliasIdxRaw ||
   77.26 +          // oop will be recorded in oop map if load crosses safepoint
   77.27 +          rt->isa_oopptr() || is_immutable_value(adr),
   77.28 +          "raw memory operations should have control edge");
   77.29    switch (bt) {
   77.30    case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int()    );
   77.31    case T_BYTE:    return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int()    );
   77.32 @@ -2064,6 +2079,8 @@
   77.33  // Polymorphic factory method:
   77.34  StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt ) {
   77.35    Compile* C = gvn.C;
   77.36 +  assert( C->get_alias_index(adr_type) != Compile::AliasIdxRaw ||
   77.37 +          ctl != NULL, "raw memory operations should have control edge");
   77.38  
   77.39    switch (bt) {
   77.40    case T_BOOLEAN:
    78.1 --- a/src/share/vm/opto/memnode.hpp	Thu Jun 24 15:38:42 2010 -0700
    78.2 +++ b/src/share/vm/opto/memnode.hpp	Mon Jun 28 12:03:05 2010 -0400
    78.3 @@ -189,6 +189,10 @@
    78.4  #ifndef PRODUCT
    78.5    virtual void dump_spec(outputStream *st) const;
    78.6  #endif
    78.7 +#ifdef ASSERT
    78.8 +  // Helper function to allow a raw load without control edge for some cases
    78.9 +  static bool is_immutable_value(Node* adr);
   78.10 +#endif
   78.11  protected:
   78.12    const Type* load_array_final_field(const TypeKlassPtr *tkls,
   78.13                                       ciKlass* klass) const;
    79.1 --- a/src/share/vm/opto/parse1.cpp	Thu Jun 24 15:38:42 2010 -0700
    79.2 +++ b/src/share/vm/opto/parse1.cpp	Mon Jun 28 12:03:05 2010 -0400
    79.3 @@ -88,15 +88,16 @@
    79.4                                       Node *local_addrs_base) {
    79.5    Node *mem = memory(Compile::AliasIdxRaw);
    79.6    Node *adr = basic_plus_adr( local_addrs_base, local_addrs, -index*wordSize );
    79.7 +  Node *ctl = control();
    79.8  
    79.9    // Very similar to LoadNode::make, except we handle un-aligned longs and
   79.10    // doubles on Sparc.  Intel can handle them just fine directly.
   79.11    Node *l;
   79.12    switch( bt ) {                // Signature is flattened
   79.13 -  case T_INT:     l = new (C, 3) LoadINode( 0, mem, adr, TypeRawPtr::BOTTOM ); break;
   79.14 -  case T_FLOAT:   l = new (C, 3) LoadFNode( 0, mem, adr, TypeRawPtr::BOTTOM ); break;
   79.15 -  case T_ADDRESS: l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM  ); break;
   79.16 -  case T_OBJECT:  l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break;
   79.17 +  case T_INT:     l = new (C, 3) LoadINode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
   79.18 +  case T_FLOAT:   l = new (C, 3) LoadFNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
   79.19 +  case T_ADDRESS: l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM  ); break;
   79.20 +  case T_OBJECT:  l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break;
   79.21    case T_LONG:
   79.22    case T_DOUBLE: {
   79.23      // Since arguments are in reverse order, the argument address 'adr'
   79.24 @@ -104,12 +105,12 @@
   79.25      adr = basic_plus_adr( local_addrs_base, local_addrs, -(index+1)*wordSize );
   79.26      if( Matcher::misaligned_doubles_ok ) {
   79.27        l = (bt == T_DOUBLE)
   79.28 -        ? (Node*)new (C, 3) LoadDNode( 0, mem, adr, TypeRawPtr::BOTTOM )
   79.29 -        : (Node*)new (C, 3) LoadLNode( 0, mem, adr, TypeRawPtr::BOTTOM );
   79.30 +        ? (Node*)new (C, 3) LoadDNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
   79.31 +        : (Node*)new (C, 3) LoadLNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
   79.32      } else {
   79.33        l = (bt == T_DOUBLE)
   79.34 -        ? (Node*)new (C, 3) LoadD_unalignedNode( 0, mem, adr, TypeRawPtr::BOTTOM )
   79.35 -        : (Node*)new (C, 3) LoadL_unalignedNode( 0, mem, adr, TypeRawPtr::BOTTOM );
   79.36 +        ? (Node*)new (C, 3) LoadD_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
   79.37 +        : (Node*)new (C, 3) LoadL_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
   79.38      }
   79.39      break;
   79.40    }
    80.1 --- a/src/share/vm/opto/parse2.cpp	Thu Jun 24 15:38:42 2010 -0700
    80.2 +++ b/src/share/vm/opto/parse2.cpp	Mon Jun 28 12:03:05 2010 -0400
    80.3 @@ -1324,33 +1324,21 @@
    80.4    case Bytecodes::_ldc_w:
    80.5    case Bytecodes::_ldc2_w:
    80.6      // If the constant is unresolved, run this BC once in the interpreter.
    80.7 -    if (iter().is_unresolved_string()) {
    80.8 -      uncommon_trap(Deoptimization::make_trap_request
    80.9 -                    (Deoptimization::Reason_unloaded,
   80.10 -                     Deoptimization::Action_reinterpret,
   80.11 -                     iter().get_constant_index()),
   80.12 -                    NULL, "unresolved_string");
   80.13 -      break;
   80.14 -    } else {
   80.15 +    {
   80.16        ciConstant constant = iter().get_constant();
   80.17 -      if (constant.basic_type() == T_OBJECT) {
   80.18 -        ciObject* c = constant.as_object();
   80.19 -        if (c->is_klass()) {
   80.20 -          // The constant returned for a klass is the ciKlass for the
   80.21 -          // entry.  We want the java_mirror so get it.
   80.22 -          ciKlass* klass = c->as_klass();
   80.23 -          if (klass->is_loaded()) {
   80.24 -            constant = ciConstant(T_OBJECT, klass->java_mirror());
   80.25 -          } else {
   80.26 -            uncommon_trap(Deoptimization::make_trap_request
   80.27 -                          (Deoptimization::Reason_unloaded,
   80.28 -                           Deoptimization::Action_reinterpret,
   80.29 -                           iter().get_constant_index()),
   80.30 -                          NULL, "unresolved_klass");
   80.31 -            break;
   80.32 -          }
   80.33 -        }
   80.34 +      if (constant.basic_type() == T_OBJECT &&
   80.35 +          !constant.as_object()->is_loaded()) {
   80.36 +        int index = iter().get_constant_pool_index();
   80.37 +        constantTag tag = iter().get_constant_pool_tag(index);
   80.38 +        uncommon_trap(Deoptimization::make_trap_request
   80.39 +                      (Deoptimization::Reason_unloaded,
   80.40 +                       Deoptimization::Action_reinterpret,
   80.41 +                       index),
   80.42 +                      NULL, tag.internal_name());
   80.43 +        break;
   80.44        }
   80.45 +      assert(constant.basic_type() != T_OBJECT || !constant.as_object()->is_klass(),
   80.46 +             "must be java_mirror of klass");
   80.47        bool pushed = push_constant(constant, true);
   80.48        guarantee(pushed, "must be possible to push this constant");
   80.49      }
    81.1 --- a/src/share/vm/prims/jvm.h	Thu Jun 24 15:38:42 2010 -0700
    81.2 +++ b/src/share/vm/prims/jvm.h	Mon Jun 28 12:03:05 2010 -0400
    81.3 @@ -1044,7 +1044,22 @@
    81.4      JVM_CONSTANT_Fieldref,
    81.5      JVM_CONSTANT_Methodref,
    81.6      JVM_CONSTANT_InterfaceMethodref,
    81.7 -    JVM_CONSTANT_NameAndType
    81.8 +    JVM_CONSTANT_NameAndType,
    81.9 +    JVM_CONSTANT_MethodHandle           = 15,  // JSR 292
   81.10 +    JVM_CONSTANT_MethodType             = 16   // JSR 292
   81.11 +};
   81.12 +
   81.13 +/* JVM_CONSTANT_MethodHandle subtypes */
   81.14 +enum {
   81.15 +    JVM_REF_getField                = 1,
   81.16 +    JVM_REF_getStatic               = 2,
   81.17 +    JVM_REF_putField                = 3,
   81.18 +    JVM_REF_putStatic               = 4,
   81.19 +    JVM_REF_invokeVirtual           = 5,
   81.20 +    JVM_REF_invokeStatic            = 6,
   81.21 +    JVM_REF_invokeSpecial           = 7,
   81.22 +    JVM_REF_newInvokeSpecial        = 8,
   81.23 +    JVM_REF_invokeInterface         = 9
   81.24  };
   81.25  
   81.26  /* Used in the newarray instruction. */
    82.1 --- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Thu Jun 24 15:38:42 2010 -0700
    82.2 +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp	Mon Jun 28 12:03:05 2010 -0400
    82.3 @@ -217,21 +217,21 @@
    82.4  
    82.5  class nmethodDesc: public CHeapObj {
    82.6   private:
    82.7 -  methodHandle _method;
    82.8 +  jmethodID _jmethod_id;
    82.9    address _code_begin;
   82.10    address _code_end;
   82.11    jvmtiAddrLocationMap* _map;
   82.12    jint _map_length;
   82.13   public:
   82.14 -  nmethodDesc(methodHandle method, address code_begin, address code_end,
   82.15 +  nmethodDesc(jmethodID jmethod_id, address code_begin, address code_end,
   82.16                jvmtiAddrLocationMap* map, jint map_length) {
   82.17 -    _method = method;
   82.18 +    _jmethod_id = jmethod_id;
   82.19      _code_begin = code_begin;
   82.20      _code_end = code_end;
   82.21      _map = map;
   82.22      _map_length = map_length;
   82.23    }
   82.24 -  methodHandle method() const           { return _method; }
   82.25 +  jmethodID jmethod_id() const          { return _jmethod_id; }
   82.26    address code_begin() const            { return _code_begin; }
   82.27    address code_end() const              { return _code_end; }
   82.28    jvmtiAddrLocationMap* map() const     { return _map; }
   82.29 @@ -323,8 +323,7 @@
   82.30    JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &map, &map_length);
   82.31  
   82.32    // record the nmethod details
   82.33 -  methodHandle mh(nm->method());
   82.34 -  nmethodDesc* snm = new nmethodDesc(mh,
   82.35 +  nmethodDesc* snm = new nmethodDesc(nm->get_and_cache_jmethod_id(),
   82.36                                       nm->code_begin(),
   82.37                                       nm->code_end(),
   82.38                                       map,
   82.39 @@ -367,8 +366,7 @@
   82.40    // iterate over the  list and post an event for each nmethod
   82.41    nmethodDesc* nm_desc = collector.first();
   82.42    while (nm_desc != NULL) {
   82.43 -    methodOop method = nm_desc->method()();
   82.44 -    jmethodID mid = method->jmethod_id();
   82.45 +    jmethodID mid = nm_desc->jmethod_id();
   82.46      assert(mid != NULL, "checking");
   82.47      JvmtiExport::post_compiled_method_load(env, mid,
   82.48                                             (jint)(nm_desc->code_end() - nm_desc->code_begin()),
    83.1 --- a/src/share/vm/prims/methodComparator.cpp	Thu Jun 24 15:38:42 2010 -0700
    83.2 +++ b/src/share/vm/prims/methodComparator.cpp	Mon Jun 28 12:03:05 2010 -0400
    83.3 @@ -163,10 +163,10 @@
    83.4  
    83.5    case Bytecodes::_ldc   : // fall through
    83.6    case Bytecodes::_ldc_w : {
    83.7 -    Bytecode_loadconstant* ldc_old = Bytecode_loadconstant_at(_s_old->method()(), _s_old->bcp());
    83.8 -    Bytecode_loadconstant* ldc_new = Bytecode_loadconstant_at(_s_new->method()(), _s_new->bcp());
    83.9 -    int cpi_old = ldc_old->index();
   83.10 -    int cpi_new = ldc_new->index();
   83.11 +    Bytecode_loadconstant* ldc_old = Bytecode_loadconstant_at(_s_old->method(), _s_old->bci());
   83.12 +    Bytecode_loadconstant* ldc_new = Bytecode_loadconstant_at(_s_new->method(), _s_new->bci());
   83.13 +    int cpi_old = ldc_old->pool_index();
   83.14 +    int cpi_new = ldc_new->pool_index();
   83.15      constantTag tag_old = _old_cp->tag_at(cpi_old);
   83.16      constantTag tag_new = _new_cp->tag_at(cpi_new);
   83.17      if (tag_old.is_int() || tag_old.is_float()) {
   83.18 @@ -187,12 +187,30 @@
   83.19        if (strcmp(_old_cp->string_at_noresolve(cpi_old),
   83.20                   _new_cp->string_at_noresolve(cpi_new)) != 0)
   83.21          return false;
   83.22 -    } else { // tag_old should be klass - 4881222
   83.23 +    } else if (tag_old.is_klass() || tag_old.is_unresolved_klass()) {
   83.24 +      // tag_old should be klass - 4881222
   83.25        if (! (tag_new.is_unresolved_klass() || tag_new.is_klass()))
   83.26          return false;
   83.27        if (_old_cp->klass_at_noresolve(cpi_old) !=
   83.28            _new_cp->klass_at_noresolve(cpi_new))
   83.29          return false;
   83.30 +    } else if (tag_old.is_method_type() && tag_new.is_method_type()) {
   83.31 +      int mti_old = _old_cp->method_type_index_at(cpi_old);
   83.32 +      int mti_new = _new_cp->method_type_index_at(cpi_new);
   83.33 +      if ((_old_cp->symbol_at(mti_old) != _new_cp->symbol_at(mti_new)))
   83.34 +        return false;
   83.35 +    } else if (tag_old.is_method_handle() && tag_new.is_method_handle()) {
   83.36 +      if (_old_cp->method_handle_ref_kind_at(cpi_old) !=
   83.37 +          _new_cp->method_handle_ref_kind_at(cpi_new))
   83.38 +        return false;
   83.39 +      int mhi_old = _old_cp->method_handle_index_at(cpi_old);
   83.40 +      int mhi_new = _new_cp->method_handle_index_at(cpi_new);
   83.41 +      if ((_old_cp->uncached_klass_ref_at_noresolve(mhi_old) != _new_cp->uncached_klass_ref_at_noresolve(mhi_new)) ||
   83.42 +          (_old_cp->uncached_name_ref_at(mhi_old) != _new_cp->uncached_name_ref_at(mhi_new)) ||
   83.43 +          (_old_cp->uncached_signature_ref_at(mhi_old) != _new_cp->uncached_signature_ref_at(mhi_new)))
   83.44 +        return false;
   83.45 +    } else {
   83.46 +      return false;  // unknown tag
   83.47      }
   83.48      break;
   83.49    }
    84.1 --- a/src/share/vm/runtime/arguments.cpp	Thu Jun 24 15:38:42 2010 -0700
    84.2 +++ b/src/share/vm/runtime/arguments.cpp	Mon Jun 28 12:03:05 2010 -0400
    84.3 @@ -1376,11 +1376,6 @@
    84.4    }
    84.5    no_shared_spaces();
    84.6  
    84.7 -  // Set the maximum pause time goal to be a reasonable default.
    84.8 -  if (FLAG_IS_DEFAULT(MaxGCPauseMillis)) {
    84.9 -    FLAG_SET_DEFAULT(MaxGCPauseMillis, 200);
   84.10 -  }
   84.11 -
   84.12    if (FLAG_IS_DEFAULT(MarkStackSize)) {
   84.13      FLAG_SET_DEFAULT(MarkStackSize, 128 * TASKQUEUE_SIZE);
   84.14    }
    85.1 --- a/src/share/vm/runtime/globals.hpp	Thu Jun 24 15:38:42 2010 -0700
    85.2 +++ b/src/share/vm/runtime/globals.hpp	Mon Jun 28 12:03:05 2010 -0400
    85.3 @@ -1975,7 +1975,7 @@
    85.4            "Adaptive size policy maximum GC pause time goal in msec, "       \
    85.5            "or (G1 Only) the max. GC time per MMU time slice")               \
    85.6                                                                              \
    85.7 -  product(intx, GCPauseIntervalMillis, 500,                                 \
    85.8 +  product(uintx, GCPauseIntervalMillis, 0,                                  \
    85.9            "Time slice for MMU specification")                               \
   85.10                                                                              \
   85.11    product(uintx, MaxGCMinorPauseMillis, max_uintx,                          \
    86.1 --- a/src/share/vm/runtime/jniHandles.cpp	Thu Jun 24 15:38:42 2010 -0700
    86.2 +++ b/src/share/vm/runtime/jniHandles.cpp	Mon Jun 28 12:03:05 2010 -0400
    86.3 @@ -66,6 +66,7 @@
    86.4  
    86.5  
    86.6  jobject JNIHandles::make_global(Handle obj) {
    86.7 +  assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
    86.8    jobject res = NULL;
    86.9    if (!obj.is_null()) {
   86.10      // ignore null handles
   86.11 @@ -81,6 +82,7 @@
   86.12  
   86.13  
   86.14  jobject JNIHandles::make_weak_global(Handle obj) {
   86.15 +  assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
   86.16    jobject res = NULL;
   86.17    if (!obj.is_null()) {
   86.18      // ignore null handles
    87.1 --- a/src/share/vm/runtime/sharedRuntime.cpp	Thu Jun 24 15:38:42 2010 -0700
    87.2 +++ b/src/share/vm/runtime/sharedRuntime.cpp	Mon Jun 28 12:03:05 2010 -0400
    87.3 @@ -779,7 +779,7 @@
    87.4  
    87.5    // Find bytecode
    87.6    Bytecode_invoke* bytecode = Bytecode_invoke_at(caller, bci);
    87.7 -  bc = bytecode->adjusted_invoke_code();
    87.8 +  bc = bytecode->java_code();
    87.9    int bytecode_index = bytecode->index();
   87.10  
   87.11    // Find receiver for non-static call
    88.1 --- a/src/share/vm/runtime/stubRoutines.cpp	Thu Jun 24 15:38:42 2010 -0700
    88.2 +++ b/src/share/vm/runtime/stubRoutines.cpp	Mon Jun 28 12:03:05 2010 -0400
    88.3 @@ -135,28 +135,32 @@
    88.4  static void test_arraycopy_func(address func, int alignment) {
    88.5    int v = 0xcc;
    88.6    int v2 = 0x11;
    88.7 -  jlong lbuffer[2];
    88.8 -  jlong lbuffer2[2];
    88.9 -  address buffer  = (address) lbuffer;
   88.10 -  address buffer2 = (address) lbuffer2;
   88.11 +  jlong lbuffer[8];
   88.12 +  jlong lbuffer2[8];
   88.13 +  address fbuffer  = (address) lbuffer;
   88.14 +  address fbuffer2 = (address) lbuffer2;
   88.15    unsigned int i;
   88.16    for (i = 0; i < sizeof(lbuffer); i++) {
   88.17 -    buffer[i] = v; buffer2[i] = v2;
   88.18 +    fbuffer[i] = v; fbuffer2[i] = v2;
   88.19    }
   88.20 +  // C++ does not guarantee jlong[] array alignment to 8 bytes.
   88.21 +  // Use middle of array to check that memory before it is not modified.
   88.22 +  address buffer  = (address) round_to((intptr_t)&lbuffer[4], BytesPerLong);
   88.23 +  address buffer2 = (address) round_to((intptr_t)&lbuffer2[4], BytesPerLong);
   88.24    // do an aligned copy
   88.25    ((arraycopy_fn)func)(buffer, buffer2, 0);
   88.26    for (i = 0; i < sizeof(lbuffer); i++) {
   88.27 -    assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything");
   88.28 +    assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
   88.29    }
   88.30    // adjust destination alignment
   88.31    ((arraycopy_fn)func)(buffer, buffer2 + alignment, 0);
   88.32    for (i = 0; i < sizeof(lbuffer); i++) {
   88.33 -    assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything");
   88.34 +    assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
   88.35    }
   88.36    // adjust source alignment
   88.37    ((arraycopy_fn)func)(buffer + alignment, buffer2, 0);
   88.38    for (i = 0; i < sizeof(lbuffer); i++) {
   88.39 -    assert(buffer[i] == v && buffer2[i] == v2, "shouldn't have copied anything");
   88.40 +    assert(fbuffer[i] == v && fbuffer2[i] == v2, "shouldn't have copied anything");
   88.41    }
   88.42  }
   88.43  #endif
   88.44 @@ -183,7 +187,7 @@
   88.45    test_arraycopy_func(arrayof_##type##_arraycopy(),          sizeof(HeapWord)); \
   88.46    test_arraycopy_func(arrayof_##type##_disjoint_arraycopy(), sizeof(HeapWord))
   88.47  
   88.48 -  // Make sure all the arraycopy stubs properly handle zeros
   88.49 +  // Make sure all the arraycopy stubs properly handle zero count
   88.50    TEST_ARRAYCOPY(jbyte);
   88.51    TEST_ARRAYCOPY(jshort);
   88.52    TEST_ARRAYCOPY(jint);
   88.53 @@ -191,6 +195,25 @@
   88.54  
   88.55  #undef TEST_ARRAYCOPY
   88.56  
   88.57 +#define TEST_COPYRTN(type) \
   88.58 +  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_##type##s_atomic),  sizeof(type)); \
   88.59 +  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::arrayof_conjoint_##type##s), (int)MAX2(sizeof(HeapWord), sizeof(type)))
   88.60 +
   88.61 +  // Make sure all the copy runtime routines properly handle zero count
   88.62 +  TEST_COPYRTN(jbyte);
   88.63 +  TEST_COPYRTN(jshort);
   88.64 +  TEST_COPYRTN(jint);
   88.65 +  TEST_COPYRTN(jlong);
   88.66 +
   88.67 +#undef TEST_COPYRTN
   88.68 +
   88.69 +  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::conjoint_words), sizeof(HeapWord));
   88.70 +  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words), sizeof(HeapWord));
   88.71 +  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::disjoint_words_atomic), sizeof(HeapWord));
   88.72 +  // Aligned to BytesPerLong
   88.73 +  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_conjoint_words), sizeof(jlong));
   88.74 +  test_arraycopy_func(CAST_FROM_FN_PTR(address, Copy::aligned_disjoint_words), sizeof(jlong));
   88.75 +
   88.76  #endif
   88.77  }
   88.78  
   88.79 @@ -221,15 +244,13 @@
   88.80  #ifndef PRODUCT
   88.81    SharedRuntime::_jbyte_array_copy_ctr++;      // Slow-path byte array copy
   88.82  #endif // !PRODUCT
   88.83 -  assert(count != 0, "count should be non-zero");
   88.84 -  Copy::conjoint_bytes_atomic(src, dest, count);
   88.85 +  Copy::conjoint_jbytes_atomic(src, dest, count);
   88.86  JRT_END
   88.87  
   88.88  JRT_LEAF(void, StubRoutines::jshort_copy(jshort* src, jshort* dest, size_t count))
   88.89  #ifndef PRODUCT
   88.90    SharedRuntime::_jshort_array_copy_ctr++;     // Slow-path short/char array copy
   88.91  #endif // !PRODUCT
   88.92 -  assert(count != 0, "count should be non-zero");
   88.93    Copy::conjoint_jshorts_atomic(src, dest, count);
   88.94  JRT_END
   88.95  
   88.96 @@ -237,7 +258,6 @@
   88.97  #ifndef PRODUCT
   88.98    SharedRuntime::_jint_array_copy_ctr++;       // Slow-path int/float array copy
   88.99  #endif // !PRODUCT
  88.100 -  assert(count != 0, "count should be non-zero");
  88.101    Copy::conjoint_jints_atomic(src, dest, count);
  88.102  JRT_END
  88.103  
  88.104 @@ -245,7 +265,6 @@
  88.105  #ifndef PRODUCT
  88.106    SharedRuntime::_jlong_array_copy_ctr++;      // Slow-path long/double array copy
  88.107  #endif // !PRODUCT
  88.108 -  assert(count != 0, "count should be non-zero");
  88.109    Copy::conjoint_jlongs_atomic(src, dest, count);
  88.110  JRT_END
  88.111  
  88.112 @@ -263,15 +282,13 @@
  88.113  #ifndef PRODUCT
  88.114    SharedRuntime::_jbyte_array_copy_ctr++;      // Slow-path byte array copy
  88.115  #endif // !PRODUCT
  88.116 -  assert(count != 0, "count should be non-zero");
  88.117 -  Copy::arrayof_conjoint_bytes(src, dest, count);
  88.118 +  Copy::arrayof_conjoint_jbytes(src, dest, count);
  88.119  JRT_END
  88.120  
  88.121  JRT_LEAF(void, StubRoutines::arrayof_jshort_copy(HeapWord* src, HeapWord* dest, size_t count))
  88.122  #ifndef PRODUCT
  88.123    SharedRuntime::_jshort_array_copy_ctr++;     // Slow-path short/char array copy
  88.124  #endif // !PRODUCT
  88.125 -  assert(count != 0, "count should be non-zero");
  88.126    Copy::arrayof_conjoint_jshorts(src, dest, count);
  88.127  JRT_END
  88.128  
  88.129 @@ -279,7 +296,6 @@
  88.130  #ifndef PRODUCT
  88.131    SharedRuntime::_jint_array_copy_ctr++;       // Slow-path int/float array copy
  88.132  #endif // !PRODUCT
  88.133 -  assert(count != 0, "count should be non-zero");
  88.134    Copy::arrayof_conjoint_jints(src, dest, count);
  88.135  JRT_END
  88.136  
  88.137 @@ -287,7 +303,6 @@
  88.138  #ifndef PRODUCT
  88.139    SharedRuntime::_jlong_array_copy_ctr++;       // Slow-path int/float array copy
  88.140  #endif // !PRODUCT
  88.141 -  assert(count != 0, "count should be non-zero");
  88.142    Copy::arrayof_conjoint_jlongs(src, dest, count);
  88.143  JRT_END
  88.144  
    89.1 --- a/src/share/vm/runtime/sweeper.cpp	Thu Jun 24 15:38:42 2010 -0700
    89.2 +++ b/src/share/vm/runtime/sweeper.cpp	Mon Jun 28 12:03:05 2010 -0400
    89.3 @@ -26,7 +26,7 @@
    89.4  # include "incls/_sweeper.cpp.incl"
    89.5  
    89.6  long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
    89.7 -CodeBlob* NMethodSweeper::_current = NULL;   // Current nmethod
    89.8 +nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
    89.9  int       NMethodSweeper::_seen = 0 ;        // No. of blobs we have currently processed in current pass of CodeCache
   89.10  int       NMethodSweeper::_invocations = 0;  // No. of invocations left until we are completed with this pass
   89.11  
   89.12 @@ -171,20 +171,16 @@
   89.13        // Since we will give up the CodeCache_lock, always skip ahead to an nmethod.
   89.14        // Other blobs can be deleted by other threads
   89.15        // Read next before we potentially delete current
   89.16 -      CodeBlob* next = CodeCache::next_nmethod(_current);
   89.17 +      nmethod* next = CodeCache::next_nmethod(_current);
   89.18  
   89.19        // Now ready to process nmethod and give up CodeCache_lock
   89.20        {
   89.21          MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   89.22 -        process_nmethod((nmethod *)_current);
   89.23 +        process_nmethod(_current);
   89.24        }
   89.25        _seen++;
   89.26        _current = next;
   89.27      }
   89.28 -
   89.29 -    // Skip forward to the next nmethod (if any). Code blobs other than nmethods
   89.30 -    // can be freed async to us and make _current invalid while we sleep.
   89.31 -    _current = CodeCache::next_nmethod(_current);
   89.32    }
   89.33  
   89.34    if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) {
    90.1 --- a/src/share/vm/runtime/sweeper.hpp	Thu Jun 24 15:38:42 2010 -0700
    90.2 +++ b/src/share/vm/runtime/sweeper.hpp	Mon Jun 28 12:03:05 2010 -0400
    90.3 @@ -29,7 +29,7 @@
    90.4  
    90.5  class NMethodSweeper : public AllStatic {
    90.6    static long      _traversals;   // Stack traversal count
    90.7 -  static CodeBlob* _current;      // Current nmethod
    90.8 +  static nmethod*  _current;      // Current nmethod
    90.9    static int       _seen;         // Nof. nmethod we have currently processed in current pass of CodeCache
   90.10    static int       _invocations;  // No. of invocations left until we are completed with this pass
   90.11  
    91.1 --- a/src/share/vm/runtime/thread.cpp	Thu Jun 24 15:38:42 2010 -0700
    91.2 +++ b/src/share/vm/runtime/thread.cpp	Mon Jun 28 12:03:05 2010 -0400
    91.3 @@ -2700,7 +2700,7 @@
    91.4    if (in_bytes(size_in_bytes) != 0) {
    91.5      _popframe_preserved_args = NEW_C_HEAP_ARRAY(char, in_bytes(size_in_bytes));
    91.6      _popframe_preserved_args_size = in_bytes(size_in_bytes);
    91.7 -    Copy::conjoint_bytes(start, _popframe_preserved_args, _popframe_preserved_args_size);
    91.8 +    Copy::conjoint_jbytes(start, _popframe_preserved_args, _popframe_preserved_args_size);
    91.9    }
   91.10  }
   91.11  
    92.1 --- a/src/share/vm/runtime/vframeArray.cpp	Thu Jun 24 15:38:42 2010 -0700
    92.2 +++ b/src/share/vm/runtime/vframeArray.cpp	Mon Jun 28 12:03:05 2010 -0400
    92.3 @@ -355,9 +355,9 @@
    92.4        } else {
    92.5          base = iframe()->interpreter_frame_expression_stack();
    92.6        }
    92.7 -      Copy::conjoint_bytes(saved_args,
    92.8 -                           base,
    92.9 -                           popframe_preserved_args_size_in_bytes);
   92.10 +      Copy::conjoint_jbytes(saved_args,
   92.11 +                            base,
   92.12 +                            popframe_preserved_args_size_in_bytes);
   92.13        thread->popframe_free_preserved_args();
   92.14      }
   92.15    }
    93.1 --- a/src/share/vm/runtime/virtualspace.cpp	Thu Jun 24 15:38:42 2010 -0700
    93.2 +++ b/src/share/vm/runtime/virtualspace.cpp	Mon Jun 28 12:03:05 2010 -0400
    93.3 @@ -111,6 +111,35 @@
    93.4    return result;
    93.5  }
    93.6  
    93.7 +// Helper method.
    93.8 +static bool failed_to_reserve_as_requested(char* base, char* requested_address,
    93.9 +                                           const size_t size, bool special)
   93.10 +{
   93.11 +  if (base == requested_address || requested_address == NULL)
   93.12 +    return false; // did not fail
   93.13 +
   93.14 +  if (base != NULL) {
   93.15 +    // Different reserve address may be acceptable in other cases
   93.16 +    // but for compressed oops heap should be at requested address.
   93.17 +    assert(UseCompressedOops, "currently requested address used only for compressed oops");
   93.18 +    if (PrintCompressedOopsMode) {
   93.19 +      tty->cr();
   93.20 +      tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address);
   93.21 +    }
   93.22 +    // OS ignored requested address. Try different address.
   93.23 +    if (special) {
   93.24 +      if (!os::release_memory_special(base, size)) {
   93.25 +        fatal("os::release_memory_special failed");
   93.26 +      }
   93.27 +    } else {
   93.28 +      if (!os::release_memory(base, size)) {
   93.29 +        fatal("os::release_memory failed");
   93.30 +      }
   93.31 +    }
   93.32 +  }
   93.33 +  return true;
   93.34 +}
   93.35 +
   93.36  ReservedSpace::ReservedSpace(const size_t prefix_size,
   93.37                               const size_t prefix_align,
   93.38                               const size_t suffix_size,
   93.39 @@ -129,6 +158,10 @@
   93.40    assert((suffix_align & prefix_align - 1) == 0,
   93.41      "suffix_align not divisible by prefix_align");
   93.42  
   93.43 +  // Assert that if noaccess_prefix is used, it is the same as prefix_align.
   93.44 +  assert(noaccess_prefix == 0 ||
   93.45 +         noaccess_prefix == prefix_align, "noaccess prefix wrong");
   93.46 +
   93.47    // Add in noaccess_prefix to prefix_size;
   93.48    const size_t adjusted_prefix_size = prefix_size + noaccess_prefix;
   93.49    const size_t size = adjusted_prefix_size + suffix_size;
   93.50 @@ -150,15 +183,16 @@
   93.51    _noaccess_prefix = 0;
   93.52    _executable = false;
   93.53  
   93.54 -  // Assert that if noaccess_prefix is used, it is the same as prefix_align.
   93.55 -  assert(noaccess_prefix == 0 ||
   93.56 -         noaccess_prefix == prefix_align, "noaccess prefix wrong");
   93.57 -
   93.58    // Optimistically try to reserve the exact size needed.
   93.59    char* addr;
   93.60    if (requested_address != 0) {
   93.61 -    addr = os::attempt_reserve_memory_at(size,
   93.62 -                                         requested_address-noaccess_prefix);
   93.63 +    requested_address -= noaccess_prefix; // adjust address
   93.64 +    assert(requested_address != NULL, "huge noaccess prefix?");
   93.65 +    addr = os::attempt_reserve_memory_at(size, requested_address);
   93.66 +    if (failed_to_reserve_as_requested(addr, requested_address, size, false)) {
   93.67 +      // OS ignored requested address. Try different address.
   93.68 +      addr = NULL;
   93.69 +    }
   93.70    } else {
   93.71      addr = os::reserve_memory(size, NULL, prefix_align);
   93.72    }
   93.73 @@ -222,11 +256,20 @@
   93.74    bool special = large && !os::can_commit_large_page_memory();
   93.75    char* base = NULL;
   93.76  
   93.77 +  if (requested_address != 0) {
   93.78 +    requested_address -= noaccess_prefix; // adjust requested address
   93.79 +    assert(requested_address != NULL, "huge noaccess prefix?");
   93.80 +  }
   93.81 +
   93.82    if (special) {
   93.83  
   93.84      base = os::reserve_memory_special(size, requested_address, executable);
   93.85  
   93.86      if (base != NULL) {
   93.87 +      if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
   93.88 +        // OS ignored requested address. Try different address.
   93.89 +        return;
   93.90 +      }
   93.91        // Check alignment constraints
   93.92        if (alignment > 0) {
   93.93          assert((uintptr_t) base % alignment == 0,
   93.94 @@ -235,6 +278,13 @@
   93.95        _special = true;
   93.96      } else {
   93.97        // failed; try to reserve regular memory below
   93.98 +      if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
   93.99 +                            !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
  93.100 +        if (PrintCompressedOopsMode) {
  93.101 +          tty->cr();
  93.102 +          tty->print_cr("Reserve regular memory without large pages.");
  93.103 +        }
  93.104 +      }
  93.105      }
  93.106    }
  93.107  
  93.108 @@ -248,8 +298,11 @@
  93.109      // important.  If available space is not detected, return NULL.
  93.110  
  93.111      if (requested_address != 0) {
  93.112 -      base = os::attempt_reserve_memory_at(size,
  93.113 -                                           requested_address-noaccess_prefix);
  93.114 +      base = os::attempt_reserve_memory_at(size, requested_address);
  93.115 +      if (failed_to_reserve_as_requested(base, requested_address, size, false)) {
  93.116 +        // OS ignored requested address. Try different address.
  93.117 +        base = NULL;
  93.118 +      }
  93.119      } else {
  93.120        base = os::reserve_memory(size, NULL, alignment);
  93.121      }
  93.122 @@ -365,7 +418,12 @@
  93.123  }
  93.124  
  93.125  void ReservedSpace::protect_noaccess_prefix(const size_t size) {
  93.126 -  // If there is noaccess prefix, return.
  93.127 +  assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL &&
  93.128 +                                      (size_t(_base + _size) > OopEncodingHeapMax) &&
  93.129 +                                      Universe::narrow_oop_use_implicit_null_checks()),
  93.130 +         "noaccess_prefix should be used only with non zero based compressed oops");
  93.131 +
  93.132 +  // If there is no noaccess prefix, return.
  93.133    if (_noaccess_prefix == 0) return;
  93.134  
  93.135    assert(_noaccess_prefix >= (size_t)os::vm_page_size(),
  93.136 @@ -377,6 +435,10 @@
  93.137                            _special)) {
  93.138      fatal("cannot protect protection page");
  93.139    }
  93.140 +  if (PrintCompressedOopsMode) {
  93.141 +    tty->cr();
  93.142 +    tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix);
  93.143 +  }
  93.144  
  93.145    _base += _noaccess_prefix;
  93.146    _size -= _noaccess_prefix;
    94.1 --- a/src/share/vm/utilities/constantTag.cpp	Thu Jun 24 15:38:42 2010 -0700
    94.2 +++ b/src/share/vm/utilities/constantTag.cpp	Mon Jun 28 12:03:05 2010 -0400
    94.3 @@ -28,56 +28,85 @@
    94.4  #ifndef PRODUCT
    94.5  
    94.6  void constantTag::print_on(outputStream* st) const {
    94.7 +  st->print(internal_name());
    94.8 +}
    94.9 +
   94.10 +#endif // PRODUCT
   94.11 +
   94.12 +BasicType constantTag::basic_type() const {
   94.13    switch (_tag) {
   94.14 +    case JVM_CONSTANT_Integer :
   94.15 +      return T_INT;
   94.16 +    case JVM_CONSTANT_Float :
   94.17 +      return T_FLOAT;
   94.18 +    case JVM_CONSTANT_Long :
   94.19 +      return T_LONG;
   94.20 +    case JVM_CONSTANT_Double :
   94.21 +      return T_DOUBLE;
   94.22 +
   94.23      case JVM_CONSTANT_Class :
   94.24 -      st->print("Class");
   94.25 -      break;
   94.26 -    case JVM_CONSTANT_Fieldref :
   94.27 -      st->print("Field");
   94.28 -      break;
   94.29 -    case JVM_CONSTANT_Methodref :
   94.30 -      st->print("Method");
   94.31 -      break;
   94.32 -    case JVM_CONSTANT_InterfaceMethodref :
   94.33 -      st->print("InterfaceMethod");
   94.34 -      break;
   94.35      case JVM_CONSTANT_String :
   94.36 -      st->print("String");
   94.37 -      break;
   94.38 -    case JVM_CONSTANT_Integer :
   94.39 -      st->print("Integer");
   94.40 -      break;
   94.41 -    case JVM_CONSTANT_Float :
   94.42 -      st->print("Float");
   94.43 -      break;
   94.44 -    case JVM_CONSTANT_Long :
   94.45 -      st->print("Long");
   94.46 -      break;
   94.47 -    case JVM_CONSTANT_Double :
   94.48 -      st->print("Double");
   94.49 -      break;
   94.50 -    case JVM_CONSTANT_NameAndType :
   94.51 -      st->print("NameAndType");
   94.52 -      break;
   94.53 -    case JVM_CONSTANT_Utf8 :
   94.54 -      st->print("Utf8");
   94.55 -      break;
   94.56      case JVM_CONSTANT_UnresolvedClass :
   94.57 -      st->print("Unresolved class");
   94.58 -      break;
   94.59 +    case JVM_CONSTANT_UnresolvedClassInError :
   94.60      case JVM_CONSTANT_ClassIndex :
   94.61 -      st->print("Unresolved class index");
   94.62 -      break;
   94.63      case JVM_CONSTANT_UnresolvedString :
   94.64 -      st->print("Unresolved string");
   94.65 -      break;
   94.66      case JVM_CONSTANT_StringIndex :
   94.67 -      st->print("Unresolved string index");
   94.68 -      break;
   94.69 +    case JVM_CONSTANT_MethodHandle :
   94.70 +    case JVM_CONSTANT_MethodType :
   94.71 +    case JVM_CONSTANT_Object :
   94.72 +      return T_OBJECT;
   94.73      default:
   94.74        ShouldNotReachHere();
   94.75 -      break;
   94.76 +      return T_ILLEGAL;
   94.77    }
   94.78  }
   94.79  
   94.80 -#endif // PRODUCT
   94.81 +
   94.82 +
   94.83 +const char* constantTag::internal_name() const {
   94.84 +  switch (_tag) {
   94.85 +    case JVM_CONSTANT_Invalid :
   94.86 +      return "Invalid index";
   94.87 +    case JVM_CONSTANT_Class :
   94.88 +      return "Class";
   94.89 +    case JVM_CONSTANT_Fieldref :
   94.90 +      return "Field";
   94.91 +    case JVM_CONSTANT_Methodref :
   94.92 +      return "Method";
   94.93 +    case JVM_CONSTANT_InterfaceMethodref :
   94.94 +      return "InterfaceMethod";
   94.95 +    case JVM_CONSTANT_String :
   94.96 +      return "String";
   94.97 +    case JVM_CONSTANT_Integer :
   94.98 +      return "Integer";
   94.99 +    case JVM_CONSTANT_Float :
  94.100 +      return "Float";
  94.101 +    case JVM_CONSTANT_Long :
  94.102 +      return "Long";
  94.103 +    case JVM_CONSTANT_Double :
  94.104 +      return "Double";
  94.105 +    case JVM_CONSTANT_NameAndType :
  94.106 +      return "NameAndType";
  94.107 +    case JVM_CONSTANT_MethodHandle :
  94.108 +      return "MethodHandle";
  94.109 +    case JVM_CONSTANT_MethodType :
  94.110 +      return "MethodType";
  94.111 +    case JVM_CONSTANT_Object :
  94.112 +      return "Object";
  94.113 +    case JVM_CONSTANT_Utf8 :
  94.114 +      return "Utf8";
  94.115 +    case JVM_CONSTANT_UnresolvedClass :
  94.116 +      return "Unresolved Class";
  94.117 +    case JVM_CONSTANT_UnresolvedClassInError :
  94.118 +      return "Unresolved Class Error";
  94.119 +    case JVM_CONSTANT_ClassIndex :
  94.120 +      return "Unresolved Class Index";
  94.121 +    case JVM_CONSTANT_UnresolvedString :
  94.122 +      return "Unresolved String";
  94.123 +    case JVM_CONSTANT_StringIndex :
  94.124 +      return "Unresolved String Index";
  94.125 +    default:
  94.126 +      ShouldNotReachHere();
  94.127 +      return "Illegal";
  94.128 +  }
  94.129 +}
    95.1 --- a/src/share/vm/utilities/constantTag.hpp	Thu Jun 24 15:38:42 2010 -0700
    95.2 +++ b/src/share/vm/utilities/constantTag.hpp	Mon Jun 28 12:03:05 2010 -0400
    95.3 @@ -78,13 +78,24 @@
    95.4    bool is_field_or_method() const   { return is_field() || is_method() || is_interface_method(); }
    95.5    bool is_symbol() const            { return is_utf8(); }
    95.6  
    95.7 +  bool is_method_type() const              { return _tag == JVM_CONSTANT_MethodType; }
    95.8 +  bool is_method_handle() const            { return _tag == JVM_CONSTANT_MethodHandle; }
    95.9 +
   95.10 +  constantTag() {
   95.11 +    _tag = JVM_CONSTANT_Invalid;
   95.12 +  }
   95.13    constantTag(jbyte tag) {
   95.14      assert((tag >= 0 && tag <= JVM_CONSTANT_NameAndType) ||
   95.15 +           (tag >= JVM_CONSTANT_MethodHandle && tag <= JVM_CONSTANT_MethodType) ||
   95.16             (tag >= JVM_CONSTANT_InternalMin && tag <= JVM_CONSTANT_InternalMax), "Invalid constant tag");
   95.17      _tag = tag;
   95.18    }
   95.19  
   95.20    jbyte value()                      { return _tag; }
   95.21  
   95.22 +  BasicType basic_type() const;        // if used with ldc, what kind of value gets pushed?
   95.23 +
   95.24 +  const char* internal_name() const;  // for error reporting
   95.25 +
   95.26    void print_on(outputStream* st) const PRODUCT_RETURN;
   95.27  };
    96.1 --- a/src/share/vm/utilities/copy.cpp	Thu Jun 24 15:38:42 2010 -0700
    96.2 +++ b/src/share/vm/utilities/copy.cpp	Mon Jun 28 12:03:05 2010 -0400
    96.3 @@ -48,7 +48,7 @@
    96.4      Copy::conjoint_jshorts_atomic((jshort*) src, (jshort*) dst, size / sizeof(jshort));
    96.5    } else {
    96.6      // Not aligned, so no need to be atomic.
    96.7 -    Copy::conjoint_bytes((void*) src, (void*) dst, size);
    96.8 +    Copy::conjoint_jbytes((void*) src, (void*) dst, size);
    96.9    }
   96.10  }
   96.11  
    97.1 --- a/src/share/vm/utilities/copy.hpp	Thu Jun 24 15:38:42 2010 -0700
    97.2 +++ b/src/share/vm/utilities/copy.hpp	Mon Jun 28 12:03:05 2010 -0400
    97.3 @@ -73,6 +73,9 @@
    97.4    // whole alignment units.  E.g., if BytesPerLong is 2x word alignment, an odd
    97.5    // count may copy an extra word.  In the arrayof case, we are allowed to copy
    97.6    // only the number of copy units specified.
    97.7 +  //
    97.8 +  // All callees check count for 0.
    97.9 +  //
   97.10  
   97.11    // HeapWords
   97.12  
   97.13 @@ -99,7 +102,6 @@
   97.14    // Object-aligned words,  conjoint, not atomic on each word
   97.15    static void aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
   97.16      assert_params_aligned(from, to);
   97.17 -    assert_non_zero(count);
   97.18      pd_aligned_conjoint_words(from, to, count);
   97.19    }
   97.20  
   97.21 @@ -107,49 +109,42 @@
   97.22    static void aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
   97.23      assert_params_aligned(from, to);
   97.24      assert_disjoint(from, to, count);
   97.25 -    assert_non_zero(count);
   97.26      pd_aligned_disjoint_words(from, to, count);
   97.27    }
   97.28  
   97.29    // bytes, jshorts, jints, jlongs, oops
   97.30  
   97.31    // bytes,                 conjoint, not atomic on each byte (not that it matters)
   97.32 -  static void conjoint_bytes(void* from, void* to, size_t count) {
   97.33 -    assert_non_zero(count);
   97.34 +  static void conjoint_jbytes(void* from, void* to, size_t count) {
   97.35      pd_conjoint_bytes(from, to, count);
   97.36    }
   97.37  
   97.38    // bytes,                 conjoint, atomic on each byte (not that it matters)
   97.39 -  static void conjoint_bytes_atomic(void* from, void* to, size_t count) {
   97.40 -    assert_non_zero(count);
   97.41 +  static void conjoint_jbytes_atomic(void* from, void* to, size_t count) {
   97.42      pd_conjoint_bytes(from, to, count);
   97.43    }
   97.44  
   97.45    // jshorts,               conjoint, atomic on each jshort
   97.46    static void conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
   97.47      assert_params_ok(from, to, LogBytesPerShort);
   97.48 -    assert_non_zero(count);
   97.49      pd_conjoint_jshorts_atomic(from, to, count);
   97.50    }
   97.51  
   97.52    // jints,                 conjoint, atomic on each jint
   97.53    static void conjoint_jints_atomic(jint* from, jint* to, size_t count) {
   97.54      assert_params_ok(from, to, LogBytesPerInt);
   97.55 -    assert_non_zero(count);
   97.56      pd_conjoint_jints_atomic(from, to, count);
   97.57    }
   97.58  
   97.59    // jlongs,                conjoint, atomic on each jlong
   97.60    static void conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
   97.61      assert_params_ok(from, to, LogBytesPerLong);
   97.62 -    assert_non_zero(count);
   97.63      pd_conjoint_jlongs_atomic(from, to, count);
   97.64    }
   97.65  
   97.66    // oops,                  conjoint, atomic on each oop
   97.67    static void conjoint_oops_atomic(oop* from, oop* to, size_t count) {
   97.68      assert_params_ok(from, to, LogBytesPerHeapOop);
   97.69 -    assert_non_zero(count);
   97.70      pd_conjoint_oops_atomic(from, to, count);
   97.71    }
   97.72  
   97.73 @@ -157,7 +152,6 @@
   97.74    static void conjoint_oops_atomic(narrowOop* from, narrowOop* to, size_t count) {
   97.75      assert(sizeof(narrowOop) == sizeof(jint), "this cast is wrong");
   97.76      assert_params_ok(from, to, LogBytesPerInt);
   97.77 -    assert_non_zero(count);
   97.78      pd_conjoint_jints_atomic((jint*)from, (jint*)to, count);
   97.79    }
   97.80  
   97.81 @@ -168,36 +162,31 @@
   97.82    static void conjoint_memory_atomic(void* from, void* to, size_t size);
   97.83  
   97.84    // bytes,                 conjoint array, atomic on each byte (not that it matters)
   97.85 -  static void arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
   97.86 -    assert_non_zero(count);
   97.87 +  static void arrayof_conjoint_jbytes(HeapWord* from, HeapWord* to, size_t count) {
   97.88      pd_arrayof_conjoint_bytes(from, to, count);
   97.89    }
   97.90  
   97.91    // jshorts,               conjoint array, atomic on each jshort
   97.92    static void arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
   97.93      assert_params_ok(from, to, LogBytesPerShort);
   97.94 -    assert_non_zero(count);
   97.95      pd_arrayof_conjoint_jshorts(from, to, count);
   97.96    }
   97.97  
   97.98    // jints,                 conjoint array, atomic on each jint
   97.99    static void arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
  97.100      assert_params_ok(from, to, LogBytesPerInt);
  97.101 -    assert_non_zero(count);
  97.102      pd_arrayof_conjoint_jints(from, to, count);
  97.103    }
  97.104  
  97.105    // jlongs,                conjoint array, atomic on each jlong
  97.106    static void arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
  97.107      assert_params_ok(from, to, LogBytesPerLong);
  97.108 -    assert_non_zero(count);
  97.109      pd_arrayof_conjoint_jlongs(from, to, count);
  97.110    }
  97.111  
  97.112    // oops,                  conjoint array, atomic on each oop
  97.113    static void arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
  97.114      assert_params_ok(from, to, LogBytesPerHeapOop);
  97.115 -    assert_non_zero(count);
  97.116      pd_arrayof_conjoint_oops(from, to, count);
  97.117    }
  97.118  
  97.119 @@ -319,14 +308,6 @@
  97.120  #endif
  97.121    }
  97.122  
  97.123 -  static void assert_non_zero(size_t count) {
  97.124 -#ifdef ASSERT
  97.125 -    if (count == 0) {
  97.126 -      basic_fatal("count must be non-zero");
  97.127 -    }
  97.128 -#endif
  97.129 -  }
  97.130 -
  97.131    static void assert_byte_count_ok(size_t byte_count, size_t unit_size) {
  97.132  #ifdef ASSERT
  97.133      if ((size_t)round_to(byte_count, unit_size) != byte_count) {

mercurial