Merge

Fri, 09 Sep 2011 16:17:16 -0700

author
jcoomes
date
Fri, 09 Sep 2011 16:17:16 -0700
changeset 3123
79f9a3ed607a
parent 3076
dce7d24674f4
parent 3122
e984655be425
child 3124
513a84dd0f8b

Merge

.hgtags file | annotate | diff | comparison | revisions
agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64Frame.java file | annotate | diff | comparison | revisions
agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64RegisterMap.java file | annotate | diff | comparison | revisions
make/solaris/makefiles/mapfile-vers-nonproduct file | annotate | diff | comparison | revisions
src/share/vm/runtime/reflectionCompat.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Thu Sep 08 16:59:27 2011 -0700
     1.2 +++ b/.hgtags	Fri Sep 09 16:17:16 2011 -0700
     1.3 @@ -178,3 +178,7 @@
     1.4  31e253c1da429124bb87570ab095d9bc89850d0a jdk8-b02
     1.5  3a2fb61165dfc72e398179a2796d740c8da5b8c0 jdk8-b03
     1.6  0fa3ace511fe98fe948e751531f3e2b7c60c8376 jdk8-b04
     1.7 +0cc8a70952c368e06de2adab1f2649a408f5e577 hs22-b01
     1.8 +7c29742c41b44fb0cd5a13c7ac8834f3f2ca649e hs22-b02
     1.9 +3a2fb61165dfc72e398179a2796d740c8da5b8c0 hs22-b03
    1.10 +ce9bde819dcba4a5d2822229d9183e69c74326ca hs22-b04
     2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Thu Sep 08 16:59:27 2011 -0700
     2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Fri Sep 09 16:17:16 2011 -0700
     2.3 @@ -1740,7 +1740,7 @@
     2.4        else if (f.isCompiledFrame())    { tty.print("compiled"); }
     2.5        else if (f.isEntryFrame())       { tty.print("entry"); }
     2.6        else if (f.isNativeFrame())      { tty.print("native"); }
     2.7 -      else if (f.isGlueFrame())        { tty.print("glue"); }
     2.8 +      else if (f.isRuntimeFrame())     { tty.print("runtime"); }
     2.9        else { tty.print("external"); }
    2.10        tty.print(" frame with PC = " + f.getPC() + ", SP = " + f.getSP() + ", FP = " + f.getFP());
    2.11        if (f.isSignalHandlerFrameDbg()) {
     3.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java	Thu Sep 08 16:59:27 2011 -0700
     3.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java	Fri Sep 09 16:17:16 2011 -0700
     3.3 @@ -102,6 +102,11 @@
     3.4    /** On-Stack Replacement method */
     3.5    public boolean isOSRMethod()          { return false; }
     3.6  
     3.7 +  public NMethod asNMethodOrNull() {
     3.8 +    if (isNMethod()) return (NMethod)this;
     3.9 +    return null;
    3.10 +  }
    3.11 +
    3.12    // Boundaries
    3.13    public Address headerBegin() {
    3.14      return addr;
    3.15 @@ -195,7 +200,7 @@
    3.16    }
    3.17  
    3.18    // Returns true, if the next frame is responsible for GC'ing oops passed as arguments
    3.19 -  public boolean callerMustGCArguments(JavaThread thread) { return false; }
    3.20 +  public boolean callerMustGCArguments() { return false; }
    3.21  
    3.22    public String getName() {
    3.23      return CStringUtilities.getString(nameField.getValue(addr));
     4.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Thu Sep 08 16:59:27 2011 -0700
     4.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java	Fri Sep 09 16:17:16 2011 -0700
     4.3 @@ -59,6 +59,7 @@
     4.4      virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class);
     4.5      virtualConstructor.addMapping("RicochetBlob", RicochetBlob.class);
     4.6      virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
     4.7 +    virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
     4.8      virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
     4.9      virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class);
    4.10      if (VM.getVM().isServerCompiler()) {
    4.11 @@ -126,6 +127,10 @@
    4.12        Assert.that(result.blobContains(start) || result.blobContains(start.addOffsetTo(8)),
    4.13                                                                      "found wrong CodeBlob");
    4.14      }
    4.15 +    if (result.isRicochetBlob()) {
    4.16 +      // This should probably be done for other SingletonBlobs
    4.17 +      return VM.getVM().ricochetBlob();
    4.18 +    }
    4.19      return result;
    4.20    }
    4.21  
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/MethodHandlesAdapterBlob.java	Fri Sep 09 16:17:16 2011 -0700
     5.3 @@ -0,0 +1,58 @@
     5.4 +/*
     5.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.23 + * or visit www.oracle.com if you need additional information or have any
    5.24 + * questions.
    5.25 + *
    5.26 + */
    5.27 +
    5.28 +package sun.jvm.hotspot.code;
    5.29 +
    5.30 +import java.util.*;
    5.31 +import sun.jvm.hotspot.debugger.*;
    5.32 +import sun.jvm.hotspot.runtime.*;
    5.33 +import sun.jvm.hotspot.types.*;
    5.34 +
    5.35 +public class MethodHandlesAdapterBlob extends AdapterBlob {
    5.36 +  static {
    5.37 +    VM.registerVMInitializedObserver(new Observer() {
    5.38 +        public void update(Observable o, Object data) {
    5.39 +          initialize(VM.getVM().getTypeDataBase());
    5.40 +        }
    5.41 +      });
    5.42 +  }
    5.43 +
    5.44 +  private static void initialize(TypeDataBase db) {
    5.45 +    Type type = db.lookupType("MethodHandlesAdapterBlob");
    5.46 +
    5.47 +    // FIXME: add any needed fields
    5.48 +  }
    5.49 +
    5.50 +  public MethodHandlesAdapterBlob(Address addr) {
    5.51 +    super(addr);
    5.52 +  }
    5.53 +
    5.54 +  public boolean isMethodHandlesAdapterBlob() {
    5.55 +    return true;
    5.56 +  }
    5.57 +
    5.58 +  public String getName() {
    5.59 +    return "MethodHandlesAdapterBlob: " + super.getName();
    5.60 +  }
    5.61 +}
     6.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Thu Sep 08 16:59:27 2011 -0700
     6.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java	Fri Sep 09 16:17:16 2011 -0700
     6.3 @@ -46,6 +46,7 @@
     6.4    /** Offsets for different nmethod parts */
     6.5    private static CIntegerField exceptionOffsetField;
     6.6    private static CIntegerField deoptOffsetField;
     6.7 +  private static CIntegerField deoptMhOffsetField;
     6.8    private static CIntegerField origPCOffsetField;
     6.9    private static CIntegerField stubOffsetField;
    6.10    private static CIntegerField oopsOffsetField;
    6.11 @@ -95,6 +96,7 @@
    6.12  
    6.13      exceptionOffsetField        = type.getCIntegerField("_exception_offset");
    6.14      deoptOffsetField            = type.getCIntegerField("_deoptimize_offset");
    6.15 +    deoptMhOffsetField          = type.getCIntegerField("_deoptimize_mh_offset");
    6.16      origPCOffsetField           = type.getCIntegerField("_orig_pc_offset");
    6.17      stubOffsetField             = type.getCIntegerField("_stub_offset");
    6.18      oopsOffsetField             = type.getCIntegerField("_oops_offset");
    6.19 @@ -136,10 +138,11 @@
    6.20    /** Boundaries for different parts */
    6.21    public Address constantsBegin()       { return contentBegin();                                     }
    6.22    public Address constantsEnd()         { return getEntryPoint();                                    }
    6.23 -  public Address instsBegin()           { return codeBegin();                                       }
    6.24 +  public Address instsBegin()           { return codeBegin();                                        }
    6.25    public Address instsEnd()             { return headerBegin().addOffsetTo(getStubOffset());         }
    6.26    public Address exceptionBegin()       { return headerBegin().addOffsetTo(getExceptionOffset());    }
    6.27 -  public Address deoptBegin()           { return headerBegin().addOffsetTo(getDeoptOffset());        }
    6.28 +  public Address deoptHandlerBegin()    { return headerBegin().addOffsetTo(getDeoptOffset());        }
    6.29 +  public Address deoptMhHandlerBegin()  { return headerBegin().addOffsetTo(getDeoptMhOffset());      }
    6.30    public Address stubBegin()            { return headerBegin().addOffsetTo(getStubOffset());         }
    6.31    public Address stubEnd()              { return headerBegin().addOffsetTo(getOopsOffset());         }
    6.32    public Address oopsBegin()            { return headerBegin().addOffsetTo(getOopsOffset());         }
    6.33 @@ -250,6 +253,22 @@
    6.34      return (int) scavengeRootStateField.getValue(addr);
    6.35    }
    6.36  
    6.37 +  // MethodHandle
    6.38 +  public boolean isMethodHandleReturn(Address returnPc) {
    6.39 +    // Hard to read a bit fields from Java and it's only there for performance
    6.40 +    // so just go directly to the PCDesc
    6.41 +    // if (!hasMethodHandleInvokes())  return false;
    6.42 +    PCDesc pd = getPCDescAt(returnPc);
    6.43 +    if (pd == null)
    6.44 +      return false;
    6.45 +    return pd.isMethodHandleInvoke();
    6.46 +  }
    6.47 +
    6.48 +  // Deopt
    6.49 +  // Return true is the PC is one would expect if the frame is being deopted.
    6.50 +  public boolean isDeoptPc      (Address pc) { return isDeoptEntry(pc) || isDeoptMhEntry(pc); }
    6.51 +  public boolean isDeoptEntry   (Address pc) { return pc == deoptHandlerBegin(); }
    6.52 +  public boolean isDeoptMhEntry (Address pc) { return pc == deoptMhHandlerBegin(); }
    6.53  
    6.54    /** Tells whether frames described by this nmethod can be
    6.55        deoptimized. Note: native wrappers cannot be deoptimized. */
    6.56 @@ -388,6 +407,7 @@
    6.57    private int getEntryBCI()           { return (int) entryBCIField          .getValue(addr); }
    6.58    private int getExceptionOffset()    { return (int) exceptionOffsetField   .getValue(addr); }
    6.59    private int getDeoptOffset()        { return (int) deoptOffsetField       .getValue(addr); }
    6.60 +  private int getDeoptMhOffset()      { return (int) deoptMhOffsetField     .getValue(addr); }
    6.61    private int getStubOffset()         { return (int) stubOffsetField        .getValue(addr); }
    6.62    private int getOopsOffset()         { return (int) oopsOffsetField        .getValue(addr); }
    6.63    private int getScopesDataOffset()   { return (int) scopesDataOffsetField  .getValue(addr); }
     7.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java	Thu Sep 08 16:59:27 2011 -0700
     7.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/PCDesc.java	Fri Sep 09 16:17:16 2011 -0700
     7.3 @@ -38,6 +38,9 @@
     7.4    private static CIntegerField scopeDecodeOffsetField;
     7.5    private static CIntegerField objDecodeOffsetField;
     7.6    private static CIntegerField pcFlagsField;
     7.7 +  private static int reexecuteMask;
     7.8 +  private static int isMethodHandleInvokeMask;
     7.9 +  private static int returnOopMask;
    7.10  
    7.11    static {
    7.12      VM.registerVMInitializedObserver(new Observer() {
    7.13 @@ -54,6 +57,10 @@
    7.14      scopeDecodeOffsetField = type.getCIntegerField("_scope_decode_offset");
    7.15      objDecodeOffsetField   = type.getCIntegerField("_obj_decode_offset");
    7.16      pcFlagsField           = type.getCIntegerField("_flags");
    7.17 +
    7.18 +    reexecuteMask            = db.lookupIntConstant("PcDesc::PCDESC_reexecute");
    7.19 +    isMethodHandleInvokeMask = db.lookupIntConstant("PcDesc::PCDESC_is_method_handle_invoke");
    7.20 +    returnOopMask            = db.lookupIntConstant("PcDesc::PCDESC_return_oop");
    7.21    }
    7.22  
    7.23    public PCDesc(Address addr) {
    7.24 @@ -81,7 +88,12 @@
    7.25  
    7.26    public boolean getReexecute() {
    7.27      int flags = (int)pcFlagsField.getValue(addr);
    7.28 -    return ((flags & 0x1)== 1); //first is the reexecute bit
    7.29 +    return (flags & reexecuteMask) != 0;
    7.30 +  }
    7.31 +
    7.32 +  public boolean isMethodHandleInvoke() {
    7.33 +    int flags = (int)pcFlagsField.getValue(addr);
    7.34 +    return (flags & isMethodHandleInvokeMask) != 0;
    7.35    }
    7.36  
    7.37    public void print(NMethod code) {
     8.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java	Thu Sep 08 16:59:27 2011 -0700
     8.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java	Fri Sep 09 16:17:16 2011 -0700
     8.3 @@ -41,11 +41,15 @@
     8.4    }
     8.5  
     8.6    private static void initialize(TypeDataBase db) {
     8.7 -    // Type type = db.lookupType("RicochetBlob");
     8.8 +    Type type = db.lookupType("RicochetBlob");
     8.9  
    8.10 -    // FIXME: add any needed fields
    8.11 +    bounceOffsetField                = type.getCIntegerField("_bounce_offset");
    8.12 +    exceptionOffsetField             = type.getCIntegerField("_exception_offset");
    8.13    }
    8.14  
    8.15 +  private static CIntegerField bounceOffsetField;
    8.16 +  private static CIntegerField exceptionOffsetField;
    8.17 +
    8.18    public RicochetBlob(Address addr) {
    8.19      super(addr);
    8.20    }
    8.21 @@ -53,4 +57,14 @@
    8.22    public boolean isRicochetBlob() {
    8.23      return true;
    8.24    }
    8.25 +
    8.26 +  public Address bounceAddr() {
    8.27 +    return codeBegin().addOffsetTo(bounceOffsetField.getValue(addr));
    8.28 +  }
    8.29 +
    8.30 +  public boolean returnsToBounceAddr(Address pc) {
    8.31 +    Address bouncePc = bounceAddr();
    8.32 +    return (pc.equals(bouncePc) || pc.addOffsetTo(Frame.pcReturnOffset()).equals(bouncePc));
    8.33 +  }
    8.34 +
    8.35  }
     9.1 --- a/agent/src/share/classes/sun/jvm/hotspot/code/RuntimeStub.java	Thu Sep 08 16:59:27 2011 -0700
     9.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/RuntimeStub.java	Fri Sep 09 16:17:16 2011 -0700
     9.3 @@ -30,6 +30,8 @@
     9.4  import sun.jvm.hotspot.types.*;
     9.5  
     9.6  public class RuntimeStub extends CodeBlob {
     9.7 +  private static CIntegerField callerMustGCArgumentsField;
     9.8 +
     9.9    static {
    9.10      VM.registerVMInitializedObserver(new Observer() {
    9.11          public void update(Observable o, Object data) {
    9.12 @@ -40,6 +42,7 @@
    9.13  
    9.14    private static void initialize(TypeDataBase db) {
    9.15      Type type = db.lookupType("RuntimeStub");
    9.16 +    callerMustGCArgumentsField                = type.getCIntegerField("_caller_must_gc_arguments");
    9.17  
    9.18      // FIXME: add any needed fields
    9.19    }
    9.20 @@ -52,6 +55,11 @@
    9.21      return true;
    9.22    }
    9.23  
    9.24 +  public boolean callerMustGCArguments() {
    9.25 +    return callerMustGCArgumentsField.getValue(addr) != 0;
    9.26 +  }
    9.27 +
    9.28 +
    9.29    public String getName() {
    9.30      return "RuntimeStub: " + super.getName();
    9.31    }
    10.1 --- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java	Thu Sep 08 16:59:27 2011 -0700
    10.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java	Fri Sep 09 16:17:16 2011 -0700
    10.3 @@ -246,7 +246,7 @@
    10.4      }
    10.5  
    10.6      // Check if caller must update oop argument
    10.7 -    regMap.setIncludeArgumentOops(cb.callerMustGCArguments(regMap.getThread()));
    10.8 +    regMap.setIncludeArgumentOops(cb.callerMustGCArguments());
    10.9  
   10.10      int nofCallee = 0;
   10.11      Address[] locs = new Address[2 * REG_COUNT + 1];
    11.1 --- a/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Thu Sep 08 16:59:27 2011 -0700
    11.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/interpreter/BytecodeLoadConstant.java	Fri Sep 09 16:17:16 2011 -0700
    11.3 @@ -90,7 +90,7 @@
    11.4             jcode == Bytecodes._ldc2_w;
    11.5      if (! codeOk) return false;
    11.6  
    11.7 -    ConstantTag ctag = method().getConstants().getTagAt(rawIndex());
    11.8 +    ConstantTag ctag = method().getConstants().getTagAt(poolIndex());
    11.9      if (jcode == Bytecodes._ldc2_w) {
   11.10         // has to be double or long
   11.11         return (ctag.isDouble() || ctag.isLong()) ? true: false;
    12.1 --- a/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java	Thu Sep 08 16:59:27 2011 -0700
    12.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java	Fri Sep 09 16:17:16 2011 -0700
    12.3 @@ -28,11 +28,13 @@
    12.4  
    12.5  import com.sun.jdi.*;
    12.6  
    12.7 +import sun.jvm.hotspot.memory.SystemDictionary;
    12.8  import sun.jvm.hotspot.oops.Instance;
    12.9  import sun.jvm.hotspot.oops.InstanceKlass;
   12.10  import sun.jvm.hotspot.oops.ArrayKlass;
   12.11  import sun.jvm.hotspot.oops.JVMDIClassStatus;
   12.12  import sun.jvm.hotspot.oops.Klass;
   12.13 +import sun.jvm.hotspot.oops.ObjArray;
   12.14  import sun.jvm.hotspot.oops.Oop;
   12.15  import sun.jvm.hotspot.oops.Symbol;
   12.16  import sun.jvm.hotspot.oops.DefaultHeapVisitor;
   12.17 @@ -53,6 +55,7 @@
   12.18      private SoftReference methodsCache;
   12.19      private SoftReference allMethodsCache;
   12.20      private SoftReference nestedTypesCache;
   12.21 +    private SoftReference methodInvokesCache;
   12.22  
   12.23      /* to mark when no info available */
   12.24      static final SDE NO_SDE_INFO_MARK = new SDE();
   12.25 @@ -82,6 +85,27 @@
   12.26                  return method;
   12.27              }
   12.28          }
   12.29 +        if (ref.getMethodHolder().equals(SystemDictionary.getMethodHandleKlass())) {
   12.30 +          // invoke methods are generated as needed, so make mirrors as needed
   12.31 +          List mis = null;
   12.32 +          if (methodInvokesCache == null) {
   12.33 +            mis = new ArrayList();
   12.34 +            methodInvokesCache = new SoftReference(mis);
   12.35 +          } else {
   12.36 +            mis = (List)methodInvokesCache.get();
   12.37 +          }
   12.38 +          it = mis.iterator();
   12.39 +          while (it.hasNext()) {
   12.40 +            MethodImpl method = (MethodImpl)it.next();
   12.41 +            if (ref.equals(method.ref())) {
   12.42 +              return method;
   12.43 +            }
   12.44 +          }
   12.45 +
   12.46 +          MethodImpl method = MethodImpl.createMethodImpl(vm, this, ref);
   12.47 +          mis.add(method);
   12.48 +          return method;
   12.49 +        }
   12.50          throw new IllegalArgumentException("Invalid method id: " + ref);
   12.51      }
   12.52  
    13.1 --- a/agent/src/share/classes/sun/jvm/hotspot/jdi/StackFrameImpl.java	Thu Sep 08 16:59:27 2011 -0700
    13.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/StackFrameImpl.java	Fri Sep 09 16:17:16 2011 -0700
    13.3 @@ -123,6 +123,9 @@
    13.4                  Assert.that(values.size() > 0, "this is missing");
    13.5              }
    13.6              // 'this' at index 0.
    13.7 +            if (values.get(0).getType() == BasicType.getTConflict()) {
    13.8 +              return null;
    13.9 +            }
   13.10              OopHandle handle = values.oopHandleAt(0);
   13.11              ObjectHeap heap = vm.saObjectHeap();
   13.12              thisObject = vm.objectMirror(heap.newOop(handle));
   13.13 @@ -210,6 +213,8 @@
   13.14          validateStackFrame();
   13.15          StackValueCollection values = saFrame.getLocals();
   13.16          MethodImpl mmm = (MethodImpl)location.method();
   13.17 +        if (mmm.isNative())
   13.18 +            return null;
   13.19          List argSigs = mmm.argumentSignatures();
   13.20          int count = argSigs.size();
   13.21          List res = new ArrayList(0);
   13.22 @@ -231,34 +236,67 @@
   13.23          ValueImpl valueImpl = null;
   13.24          OopHandle handle = null;
   13.25          ObjectHeap heap = vm.saObjectHeap();
   13.26 -        if (variableType == BasicType.T_BOOLEAN) {
   13.27 +        if (values.get(ss).getType() == BasicType.getTConflict()) {
   13.28 +          // Dead locals, so just represent them as a zero of the appropriate type
   13.29 +          if (variableType == BasicType.T_BOOLEAN) {
   13.30 +            valueImpl = (BooleanValueImpl) vm.mirrorOf(false);
   13.31 +          } else if (variableType == BasicType.T_CHAR) {
   13.32 +            valueImpl = (CharValueImpl) vm.mirrorOf((char)0);
   13.33 +          } else if (variableType == BasicType.T_FLOAT) {
   13.34 +            valueImpl = (FloatValueImpl) vm.mirrorOf((float)0);
   13.35 +          } else if (variableType == BasicType.T_DOUBLE) {
   13.36 +            valueImpl = (DoubleValueImpl) vm.mirrorOf((double)0);
   13.37 +          } else if (variableType == BasicType.T_BYTE) {
   13.38 +            valueImpl = (ByteValueImpl) vm.mirrorOf((byte)0);
   13.39 +          } else if (variableType == BasicType.T_SHORT) {
   13.40 +            valueImpl = (ShortValueImpl) vm.mirrorOf((short)0);
   13.41 +          } else if (variableType == BasicType.T_INT) {
   13.42 +            valueImpl = (IntegerValueImpl) vm.mirrorOf((int)0);
   13.43 +          } else if (variableType == BasicType.T_LONG) {
   13.44 +            valueImpl = (LongValueImpl) vm.mirrorOf((long)0);
   13.45 +          } else if (variableType == BasicType.T_OBJECT) {
   13.46 +            // we may have an [Ljava/lang/Object; - i.e., Object[] with the
   13.47 +            // elements themselves may be arrays because every array is an Object.
   13.48 +            handle = null;
   13.49 +            valueImpl = (ObjectReferenceImpl) vm.objectMirror(heap.newOop(handle));
   13.50 +          } else if (variableType == BasicType.T_ARRAY) {
   13.51 +            handle = null;
   13.52 +            valueImpl = vm.arrayMirror((Array)heap.newOop(handle));
   13.53 +          } else if (variableType == BasicType.T_VOID) {
   13.54 +            valueImpl = new VoidValueImpl(vm);
   13.55 +          } else {
   13.56 +            throw new RuntimeException("Should not read here");
   13.57 +          }
   13.58 +        } else {
   13.59 +          if (variableType == BasicType.T_BOOLEAN) {
   13.60              valueImpl = (BooleanValueImpl) vm.mirrorOf(values.booleanAt(ss));
   13.61 -        } else if (variableType == BasicType.T_CHAR) {
   13.62 +          } else if (variableType == BasicType.T_CHAR) {
   13.63              valueImpl = (CharValueImpl) vm.mirrorOf(values.charAt(ss));
   13.64 -        } else if (variableType == BasicType.T_FLOAT) {
   13.65 +          } else if (variableType == BasicType.T_FLOAT) {
   13.66              valueImpl = (FloatValueImpl) vm.mirrorOf(values.floatAt(ss));
   13.67 -        } else if (variableType == BasicType.T_DOUBLE) {
   13.68 +          } else if (variableType == BasicType.T_DOUBLE) {
   13.69              valueImpl = (DoubleValueImpl) vm.mirrorOf(values.doubleAt(ss));
   13.70 -        } else if (variableType == BasicType.T_BYTE) {
   13.71 +          } else if (variableType == BasicType.T_BYTE) {
   13.72              valueImpl = (ByteValueImpl) vm.mirrorOf(values.byteAt(ss));
   13.73 -        } else if (variableType == BasicType.T_SHORT) {
   13.74 +          } else if (variableType == BasicType.T_SHORT) {
   13.75              valueImpl = (ShortValueImpl) vm.mirrorOf(values.shortAt(ss));
   13.76 -        } else if (variableType == BasicType.T_INT) {
   13.77 +          } else if (variableType == BasicType.T_INT) {
   13.78              valueImpl = (IntegerValueImpl) vm.mirrorOf(values.intAt(ss));
   13.79 -        } else if (variableType == BasicType.T_LONG) {
   13.80 +          } else if (variableType == BasicType.T_LONG) {
   13.81              valueImpl = (LongValueImpl) vm.mirrorOf(values.longAt(ss));
   13.82 -        } else if (variableType == BasicType.T_OBJECT) {
   13.83 +          } else if (variableType == BasicType.T_OBJECT) {
   13.84              // we may have an [Ljava/lang/Object; - i.e., Object[] with the
   13.85              // elements themselves may be arrays because every array is an Object.
   13.86              handle = values.oopHandleAt(ss);
   13.87              valueImpl = (ObjectReferenceImpl) vm.objectMirror(heap.newOop(handle));
   13.88 -        } else if (variableType == BasicType.T_ARRAY) {
   13.89 +          } else if (variableType == BasicType.T_ARRAY) {
   13.90              handle = values.oopHandleAt(ss);
   13.91              valueImpl = vm.arrayMirror((Array)heap.newOop(handle));
   13.92 -        } else if (variableType == BasicType.T_VOID) {
   13.93 +          } else if (variableType == BasicType.T_VOID) {
   13.94              valueImpl = new VoidValueImpl(vm);
   13.95 -        } else {
   13.96 +          } else {
   13.97              throw new RuntimeException("Should not read here");
   13.98 +          }
   13.99          }
  13.100  
  13.101          return valueImpl;
    14.1 --- a/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java	Thu Sep 08 16:59:27 2011 -0700
    14.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java	Fri Sep 09 16:17:16 2011 -0700
    14.3 @@ -44,6 +44,7 @@
    14.4    private static sun.jvm.hotspot.types.OopField systemKlassField;
    14.5    private static sun.jvm.hotspot.types.OopField threadKlassField;
    14.6    private static sun.jvm.hotspot.types.OopField threadGroupKlassField;
    14.7 +  private static sun.jvm.hotspot.types.OopField methodHandleKlassField;
    14.8  
    14.9    static {
   14.10      VM.registerVMInitializedObserver(new Observer() {
   14.11 @@ -69,6 +70,7 @@
   14.12      systemKlassField = type.getOopField(WK_KLASS("System_klass"));
   14.13      threadKlassField = type.getOopField(WK_KLASS("Thread_klass"));
   14.14      threadGroupKlassField = type.getOopField(WK_KLASS("ThreadGroup_klass"));
   14.15 +    methodHandleKlassField = type.getOopField(WK_KLASS("MethodHandle_klass"));
   14.16    }
   14.17  
   14.18    // This WK functions must follow the definitions in systemDictionary.hpp:
   14.19 @@ -127,6 +129,10 @@
   14.20      return (InstanceKlass) newOop(systemKlassField.getValue());
   14.21    }
   14.22  
   14.23 +  public static InstanceKlass getMethodHandleKlass() {
   14.24 +    return (InstanceKlass) newOop(methodHandleKlassField.getValue());
   14.25 +  }
   14.26 +
   14.27    public InstanceKlass getAbstractOwnableSynchronizerKlass() {
   14.28      return (InstanceKlass) find("java/util/concurrent/locks/AbstractOwnableSynchronizer",
   14.29                                  null, null);
    15.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java	Thu Sep 08 16:59:27 2011 -0700
    15.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java	Fri Sep 09 16:17:16 2011 -0700
    15.3 @@ -93,6 +93,8 @@
    15.4    }
    15.5  
    15.6    public StackValueCollection getLocals() {
    15.7 +    if (getScope() == null)
    15.8 +      return new StackValueCollection();
    15.9      List scvList = getScope().getLocals();
   15.10      if (scvList == null)
   15.11        return new StackValueCollection();
   15.12 @@ -108,6 +110,8 @@
   15.13    }
   15.14  
   15.15    public StackValueCollection getExpressions() {
   15.16 +    if (getScope() == null)
   15.17 +      return new StackValueCollection();
   15.18      List scvList = getScope().getExpressions();
   15.19      if (scvList == null)
   15.20        return new StackValueCollection();
    16.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Thu Sep 08 16:59:27 2011 -0700
    16.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Fri Sep 09 16:17:16 2011 -0700
    16.3 @@ -33,6 +33,7 @@
    16.4  import sun.jvm.hotspot.debugger.*;
    16.5  import sun.jvm.hotspot.interpreter.*;
    16.6  import sun.jvm.hotspot.oops.*;
    16.7 +import sun.jvm.hotspot.runtime.sparc.SPARCFrame;
    16.8  import sun.jvm.hotspot.types.*;
    16.9  import sun.jvm.hotspot.utilities.*;
   16.10  
   16.11 @@ -74,11 +75,19 @@
   16.12    /** Size of constMethodOopDesc for computing BCI from BCP (FIXME: hack) */
   16.13    private static long    constMethodOopDescSize;
   16.14  
   16.15 +  private static int pcReturnOffset;
   16.16 +
   16.17 +  public static int pcReturnOffset() {
   16.18 +    return pcReturnOffset;
   16.19 +  }
   16.20 +
   16.21    private static synchronized void initialize(TypeDataBase db) {
   16.22      Type constMethodOopType = db.lookupType("constMethodOopDesc");
   16.23      // FIXME: not sure whether alignment here is correct or how to
   16.24      // force it (round up to address size?)
   16.25      constMethodOopDescSize = constMethodOopType.getSize();
   16.26 +
   16.27 +    pcReturnOffset = db.lookupIntConstant("frame::pc_return_offset").intValue();
   16.28    }
   16.29  
   16.30    protected int bcpToBci(Address bcp, ConstMethod cm) {
   16.31 @@ -106,6 +115,10 @@
   16.32    public void    setPC(Address newpc) { pc = newpc; }
   16.33    public boolean isDeoptimized()      { return deoptimized; }
   16.34  
   16.35 +  public CodeBlob cb() {
   16.36 +    return VM.getVM().getCodeCache().findBlob(getPC());
   16.37 +  }
   16.38 +
   16.39    public abstract Address getSP();
   16.40    public abstract Address getID();
   16.41    public abstract Address getFP();
   16.42 @@ -134,6 +147,12 @@
   16.43      }
   16.44    }
   16.45  
   16.46 +  public boolean isRicochetFrame() {
   16.47 +    CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
   16.48 +    RicochetBlob rcb = VM.getVM().ricochetBlob();
   16.49 +    return (cb == rcb && rcb != null && rcb.returnsToBounceAddr(getPC()));
   16.50 +  }
   16.51 +
   16.52    public boolean isCompiledFrame() {
   16.53      if (Assert.ASSERTS_ENABLED) {
   16.54        Assert.that(!VM.getVM().isCore(), "noncore builds only");
   16.55 @@ -142,7 +161,7 @@
   16.56      return (cb != null && cb.isJavaMethod());
   16.57    }
   16.58  
   16.59 -  public boolean isGlueFrame() {
   16.60 +  public boolean isRuntimeFrame() {
   16.61      if (Assert.ASSERTS_ENABLED) {
   16.62        Assert.that(!VM.getVM().isCore(), "noncore builds only");
   16.63      }
   16.64 @@ -197,7 +216,8 @@
   16.65    public Frame realSender(RegisterMap map) {
   16.66      if (!VM.getVM().isCore()) {
   16.67        Frame result = sender(map);
   16.68 -      while (result.isGlueFrame()) {
   16.69 +      while (result.isRuntimeFrame() ||
   16.70 +             result.isRicochetFrame()) {
   16.71          result = result.sender(map);
   16.72        }
   16.73        return result;
   16.74 @@ -611,6 +631,9 @@
   16.75      if (Assert.ASSERTS_ENABLED) {
   16.76        Assert.that(cb != null, "sanity check");
   16.77      }
   16.78 +    if (cb == VM.getVM().ricochetBlob()) {
   16.79 +      oopsRicochetDo(oopVisitor, regMap);
   16.80 +    }
   16.81      if (cb.getOopMaps() != null) {
   16.82        OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
   16.83  
   16.84 @@ -627,6 +650,10 @@
   16.85      //    }
   16.86    }
   16.87  
   16.88 +  private void oopsRicochetDo      (AddressVisitor oopVisitor, RegisterMap regMap) {
   16.89 +    // XXX Empty for now
   16.90 +  }
   16.91 +
   16.92    // FIXME: implement the above routines, plus add
   16.93    // oops_interpreted_arguments_do and oops_compiled_arguments_do
   16.94  }
    17.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java	Thu Sep 08 16:59:27 2011 -0700
    17.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaVFrame.java	Fri Sep 09 16:17:16 2011 -0700
    17.3 @@ -128,14 +128,14 @@
    17.4        }
    17.5  
    17.6        // dynamic part - we just compare the frame pointer
    17.7 -      if (! getFrame().getFP().equals(other.getFrame().getFP())) {
    17.8 +      if (! getFrame().equals(other.getFrame())) {
    17.9            return false;
   17.10        }
   17.11        return true;
   17.12    }
   17.13  
   17.14    public int hashCode() {
   17.15 -      return getMethod().hashCode() ^ getBCI() ^ getFrame().getFP().hashCode();
   17.16 +      return getMethod().hashCode() ^ getBCI() ^ getFrame().hashCode();
   17.17    }
   17.18  
   17.19    /** Structural compare */
    18.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java	Thu Sep 08 16:59:27 2011 -0700
    18.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/StackValue.java	Fri Sep 09 16:17:16 2011 -0700
    18.3 @@ -100,7 +100,7 @@
    18.4  
    18.5    public int hashCode() {
    18.6      if (type == BasicType.getTObject()) {
    18.7 -      return handleValue.hashCode();
    18.8 +      return handleValue != null ? handleValue.hashCode() : 5;
    18.9      } else {
   18.10        // Returns 0 for conflict type
   18.11        return (int) integerValue;
    19.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java	Thu Sep 08 16:59:27 2011 -0700
    19.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VFrame.java	Fri Sep 09 16:17:16 2011 -0700
    19.3 @@ -77,7 +77,7 @@
    19.4            return new CompiledVFrame(f, regMap, thread, scope, mayBeImprecise);
    19.5          }
    19.6  
    19.7 -        if (f.isGlueFrame()) {
    19.8 +        if (f.isRuntimeFrame()) {
    19.9            // This is a conversion frame. Skip this frame and try again.
   19.10            RegisterMap tempMap = regMap.copy();
   19.11            Frame s = f.sender(tempMap);
    20.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Sep 08 16:59:27 2011 -0700
    20.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java	Fri Sep 09 16:17:16 2011 -0700
    20.3 @@ -30,6 +30,7 @@
    20.4  import java.util.regex.*;
    20.5  import sun.jvm.hotspot.code.*;
    20.6  import sun.jvm.hotspot.c1.*;
    20.7 +import sun.jvm.hotspot.code.*;
    20.8  import sun.jvm.hotspot.debugger.*;
    20.9  import sun.jvm.hotspot.interpreter.*;
   20.10  import sun.jvm.hotspot.memory.*;
   20.11 @@ -85,6 +86,9 @@
   20.12    private Interpreter  interpreter;
   20.13    private StubRoutines stubRoutines;
   20.14    private Bytes        bytes;
   20.15 +
   20.16 +  private RicochetBlob ricochetBlob;
   20.17 +
   20.18    /** Flags indicating whether we are attached to a core, C1, or C2 build */
   20.19    private boolean      usingClientCompiler;
   20.20    private boolean      usingServerCompiler;
   20.21 @@ -618,6 +622,18 @@
   20.22      return stubRoutines;
   20.23    }
   20.24  
   20.25 +  public RicochetBlob ricochetBlob() {
   20.26 +    if (ricochetBlob == null) {
   20.27 +      Type ricochetType  = db.lookupType("SharedRuntime");
   20.28 +      AddressField ricochetBlobAddress = ricochetType.getAddressField("_ricochet_blob");
   20.29 +      Address addr = ricochetBlobAddress.getValue();
   20.30 +      if (addr != null) {
   20.31 +        ricochetBlob = new RicochetBlob(addr);
   20.32 +      }
   20.33 +    }
   20.34 +    return ricochetBlob;
   20.35 +  }
   20.36 +
   20.37    public VMRegImpl getVMRegImplInfo() {
   20.38      if (vmregImpl == null) {
   20.39        vmregImpl = new VMRegImpl();
    21.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64CurrentFrameGuess.java	Thu Sep 08 16:59:27 2011 -0700
    21.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64CurrentFrameGuess.java	Fri Sep 09 16:17:16 2011 -0700
    21.3 @@ -29,6 +29,7 @@
    21.4  import sun.jvm.hotspot.code.*;
    21.5  import sun.jvm.hotspot.interpreter.*;
    21.6  import sun.jvm.hotspot.runtime.*;
    21.7 +import sun.jvm.hotspot.runtime.x86.*;
    21.8  
    21.9  /** <P> Should be able to be used on all amd64 platforms we support
   21.10      (Linux/amd64) to implement JavaThread's
   21.11 @@ -123,7 +124,7 @@
   21.12               offset += vm.getAddressSize()) {
   21.13            try {
   21.14              Address curSP = sp.addOffsetTo(offset);
   21.15 -            Frame frame = new AMD64Frame(curSP, null, pc);
   21.16 +            Frame frame = new X86Frame(curSP, null, pc);
   21.17              RegisterMap map = thread.newRegisterMap(false);
   21.18              while (frame != null) {
   21.19                if (frame.isEntryFrame() && frame.entryFrameIsFirst()) {
    22.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64Frame.java	Thu Sep 08 16:59:27 2011 -0700
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,528 +0,0 @@
    22.4 -/*
    22.5 - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
    22.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    22.7 - *
    22.8 - * This code is free software; you can redistribute it and/or modify it
    22.9 - * under the terms of the GNU General Public License version 2 only, as
   22.10 - * published by the Free Software Foundation.
   22.11 - *
   22.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   22.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   22.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   22.15 - * version 2 for more details (a copy is included in the LICENSE file that
   22.16 - * accompanied this code).
   22.17 - *
   22.18 - * You should have received a copy of the GNU General Public License version
   22.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   22.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   22.21 - *
   22.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22.23 - * or visit www.oracle.com if you need additional information or have any
   22.24 - * questions.
   22.25 - *
   22.26 - */
   22.27 -
   22.28 -package sun.jvm.hotspot.runtime.amd64;
   22.29 -
   22.30 -import java.util.*;
   22.31 -import sun.jvm.hotspot.code.*;
   22.32 -import sun.jvm.hotspot.compiler.*;
   22.33 -import sun.jvm.hotspot.debugger.*;
   22.34 -import sun.jvm.hotspot.oops.*;
   22.35 -import sun.jvm.hotspot.runtime.*;
   22.36 -import sun.jvm.hotspot.types.*;
   22.37 -import sun.jvm.hotspot.utilities.*;
   22.38 -
   22.39 -/** Specialization of and implementation of abstract methods of the
   22.40 -    Frame class for the amd64 CPU. */
   22.41 -
   22.42 -public class AMD64Frame extends Frame {
   22.43 -  private static final boolean DEBUG;
   22.44 -  static {
   22.45 -    DEBUG = System.getProperty("sun.jvm.hotspot.runtime.amd64.AMD64Frame.DEBUG") != null;
   22.46 -  }
   22.47 -
   22.48 -  // refer to frame_amd64.hpp
   22.49 -  private static final int PC_RETURN_OFFSET           =  0;
   22.50 -  // All frames
   22.51 -  private static final int LINK_OFFSET                =  0;
   22.52 -  private static final int RETURN_ADDR_OFFSET         =  1;
   22.53 -  private static final int SENDER_SP_OFFSET           =  2;
   22.54 -
   22.55 -  // Interpreter frames
   22.56 -  private static final int INTERPRETER_FRAME_MIRROR_OFFSET    =  2; // for native calls only
   22.57 -  private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1;
   22.58 -  private static final int INTERPRETER_FRAME_LAST_SP_OFFSET   = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
   22.59 -  private static final int INTERPRETER_FRAME_METHOD_OFFSET    = INTERPRETER_FRAME_LAST_SP_OFFSET - 1;
   22.60 -  private static       int INTERPRETER_FRAME_MDX_OFFSET;         // Non-core builds only
   22.61 -  private static       int INTERPRETER_FRAME_CACHE_OFFSET;
   22.62 -  private static       int INTERPRETER_FRAME_LOCALS_OFFSET;
   22.63 -  private static       int INTERPRETER_FRAME_BCX_OFFSET;
   22.64 -  private static       int INTERPRETER_FRAME_INITIAL_SP_OFFSET;
   22.65 -  private static       int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET;
   22.66 -  private static       int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET;
   22.67 -
   22.68 -  // Entry frames
   22.69 -  private static final int ENTRY_FRAME_CALL_WRAPPER_OFFSET   =  -6;
   22.70 -
   22.71 -  // Native frames
   22.72 -  private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET =  2;
   22.73 -
   22.74 -  static {
   22.75 -    VM.registerVMInitializedObserver(new Observer() {
   22.76 -        public void update(Observable o, Object data) {
   22.77 -          initialize(VM.getVM().getTypeDataBase());
   22.78 -        }
   22.79 -      });
   22.80 -  }
   22.81 -
   22.82 -  private static synchronized void initialize(TypeDataBase db) {
   22.83 -    if (VM.getVM().isCore()) {
   22.84 -      INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
   22.85 -    } else {
   22.86 -      INTERPRETER_FRAME_MDX_OFFSET   = INTERPRETER_FRAME_METHOD_OFFSET - 1;
   22.87 -      INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
   22.88 -    }
   22.89 -    INTERPRETER_FRAME_LOCALS_OFFSET               = INTERPRETER_FRAME_CACHE_OFFSET - 1;
   22.90 -    INTERPRETER_FRAME_BCX_OFFSET                  = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
   22.91 -    INTERPRETER_FRAME_INITIAL_SP_OFFSET           = INTERPRETER_FRAME_BCX_OFFSET - 1;
   22.92 -    INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET    = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
   22.93 -    INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
   22.94 -  }
   22.95 -
   22.96 -  // an additional field beyond sp and pc:
   22.97 -  Address raw_fp; // frame pointer
   22.98 -  private Address raw_unextendedSP;
   22.99 -
  22.100 -  private AMD64Frame() {
  22.101 -  }
  22.102 -
  22.103 -  private void adjustForDeopt() {
  22.104 -    if ( pc != null) {
  22.105 -      // Look for a deopt pc and if it is deopted convert to original pc
  22.106 -      CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
  22.107 -      if (cb != null && cb.isJavaMethod()) {
  22.108 -        NMethod nm = (NMethod) cb;
  22.109 -        if (pc.equals(nm.deoptBegin())) {
  22.110 -          // adjust pc if frame is deoptimized.
  22.111 -          if (Assert.ASSERTS_ENABLED) {
  22.112 -            Assert.that(this.getUnextendedSP() != null, "null SP in Java frame");
  22.113 -          }
  22.114 -          pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset());
  22.115 -          deoptimized = true;
  22.116 -        }
  22.117 -      }
  22.118 -    }
  22.119 -  }
  22.120 -
  22.121 -  public AMD64Frame(Address raw_sp, Address raw_fp, Address pc) {
  22.122 -    this.raw_sp = raw_sp;
  22.123 -    this.raw_unextendedSP = raw_sp;
  22.124 -    this.raw_fp = raw_fp;
  22.125 -    this.pc = pc;
  22.126 -
  22.127 -    // Frame must be fully constructed before this call
  22.128 -    adjustForDeopt();
  22.129 -
  22.130 -    if (DEBUG) {
  22.131 -      System.out.println("AMD64Frame(sp, fp, pc): " + this);
  22.132 -      dumpStack();
  22.133 -    }
  22.134 -  }
  22.135 -
  22.136 -  public AMD64Frame(Address raw_sp, Address raw_fp) {
  22.137 -    this.raw_sp = raw_sp;
  22.138 -    this.raw_unextendedSP = raw_sp;
  22.139 -    this.raw_fp = raw_fp;
  22.140 -    this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
  22.141 -
  22.142 -    // Frame must be fully constructed before this call
  22.143 -    adjustForDeopt();
  22.144 -
  22.145 -    if (DEBUG) {
  22.146 -      System.out.println("AMD64Frame(sp, fp): " + this);
  22.147 -      dumpStack();
  22.148 -    }
  22.149 -  }
  22.150 -
  22.151 -  // This constructor should really take the unextended SP as an arg
  22.152 -  // but then the constructor is ambiguous with constructor that takes
  22.153 -  // a PC so take an int and convert it.
  22.154 -  public AMD64Frame(Address raw_sp, Address raw_fp, long extension) {
  22.155 -    this.raw_sp = raw_sp;
  22.156 -    if ( raw_sp == null) {
  22.157 -      this.raw_unextendedSP = null;
  22.158 -    } else {
  22.159 -      this.raw_unextendedSP = raw_sp.addOffsetTo(extension);
  22.160 -    }
  22.161 -    this.raw_fp = raw_fp;
  22.162 -    this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
  22.163 -
  22.164 -    // Frame must be fully constructed before this call
  22.165 -    adjustForDeopt();
  22.166 -
  22.167 -    if (DEBUG) {
  22.168 -      System.out.println("AMD64Frame(sp, fp, extension): " + this);
  22.169 -      dumpStack();
  22.170 -    }
  22.171 -
  22.172 -  }
  22.173 -
  22.174 -  public Object clone() {
  22.175 -    AMD64Frame frame = new AMD64Frame();
  22.176 -    frame.raw_sp = raw_sp;
  22.177 -    frame.raw_unextendedSP = raw_unextendedSP;
  22.178 -    frame.raw_fp = raw_fp;
  22.179 -    frame.pc = pc;
  22.180 -    frame.deoptimized = deoptimized;
  22.181 -    return frame;
  22.182 -  }
  22.183 -
  22.184 -  public boolean equals(Object arg) {
  22.185 -    if (arg == null) {
  22.186 -      return false;
  22.187 -    }
  22.188 -
  22.189 -    if (!(arg instanceof AMD64Frame)) {
  22.190 -      return false;
  22.191 -    }
  22.192 -
  22.193 -    AMD64Frame other = (AMD64Frame) arg;
  22.194 -
  22.195 -    return (AddressOps.equal(getSP(), other.getSP()) &&
  22.196 -            AddressOps.equal(getFP(), other.getFP()) &&
  22.197 -            AddressOps.equal(getUnextendedSP(), other.getUnextendedSP()) &&
  22.198 -            AddressOps.equal(getPC(), other.getPC()));
  22.199 -  }
  22.200 -
  22.201 -  public int hashCode() {
  22.202 -    if (raw_sp == null) {
  22.203 -      return 0;
  22.204 -    }
  22.205 -
  22.206 -    return raw_sp.hashCode();
  22.207 -  }
  22.208 -
  22.209 -  public String toString() {
  22.210 -    return "sp: " + (getSP() == null? "null" : getSP().toString()) +
  22.211 -         ", unextendedSP: " + (getUnextendedSP() == null? "null" : getUnextendedSP().toString()) +
  22.212 -         ", fp: " + (getFP() == null? "null" : getFP().toString()) +
  22.213 -         ", pc: " + (pc == null? "null" : pc.toString());
  22.214 -  }
  22.215 -
  22.216 -  // accessors for the instance variables
  22.217 -  public Address getFP() { return raw_fp; }
  22.218 -  public Address getSP() { return raw_sp; }
  22.219 -  public Address getID() { return raw_sp; }
  22.220 -
  22.221 -  // FIXME: not implemented yet (should be done for Solaris/AMD64)
  22.222 -  public boolean isSignalHandlerFrameDbg() { return false; }
  22.223 -  public int     getSignalNumberDbg()      { return 0;     }
  22.224 -  public String  getSignalNameDbg()        { return null;  }
  22.225 -
  22.226 -  public boolean isInterpretedFrameValid() {
  22.227 -    if (Assert.ASSERTS_ENABLED) {
  22.228 -      Assert.that(isInterpretedFrame(), "Not an interpreted frame");
  22.229 -    }
  22.230 -
  22.231 -    // These are reasonable sanity checks
  22.232 -    if (getFP() == null || getFP().andWithMask(0x3) != null) {
  22.233 -      return false;
  22.234 -    }
  22.235 -
  22.236 -    if (getSP() == null || getSP().andWithMask(0x3) != null) {
  22.237 -      return false;
  22.238 -    }
  22.239 -
  22.240 -    if (getFP().addOffsetTo(INTERPRETER_FRAME_INITIAL_SP_OFFSET * VM.getVM().getAddressSize()).lessThan(getSP())) {
  22.241 -      return false;
  22.242 -    }
  22.243 -
  22.244 -    // These are hacks to keep us out of trouble.
  22.245 -    // The problem with these is that they mask other problems
  22.246 -    if (getFP().lessThanOrEqual(getSP())) {
  22.247 -      // this attempts to deal with unsigned comparison above
  22.248 -      return false;
  22.249 -    }
  22.250 -
  22.251 -    if (getFP().minus(getSP()) > 4096 * VM.getVM().getAddressSize()) {
  22.252 -      // stack frames shouldn't be large.
  22.253 -      return false;
  22.254 -    }
  22.255 -
  22.256 -    return true;
  22.257 -  }
  22.258 -
  22.259 -  // FIXME: not applicable in current system
  22.260 -  //  void    patch_pc(Thread* thread, address pc);
  22.261 -
  22.262 -  public Frame sender(RegisterMap regMap, CodeBlob cb) {
  22.263 -    AMD64RegisterMap map = (AMD64RegisterMap) regMap;
  22.264 -
  22.265 -    if (Assert.ASSERTS_ENABLED) {
  22.266 -      Assert.that(map != null, "map must be set");
  22.267 -    }
  22.268 -
  22.269 -    // Default is we done have to follow them. The sender_for_xxx will
  22.270 -    // update it accordingly
  22.271 -    map.setIncludeArgumentOops(false);
  22.272 -
  22.273 -    if (isEntryFrame())       return senderForEntryFrame(map);
  22.274 -    if (isInterpretedFrame()) return senderForInterpreterFrame(map);
  22.275 -
  22.276 -
  22.277 -    if (!VM.getVM().isCore()) {
  22.278 -      if(cb == null) {
  22.279 -        cb = VM.getVM().getCodeCache().findBlob(getPC());
  22.280 -      } else {
  22.281 -        if (Assert.ASSERTS_ENABLED) {
  22.282 -          Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
  22.283 -        }
  22.284 -      }
  22.285 -
  22.286 -      if (cb != null) {
  22.287 -         return senderForCompiledFrame(map, cb);
  22.288 -      }
  22.289 -    }
  22.290 -
  22.291 -    // Must be native-compiled frame, i.e. the marshaling code for native
  22.292 -    // methods that exists in the core system.
  22.293 -    return new AMD64Frame(getSenderSP(), getLink(), getSenderPC());
  22.294 -  }
  22.295 -
  22.296 -  private Frame senderForEntryFrame(AMD64RegisterMap map) {
  22.297 -    if (Assert.ASSERTS_ENABLED) {
  22.298 -      Assert.that(map != null, "map must be set");
  22.299 -    }
  22.300 -    // Java frame called from C; skip all C frames and return top C
  22.301 -    // frame of that chunk as the sender
  22.302 -    AMD64JavaCallWrapper jcw = (AMD64JavaCallWrapper) getEntryFrameCallWrapper();
  22.303 -    if (Assert.ASSERTS_ENABLED) {
  22.304 -      Assert.that(!entryFrameIsFirst(), "next Java fp must be non zero");
  22.305 -      Assert.that(jcw.getLastJavaSP().greaterThan(getSP()), "must be above this frame on stack");
  22.306 -    }
  22.307 -    AMD64Frame fr;
  22.308 -    if (jcw.getLastJavaPC() != null) {
  22.309 -      fr = new AMD64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP(), jcw.getLastJavaPC());
  22.310 -    } else {
  22.311 -      fr = new AMD64Frame(jcw.getLastJavaSP(), jcw.getLastJavaFP());
  22.312 -    }
  22.313 -    map.clear();
  22.314 -    if (Assert.ASSERTS_ENABLED) {
  22.315 -      Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
  22.316 -    }
  22.317 -    return fr;
  22.318 -  }
  22.319 -
  22.320 -  private Frame senderForInterpreterFrame(AMD64RegisterMap map) {
  22.321 -    Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
  22.322 -    Address sp = addressOfStackSlot(SENDER_SP_OFFSET);
  22.323 -    // We do not need to update the callee-save register mapping because above
  22.324 -    // us is either another interpreter frame or a converter-frame, but never
  22.325 -    // directly a compiled frame.
  22.326 -    // 11/24/04 SFG. This is no longer true after adapter were removed. However at the moment
  22.327 -    // C2 no longer uses callee save register for java calls so there are no callee register
  22.328 -    // to find.
  22.329 -    return new AMD64Frame(sp, getLink(), unextendedSP.minus(sp));
  22.330 -  }
  22.331 -
  22.332 -  private Frame senderForCompiledFrame(AMD64RegisterMap map, CodeBlob cb) {
  22.333 -    //
  22.334 -    // NOTE: some of this code is (unfortunately) duplicated in AMD64CurrentFrameGuess
  22.335 -    //
  22.336 -
  22.337 -    if (Assert.ASSERTS_ENABLED) {
  22.338 -      Assert.that(map != null, "map must be set");
  22.339 -    }
  22.340 -
  22.341 -    // frame owned by optimizing compiler
  22.342 -    Address        sender_sp = null;
  22.343 -
  22.344 -
  22.345 -    if (VM.getVM().isClientCompiler()) {
  22.346 -      sender_sp        = addressOfStackSlot(SENDER_SP_OFFSET);
  22.347 -    } else {
  22.348 -      if (Assert.ASSERTS_ENABLED) {
  22.349 -        Assert.that(cb.getFrameSize() >= 0, "Compiled by Compiler1: do not use");
  22.350 -      }
  22.351 -      sender_sp = getUnextendedSP().addOffsetTo(cb.getFrameSize());
  22.352 -    }
  22.353 -
  22.354 -    // On Intel the return_address is always the word on the stack
  22.355 -    Address sender_pc = sender_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
  22.356 -
  22.357 -    if (map.getUpdateMap() && cb.getOopMaps() != null) {
  22.358 -      OopMapSet.updateRegisterMap(this, cb, map, true);
  22.359 -    }
  22.360 -
  22.361 -    if (VM.getVM().isClientCompiler()) {
  22.362 -      // Move this here for C1 and collecting oops in arguments (According to Rene)
  22.363 -      map.setIncludeArgumentOops(cb.callerMustGCArguments(map.getThread()));
  22.364 -    }
  22.365 -
  22.366 -    Address saved_fp = null;
  22.367 -    if (VM.getVM().isClientCompiler()) {
  22.368 -      saved_fp = getFP().getAddressAt(0);
  22.369 -    } else if (VM.getVM().isServerCompiler() &&
  22.370 -               (VM.getVM().getInterpreter().contains(sender_pc) ||
  22.371 -               VM.getVM().getStubRoutines().returnsToCallStub(sender_pc))) {
  22.372 -      // C2 prologue saves EBP in the usual place.
  22.373 -      // however only use it if the sender had link infomration in it.
  22.374 -      saved_fp = sender_sp.getAddressAt(-2 * VM.getVM().getAddressSize());
  22.375 -    }
  22.376 -
  22.377 -    return new AMD64Frame(sender_sp, saved_fp, sender_pc);
  22.378 -  }
  22.379 -
  22.380 -  protected boolean hasSenderPD() {
  22.381 -    // FIXME
  22.382 -    // Check for null ebp? Need to do some tests.
  22.383 -    return true;
  22.384 -  }
  22.385 -
  22.386 -  public long frameSize() {
  22.387 -    return (getSenderSP().minus(getSP()) / VM.getVM().getAddressSize());
  22.388 -  }
  22.389 -
  22.390 -  public Address getLink() {
  22.391 -    return addressOfStackSlot(LINK_OFFSET).getAddressAt(0);
  22.392 -  }
  22.393 -
  22.394 -  // FIXME: not implementable yet
  22.395 -  //inline void      frame::set_link(intptr_t* addr)  { *(intptr_t **)addr_at(link_offset) = addr; }
  22.396 -
  22.397 -  public Address getUnextendedSP() { return raw_unextendedSP; }
  22.398 -
  22.399 -  // Return address:
  22.400 -  public Address getSenderPCAddr() { return addressOfStackSlot(RETURN_ADDR_OFFSET); }
  22.401 -  public Address getSenderPC()     { return getSenderPCAddr().getAddressAt(0);      }
  22.402 -
  22.403 -  // return address of param, zero origin index.
  22.404 -  public Address getNativeParamAddr(int idx) {
  22.405 -    return addressOfStackSlot(NATIVE_FRAME_INITIAL_PARAM_OFFSET + idx);
  22.406 -  }
  22.407 -
  22.408 -  public Address getSenderSP()     { return addressOfStackSlot(SENDER_SP_OFFSET); }
  22.409 -
  22.410 -  public Address compiledArgumentToLocationPD(VMReg reg, RegisterMap regMap, int argSize) {
  22.411 -    if (VM.getVM().isCore() || VM.getVM().isClientCompiler()) {
  22.412 -      throw new RuntimeException("Should not reach here");
  22.413 -    }
  22.414 -
  22.415 -    return oopMapRegToLocation(reg, regMap);
  22.416 -  }
  22.417 -
  22.418 -  public Address addressOfInterpreterFrameLocals() {
  22.419 -    return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET);
  22.420 -  }
  22.421 -
  22.422 -  private Address addressOfInterpreterFrameBCX() {
  22.423 -    return addressOfStackSlot(INTERPRETER_FRAME_BCX_OFFSET);
  22.424 -  }
  22.425 -
  22.426 -  public int getInterpreterFrameBCI() {
  22.427 -    // FIXME: this is not atomic with respect to GC and is unsuitable
  22.428 -    // for use in a non-debugging, or reflective, system. Need to
  22.429 -    // figure out how to express this.
  22.430 -    Address bcp = addressOfInterpreterFrameBCX().getAddressAt(0);
  22.431 -    OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0);
  22.432 -    Method method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle);
  22.433 -    return (int) bcpToBci(bcp, method);
  22.434 -  }
  22.435 -
  22.436 -  public Address addressOfInterpreterFrameMDX() {
  22.437 -    return addressOfStackSlot(INTERPRETER_FRAME_MDX_OFFSET);
  22.438 -  }
  22.439 -
  22.440 -  // FIXME
  22.441 -  //inline int frame::interpreter_frame_monitor_size() {
  22.442 -  //  return BasicObjectLock::size();
  22.443 -  //}
  22.444 -
  22.445 -  // expression stack
  22.446 -  // (the max_stack arguments are used by the GC; see class FrameClosure)
  22.447 -
  22.448 -  public Address addressOfInterpreterFrameExpressionStack() {
  22.449 -    Address monitorEnd = interpreterFrameMonitorEnd().address();
  22.450 -    return monitorEnd.addOffsetTo(-1 * VM.getVM().getAddressSize());
  22.451 -  }
  22.452 -
  22.453 -  public int getInterpreterFrameExpressionStackDirection() { return -1; }
  22.454 -
  22.455 -  // top of expression stack
  22.456 -  public Address addressOfInterpreterFrameTOS() {
  22.457 -    return getSP();
  22.458 -  }
  22.459 -
  22.460 -  /** Expression stack from top down */
  22.461 -  public Address addressOfInterpreterFrameTOSAt(int slot) {
  22.462 -    return addressOfInterpreterFrameTOS().addOffsetTo(slot * VM.getVM().getAddressSize());
  22.463 -  }
  22.464 -
  22.465 -  public Address getInterpreterFrameSenderSP() {
  22.466 -    if (Assert.ASSERTS_ENABLED) {
  22.467 -      Assert.that(isInterpretedFrame(), "interpreted frame expected");
  22.468 -    }
  22.469 -    return addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
  22.470 -  }
  22.471 -
  22.472 -  // Monitors
  22.473 -  public BasicObjectLock interpreterFrameMonitorBegin() {
  22.474 -    return new BasicObjectLock(addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET));
  22.475 -  }
  22.476 -
  22.477 -  public BasicObjectLock interpreterFrameMonitorEnd() {
  22.478 -    Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0);
  22.479 -    if (Assert.ASSERTS_ENABLED) {
  22.480 -      // make sure the pointer points inside the frame
  22.481 -      Assert.that(AddressOps.gt(getFP(), result), "result must <  than frame pointer");
  22.482 -      Assert.that(AddressOps.lte(getSP(), result), "result must >= than stack pointer");
  22.483 -    }
  22.484 -    return new BasicObjectLock(result);
  22.485 -  }
  22.486 -
  22.487 -  public int interpreterFrameMonitorSize() {
  22.488 -    return BasicObjectLock.size();
  22.489 -  }
  22.490 -
  22.491 -  // Method
  22.492 -  public Address addressOfInterpreterFrameMethod() {
  22.493 -    return addressOfStackSlot(INTERPRETER_FRAME_METHOD_OFFSET);
  22.494 -  }
  22.495 -
  22.496 -  // Constant pool cache
  22.497 -  public Address addressOfInterpreterFrameCPCache() {
  22.498 -    return addressOfStackSlot(INTERPRETER_FRAME_CACHE_OFFSET);
  22.499 -  }
  22.500 -
  22.501 -  // Entry frames
  22.502 -  public JavaCallWrapper getEntryFrameCallWrapper() {
  22.503 -    return new AMD64JavaCallWrapper(addressOfStackSlot(ENTRY_FRAME_CALL_WRAPPER_OFFSET).getAddressAt(0));
  22.504 -  }
  22.505 -
  22.506 -  protected Address addressOfSavedOopResult() {
  22.507 -    // offset is 2 for compiler2 and 3 for compiler1
  22.508 -    return getSP().addOffsetTo((VM.getVM().isClientCompiler() ? 2 : 3) *
  22.509 -                               VM.getVM().getAddressSize());
  22.510 -  }
  22.511 -
  22.512 -  protected Address addressOfSavedReceiver() {
  22.513 -    return getSP().addOffsetTo(-4 * VM.getVM().getAddressSize());
  22.514 -  }
  22.515 -
  22.516 -  private void dumpStack() {
  22.517 -    if (getFP() != null) {
  22.518 -      for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
  22.519 -           AddressOps.lte(addr, getFP().addOffsetTo(5 * VM.getVM().getAddressSize()));
  22.520 -           addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
  22.521 -        System.out.println(addr + ": " + addr.getAddressAt(0));
  22.522 -      }
  22.523 -    } else {
  22.524 -      for (Address addr = getSP().addOffsetTo(-5 * VM.getVM().getAddressSize());
  22.525 -           AddressOps.lte(addr, getSP().addOffsetTo(20 * VM.getVM().getAddressSize()));
  22.526 -           addr = addr.addOffsetTo(VM.getVM().getAddressSize())) {
  22.527 -        System.out.println(addr + ": " + addr.getAddressAt(0));
  22.528 -      }
  22.529 -    }
  22.530 -  }
  22.531 -}
    23.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/amd64/AMD64RegisterMap.java	Thu Sep 08 16:59:27 2011 -0700
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,52 +0,0 @@
    23.4 -/*
    23.5 - * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
    23.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    23.7 - *
    23.8 - * This code is free software; you can redistribute it and/or modify it
    23.9 - * under the terms of the GNU General Public License version 2 only, as
   23.10 - * published by the Free Software Foundation.
   23.11 - *
   23.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   23.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   23.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   23.15 - * version 2 for more details (a copy is included in the LICENSE file that
   23.16 - * accompanied this code).
   23.17 - *
   23.18 - * You should have received a copy of the GNU General Public License version
   23.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   23.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   23.21 - *
   23.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   23.23 - * or visit www.oracle.com if you need additional information or have any
   23.24 - * questions.
   23.25 - *
   23.26 - */
   23.27 -
   23.28 -package sun.jvm.hotspot.runtime.amd64;
   23.29 -
   23.30 -import sun.jvm.hotspot.asm.amd64.*;
   23.31 -import sun.jvm.hotspot.debugger.*;
   23.32 -import sun.jvm.hotspot.runtime.*;
   23.33 -
   23.34 -public class AMD64RegisterMap extends RegisterMap {
   23.35 -
   23.36 -  /** This is the only public constructor */
   23.37 -  public AMD64RegisterMap(JavaThread thread, boolean updateMap) {
   23.38 -    super(thread, updateMap);
   23.39 -  }
   23.40 -
   23.41 -  protected AMD64RegisterMap(RegisterMap map) {
   23.42 -    super(map);
   23.43 -  }
   23.44 -
   23.45 -  public Object clone() {
   23.46 -    AMD64RegisterMap retval = new AMD64RegisterMap(this);
   23.47 -    return retval;
   23.48 -  }
   23.49 -
   23.50 -  // no PD state to clear or copy:
   23.51 -  protected void clearPD() {}
   23.52 -  protected void initializePD() {}
   23.53 -  protected void initializeFromPD(RegisterMap map) {}
   23.54 -  protected Address getLocationPD(VMReg reg) { return null; }
   23.55 -}
    24.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_amd64/LinuxAMD64JavaThreadPDAccess.java	Thu Sep 08 16:59:27 2011 -0700
    24.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_amd64/LinuxAMD64JavaThreadPDAccess.java	Fri Sep 09 16:17:16 2011 -0700
    24.3 @@ -30,6 +30,7 @@
    24.4  import sun.jvm.hotspot.debugger.amd64.*;
    24.5  import sun.jvm.hotspot.runtime.*;
    24.6  import sun.jvm.hotspot.runtime.amd64.*;
    24.7 +import sun.jvm.hotspot.runtime.x86.*;
    24.8  import sun.jvm.hotspot.types.*;
    24.9  import sun.jvm.hotspot.utilities.*;
   24.10  
   24.11 @@ -80,11 +81,11 @@
   24.12      if (fp == null) {
   24.13        return null; // no information
   24.14      }
   24.15 -    return new AMD64Frame(thread.getLastJavaSP(), fp);
   24.16 +    return new X86Frame(thread.getLastJavaSP(), fp);
   24.17    }
   24.18  
   24.19    public    RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
   24.20 -    return new AMD64RegisterMap(thread, updateMap);
   24.21 +    return new X86RegisterMap(thread, updateMap);
   24.22    }
   24.23  
   24.24    public    Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
   24.25 @@ -95,9 +96,9 @@
   24.26        return null;
   24.27      }
   24.28      if (guesser.getPC() == null) {
   24.29 -      return new AMD64Frame(guesser.getSP(), guesser.getFP());
   24.30 +      return new X86Frame(guesser.getSP(), guesser.getFP());
   24.31      } else {
   24.32 -      return new AMD64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
   24.33 +      return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
   24.34      }
   24.35    }
   24.36  
    25.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_amd64/SolarisAMD64JavaThreadPDAccess.java	Thu Sep 08 16:59:27 2011 -0700
    25.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_amd64/SolarisAMD64JavaThreadPDAccess.java	Fri Sep 09 16:17:16 2011 -0700
    25.3 @@ -30,6 +30,7 @@
    25.4  import sun.jvm.hotspot.debugger.amd64.*;
    25.5  import sun.jvm.hotspot.runtime.*;
    25.6  import sun.jvm.hotspot.runtime.amd64.*;
    25.7 +import sun.jvm.hotspot.runtime.x86.*;
    25.8  import sun.jvm.hotspot.types.*;
    25.9  import sun.jvm.hotspot.utilities.*;
   25.10  
   25.11 @@ -84,14 +85,14 @@
   25.12          }
   25.13          Address pc =  thread.getLastJavaPC();
   25.14          if ( pc != null ) {
   25.15 -            return new AMD64Frame(thread.getLastJavaSP(), fp, pc);
   25.16 +            return new X86Frame(thread.getLastJavaSP(), fp, pc);
   25.17          } else {
   25.18 -            return new AMD64Frame(thread.getLastJavaSP(), fp);
   25.19 +            return new X86Frame(thread.getLastJavaSP(), fp);
   25.20          }
   25.21      }
   25.22  
   25.23      public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
   25.24 -        return new AMD64RegisterMap(thread, updateMap);
   25.25 +        return new X86RegisterMap(thread, updateMap);
   25.26      }
   25.27  
   25.28      public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
   25.29 @@ -102,9 +103,9 @@
   25.30              return null;
   25.31          }
   25.32          if (guesser.getPC() == null) {
   25.33 -            return new AMD64Frame(guesser.getSP(), guesser.getFP());
   25.34 +            return new X86Frame(guesser.getSP(), guesser.getFP());
   25.35          } else {
   25.36 -            return new AMD64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
   25.37 +            return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
   25.38          }
   25.39      }
   25.40  
    26.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Thu Sep 08 16:59:27 2011 -0700
    26.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Fri Sep 09 16:17:16 2011 -0700
    26.3 @@ -236,7 +236,7 @@
    26.4        CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
    26.5        if (cb != null && cb.isJavaMethod()) {
    26.6          NMethod nm = (NMethod) cb;
    26.7 -        if (pc.equals(nm.deoptBegin())) {
    26.8 +        if (pc.equals(nm.deoptHandlerBegin())) {
    26.9            // adjust pc if frame is deoptimized.
   26.10            pc = this.getUnextendedSP().getAddressAt(nm.origPCOffset());
   26.11            deoptimized = true;
   26.12 @@ -559,49 +559,46 @@
   26.13        }
   26.14      }
   26.15  
   26.16 -    if (!VM.getVM().isCore()) {
   26.17 -      // Note:  The version of this operation on any platform with callee-save
   26.18 -      //        registers must update the register map (if not null).
   26.19 -      //        In order to do this correctly, the various subtypes of
   26.20 -      //        of frame (interpreted, compiled, glue, native),
   26.21 -      //        must be distinguished.  There is no need on SPARC for
   26.22 -      //        such distinctions, because all callee-save registers are
   26.23 -      //        preserved for all frames via SPARC-specific mechanisms.
   26.24 -      //
   26.25 -      //        *** HOWEVER, *** if and when we make any floating-point
   26.26 -      //        registers callee-saved, then we will have to copy over
   26.27 -      //        the RegisterMap update logic from the Intel code.
   26.28 +    // Note:  The version of this operation on any platform with callee-save
   26.29 +    //        registers must update the register map (if not null).
   26.30 +    //        In order to do this correctly, the various subtypes of
   26.31 +    //        of frame (interpreted, compiled, glue, native),
   26.32 +    //        must be distinguished.  There is no need on SPARC for
   26.33 +    //        such distinctions, because all callee-save registers are
   26.34 +    //        preserved for all frames via SPARC-specific mechanisms.
   26.35 +    //
   26.36 +    //        *** HOWEVER, *** if and when we make any floating-point
   26.37 +    //        registers callee-saved, then we will have to copy over
   26.38 +    //        the RegisterMap update logic from the Intel code.
   26.39  
   26.40 +    if (isRicochetFrame()) return senderForRicochetFrame(map);
   26.41  
   26.42 -      // The constructor of the sender must know whether this frame is interpreted so it can set the
   26.43 -      // sender's _interpreter_sp_adjustment field.
   26.44 -      if (VM.getVM().getInterpreter().contains(pc)) {
   26.45 -        isInterpreted = true;
   26.46 -        map.makeIntegerRegsUnsaved();
   26.47 +    // The constructor of the sender must know whether this frame is interpreted so it can set the
   26.48 +    // sender's _interpreter_sp_adjustment field.
   26.49 +    if (VM.getVM().getInterpreter().contains(pc)) {
   26.50 +      isInterpreted = true;
   26.51 +      map.makeIntegerRegsUnsaved();
   26.52 +      map.shiftWindow(sp, youngerSP);
   26.53 +    } else {
   26.54 +      // Find a CodeBlob containing this frame's pc or elide the lookup and use the
   26.55 +      // supplied blob which is already known to be associated with this frame.
   26.56 +      cb = VM.getVM().getCodeCache().findBlob(pc);
   26.57 +      if (cb != null) {
   26.58 +        // Update the location of all implicitly saved registers
   26.59 +        // as the address of these registers in the register save
   26.60 +        // area (for %o registers we use the address of the %i
   26.61 +        // register in the next younger frame)
   26.62          map.shiftWindow(sp, youngerSP);
   26.63 -      } else {
   26.64 -        // Find a CodeBlob containing this frame's pc or elide the lookup and use the
   26.65 -        // supplied blob which is already known to be associated with this frame.
   26.66 -        cb = VM.getVM().getCodeCache().findBlob(pc);
   26.67 -        if (cb != null) {
   26.68 -
   26.69 -          if (cb.callerMustGCArguments(map.getThread())) {
   26.70 +        if (map.getUpdateMap()) {
   26.71 +          if (cb.callerMustGCArguments()) {
   26.72              map.setIncludeArgumentOops(true);
   26.73            }
   26.74 -
   26.75 -          // Update the location of all implicitly saved registers
   26.76 -          // as the address of these registers in the register save
   26.77 -          // area (for %o registers we use the address of the %i
   26.78 -          // register in the next younger frame)
   26.79 -          map.shiftWindow(sp, youngerSP);
   26.80 -          if (map.getUpdateMap()) {
   26.81 -            if (cb.getOopMaps() != null) {
   26.82 -              OopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
   26.83 -            }
   26.84 +          if (cb.getOopMaps() != null) {
   26.85 +            OopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
   26.86            }
   26.87          }
   26.88        }
   26.89 -    } // #ifndef CORE
   26.90 +    }
   26.91  
   26.92      return new SPARCFrame(biasSP(sp), biasSP(youngerSP), isInterpreted);
   26.93    }
   26.94 @@ -948,6 +945,20 @@
   26.95    }
   26.96  
   26.97  
   26.98 +  private Frame senderForRicochetFrame(SPARCRegisterMap map) {
   26.99 +    if (DEBUG) {
  26.100 +      System.out.println("senderForRicochetFrame");
  26.101 +    }
  26.102 +    //RicochetFrame* f = RicochetFrame::from_frame(fr);
  26.103 +    // Cf. is_interpreted_frame path of frame::sender
  26.104 +    Address youngerSP = getSP();
  26.105 +    Address sp        = getSenderSP();
  26.106 +    map.makeIntegerRegsUnsaved();
  26.107 +    map.shiftWindow(sp, youngerSP);
  26.108 +    boolean thisFrameAdjustedStack = true;  // I5_savedSP is live in this RF
  26.109 +    return new SPARCFrame(sp, youngerSP, thisFrameAdjustedStack);
  26.110 +  }
  26.111 +
  26.112    private Frame senderForEntryFrame(RegisterMap regMap) {
  26.113      SPARCRegisterMap map = (SPARCRegisterMap) regMap;
  26.114  
  26.115 @@ -965,10 +976,8 @@
  26.116      Address lastJavaPC = jcw.getLastJavaPC();
  26.117      map.clear();
  26.118  
  26.119 -    if (!VM.getVM().isCore()) {
  26.120 -      map.makeIntegerRegsUnsaved();
  26.121 -      map.shiftWindow(lastJavaSP, null);
  26.122 -    }
  26.123 +    map.makeIntegerRegsUnsaved();
  26.124 +    map.shiftWindow(lastJavaSP, null);
  26.125  
  26.126      if (Assert.ASSERTS_ENABLED) {
  26.127        Assert.that(map.getIncludeArgumentOops(), "should be set by clear");
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCRicochetFrame.java	Fri Sep 09 16:17:16 2011 -0700
    27.3 @@ -0,0 +1,77 @@
    27.4 +/*
    27.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.7 + *
    27.8 + * This code is free software; you can redistribute it and/or modify it
    27.9 + * under the terms of the GNU General Public License version 2 only, as
   27.10 + * published by the Free Software Foundation.
   27.11 + *
   27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   27.15 + * version 2 for more details (a copy is included in the LICENSE file that
   27.16 + * accompanied this code).
   27.17 + *
   27.18 + * You should have received a copy of the GNU General Public License version
   27.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   27.21 + *
   27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   27.23 + * or visit www.oracle.com if you need additional information or have any
   27.24 + * questions.
   27.25 + *
   27.26 + */
   27.27 +
   27.28 +package sun.jvm.hotspot.runtime.sparc;
   27.29 +
   27.30 +import java.util.*;
   27.31 +import sun.jvm.hotspot.asm.sparc.SPARCRegister;
   27.32 +import sun.jvm.hotspot.asm.sparc.SPARCRegisters;
   27.33 +import sun.jvm.hotspot.debugger.*;
   27.34 +import sun.jvm.hotspot.runtime.*;
   27.35 +import sun.jvm.hotspot.types.*;
   27.36 +
   27.37 +public class SPARCRicochetFrame {
   27.38 +  static {
   27.39 +    VM.registerVMInitializedObserver(new Observer() {
   27.40 +        public void update(Observable o, Object data) {
   27.41 +          initialize(VM.getVM().getTypeDataBase());
   27.42 +        }
   27.43 +      });
   27.44 +  }
   27.45 +
   27.46 +  private SPARCFrame frame;
   27.47 +
   27.48 +  private static void initialize(TypeDataBase db) {
   27.49 +    // Type type = db.lookupType("MethodHandles::RicochetFrame");
   27.50 +
   27.51 +  }
   27.52 +
   27.53 +  static SPARCRicochetFrame fromFrame(SPARCFrame f) {
   27.54 +    return new SPARCRicochetFrame(f);
   27.55 +  }
   27.56 +
   27.57 +  private SPARCRicochetFrame(SPARCFrame f) {
   27.58 +    frame = f;
   27.59 +  }
   27.60 +
   27.61 +  private Address registerValue(SPARCRegister reg) {
   27.62 +    return frame.getSP().addOffsetTo(reg.spOffsetInSavedWindow()).getAddressAt(0);
   27.63 +  }
   27.64 +
   27.65 +  public Address savedArgsBase() {
   27.66 +    return registerValue(SPARCRegisters.L4);
   27.67 +  }
   27.68 +  public Address exactSenderSP() {
   27.69 +    return registerValue(SPARCRegisters.I5);
   27.70 +  }
   27.71 +  public Address senderLink() {
   27.72 +    return frame.getSenderSP();
   27.73 +  }
   27.74 +  public Address senderPC() {
   27.75 +    return frame.getSenderPC();
   27.76 +  }
   27.77 +  public Address extendedSenderSP() {
   27.78 +    return savedArgsBase();
   27.79 +  }
   27.80 +}
    28.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java	Thu Sep 08 16:59:27 2011 -0700
    28.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/win32_amd64/Win32AMD64JavaThreadPDAccess.java	Fri Sep 09 16:17:16 2011 -0700
    28.3 @@ -31,6 +31,7 @@
    28.4  import sun.jvm.hotspot.debugger.amd64.*;
    28.5  import sun.jvm.hotspot.runtime.*;
    28.6  import sun.jvm.hotspot.runtime.amd64.*;
    28.7 +import sun.jvm.hotspot.runtime.x86.*;
    28.8  import sun.jvm.hotspot.types.*;
    28.9  import sun.jvm.hotspot.utilities.*;
   28.10  
   28.11 @@ -86,14 +87,14 @@
   28.12      }
   28.13      Address pc =  thread.getLastJavaPC();
   28.14      if ( pc != null ) {
   28.15 -      return new AMD64Frame(thread.getLastJavaSP(), fp, pc);
   28.16 +      return new X86Frame(thread.getLastJavaSP(), fp, pc);
   28.17      } else {
   28.18 -      return new AMD64Frame(thread.getLastJavaSP(), fp);
   28.19 +      return new X86Frame(thread.getLastJavaSP(), fp);
   28.20      }
   28.21    }
   28.22  
   28.23    public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
   28.24 -    return new AMD64RegisterMap(thread, updateMap);
   28.25 +    return new X86RegisterMap(thread, updateMap);
   28.26    }
   28.27  
   28.28    public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
   28.29 @@ -104,9 +105,9 @@
   28.30        return null;
   28.31      }
   28.32      if (guesser.getPC() == null) {
   28.33 -      return new AMD64Frame(guesser.getSP(), guesser.getFP());
   28.34 +      return new X86Frame(guesser.getSP(), guesser.getFP());
   28.35      } else {
   28.36 -      return new AMD64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
   28.37 +      return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
   28.38      }
   28.39    }
   28.40  
    29.1 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Thu Sep 08 16:59:27 2011 -0700
    29.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Fri Sep 09 16:17:16 2011 -0700
    29.3 @@ -25,7 +25,6 @@
    29.4  package sun.jvm.hotspot.runtime.x86;
    29.5  
    29.6  import java.util.*;
    29.7 -import sun.jvm.hotspot.asm.x86.*;
    29.8  import sun.jvm.hotspot.code.*;
    29.9  import sun.jvm.hotspot.compiler.*;
   29.10  import sun.jvm.hotspot.debugger.*;
   29.11 @@ -62,11 +61,13 @@
   29.12    private static       int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET;
   29.13  
   29.14    // Entry frames
   29.15 -  private static final int ENTRY_FRAME_CALL_WRAPPER_OFFSET   =  2;
   29.16 +  private static       int ENTRY_FRAME_CALL_WRAPPER_OFFSET;
   29.17  
   29.18    // Native frames
   29.19    private static final int NATIVE_FRAME_INITIAL_PARAM_OFFSET =  2;
   29.20  
   29.21 +  private static VMReg rbp;
   29.22 +
   29.23    static {
   29.24      VM.registerVMInitializedObserver(new Observer() {
   29.25          public void update(Observable o, Object data) {
   29.26 @@ -76,19 +77,23 @@
   29.27    }
   29.28  
   29.29    private static synchronized void initialize(TypeDataBase db) {
   29.30 -    if (VM.getVM().isCore()) {
   29.31 -      INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_METHOD_OFFSET - 1;
   29.32 -    } else {
   29.33 -      INTERPRETER_FRAME_MDX_OFFSET   = INTERPRETER_FRAME_METHOD_OFFSET - 1;
   29.34 -      INTERPRETER_FRAME_CACHE_OFFSET = INTERPRETER_FRAME_MDX_OFFSET - 1;
   29.35 -    }
   29.36 +    INTERPRETER_FRAME_MDX_OFFSET                  = INTERPRETER_FRAME_METHOD_OFFSET - 1;
   29.37 +    INTERPRETER_FRAME_CACHE_OFFSET                = INTERPRETER_FRAME_MDX_OFFSET - 1;
   29.38      INTERPRETER_FRAME_LOCALS_OFFSET               = INTERPRETER_FRAME_CACHE_OFFSET - 1;
   29.39      INTERPRETER_FRAME_BCX_OFFSET                  = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
   29.40      INTERPRETER_FRAME_INITIAL_SP_OFFSET           = INTERPRETER_FRAME_BCX_OFFSET - 1;
   29.41      INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET    = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
   29.42      INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
   29.43 +
   29.44 +    ENTRY_FRAME_CALL_WRAPPER_OFFSET = db.lookupIntConstant("frame::entry_frame_call_wrapper_offset");
   29.45 +    if (VM.getVM().getAddressSize() == 4) {
   29.46 +      rbp = new VMReg(5);
   29.47 +    } else {
   29.48 +      rbp = new VMReg(5 << 1);
   29.49 +    }
   29.50    }
   29.51  
   29.52 +
   29.53    // an additional field beyond sp and pc:
   29.54    Address raw_fp; // frame pointer
   29.55    private Address raw_unextendedSP;
   29.56 @@ -102,7 +107,7 @@
   29.57        CodeBlob cb = VM.getVM().getCodeCache().findBlob(pc);
   29.58        if (cb != null && cb.isJavaMethod()) {
   29.59          NMethod nm = (NMethod) cb;
   29.60 -        if (pc.equals(nm.deoptBegin())) {
   29.61 +        if (pc.equals(nm.deoptHandlerBegin())) {
   29.62            if (Assert.ASSERTS_ENABLED) {
   29.63              Assert.that(this.getUnextendedSP() != null, "null SP in Java frame");
   29.64            }
   29.65 @@ -119,6 +124,7 @@
   29.66      this.raw_unextendedSP = raw_sp;
   29.67      this.raw_fp = raw_fp;
   29.68      this.pc = pc;
   29.69 +    adjustUnextendedSP();
   29.70  
   29.71      // Frame must be fully constructed before this call
   29.72      adjustForDeopt();
   29.73 @@ -134,6 +140,7 @@
   29.74      this.raw_unextendedSP = raw_sp;
   29.75      this.raw_fp = raw_fp;
   29.76      this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
   29.77 +    adjustUnextendedSP();
   29.78  
   29.79      // Frame must be fully constructed before this call
   29.80      adjustForDeopt();
   29.81 @@ -144,24 +151,18 @@
   29.82      }
   29.83    }
   29.84  
   29.85 -  // This constructor should really take the unextended SP as an arg
   29.86 -  // but then the constructor is ambiguous with constructor that takes
   29.87 -  // a PC so take an int and convert it.
   29.88 -  public X86Frame(Address raw_sp, Address raw_fp, long extension) {
   29.89 +  public X86Frame(Address raw_sp, Address raw_unextendedSp, Address raw_fp, Address pc) {
   29.90      this.raw_sp = raw_sp;
   29.91 -    if (raw_sp == null) {
   29.92 -      this.raw_unextendedSP = null;
   29.93 -    } else {
   29.94 -      this.raw_unextendedSP = raw_sp.addOffsetTo(extension);
   29.95 -    }
   29.96 +    this.raw_unextendedSP = raw_unextendedSp;
   29.97      this.raw_fp = raw_fp;
   29.98 -    this.pc = raw_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
   29.99 +    this.pc = pc;
  29.100 +    adjustUnextendedSP();
  29.101  
  29.102      // Frame must be fully constructed before this call
  29.103      adjustForDeopt();
  29.104  
  29.105      if (DEBUG) {
  29.106 -      System.out.println("X86Frame(sp, fp): " + this);
  29.107 +      System.out.println("X86Frame(sp, unextendedSP, fp, pc): " + this);
  29.108        dumpStack();
  29.109      }
  29.110  
  29.111 @@ -172,7 +173,6 @@
  29.112      frame.raw_sp = raw_sp;
  29.113      frame.raw_unextendedSP = raw_unextendedSP;
  29.114      frame.raw_fp = raw_fp;
  29.115 -    frame.raw_fp = raw_fp;
  29.116      frame.pc = pc;
  29.117      frame.deoptimized = deoptimized;
  29.118      return frame;
  29.119 @@ -269,19 +269,18 @@
  29.120  
  29.121      if (isEntryFrame())       return senderForEntryFrame(map);
  29.122      if (isInterpretedFrame()) return senderForInterpreterFrame(map);
  29.123 +    if (isRicochetFrame())    return senderForRicochetFrame(map);
  29.124  
  29.125 -    if (!VM.getVM().isCore()) {
  29.126 -      if(cb == null) {
  29.127 -        cb = VM.getVM().getCodeCache().findBlob(getPC());
  29.128 -      } else {
  29.129 -        if (Assert.ASSERTS_ENABLED) {
  29.130 -          Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
  29.131 -        }
  29.132 +    if(cb == null) {
  29.133 +      cb = VM.getVM().getCodeCache().findBlob(getPC());
  29.134 +    } else {
  29.135 +      if (Assert.ASSERTS_ENABLED) {
  29.136 +        Assert.that(cb.equals(VM.getVM().getCodeCache().findBlob(getPC())), "Must be the same");
  29.137        }
  29.138 +    }
  29.139  
  29.140 -      if (cb != null) {
  29.141 -         return senderForCompiledFrame(map, cb);
  29.142 -      }
  29.143 +    if (cb != null) {
  29.144 +      return senderForCompiledFrame(map, cb);
  29.145      }
  29.146  
  29.147      // Must be native-compiled frame, i.e. the marshaling code for native
  29.148 @@ -289,7 +288,20 @@
  29.149      return new X86Frame(getSenderSP(), getLink(), getSenderPC());
  29.150    }
  29.151  
  29.152 +  private Frame senderForRicochetFrame(X86RegisterMap map) {
  29.153 +    if (DEBUG) {
  29.154 +      System.out.println("senderForRicochetFrame");
  29.155 +    }
  29.156 +    X86RicochetFrame f = X86RicochetFrame.fromFrame(this);
  29.157 +    if (map.getUpdateMap())
  29.158 +      updateMapWithSavedLink(map, f.senderLinkAddress());
  29.159 +    return new X86Frame(f.extendedSenderSP(), f.exactSenderSP(), f.senderLink(), f.senderPC());
  29.160 +  }
  29.161 +
  29.162    private Frame senderForEntryFrame(X86RegisterMap map) {
  29.163 +    if (DEBUG) {
  29.164 +      System.out.println("senderForEntryFrame");
  29.165 +    }
  29.166      if (Assert.ASSERTS_ENABLED) {
  29.167        Assert.that(map != null, "map must be set");
  29.168      }
  29.169 @@ -313,7 +325,37 @@
  29.170      return fr;
  29.171    }
  29.172  
  29.173 +  //------------------------------------------------------------------------------
  29.174 +  // frame::adjust_unextended_sp
  29.175 +  private void adjustUnextendedSP() {
  29.176 +    // If we are returning to a compiled MethodHandle call site, the
  29.177 +    // saved_fp will in fact be a saved value of the unextended SP.  The
  29.178 +    // simplest way to tell whether we are returning to such a call site
  29.179 +    // is as follows:
  29.180 +
  29.181 +    CodeBlob cb = cb();
  29.182 +    NMethod senderNm = (cb == null) ? null : cb.asNMethodOrNull();
  29.183 +    if (senderNm != null) {
  29.184 +      // If the sender PC is a deoptimization point, get the original
  29.185 +      // PC.  For MethodHandle call site the unextended_sp is stored in
  29.186 +      // saved_fp.
  29.187 +      if (senderNm.isDeoptMhEntry(getPC())) {
  29.188 +        // DEBUG_ONLY(verifyDeoptMhOriginalPc(senderNm, getFP()));
  29.189 +        raw_unextendedSP = getFP();
  29.190 +      }
  29.191 +      else if (senderNm.isDeoptEntry(getPC())) {
  29.192 +        // DEBUG_ONLY(verifyDeoptOriginalPc(senderNm, raw_unextendedSp));
  29.193 +      }
  29.194 +      else if (senderNm.isMethodHandleReturn(getPC())) {
  29.195 +        raw_unextendedSP = getFP();
  29.196 +      }
  29.197 +    }
  29.198 +  }
  29.199 +
  29.200    private Frame senderForInterpreterFrame(X86RegisterMap map) {
  29.201 +    if (DEBUG) {
  29.202 +      System.out.println("senderForInterpreterFrame");
  29.203 +    }
  29.204      Address unextendedSP = addressOfStackSlot(INTERPRETER_FRAME_SENDER_SP_OFFSET).getAddressAt(0);
  29.205      Address sp = addressOfStackSlot(SENDER_SP_OFFSET);
  29.206      // We do not need to update the callee-save register mapping because above
  29.207 @@ -323,10 +365,21 @@
  29.208      // However c2 no longer uses callee save register for java calls so there
  29.209      // are no callee register to find.
  29.210  
  29.211 -    return new X86Frame(sp, getLink(), unextendedSP.minus(sp));
  29.212 +    if (map.getUpdateMap())
  29.213 +      updateMapWithSavedLink(map, addressOfStackSlot(LINK_OFFSET));
  29.214 +
  29.215 +    return new X86Frame(sp, unextendedSP, getLink(), getSenderPC());
  29.216 +  }
  29.217 +
  29.218 +  private void updateMapWithSavedLink(RegisterMap map, Address savedFPAddr) {
  29.219 +    map.setLocation(rbp, savedFPAddr);
  29.220    }
  29.221  
  29.222    private Frame senderForCompiledFrame(X86RegisterMap map, CodeBlob cb) {
  29.223 +    if (DEBUG) {
  29.224 +      System.out.println("senderForCompiledFrame");
  29.225 +    }
  29.226 +
  29.227      //
  29.228      // NOTE: some of this code is (unfortunately) duplicated in X86CurrentFrameGuess
  29.229      //
  29.230 @@ -336,41 +389,35 @@
  29.231      }
  29.232  
  29.233      // frame owned by optimizing compiler
  29.234 -    Address        sender_sp = null;
  29.235 +    if (Assert.ASSERTS_ENABLED) {
  29.236 +        Assert.that(cb.getFrameSize() >= 0, "must have non-zero frame size");
  29.237 +    }
  29.238 +    Address senderSP = getUnextendedSP().addOffsetTo(cb.getFrameSize());
  29.239  
  29.240 -    if (VM.getVM().isClientCompiler()) {
  29.241 -      sender_sp        = addressOfStackSlot(SENDER_SP_OFFSET);
  29.242 -    } else {
  29.243 -      if (Assert.ASSERTS_ENABLED) {
  29.244 -        Assert.that(cb.getFrameSize() >= 0, "Compiled by Compiler1: do not use");
  29.245 +    // On Intel the return_address is always the word on the stack
  29.246 +    Address senderPC = senderSP.getAddressAt(-1 * VM.getVM().getAddressSize());
  29.247 +
  29.248 +    // This is the saved value of EBP which may or may not really be an FP.
  29.249 +    // It is only an FP if the sender is an interpreter frame (or C1?).
  29.250 +    Address savedFPAddr = senderSP.addOffsetTo(- SENDER_SP_OFFSET * VM.getVM().getAddressSize());
  29.251 +
  29.252 +    if (map.getUpdateMap()) {
  29.253 +      // Tell GC to use argument oopmaps for some runtime stubs that need it.
  29.254 +      // For C1, the runtime stub might not have oop maps, so set this flag
  29.255 +      // outside of update_register_map.
  29.256 +      map.setIncludeArgumentOops(cb.callerMustGCArguments());
  29.257 +
  29.258 +      if (cb.getOopMaps() != null) {
  29.259 +        OopMapSet.updateRegisterMap(this, cb, map, true);
  29.260        }
  29.261 -      sender_sp = getUnextendedSP().addOffsetTo(cb.getFrameSize());
  29.262 +
  29.263 +      // Since the prolog does the save and restore of EBP there is no oopmap
  29.264 +      // for it so we must fill in its location as if there was an oopmap entry
  29.265 +      // since if our caller was compiled code there could be live jvm state in it.
  29.266 +      updateMapWithSavedLink(map, savedFPAddr);
  29.267      }
  29.268  
  29.269 -    // On Intel the return_address is always the word on the stack
  29.270 -    Address sender_pc = sender_sp.getAddressAt(-1 * VM.getVM().getAddressSize());
  29.271 -
  29.272 -    if (map.getUpdateMap() && cb.getOopMaps() != null) {
  29.273 -      OopMapSet.updateRegisterMap(this, cb, map, true);
  29.274 -    }
  29.275 -
  29.276 -    if (VM.getVM().isClientCompiler()) {
  29.277 -      // Move this here for C1 and collecting oops in arguments (According to Rene)
  29.278 -      map.setIncludeArgumentOops(cb.callerMustGCArguments(map.getThread()));
  29.279 -    }
  29.280 -
  29.281 -    Address saved_fp = null;
  29.282 -    if (VM.getVM().isClientCompiler()) {
  29.283 -      saved_fp = getFP().getAddressAt(0);
  29.284 -    } else if (VM.getVM().isServerCompiler() &&
  29.285 -               (VM.getVM().getInterpreter().contains(sender_pc) ||
  29.286 -               VM.getVM().getStubRoutines().returnsToCallStub(sender_pc))) {
  29.287 -      // C2 prologue saves EBP in the usual place.
  29.288 -      // however only use it if the sender had link infomration in it.
  29.289 -      saved_fp = sender_sp.getAddressAt(-2 * VM.getVM().getAddressSize());
  29.290 -    }
  29.291 -
  29.292 -    return new X86Frame(sender_sp, saved_fp, sender_pc);
  29.293 +    return new X86Frame(senderSP, savedFPAddr.getAddressAt(0), senderPC);
  29.294    }
  29.295  
  29.296    protected boolean hasSenderPD() {
  29.297 @@ -403,14 +450,6 @@
  29.298  
  29.299    public Address getSenderSP()     { return addressOfStackSlot(SENDER_SP_OFFSET); }
  29.300  
  29.301 -  public Address compiledArgumentToLocationPD(VMReg reg, RegisterMap regMap, int argSize) {
  29.302 -    if (VM.getVM().isCore() || VM.getVM().isClientCompiler()) {
  29.303 -      throw new RuntimeException("Should not reach here");
  29.304 -    }
  29.305 -
  29.306 -    return oopMapRegToLocation(reg, regMap);
  29.307 -  }
  29.308 -
  29.309    public Address addressOfInterpreterFrameLocals() {
  29.310      return addressOfStackSlot(INTERPRETER_FRAME_LOCALS_OFFSET);
  29.311    }
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86RicochetFrame.java	Fri Sep 09 16:17:16 2011 -0700
    30.3 @@ -0,0 +1,81 @@
    30.4 +/*
    30.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    30.7 + *
    30.8 + * This code is free software; you can redistribute it and/or modify it
    30.9 + * under the terms of the GNU General Public License version 2 only, as
   30.10 + * published by the Free Software Foundation.
   30.11 + *
   30.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   30.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   30.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   30.15 + * version 2 for more details (a copy is included in the LICENSE file that
   30.16 + * accompanied this code).
   30.17 + *
   30.18 + * You should have received a copy of the GNU General Public License version
   30.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   30.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   30.21 + *
   30.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   30.23 + * or visit www.oracle.com if you need additional information or have any
   30.24 + * questions.
   30.25 + *
   30.26 + */
   30.27 +
   30.28 +package sun.jvm.hotspot.runtime.x86;
   30.29 +
   30.30 +import java.util.*;
   30.31 +import sun.jvm.hotspot.debugger.*;
   30.32 +import sun.jvm.hotspot.runtime.*;
   30.33 +import sun.jvm.hotspot.types.*;
   30.34 +
   30.35 +public class X86RicochetFrame extends VMObject {
   30.36 +  static {
   30.37 +    VM.registerVMInitializedObserver(new Observer() {
   30.38 +        public void update(Observable o, Object data) {
   30.39 +          initialize(VM.getVM().getTypeDataBase());
   30.40 +        }
   30.41 +      });
   30.42 +  }
   30.43 +
   30.44 +  private static void initialize(TypeDataBase db) {
   30.45 +    Type type = db.lookupType("MethodHandles::RicochetFrame");
   30.46 +
   30.47 +    senderLinkField    = type.getAddressField("_sender_link");
   30.48 +    savedArgsBaseField = type.getAddressField("_saved_args_base");
   30.49 +    exactSenderSPField = type.getAddressField("_exact_sender_sp");
   30.50 +    senderPCField      = type.getAddressField("_sender_pc");
   30.51 +  }
   30.52 +
   30.53 +  private static AddressField senderLinkField;
   30.54 +  private static AddressField savedArgsBaseField;
   30.55 +  private static AddressField exactSenderSPField;
   30.56 +  private static AddressField senderPCField;
   30.57 +
   30.58 +  static X86RicochetFrame fromFrame(X86Frame f) {
   30.59 +    return new X86RicochetFrame(f.getFP().addOffsetTo(- senderLinkField.getOffset()));
   30.60 +  }
   30.61 +
   30.62 +  private X86RicochetFrame(Address addr) {
   30.63 +    super(addr);
   30.64 +  }
   30.65 +
   30.66 +  public Address senderLink() {
   30.67 +    return senderLinkField.getValue(addr);
   30.68 +  }
   30.69 +  public Address senderLinkAddress() {
   30.70 +    return addr.addOffsetTo(senderLinkField.getOffset());
   30.71 +  }
   30.72 +  public Address savedArgsBase() {
   30.73 +    return savedArgsBaseField.getValue(addr);
   30.74 +  }
   30.75 +  public Address extendedSenderSP() {
   30.76 +    return savedArgsBase();
   30.77 +  }
   30.78 +  public Address exactSenderSP() {
   30.79 +    return exactSenderSPField.getValue(addr);
   30.80 +  }
   30.81 +  public Address senderPC() {
   30.82 +    return senderPCField.getValue(addr);
   30.83 +  }
   30.84 +}
    31.1 --- a/make/hotspot_version	Thu Sep 08 16:59:27 2011 -0700
    31.2 +++ b/make/hotspot_version	Fri Sep 09 16:17:16 2011 -0700
    31.3 @@ -35,7 +35,7 @@
    31.4  
    31.5  HS_MAJOR_VER=22
    31.6  HS_MINOR_VER=0
    31.7 -HS_BUILD_NUMBER=03
    31.8 +HS_BUILD_NUMBER=04
    31.9  
   31.10  JDK_MAJOR_VER=1
   31.11  JDK_MINOR_VER=8
    32.1 --- a/make/linux/makefiles/mapfile-vers-debug	Thu Sep 08 16:59:27 2011 -0700
    32.2 +++ b/make/linux/makefiles/mapfile-vers-debug	Fri Sep 09 16:17:16 2011 -0700
    32.3 @@ -244,24 +244,6 @@
    32.4                  JVM_Yield;
    32.5                  JVM_handle_linux_signal;
    32.6  
    32.7 -                # Old reflection routines
    32.8 -                # These do not need to be present in the product build in JDK 1.4
    32.9 -                # but their code has not been removed yet because there will not
   32.10 -                # be a substantial code savings until JVM_InvokeMethod and
   32.11 -                # JVM_NewInstanceFromConstructor can also be removed; see
   32.12 -                # reflectionCompat.hpp.
   32.13 -                JVM_GetClassConstructor;
   32.14 -                JVM_GetClassConstructors;
   32.15 -                JVM_GetClassField;
   32.16 -                JVM_GetClassFields;
   32.17 -                JVM_GetClassMethod;
   32.18 -                JVM_GetClassMethods;
   32.19 -                JVM_GetField;
   32.20 -                JVM_GetPrimitiveField;
   32.21 -                JVM_NewInstance;
   32.22 -                JVM_SetField;
   32.23 -                JVM_SetPrimitiveField;
   32.24 -
   32.25                  # debug JVM
   32.26                  JVM_AccessVMBooleanFlag;
   32.27                  JVM_AccessVMIntFlag;
    33.1 --- a/make/linux/makefiles/mapfile-vers-product	Thu Sep 08 16:59:27 2011 -0700
    33.2 +++ b/make/linux/makefiles/mapfile-vers-product	Fri Sep 09 16:17:16 2011 -0700
    33.3 @@ -244,24 +244,6 @@
    33.4                  JVM_Yield;
    33.5                  JVM_handle_linux_signal;
    33.6  
    33.7 -                # Old reflection routines
    33.8 -                # These do not need to be present in the product build in JDK 1.4
    33.9 -                # but their code has not been removed yet because there will not
   33.10 -                # be a substantial code savings until JVM_InvokeMethod and
   33.11 -                # JVM_NewInstanceFromConstructor can also be removed; see
   33.12 -                # reflectionCompat.hpp.
   33.13 -                JVM_GetClassConstructor;
   33.14 -                JVM_GetClassConstructors;
   33.15 -                JVM_GetClassField;
   33.16 -                JVM_GetClassFields;
   33.17 -                JVM_GetClassMethod;
   33.18 -                JVM_GetClassMethods;
   33.19 -                JVM_GetField;
   33.20 -                JVM_GetPrimitiveField;
   33.21 -                JVM_NewInstance;
   33.22 -                JVM_SetField;
   33.23 -                JVM_SetPrimitiveField;
   33.24 -
   33.25                  # miscellaneous functions
   33.26                  jio_fprintf;
   33.27                  jio_printf;
    34.1 --- a/make/solaris/makefiles/debug.make	Thu Sep 08 16:59:27 2011 -0700
    34.2 +++ b/make/solaris/makefiles/debug.make	Fri Sep 09 16:17:16 2011 -0700
    34.3 @@ -41,8 +41,7 @@
    34.4  
    34.5  # Linker mapfiles
    34.6  MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
    34.7 -          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug \
    34.8 -          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
    34.9 +          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
   34.10  
   34.11  # This mapfile is only needed when compiling with dtrace support, 
   34.12  # and mustn't be otherwise.
    35.1 --- a/make/solaris/makefiles/fastdebug.make	Thu Sep 08 16:59:27 2011 -0700
    35.2 +++ b/make/solaris/makefiles/fastdebug.make	Fri Sep 09 16:17:16 2011 -0700
    35.3 @@ -107,8 +107,7 @@
    35.4  
    35.5  # Linker mapfiles
    35.6  MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
    35.7 -	  $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug \
    35.8 -	  $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
    35.9 +	  $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
   35.10  
   35.11  # This mapfile is only needed when compiling with dtrace support, 
   35.12  # and mustn't be otherwise.
    36.1 --- a/make/solaris/makefiles/jvmg.make	Thu Sep 08 16:59:27 2011 -0700
    36.2 +++ b/make/solaris/makefiles/jvmg.make	Fri Sep 09 16:17:16 2011 -0700
    36.3 @@ -44,8 +44,7 @@
    36.4  
    36.5  # Linker mapfiles
    36.6  MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
    36.7 -          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug \
    36.8 -          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
    36.9 +          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-debug
   36.10  
   36.11  # This mapfile is only needed when compiling with dtrace support,
   36.12  # and mustn't be otherwise.
    37.1 --- a/make/solaris/makefiles/mapfile-vers-nonproduct	Thu Sep 08 16:59:27 2011 -0700
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,48 +0,0 @@
    37.4 -#
    37.5 -
    37.6 -#
    37.7 -# Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
    37.8 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    37.9 -#
   37.10 -# This code is free software; you can redistribute it and/or modify it
   37.11 -# under the terms of the GNU General Public License version 2 only, as
   37.12 -# published by the Free Software Foundation.
   37.13 -#
   37.14 -# This code is distributed in the hope that it will be useful, but WITHOUT
   37.15 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   37.16 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   37.17 -# version 2 for more details (a copy is included in the LICENSE file that
   37.18 -# accompanied this code).
   37.19 -#
   37.20 -# You should have received a copy of the GNU General Public License version
   37.21 -# 2 along with this work; if not, write to the Free Software Foundation,
   37.22 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   37.23 -#
   37.24 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   37.25 -# or visit www.oracle.com if you need additional information or have any
   37.26 -# questions.
   37.27 -#  
   37.28 -#
   37.29 -
   37.30 -# Define public interface.
   37.31 -
   37.32 -SUNWprivate_1.1 {
   37.33 -        global:
   37.34 -		# Old reflection routines
   37.35 -		# These do not need to be present in the product build in JDK 1.4
   37.36 -		# but their code has not been removed yet because there will not
   37.37 -		# be a substantial code savings until JVM_InvokeMethod and
   37.38 -		# JVM_NewInstanceFromConstructor can also be removed; see
   37.39 -		# reflectionCompat.hpp.
   37.40 -		JVM_GetClassConstructor;
   37.41 -		JVM_GetClassConstructors;
   37.42 -		JVM_GetClassField;
   37.43 -		JVM_GetClassFields;
   37.44 -		JVM_GetClassMethod;
   37.45 -		JVM_GetClassMethods;
   37.46 -		JVM_GetField;
   37.47 -		JVM_GetPrimitiveField;
   37.48 -		JVM_NewInstance;
   37.49 -		JVM_SetField;
   37.50 -		JVM_SetPrimitiveField;
   37.51 -};
    38.1 --- a/make/solaris/makefiles/optimized.make	Thu Sep 08 16:59:27 2011 -0700
    38.2 +++ b/make/solaris/makefiles/optimized.make	Fri Sep 09 16:17:16 2011 -0700
    38.3 @@ -48,9 +48,7 @@
    38.4  CFLAGS$(HOTSPARC_GENERIC) += $(OPT_CFLAGS/BYFILE)
    38.5  
    38.6  # Linker mapfiles
    38.7 -# NOTE: inclusion of nonproduct mapfile not necessary; read it for details
    38.8 -MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
    38.9 -          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
   38.10 +MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers
   38.11  
   38.12  # This mapfile is only needed when compiling with dtrace support, 
   38.13  # and mustn't be otherwise.
    39.1 --- a/make/solaris/makefiles/product.make	Thu Sep 08 16:59:27 2011 -0700
    39.2 +++ b/make/solaris/makefiles/product.make	Fri Sep 09 16:17:16 2011 -0700
    39.3 @@ -58,13 +58,9 @@
    39.4  # to inhibit the effect of the previous line on CFLAGS.
    39.5  
    39.6  # Linker mapfiles
    39.7 -# NOTE: inclusion of nonproduct mapfile not necessary; read it for details
    39.8 -ifdef USE_GCC
    39.9  MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers
   39.10 -else
   39.11 -MAPFILE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers \
   39.12 -          $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-nonproduct
   39.13  
   39.14 +ifndef USE_GCC
   39.15  # This mapfile is only needed when compiling with dtrace support, 
   39.16  # and mustn't be otherwise.
   39.17  MAPFILE_DTRACE = $(GAMMADIR)/make/solaris/makefiles/mapfile-vers-$(TYPE)
    40.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Sep 08 16:59:27 2011 -0700
    40.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Fri Sep 09 16:17:16 2011 -0700
    40.3 @@ -1794,7 +1794,8 @@
    40.4    mov(reg,O0); // Move arg into O0; arg might be in O7 which is about to be crushed
    40.5    stx(O7,SP,frame::register_save_words*wordSize+STACK_BIAS+7*8);
    40.6  
    40.7 -  set((intptr_t)real_msg, O1);
    40.8 +  // Size of set() should stay the same
    40.9 +  patchable_set((intptr_t)real_msg, O1);
   40.10    // Load address to call to into O7
   40.11    load_ptr_contents(a, O7);
   40.12    // Register call to verify_oop_subroutine
   40.13 @@ -1831,7 +1832,8 @@
   40.14    ld_ptr(addr.base(), addr.disp() + 8*8, O0); // Load arg into O0; arg might be in O7 which is about to be crushed
   40.15    stx(O7,SP,frame::register_save_words*wordSize+STACK_BIAS+7*8);
   40.16  
   40.17 -  set((intptr_t)real_msg, O1);
   40.18 +  // Size of set() should stay the same
   40.19 +  patchable_set((intptr_t)real_msg, O1);
   40.20    // Load address to call to into O7
   40.21    load_ptr_contents(a, O7);
   40.22    // Register call to verify_oop_subroutine
   40.23 @@ -1976,7 +1978,8 @@
   40.24      save_frame(::round_to(sizeof(RegistersForDebugging) / BytesPerWord, 2));
   40.25  
   40.26      // stop_subroutine expects message pointer in I1.
   40.27 -    set((intptr_t)msg, O1);
   40.28 +    // Size of set() should stay the same
   40.29 +    patchable_set((intptr_t)msg, O1);
   40.30  
   40.31      // factor long stop-sequence into subroutine to save space
   40.32      assert(StubRoutines::Sparc::stop_subroutine_entry_address(), "hasn't been generated yet");
   40.33 @@ -1998,7 +2001,8 @@
   40.34    save_frame(::round_to(sizeof(RegistersForDebugging) / BytesPerWord, 2));
   40.35    RegistersForDebugging::save_registers(this);
   40.36    mov(O0, L0);
   40.37 -  set((intptr_t)msg, O0);
   40.38 +  // Size of set() should stay the same
   40.39 +  patchable_set((intptr_t)msg, O0);
   40.40    call( CAST_FROM_FN_PTR(address, warning) );
   40.41    delayed()->nop();
   40.42  //  ret();
   40.43 @@ -2161,29 +2165,6 @@
   40.44  #endif
   40.45  }
   40.46  
   40.47 -void MacroAssembler::br_on_reg_cond( RCondition rc, bool a, Predict p,
   40.48 -                                     Register s1, address d,
   40.49 -                                     relocInfo::relocType rt ) {
   40.50 -  assert_not_delayed();
   40.51 -  if (VM_Version::v9_instructions_work()) {
   40.52 -    bpr(rc, a, p, s1, d, rt);
   40.53 -  } else {
   40.54 -    tst(s1);
   40.55 -    br(reg_cond_to_cc_cond(rc), a, p, d, rt);
   40.56 -  }
   40.57 -}
   40.58 -
   40.59 -void MacroAssembler::br_on_reg_cond( RCondition rc, bool a, Predict p,
   40.60 -                                     Register s1, Label& L ) {
   40.61 -  assert_not_delayed();
   40.62 -  if (VM_Version::v9_instructions_work()) {
   40.63 -    bpr(rc, a, p, s1, L);
   40.64 -  } else {
   40.65 -    tst(s1);
   40.66 -    br(reg_cond_to_cc_cond(rc), a, p, L);
   40.67 -  }
   40.68 -}
   40.69 -
   40.70  // Compare registers and branch with nop in delay slot or cbcond without delay slot.
   40.71  
   40.72  // Compare integer (32 bit) values (icc only).
   40.73 @@ -4340,22 +4321,29 @@
   40.74    } else {
   40.75      pre_val = O0;
   40.76    }
   40.77 +
   40.78    int satb_q_index_byte_offset =
   40.79      in_bytes(JavaThread::satb_mark_queue_offset() +
   40.80               PtrQueue::byte_offset_of_index());
   40.81 +
   40.82    int satb_q_buf_byte_offset =
   40.83      in_bytes(JavaThread::satb_mark_queue_offset() +
   40.84               PtrQueue::byte_offset_of_buf());
   40.85 +
   40.86    assert(in_bytes(PtrQueue::byte_width_of_index()) == sizeof(intptr_t) &&
   40.87           in_bytes(PtrQueue::byte_width_of_buf()) == sizeof(intptr_t),
   40.88           "check sizes in assembly below");
   40.89  
   40.90    __ bind(restart);
   40.91 +
   40.92 +  // Load the index into the SATB buffer. PtrQueue::_index is a size_t
   40.93 +  // so ld_ptr is appropriate.
   40.94    __ ld_ptr(G2_thread, satb_q_index_byte_offset, L0);
   40.95  
   40.96 -  __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pn, L0, refill);
   40.97 -  // If the branch is taken, no harm in executing this in the delay slot.
   40.98 -  __ delayed()->ld_ptr(G2_thread, satb_q_buf_byte_offset, L1);
   40.99 +  // index == 0?
  40.100 +  __ cmp_and_brx_short(L0, G0, Assembler::equal, Assembler::pn, refill);
  40.101 +
  40.102 +  __ ld_ptr(G2_thread, satb_q_buf_byte_offset, L1);
  40.103    __ sub(L0, oopSize, L0);
  40.104  
  40.105    __ st_ptr(pre_val, L1, L0);  // [_buf + index] := I0
  40.106 @@ -4466,9 +4454,8 @@
  40.107           tmp);
  40.108    }
  40.109  
  40.110 -  // Check on whether to annul.
  40.111 -  br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, tmp, filtered);
  40.112 -  delayed()->nop();
  40.113 +  // Is marking active?
  40.114 +  cmp_and_br_short(tmp, G0, Assembler::equal, Assembler::pt, filtered);
  40.115  
  40.116    // Do we need to load the previous value?
  40.117    if (obj != noreg) {
  40.118 @@ -4490,9 +4477,7 @@
  40.119    assert(pre_val != noreg, "must have a real register");
  40.120  
  40.121    // Is the previous value null?
  40.122 -  // Check on whether to annul.
  40.123 -  br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, pre_val, filtered);
  40.124 -  delayed()->nop();
  40.125 +  cmp_and_brx_short(pre_val, G0, Assembler::equal, Assembler::pt, filtered);
  40.126  
  40.127    // OK, it's not filtered, so we'll need to call enqueue.  In the normal
  40.128    // case, pre_val will be a scratch G-reg, but there are some cases in
  40.129 @@ -4519,39 +4504,6 @@
  40.130    bind(filtered);
  40.131  }
  40.132  
  40.133 -static jint num_ct_writes = 0;
  40.134 -static jint num_ct_writes_filtered_in_hr = 0;
  40.135 -static jint num_ct_writes_filtered_null = 0;
  40.136 -static G1CollectedHeap* g1 = NULL;
  40.137 -
  40.138 -static Thread* count_ct_writes(void* filter_val, void* new_val) {
  40.139 -  Atomic::inc(&num_ct_writes);
  40.140 -  if (filter_val == NULL) {
  40.141 -    Atomic::inc(&num_ct_writes_filtered_in_hr);
  40.142 -  } else if (new_val == NULL) {
  40.143 -    Atomic::inc(&num_ct_writes_filtered_null);
  40.144 -  } else {
  40.145 -    if (g1 == NULL) {
  40.146 -      g1 = G1CollectedHeap::heap();
  40.147 -    }
  40.148 -  }
  40.149 -  if ((num_ct_writes % 1000000) == 0) {
  40.150 -    jint num_ct_writes_filtered =
  40.151 -      num_ct_writes_filtered_in_hr +
  40.152 -      num_ct_writes_filtered_null;
  40.153 -
  40.154 -    tty->print_cr("%d potential CT writes: %5.2f%% filtered\n"
  40.155 -                  "   (%5.2f%% intra-HR, %5.2f%% null).",
  40.156 -                  num_ct_writes,
  40.157 -                  100.0*(float)num_ct_writes_filtered/(float)num_ct_writes,
  40.158 -                  100.0*(float)num_ct_writes_filtered_in_hr/
  40.159 -                  (float)num_ct_writes,
  40.160 -                  100.0*(float)num_ct_writes_filtered_null/
  40.161 -                  (float)num_ct_writes);
  40.162 -  }
  40.163 -  return Thread::current();
  40.164 -}
  40.165 -
  40.166  static address dirty_card_log_enqueue = 0;
  40.167  static u_char* dirty_card_log_enqueue_end = 0;
  40.168  
  40.169 @@ -4574,11 +4526,8 @@
  40.170    __ set(addrlit, O1); // O1 := <card table base>
  40.171    __ ldub(O0, O1, O2); // O2 := [O0 + O1]
  40.172  
  40.173 -  __ br_on_reg_cond(Assembler::rc_nz, /*annul*/false, Assembler::pt,
  40.174 -                      O2, not_already_dirty);
  40.175 -  // Get O1 + O2 into a reg by itself -- useful in the take-the-branch
  40.176 -  // case, harmless if not.
  40.177 -  __ delayed()->add(O0, O1, O3);
  40.178 +  assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code");
  40.179 +  __ cmp_and_br_short(O2, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
  40.180  
  40.181    // We didn't take the branch, so we're already dirty: return.
  40.182    // Use return-from-leaf
  40.183 @@ -4587,8 +4536,13 @@
  40.184  
  40.185    // Not dirty.
  40.186    __ bind(not_already_dirty);
  40.187 +
  40.188 +  // Get O0 + O1 into a reg by itself
  40.189 +  __ add(O0, O1, O3);
  40.190 +
  40.191    // First, dirty it.
  40.192    __ stb(G0, O3, G0);  // [cardPtr] := 0  (i.e., dirty).
  40.193 +
  40.194    int dirty_card_q_index_byte_offset =
  40.195      in_bytes(JavaThread::dirty_card_queue_offset() +
  40.196               PtrQueue::byte_offset_of_index());
  40.197 @@ -4596,12 +4550,15 @@
  40.198      in_bytes(JavaThread::dirty_card_queue_offset() +
  40.199               PtrQueue::byte_offset_of_buf());
  40.200    __ bind(restart);
  40.201 +
  40.202 +  // Load the index into the update buffer. PtrQueue::_index is
  40.203 +  // a size_t so ld_ptr is appropriate here.
  40.204    __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, L0);
  40.205  
  40.206 -  __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pn,
  40.207 -                      L0, refill);
  40.208 -  // If the branch is taken, no harm in executing this in the delay slot.
  40.209 -  __ delayed()->ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, L1);
  40.210 +  // index == 0?
  40.211 +  __ cmp_and_brx_short(L0, G0, Assembler::equal, Assembler::pn, refill);
  40.212 +
  40.213 +  __ ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, L1);
  40.214    __ sub(L0, oopSize, L0);
  40.215  
  40.216    __ st_ptr(O3, L1, L0);  // [_buf + index] := I0
  40.217 @@ -4664,6 +4621,7 @@
  40.218    G1SATBCardTableModRefBS* bs = (G1SATBCardTableModRefBS*) Universe::heap()->barrier_set();
  40.219    assert(bs->kind() == BarrierSet::G1SATBCT ||
  40.220           bs->kind() == BarrierSet::G1SATBCTLogging, "wrong barrier");
  40.221 +
  40.222    if (G1RSBarrierRegionFilter) {
  40.223      xor3(store_addr, new_val, tmp);
  40.224  #ifdef _LP64
  40.225 @@ -4672,33 +4630,8 @@
  40.226      srl(tmp, HeapRegion::LogOfHRGrainBytes, tmp);
  40.227  #endif
  40.228  
  40.229 -    if (G1PrintCTFilterStats) {
  40.230 -      guarantee(tmp->is_global(), "Or stats won't work...");
  40.231 -      // This is a sleazy hack: I'm temporarily hijacking G2, which I
  40.232 -      // promise to restore.
  40.233 -      mov(new_val, G2);
  40.234 -      save_frame(0);
  40.235 -      mov(tmp, O0);
  40.236 -      mov(G2, O1);
  40.237 -      // Save G-regs that target may use.
  40.238 -      mov(G1, L1);
  40.239 -      mov(G2, L2);
  40.240 -      mov(G3, L3);
  40.241 -      mov(G4, L4);
  40.242 -      mov(G5, L5);
  40.243 -      call(CAST_FROM_FN_PTR(address, &count_ct_writes));
  40.244 -      delayed()->nop();
  40.245 -      mov(O0, G2);
  40.246 -      // Restore G-regs that target may have used.
  40.247 -      mov(L1, G1);
  40.248 -      mov(L3, G3);
  40.249 -      mov(L4, G4);
  40.250 -      mov(L5, G5);
  40.251 -      restore(G0, G0, G0);
  40.252 -    }
  40.253 -    // XXX Should I predict this taken or not?  Does it mattern?
  40.254 -    br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, tmp, filtered);
  40.255 -    delayed()->nop();
  40.256 +    // XXX Should I predict this taken or not?  Does it matter?
  40.257 +    cmp_and_brx_short(tmp, G0, Assembler::equal, Assembler::pt, filtered);
  40.258    }
  40.259  
  40.260    // If the "store_addr" register is an "in" or "local" register, move it to
  40.261 @@ -4723,7 +4656,6 @@
  40.262    restore();
  40.263  
  40.264    bind(filtered);
  40.265 -
  40.266  }
  40.267  
  40.268  #endif  // SERIALGC
  40.269 @@ -4973,3 +4905,65 @@
  40.270    // Caller should set it:
  40.271    // add(G0, 1, result); // equals
  40.272  }
  40.273 +
  40.274 +// Use BIS for zeroing (count is in bytes).
  40.275 +void MacroAssembler::bis_zeroing(Register to, Register count, Register temp, Label& Ldone) {
  40.276 +  assert(UseBlockZeroing && VM_Version::has_block_zeroing(), "only works with BIS zeroing");
  40.277 +  Register end = count;
  40.278 +  int cache_line_size = VM_Version::prefetch_data_size();
  40.279 +  // Minimum count when BIS zeroing can be used since
  40.280 +  // it needs membar which is expensive.
  40.281 +  int block_zero_size  = MAX2(cache_line_size*3, (int)BlockZeroingLowLimit);
  40.282 +
  40.283 +  Label small_loop;
  40.284 +  // Check if count is negative (dead code) or zero.
  40.285 +  // Note, count uses 64bit in 64 bit VM.
  40.286 +  cmp_and_brx_short(count, 0, Assembler::lessEqual, Assembler::pn, Ldone);
  40.287 +
  40.288 +  // Use BIS zeroing only for big arrays since it requires membar.
  40.289 +  if (Assembler::is_simm13(block_zero_size)) { // < 4096
  40.290 +    cmp(count, block_zero_size);
  40.291 +  } else {
  40.292 +    set(block_zero_size, temp);
  40.293 +    cmp(count, temp);
  40.294 +  }
  40.295 +  br(Assembler::lessUnsigned, false, Assembler::pt, small_loop);
  40.296 +  delayed()->add(to, count, end);
  40.297 +
  40.298 +  // Note: size is >= three (32 bytes) cache lines.
  40.299 +
  40.300 +  // Clean the beginning of space up to next cache line.
  40.301 +  for (int offs = 0; offs < cache_line_size; offs += 8) {
  40.302 +    stx(G0, to, offs);
  40.303 +  }
  40.304 +
  40.305 +  // align to next cache line
  40.306 +  add(to, cache_line_size, to);
  40.307 +  and3(to, -cache_line_size, to);
  40.308 +
  40.309 +  // Note: size left >= two (32 bytes) cache lines.
  40.310 +
  40.311 +  // BIS should not be used to zero tail (64 bytes)
  40.312 +  // to avoid zeroing a header of the following object.
  40.313 +  sub(end, (cache_line_size*2)-8, end);
  40.314 +
  40.315 +  Label bis_loop;
  40.316 +  bind(bis_loop);
  40.317 +  stxa(G0, to, G0, Assembler::ASI_ST_BLKINIT_PRIMARY);
  40.318 +  add(to, cache_line_size, to);
  40.319 +  cmp_and_brx_short(to, end, Assembler::lessUnsigned, Assembler::pt, bis_loop);
  40.320 +
  40.321 +  // BIS needs membar.
  40.322 +  membar(Assembler::StoreLoad);
  40.323 +
  40.324 +  add(end, (cache_line_size*2)-8, end); // restore end
  40.325 +  cmp_and_brx_short(to, end, Assembler::greaterEqualUnsigned, Assembler::pn, Ldone);
  40.326 +
  40.327 +  // Clean the tail.
  40.328 +  bind(small_loop);
  40.329 +  stx(G0, to, 0);
  40.330 +  add(to, 8, to);
  40.331 +  cmp_and_brx_short(to, end, Assembler::lessUnsigned, Assembler::pt, small_loop);
  40.332 +  nop(); // Separate short branches
  40.333 +}
  40.334 +
    41.1 --- a/src/cpu/sparc/vm/assembler_sparc.hpp	Thu Sep 08 16:59:27 2011 -0700
    41.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp	Fri Sep 09 16:17:16 2011 -0700
    41.3 @@ -885,8 +885,9 @@
    41.4    }
    41.5  
    41.6    enum ASIs { // page 72, v9
    41.7 -    ASI_PRIMARY        = 0x80,
    41.8 -    ASI_PRIMARY_LITTLE = 0x88,
    41.9 +    ASI_PRIMARY            = 0x80,
   41.10 +    ASI_PRIMARY_NOFAULT    = 0x82,
   41.11 +    ASI_PRIMARY_LITTLE     = 0x88,
   41.12      // Block initializing store
   41.13      ASI_ST_BLKINIT_PRIMARY = 0xE2,
   41.14      // Most-Recently-Used (MRU) BIS variant
   41.15 @@ -1786,9 +1787,12 @@
   41.16                                                                             rs1(s) |
   41.17                                                                             op3(wrreg_op3) |
   41.18                                                                             u_field(2, 29, 25) |
   41.19 -                                                                           u_field(1, 13, 13) |
   41.20 +                                                                           immed(true) |
   41.21                                                                             simm(simm13a, 13)); }
   41.22 -  inline void wrasi(  Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); }
   41.23 +  inline void wrasi(Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); }
   41.24 +  // wrasi(d, imm) stores (d xor imm) to asi
   41.25 +  inline void wrasi(Register d, int simm13a) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) |
   41.26 +                                               u_field(3, 29, 25) | immed(true) | simm(simm13a, 13)); }
   41.27    inline void wrfprs( Register d) { v9_only(); emit_long( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); }
   41.28  
   41.29  
   41.30 @@ -1940,12 +1944,6 @@
   41.31    void br_null   ( Register s1, bool a, Predict p, Label& L );
   41.32    void br_notnull( Register s1, bool a, Predict p, Label& L );
   41.33  
   41.34 -  // These versions will do the most efficient thing on v8 and v9.  Perhaps
   41.35 -  // this is what the routine above was meant to do, but it didn't (and
   41.36 -  // didn't cover both target address kinds.)
   41.37 -  void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none );
   41.38 -  void br_on_reg_cond( RCondition c, bool a, Predict p, Register s1, Label& L);
   41.39 -
   41.40    //
   41.41    // Compare registers and branch with nop in delay slot or cbcond without delay slot.
   41.42    //
   41.43 @@ -2631,6 +2629,8 @@
   41.44    void char_arrays_equals(Register ary1, Register ary2,
   41.45                            Register limit, Register result,
   41.46                            Register chr1, Register chr2, Label& Ldone);
   41.47 +  // Use BIS for zeroing
   41.48 +  void bis_zeroing(Register to, Register count, Register temp, Label& Ldone);
   41.49  
   41.50  #undef VIRTUAL
   41.51  
    42.1 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Thu Sep 08 16:59:27 2011 -0700
    42.2 +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Fri Sep 09 16:17:16 2011 -0700
    42.3 @@ -421,8 +421,7 @@
    42.4    }
    42.5  
    42.6    if (__ is_in_wdisp16_range(_continuation)) {
    42.7 -    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
    42.8 -                      pre_val_reg, _continuation);
    42.9 +    __ br_null(pre_val_reg, /*annul*/false, Assembler::pt, _continuation);
   42.10    } else {
   42.11      __ cmp(pre_val_reg, G0);
   42.12      __ brx(Assembler::equal, false, Assembler::pn, _continuation);
   42.13 @@ -458,8 +457,7 @@
   42.14      // The original src operand was not a constant.
   42.15      // Generate src == null?
   42.16      if (__ is_in_wdisp16_range(_continuation)) {
   42.17 -      __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
   42.18 -                        src_reg, _continuation);
   42.19 +      __ br_null(src_reg, /*annul*/false, Assembler::pt, _continuation);
   42.20      } else {
   42.21        __ cmp(src_reg, G0);
   42.22        __ brx(Assembler::equal, false, Assembler::pt, _continuation);
   42.23 @@ -476,13 +474,9 @@
   42.24    Address ref_type_adr(tmp_reg, instanceKlass::reference_type_offset_in_bytes() + sizeof(oopDesc));
   42.25    __ ld(ref_type_adr, tmp_reg);
   42.26  
   42.27 -  if (__ is_in_wdisp16_range(_continuation)) {
   42.28 -    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
   42.29 -                      tmp_reg, _continuation);
   42.30 -  } else {
   42.31 -    __ cmp(tmp_reg, G0);
   42.32 -    __ brx(Assembler::equal, false, Assembler::pt, _continuation);
   42.33 -  }
   42.34 +  // _reference_type field is of type ReferenceType (enum)
   42.35 +  assert(REF_NONE == 0, "check this code");
   42.36 +  __ cmp_zero_and_br(Assembler::equal, tmp_reg, _continuation, /*annul*/false, Assembler::pt);
   42.37    __ delayed()->nop();
   42.38  
   42.39    // Is marking active?
   42.40 @@ -498,13 +492,8 @@
   42.41      assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
   42.42      __ ldsb(in_progress, tmp_reg);
   42.43    }
   42.44 -  if (__ is_in_wdisp16_range(_continuation)) {
   42.45 -    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
   42.46 -                      tmp_reg, _continuation);
   42.47 -  } else {
   42.48 -    __ cmp(tmp_reg, G0);
   42.49 -    __ brx(Assembler::equal, false, Assembler::pt, _continuation);
   42.50 -  }
   42.51 +
   42.52 +  __ cmp_zero_and_br(Assembler::equal, tmp_reg, _continuation, /*annul*/false, Assembler::pt);
   42.53    __ delayed()->nop();
   42.54  
   42.55    // val == null?
   42.56 @@ -512,8 +501,7 @@
   42.57    Register val_reg = val()->as_register();
   42.58  
   42.59    if (__ is_in_wdisp16_range(_continuation)) {
   42.60 -    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
   42.61 -                      val_reg, _continuation);
   42.62 +    __ br_null(val_reg, /*annul*/false, Assembler::pt, _continuation);
   42.63    } else {
   42.64      __ cmp(val_reg, G0);
   42.65      __ brx(Assembler::equal, false, Assembler::pt, _continuation);
   42.66 @@ -542,9 +530,9 @@
   42.67    assert(new_val()->is_register(), "Precondition.");
   42.68    Register addr_reg = addr()->as_pointer_register();
   42.69    Register new_val_reg = new_val()->as_register();
   42.70 +
   42.71    if (__ is_in_wdisp16_range(_continuation)) {
   42.72 -    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
   42.73 -                      new_val_reg, _continuation);
   42.74 +    __ br_null(new_val_reg, /*annul*/false, Assembler::pt, _continuation);
   42.75    } else {
   42.76      __ cmp(new_val_reg, G0);
   42.77      __ brx(Assembler::equal, false, Assembler::pn, _continuation);
    43.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Thu Sep 08 16:59:27 2011 -0700
    43.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Fri Sep 09 16:17:16 2011 -0700
    43.3 @@ -142,11 +142,6 @@
    43.4  }
    43.5  
    43.6  
    43.7 -LIR_Opr LIR_Assembler::incomingReceiverOpr() {
    43.8 -  return FrameMap::I0_oop_opr;
    43.9 -}
   43.10 -
   43.11 -
   43.12  LIR_Opr LIR_Assembler::osrBufferPointer() {
   43.13    return FrameMap::I0_opr;
   43.14  }
    44.1 --- a/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Thu Sep 08 16:59:27 2011 -0700
    44.2 +++ b/src/cpu/sparc/vm/c1_Runtime1_sparc.cpp	Fri Sep 09 16:17:16 2011 -0700
    44.3 @@ -782,13 +782,6 @@
    44.4        }
    44.5        break;
    44.6  
    44.7 -    case jvmti_exception_throw_id:
    44.8 -      { // Oexception : exception
    44.9 -        __ set_info("jvmti_exception_throw", dont_gc_arguments);
   44.10 -        oop_maps = generate_stub_call(sasm, noreg, CAST_FROM_FN_PTR(address, Runtime1::post_jvmti_exception_throw), I0);
   44.11 -      }
   44.12 -      break;
   44.13 -
   44.14      case dtrace_object_alloc_id:
   44.15        { // O0: object
   44.16          __ set_info("dtrace_object_alloc", dont_gc_arguments);
   44.17 @@ -834,14 +827,16 @@
   44.18          int satb_q_buf_byte_offset =
   44.19            in_bytes(JavaThread::satb_mark_queue_offset() +
   44.20                     PtrQueue::byte_offset_of_buf());
   44.21 +
   44.22          __ bind(restart);
   44.23 +        // Load the index into the SATB buffer. PtrQueue::_index is a
   44.24 +        // size_t so ld_ptr is appropriate
   44.25          __ ld_ptr(G2_thread, satb_q_index_byte_offset, tmp);
   44.26  
   44.27 -        __ br_on_reg_cond(Assembler::rc_z, /*annul*/false,
   44.28 -                          Assembler::pn, tmp, refill);
   44.29 +        // index == 0?
   44.30 +        __ cmp_and_brx_short(tmp, G0, Assembler::equal, Assembler::pn, refill);
   44.31  
   44.32 -        // If the branch is taken, no harm in executing this in the delay slot.
   44.33 -        __ delayed()->ld_ptr(G2_thread, satb_q_buf_byte_offset, tmp2);
   44.34 +        __ ld_ptr(G2_thread, satb_q_buf_byte_offset, tmp2);
   44.35          __ sub(tmp, oopSize, tmp);
   44.36  
   44.37          __ st_ptr(pre_val, tmp2, tmp);  // [_buf + index] := <address_of_card>
   44.38 @@ -901,11 +896,8 @@
   44.39          __ set(rs, cardtable);         // cardtable := <card table base>
   44.40          __ ldub(addr, cardtable, tmp); // tmp := [addr + cardtable]
   44.41  
   44.42 -        __ br_on_reg_cond(Assembler::rc_nz, /*annul*/false, Assembler::pt,
   44.43 -                          tmp, not_already_dirty);
   44.44 -        // Get cardtable + tmp into a reg by itself -- useful in the take-the-branch
   44.45 -        // case, harmless if not.
   44.46 -        __ delayed()->add(addr, cardtable, tmp2);
   44.47 +        assert(CardTableModRefBS::dirty_card_val() == 0, "otherwise check this code");
   44.48 +        __ cmp_and_br_short(tmp, G0, Assembler::notEqual, Assembler::pt, not_already_dirty);
   44.49  
   44.50          // We didn't take the branch, so we're already dirty: return.
   44.51          // Use return-from-leaf
   44.52 @@ -914,6 +906,10 @@
   44.53  
   44.54          // Not dirty.
   44.55          __ bind(not_already_dirty);
   44.56 +
   44.57 +        // Get cardtable + tmp into a reg by itself
   44.58 +        __ add(addr, cardtable, tmp2);
   44.59 +
   44.60          // First, dirty it.
   44.61          __ stb(G0, tmp2, 0);  // [cardPtr] := 0  (i.e., dirty).
   44.62  
   44.63 @@ -929,13 +925,17 @@
   44.64          int dirty_card_q_buf_byte_offset =
   44.65            in_bytes(JavaThread::dirty_card_queue_offset() +
   44.66                     PtrQueue::byte_offset_of_buf());
   44.67 +
   44.68          __ bind(restart);
   44.69 +
   44.70 +        // Get the index into the update buffer. PtrQueue::_index is
   44.71 +        // a size_t so ld_ptr is appropriate here.
   44.72          __ ld_ptr(G2_thread, dirty_card_q_index_byte_offset, tmp3);
   44.73  
   44.74 -        __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pn,
   44.75 -                          tmp3, refill);
   44.76 -        // If the branch is taken, no harm in executing this in the delay slot.
   44.77 -        __ delayed()->ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, tmp4);
   44.78 +        // index == 0?
   44.79 +        __ cmp_and_brx_short(tmp3, G0, Assembler::equal,  Assembler::pn, refill);
   44.80 +
   44.81 +        __ ld_ptr(G2_thread, dirty_card_q_buf_byte_offset, tmp4);
   44.82          __ sub(tmp3, oopSize, tmp3);
   44.83  
   44.84          __ st_ptr(tmp2, tmp4, tmp3);  // [_buf + index] := <address_of_card>
    45.1 --- a/src/cpu/sparc/vm/copy_sparc.hpp	Thu Sep 08 16:59:27 2011 -0700
    45.2 +++ b/src/cpu/sparc/vm/copy_sparc.hpp	Fri Sep 09 16:17:16 2011 -0700
    45.3 @@ -156,9 +156,16 @@
    45.4  #endif // _LP64
    45.5  }
    45.6  
    45.7 +typedef void (*_zero_Fn)(HeapWord* to, size_t count);
    45.8 +
    45.9  static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
   45.10    assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
   45.11  
   45.12 +  if (value == 0 && UseBlockZeroing &&
   45.13 +      (count > (BlockZeroingLowLimit >> LogHeapWordSize))) {
   45.14 +   // Call it only when block zeroing is used
   45.15 +   ((_zero_Fn)StubRoutines::zero_aligned_words())(tohw, count);
   45.16 +  } else {
   45.17     julong* to = (julong*)tohw;
   45.18     julong  v  = ((julong)value << 32) | value;
   45.19     // If count is odd, odd will be equal to 1 on 32-bit platform
   45.20 @@ -176,6 +183,7 @@
   45.21       *((juint*)to) = value;
   45.22  
   45.23     }
   45.24 +  }
   45.25  }
   45.26  
   45.27  static void pd_fill_to_bytes(void* to, size_t count, jubyte value) {
    46.1 --- a/src/cpu/sparc/vm/frame_sparc.hpp	Thu Sep 08 16:59:27 2011 -0700
    46.2 +++ b/src/cpu/sparc/vm/frame_sparc.hpp	Fri Sep 09 16:17:16 2011 -0700
    46.3 @@ -259,13 +259,8 @@
    46.4    };
    46.5  #endif /* CC_INTERP */
    46.6  
    46.7 -  // the compiler frame has many of the same fields as the interpreter frame
    46.8 -  // %%%%% factor out declarations of the shared fields
    46.9    enum compiler_frame_fixed_locals {
   46.10 -       compiler_frame_d_scratch_fp_offset          = -2,
   46.11 -       compiler_frame_vm_locals_fp_offset          = -2, // should be same as above
   46.12 -
   46.13 -       compiler_frame_vm_local_words = -compiler_frame_vm_locals_fp_offset
   46.14 +       compiler_frame_vm_locals_fp_offset          = -2
   46.15    };
   46.16  
   46.17   private:
   46.18 @@ -283,9 +278,6 @@
   46.19  
   46.20    inline void interpreter_frame_set_tos_address(intptr_t* x);
   46.21  
   46.22 -
   46.23 -  // %%%%% Another idea: instead of defining 3 fns per item, just define one returning a ref
   46.24 -
   46.25    // monitors:
   46.26  
   46.27    // next two fns read and write Lmonitors value,
   46.28 @@ -298,22 +290,8 @@
   46.29      return ((interpreterState)sp_at(interpreter_state_ptr_offset));
   46.30    }
   46.31  
   46.32 -
   46.33  #endif /* CC_INTERP */
   46.34  
   46.35 -
   46.36 -
   46.37 - // Compiled frames
   46.38 -
   46.39   public:
   46.40 -  // Tells if this register can hold 64 bits on V9 (really, V8+).
   46.41 -  static bool holds_a_doubleword(Register reg) {
   46.42 -#ifdef _LP64
   46.43 -    //    return true;
   46.44 -    return reg->is_out() || reg->is_global();
   46.45 -#else
   46.46 -    return reg->is_out() || reg->is_global();
   46.47 -#endif
   46.48 -  }
   46.49  
   46.50  #endif // CPU_SPARC_VM_FRAME_SPARC_HPP
    47.1 --- a/src/cpu/sparc/vm/methodHandles_sparc.cpp	Thu Sep 08 16:59:27 2011 -0700
    47.2 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp	Fri Sep 09 16:17:16 2011 -0700
    47.3 @@ -1262,6 +1262,15 @@
    47.4      }
    47.5      break;
    47.6  
    47.7 +  case _adapter_opt_profiling:
    47.8 +    if (java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes() != 0) {
    47.9 +      Address G3_mh_vmcount(G3_method_handle, java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes());
   47.10 +      __ ld(G3_mh_vmcount, O1_scratch);
   47.11 +      __ add(O1_scratch, 1, O1_scratch);
   47.12 +      __ st(O1_scratch, G3_mh_vmcount);
   47.13 +    }
   47.14 +    // fall through
   47.15 +
   47.16    case _adapter_retype_only:
   47.17    case _adapter_retype_raw:
   47.18      // Immediately jump to the next MH layer:
    48.1 --- a/src/cpu/sparc/vm/sparc.ad	Thu Sep 08 16:59:27 2011 -0700
    48.2 +++ b/src/cpu/sparc/vm/sparc.ad	Fri Sep 09 16:17:16 2011 -0700
    48.3 @@ -460,6 +460,8 @@
    48.4  // Must be visible to the DFA in dfa_sparc.cpp
    48.5  extern bool can_branch_register( Node *bol, Node *cmp );
    48.6  
    48.7 +extern bool use_block_zeroing(Node* count);
    48.8 +
    48.9  // Macros to extract hi & lo halves from a long pair.
   48.10  // G0 is not part of any long pair, so assert on that.
   48.11  // Prevents accidentally using G1 instead of G0.
   48.12 @@ -521,6 +523,12 @@
   48.13    return false;
   48.14  }
   48.15  
   48.16 +bool use_block_zeroing(Node* count) {
   48.17 +  // Use BIS for zeroing if count is not constant
   48.18 +  // or it is >= BlockZeroingLowLimit.
   48.19 +  return UseBlockZeroing && (count->find_intptr_t_con(BlockZeroingLowLimit) >= BlockZeroingLowLimit);
   48.20 +}
   48.21 +
   48.22  // ****************************************************************************
   48.23  
   48.24  // REQUIRED FUNCTIONALITY
   48.25 @@ -832,6 +840,7 @@
   48.26            !(n->ideal_Opcode()==Op_ConvI2D   && ld_op==Op_LoadF) &&
   48.27            !(n->ideal_Opcode()==Op_PrefetchRead  && ld_op==Op_LoadI) &&
   48.28            !(n->ideal_Opcode()==Op_PrefetchWrite && ld_op==Op_LoadI) &&
   48.29 +          !(n->ideal_Opcode()==Op_PrefetchAllocation && ld_op==Op_LoadI) &&
   48.30            !(n->ideal_Opcode()==Op_Load2I    && ld_op==Op_LoadD) &&
   48.31            !(n->ideal_Opcode()==Op_Load4C    && ld_op==Op_LoadD) &&
   48.32            !(n->ideal_Opcode()==Op_Load4S    && ld_op==Op_LoadD) &&
   48.33 @@ -2810,25 +2819,6 @@
   48.34      __ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst);
   48.35    %}
   48.36  
   48.37 -  // Compiler ensures base is doubleword aligned and cnt is count of doublewords
   48.38 -  enc_class enc_Clear_Array(iRegX cnt, iRegP base, iRegX temp) %{
   48.39 -    MacroAssembler _masm(&cbuf);
   48.40 -    Register    nof_bytes_arg   = reg_to_register_object($cnt$$reg);
   48.41 -    Register    nof_bytes_tmp    = reg_to_register_object($temp$$reg);
   48.42 -    Register    base_pointer_arg = reg_to_register_object($base$$reg);
   48.43 -  
   48.44 -    Label loop;
   48.45 -    __ mov(nof_bytes_arg, nof_bytes_tmp);
   48.46 -  
   48.47 -    // Loop and clear, walking backwards through the array.
   48.48 -    // nof_bytes_tmp (if >0) is always the number of bytes to zero
   48.49 -    __ bind(loop);
   48.50 -    __ deccc(nof_bytes_tmp, 8);
   48.51 -    __ br(Assembler::greaterEqual, true, Assembler::pt, loop);
   48.52 -    __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp);
   48.53 -    // %%%% this mini-loop must not cross a cache boundary!
   48.54 -  %}
   48.55 -
   48.56  
   48.57    enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{
   48.58      Label Ldone, Lloop;
   48.59 @@ -10257,9 +10247,9 @@
   48.60    ins_pipe(long_memory_op);
   48.61  %}
   48.62  
   48.63 -// Count and Base registers are fixed because the allocator cannot
   48.64 -// kill unknown registers.  The encodings are generic.
   48.65 +// The encodings are generic.
   48.66  instruct clear_array(iRegX cnt, iRegP base, iRegX temp, Universe dummy, flagsReg ccr) %{
   48.67 +  predicate(!use_block_zeroing(n->in(2)) );
   48.68    match(Set dummy (ClearArray cnt base));
   48.69    effect(TEMP temp, KILL ccr);
   48.70    ins_cost(300);
   48.71 @@ -10267,7 +10257,71 @@
   48.72      "loop:   SUBcc  $temp,8,$temp\t! Count down a dword of bytes\n"
   48.73      "        BRge   loop\t\t! Clearing loop\n"
   48.74      "        STX    G0,[$base+$temp]\t! delay slot" %}
   48.75 -  ins_encode( enc_Clear_Array(cnt, base, temp) );
   48.76 +
   48.77 +  ins_encode %{
   48.78 +    // Compiler ensures base is doubleword aligned and cnt is count of doublewords
   48.79 +    Register nof_bytes_arg    = $cnt$$Register;
   48.80 +    Register nof_bytes_tmp    = $temp$$Register;
   48.81 +    Register base_pointer_arg = $base$$Register;
   48.82 +
   48.83 +    Label loop;
   48.84 +    __ mov(nof_bytes_arg, nof_bytes_tmp);
   48.85 +
   48.86 +    // Loop and clear, walking backwards through the array.
   48.87 +    // nof_bytes_tmp (if >0) is always the number of bytes to zero
   48.88 +    __ bind(loop);
   48.89 +    __ deccc(nof_bytes_tmp, 8);
   48.90 +    __ br(Assembler::greaterEqual, true, Assembler::pt, loop);
   48.91 +    __ delayed()-> stx(G0, base_pointer_arg, nof_bytes_tmp);
   48.92 +    // %%%% this mini-loop must not cross a cache boundary!
   48.93 +  %}
   48.94 +  ins_pipe(long_memory_op);
   48.95 +%}
   48.96 +
   48.97 +instruct clear_array_bis(g1RegX cnt, o0RegP base, Universe dummy, flagsReg ccr) %{
   48.98 +  predicate(use_block_zeroing(n->in(2)));
   48.99 +  match(Set dummy (ClearArray cnt base));
  48.100 +  effect(USE_KILL cnt, USE_KILL base, KILL ccr);
  48.101 +  ins_cost(300);
  48.102 +  format %{ "CLEAR  [$base, $cnt]\t! ClearArray" %}
  48.103 +
  48.104 +  ins_encode %{
  48.105 +
  48.106 +    assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
  48.107 +    Register to    = $base$$Register;
  48.108 +    Register count = $cnt$$Register;
  48.109 +
  48.110 +    Label Ldone;
  48.111 +    __ nop(); // Separate short branches
  48.112 +    // Use BIS for zeroing (temp is not used).
  48.113 +    __ bis_zeroing(to, count, G0, Ldone);
  48.114 +    __ bind(Ldone);
  48.115 +
  48.116 +  %}
  48.117 +  ins_pipe(long_memory_op);
  48.118 +%}
  48.119 +
  48.120 +instruct clear_array_bis_2(g1RegX cnt, o0RegP base, iRegX tmp, Universe dummy, flagsReg ccr) %{
  48.121 +  predicate(use_block_zeroing(n->in(2)) && !Assembler::is_simm13((int)BlockZeroingLowLimit));
  48.122 +  match(Set dummy (ClearArray cnt base));
  48.123 +  effect(TEMP tmp, USE_KILL cnt, USE_KILL base, KILL ccr);
  48.124 +  ins_cost(300);
  48.125 +  format %{ "CLEAR  [$base, $cnt]\t! ClearArray" %}
  48.126 +
  48.127 +  ins_encode %{
  48.128 +
  48.129 +    assert(MinObjAlignmentInBytes >= BytesPerLong, "need alternate implementation");
  48.130 +    Register to    = $base$$Register;
  48.131 +    Register count = $cnt$$Register;
  48.132 +    Register temp  = $tmp$$Register;
  48.133 +
  48.134 +    Label Ldone;
  48.135 +    __ nop(); // Separate short branches
  48.136 +    // Use BIS for zeroing
  48.137 +    __ bis_zeroing(to, count, temp, Ldone);
  48.138 +    __ bind(Ldone);
  48.139 +
  48.140 +  %}
  48.141    ins_pipe(long_memory_op);
  48.142  %}
  48.143  
    49.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Thu Sep 08 16:59:27 2011 -0700
    49.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp	Fri Sep 09 16:17:16 2011 -0700
    49.3 @@ -1124,6 +1124,126 @@
    49.4      }
    49.5    }
    49.6  
    49.7 +  //
    49.8 +  // Generate main code for disjoint arraycopy
    49.9 +  //
   49.10 +  typedef void (StubGenerator::*CopyLoopFunc)(Register from, Register to, Register count, int count_dec,
   49.11 +                                              Label& L_loop, bool use_prefetch, bool use_bis);
   49.12 +
   49.13 +  void disjoint_copy_core(Register from, Register to, Register count, int log2_elem_size,
   49.14 +                          int iter_size, CopyLoopFunc copy_loop_func) {
   49.15 +    Label L_copy;
   49.16 +
   49.17 +    assert(log2_elem_size <= 3, "the following code should be changed");
   49.18 +    int count_dec = 16>>log2_elem_size;
   49.19 +
   49.20 +    int prefetch_dist = MAX2(ArraycopySrcPrefetchDistance, ArraycopyDstPrefetchDistance);
   49.21 +    assert(prefetch_dist < 4096, "invalid value");
   49.22 +    prefetch_dist = (prefetch_dist + (iter_size-1)) & (-iter_size); // round up to one iteration copy size
   49.23 +    int prefetch_count = (prefetch_dist >> log2_elem_size); // elements count
   49.24 +
   49.25 +    if (UseBlockCopy) {
   49.26 +      Label L_block_copy, L_block_copy_prefetch, L_skip_block_copy;
   49.27 +
   49.28 +      // 64 bytes tail + bytes copied in one loop iteration
   49.29 +      int tail_size = 64 + iter_size;
   49.30 +      int block_copy_count = (MAX2(tail_size, (int)BlockCopyLowLimit)) >> log2_elem_size;
   49.31 +      // Use BIS copy only for big arrays since it requires membar.
   49.32 +      __ set(block_copy_count, O4);
   49.33 +      __ cmp_and_br_short(count, O4, Assembler::lessUnsigned, Assembler::pt, L_skip_block_copy);
   49.34 +      // This code is for disjoint source and destination:
   49.35 +      //   to <= from || to >= from+count
   49.36 +      // but BIS will stomp over 'from' if (to > from-tail_size && to <= from)
   49.37 +      __ sub(from, to, O4);
   49.38 +      __ srax(O4, 4, O4); // divide by 16 since following short branch have only 5 bits for imm.
   49.39 +      __ cmp_and_br_short(O4, (tail_size>>4), Assembler::lessEqualUnsigned, Assembler::pn, L_skip_block_copy);
   49.40 +
   49.41 +      __ wrasi(G0, Assembler::ASI_ST_BLKINIT_PRIMARY);
   49.42 +      // BIS should not be used to copy tail (64 bytes+iter_size)
   49.43 +      // to avoid zeroing of following values.
   49.44 +      __ sub(count, (tail_size>>log2_elem_size), count); // count is still positive >= 0
   49.45 +
   49.46 +      if (prefetch_count > 0) { // rounded up to one iteration count
   49.47 +        // Do prefetching only if copy size is bigger
   49.48 +        // than prefetch distance.
   49.49 +        __ set(prefetch_count, O4);
   49.50 +        __ cmp_and_brx_short(count, O4, Assembler::less, Assembler::pt, L_block_copy);
   49.51 +        __ sub(count, prefetch_count, count);
   49.52 +
   49.53 +        (this->*copy_loop_func)(from, to, count, count_dec, L_block_copy_prefetch, true, true);
   49.54 +        __ add(count, prefetch_count, count); // restore count
   49.55 +
   49.56 +      } // prefetch_count > 0
   49.57 +
   49.58 +      (this->*copy_loop_func)(from, to, count, count_dec, L_block_copy, false, true);
   49.59 +      __ add(count, (tail_size>>log2_elem_size), count); // restore count
   49.60 +
   49.61 +      __ wrasi(G0, Assembler::ASI_PRIMARY_NOFAULT);
   49.62 +      // BIS needs membar.
   49.63 +      __ membar(Assembler::StoreLoad);
   49.64 +      // Copy tail
   49.65 +      __ ba_short(L_copy);
   49.66 +
   49.67 +      __ BIND(L_skip_block_copy);
   49.68 +    } // UseBlockCopy
   49.69 +
   49.70 +    if (prefetch_count > 0) { // rounded up to one iteration count
   49.71 +      // Do prefetching only if copy size is bigger
   49.72 +      // than prefetch distance.
   49.73 +      __ set(prefetch_count, O4);
   49.74 +      __ cmp_and_brx_short(count, O4, Assembler::lessUnsigned, Assembler::pt, L_copy);
   49.75 +      __ sub(count, prefetch_count, count);
   49.76 +
   49.77 +      Label L_copy_prefetch;
   49.78 +      (this->*copy_loop_func)(from, to, count, count_dec, L_copy_prefetch, true, false);
   49.79 +      __ add(count, prefetch_count, count); // restore count
   49.80 +
   49.81 +    } // prefetch_count > 0
   49.82 +
   49.83 +    (this->*copy_loop_func)(from, to, count, count_dec, L_copy, false, false);
   49.84 +  }
   49.85 +
   49.86 +
   49.87 +
   49.88 +  //
   49.89 +  // Helper methods for copy_16_bytes_forward_with_shift()
   49.90 +  //
   49.91 +  void copy_16_bytes_shift_loop(Register from, Register to, Register count, int count_dec,
   49.92 +                                Label& L_loop, bool use_prefetch, bool use_bis) {
   49.93 +
   49.94 +    const Register left_shift  = G1; // left  shift bit counter
   49.95 +    const Register right_shift = G5; // right shift bit counter
   49.96 +
   49.97 +    __ align(OptoLoopAlignment);
   49.98 +    __ BIND(L_loop);
   49.99 +    if (use_prefetch) {
  49.100 +      if (ArraycopySrcPrefetchDistance > 0) {
  49.101 +        __ prefetch(from, ArraycopySrcPrefetchDistance, Assembler::severalReads);
  49.102 +      }
  49.103 +      if (ArraycopyDstPrefetchDistance > 0) {
  49.104 +        __ prefetch(to, ArraycopyDstPrefetchDistance, Assembler::severalWritesAndPossiblyReads);
  49.105 +      }
  49.106 +    }
  49.107 +    __ ldx(from, 0, O4);
  49.108 +    __ ldx(from, 8, G4);
  49.109 +    __ inc(to, 16);
  49.110 +    __ inc(from, 16);
  49.111 +    __ deccc(count, count_dec); // Can we do next iteration after this one?
  49.112 +    __ srlx(O4, right_shift, G3);
  49.113 +    __ bset(G3, O3);
  49.114 +    __ sllx(O4, left_shift,  O4);
  49.115 +    __ srlx(G4, right_shift, G3);
  49.116 +    __ bset(G3, O4);
  49.117 +    if (use_bis) {
  49.118 +      __ stxa(O3, to, -16);
  49.119 +      __ stxa(O4, to, -8);
  49.120 +    } else {
  49.121 +      __ stx(O3, to, -16);
  49.122 +      __ stx(O4, to, -8);
  49.123 +    }
  49.124 +    __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
  49.125 +    __ delayed()->sllx(G4, left_shift,  O3);
  49.126 +  }
  49.127  
  49.128    // Copy big chunks forward with shift
  49.129    //
  49.130 @@ -1135,64 +1255,51 @@
  49.131    //   L_copy_bytes - copy exit label
  49.132    //
  49.133    void copy_16_bytes_forward_with_shift(Register from, Register to,
  49.134 -                     Register count, int count_dec, Label& L_copy_bytes) {
  49.135 -    Label L_loop, L_aligned_copy, L_copy_last_bytes;
  49.136 +                     Register count, int log2_elem_size, Label& L_copy_bytes) {
  49.137 +    Label L_aligned_copy, L_copy_last_bytes;
  49.138 +    assert(log2_elem_size <= 3, "the following code should be changed");
  49.139 +    int count_dec = 16>>log2_elem_size;
  49.140  
  49.141      // if both arrays have the same alignment mod 8, do 8 bytes aligned copy
  49.142 -      __ andcc(from, 7, G1); // misaligned bytes
  49.143 -      __ br(Assembler::zero, false, Assembler::pt, L_aligned_copy);
  49.144 -      __ delayed()->nop();
  49.145 +    __ andcc(from, 7, G1); // misaligned bytes
  49.146 +    __ br(Assembler::zero, false, Assembler::pt, L_aligned_copy);
  49.147 +    __ delayed()->nop();
  49.148  
  49.149      const Register left_shift  = G1; // left  shift bit counter
  49.150      const Register right_shift = G5; // right shift bit counter
  49.151  
  49.152 -      __ sll(G1, LogBitsPerByte, left_shift);
  49.153 -      __ mov(64, right_shift);
  49.154 -      __ sub(right_shift, left_shift, right_shift);
  49.155 +    __ sll(G1, LogBitsPerByte, left_shift);
  49.156 +    __ mov(64, right_shift);
  49.157 +    __ sub(right_shift, left_shift, right_shift);
  49.158  
  49.159      //
  49.160      // Load 2 aligned 8-bytes chunks and use one from previous iteration
  49.161      // to form 2 aligned 8-bytes chunks to store.
  49.162      //
  49.163 -      __ deccc(count, count_dec); // Pre-decrement 'count'
  49.164 -      __ andn(from, 7, from);     // Align address
  49.165 -      __ ldx(from, 0, O3);
  49.166 -      __ inc(from, 8);
  49.167 -      __ align(OptoLoopAlignment);
  49.168 -    __ BIND(L_loop);
  49.169 -      __ ldx(from, 0, O4);
  49.170 -      __ deccc(count, count_dec); // Can we do next iteration after this one?
  49.171 -      __ ldx(from, 8, G4);
  49.172 -      __ inc(to, 16);
  49.173 -      __ inc(from, 16);
  49.174 -      __ sllx(O3, left_shift,  O3);
  49.175 -      __ srlx(O4, right_shift, G3);
  49.176 -      __ bset(G3, O3);
  49.177 -      __ stx(O3, to, -16);
  49.178 -      __ sllx(O4, left_shift,  O4);
  49.179 -      __ srlx(G4, right_shift, G3);
  49.180 -      __ bset(G3, O4);
  49.181 -      __ stx(O4, to, -8);
  49.182 -      __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
  49.183 -      __ delayed()->mov(G4, O3);
  49.184 -
  49.185 -      __ inccc(count, count_dec>>1 ); // + 8 bytes
  49.186 -      __ brx(Assembler::negative, true, Assembler::pn, L_copy_last_bytes);
  49.187 -      __ delayed()->inc(count, count_dec>>1); // restore 'count'
  49.188 -
  49.189 -      // copy 8 bytes, part of them already loaded in O3
  49.190 -      __ ldx(from, 0, O4);
  49.191 -      __ inc(to, 8);
  49.192 -      __ inc(from, 8);
  49.193 -      __ sllx(O3, left_shift,  O3);
  49.194 -      __ srlx(O4, right_shift, G3);
  49.195 -      __ bset(O3, G3);
  49.196 -      __ stx(G3, to, -8);
  49.197 +    __ dec(count, count_dec);   // Pre-decrement 'count'
  49.198 +    __ andn(from, 7, from);     // Align address
  49.199 +    __ ldx(from, 0, O3);
  49.200 +    __ inc(from, 8);
  49.201 +    __ sllx(O3, left_shift,  O3);
  49.202 +
  49.203 +    disjoint_copy_core(from, to, count, log2_elem_size, 16, copy_16_bytes_shift_loop);
  49.204 +
  49.205 +    __ inccc(count, count_dec>>1 ); // + 8 bytes
  49.206 +    __ brx(Assembler::negative, true, Assembler::pn, L_copy_last_bytes);
  49.207 +    __ delayed()->inc(count, count_dec>>1); // restore 'count'
  49.208 +
  49.209 +    // copy 8 bytes, part of them already loaded in O3
  49.210 +    __ ldx(from, 0, O4);
  49.211 +    __ inc(to, 8);
  49.212 +    __ inc(from, 8);
  49.213 +    __ srlx(O4, right_shift, G3);
  49.214 +    __ bset(O3, G3);
  49.215 +    __ stx(G3, to, -8);
  49.216  
  49.217      __ BIND(L_copy_last_bytes);
  49.218 -      __ srl(right_shift, LogBitsPerByte, right_shift); // misaligned bytes
  49.219 -      __ br(Assembler::always, false, Assembler::pt, L_copy_bytes);
  49.220 -      __ delayed()->sub(from, right_shift, from);       // restore address
  49.221 +    __ srl(right_shift, LogBitsPerByte, right_shift); // misaligned bytes
  49.222 +    __ br(Assembler::always, false, Assembler::pt, L_copy_bytes);
  49.223 +    __ delayed()->sub(from, right_shift, from);       // restore address
  49.224  
  49.225      __ BIND(L_aligned_copy);
  49.226    }
  49.227 @@ -1348,7 +1455,7 @@
  49.228        // The compare above (count >= 23) guarantes 'count' >= 16 bytes.
  49.229        // Also jump over aligned copy after the copy with shift completed.
  49.230  
  49.231 -      copy_16_bytes_forward_with_shift(from, to, count, 16, L_copy_byte);
  49.232 +      copy_16_bytes_forward_with_shift(from, to, count, 0, L_copy_byte);
  49.233      }
  49.234  
  49.235      // Both array are 8 bytes aligned, copy 16 bytes at a time
  49.236 @@ -1576,7 +1683,7 @@
  49.237        // The compare above (count >= 11) guarantes 'count' >= 16 bytes.
  49.238        // Also jump over aligned copy after the copy with shift completed.
  49.239  
  49.240 -      copy_16_bytes_forward_with_shift(from, to, count, 8, L_copy_2_bytes);
  49.241 +      copy_16_bytes_forward_with_shift(from, to, count, 1, L_copy_2_bytes);
  49.242      }
  49.243  
  49.244      // Both array are 8 bytes aligned, copy 16 bytes at a time
  49.245 @@ -1950,6 +2057,45 @@
  49.246    }
  49.247  
  49.248    //
  49.249 +  // Helper methods for generate_disjoint_int_copy_core()
  49.250 +  //
  49.251 +  void copy_16_bytes_loop(Register from, Register to, Register count, int count_dec,
  49.252 +                          Label& L_loop, bool use_prefetch, bool use_bis) {
  49.253 +
  49.254 +    __ align(OptoLoopAlignment);
  49.255 +    __ BIND(L_loop);
  49.256 +    if (use_prefetch) {
  49.257 +      if (ArraycopySrcPrefetchDistance > 0) {
  49.258 +        __ prefetch(from, ArraycopySrcPrefetchDistance, Assembler::severalReads);
  49.259 +      }
  49.260 +      if (ArraycopyDstPrefetchDistance > 0) {
  49.261 +        __ prefetch(to, ArraycopyDstPrefetchDistance, Assembler::severalWritesAndPossiblyReads);
  49.262 +      }
  49.263 +    }
  49.264 +    __ ldx(from, 4, O4);
  49.265 +    __ ldx(from, 12, G4);
  49.266 +    __ inc(to, 16);
  49.267 +    __ inc(from, 16);
  49.268 +    __ deccc(count, 4); // Can we do next iteration after this one?
  49.269 +
  49.270 +    __ srlx(O4, 32, G3);
  49.271 +    __ bset(G3, O3);
  49.272 +    __ sllx(O4, 32, O4);
  49.273 +    __ srlx(G4, 32, G3);
  49.274 +    __ bset(G3, O4);
  49.275 +    if (use_bis) {
  49.276 +      __ stxa(O3, to, -16);
  49.277 +      __ stxa(O4, to, -8);
  49.278 +    } else {
  49.279 +      __ stx(O3, to, -16);
  49.280 +      __ stx(O4, to, -8);
  49.281 +    }
  49.282 +    __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
  49.283 +    __ delayed()->sllx(G4, 32,  O3);
  49.284 +
  49.285 +  }
  49.286 +
  49.287 +  //
  49.288    //  Generate core code for disjoint int copy (and oop copy on 32-bit).
  49.289    //  If "aligned" is true, the "from" and "to" addresses are assumed
  49.290    //  to be heapword aligned.
  49.291 @@ -1962,7 +2108,7 @@
  49.292    void generate_disjoint_int_copy_core(bool aligned) {
  49.293  
  49.294      Label L_skip_alignment, L_aligned_copy;
  49.295 -    Label L_copy_16_bytes,  L_copy_4_bytes, L_copy_4_bytes_loop, L_exit;
  49.296 +    Label L_copy_4_bytes, L_copy_4_bytes_loop, L_exit;
  49.297  
  49.298      const Register from      = O0;   // source array address
  49.299      const Register to        = O1;   // destination array address
  49.300 @@ -2013,30 +2159,16 @@
  49.301  
  49.302      // copy with shift 4 elements (16 bytes) at a time
  49.303        __ dec(count, 4);   // The cmp at the beginning guaranty count >= 4
  49.304 -
  49.305 -      __ align(OptoLoopAlignment);
  49.306 -    __ BIND(L_copy_16_bytes);
  49.307 -      __ ldx(from, 4, O4);
  49.308 -      __ deccc(count, 4); // Can we do next iteration after this one?
  49.309 -      __ ldx(from, 12, G4);
  49.310 -      __ inc(to, 16);
  49.311 -      __ inc(from, 16);
  49.312 -      __ sllx(O3, 32, O3);
  49.313 -      __ srlx(O4, 32, G3);
  49.314 -      __ bset(G3, O3);
  49.315 -      __ stx(O3, to, -16);
  49.316 -      __ sllx(O4, 32, O4);
  49.317 -      __ srlx(G4, 32, G3);
  49.318 -      __ bset(G3, O4);
  49.319 -      __ stx(O4, to, -8);
  49.320 -      __ brx(Assembler::greaterEqual, false, Assembler::pt, L_copy_16_bytes);
  49.321 -      __ delayed()->mov(G4, O3);
  49.322 +      __ sllx(O3, 32,  O3);
  49.323 +
  49.324 +      disjoint_copy_core(from, to, count, 2, 16, copy_16_bytes_loop);
  49.325  
  49.326        __ br(Assembler::always, false, Assembler::pt, L_copy_4_bytes);
  49.327        __ delayed()->inc(count, 4); // restore 'count'
  49.328  
  49.329      __ BIND(L_aligned_copy);
  49.330 -    }
  49.331 +    } // !aligned
  49.332 +
  49.333      // copy 4 elements (16 bytes) at a time
  49.334        __ and3(count, 1, G4); // Save
  49.335        __ srl(count, 1, count);
  49.336 @@ -2223,6 +2355,38 @@
  49.337    }
  49.338  
  49.339    //
  49.340 +  // Helper methods for generate_disjoint_long_copy_core()
  49.341 +  //
  49.342 +  void copy_64_bytes_loop(Register from, Register to, Register count, int count_dec,
  49.343 +                          Label& L_loop, bool use_prefetch, bool use_bis) {
  49.344 +    __ align(OptoLoopAlignment);
  49.345 +    __ BIND(L_loop);
  49.346 +    for (int off = 0; off < 64; off += 16) {
  49.347 +      if (use_prefetch && (off & 31) == 0) {
  49.348 +        if (ArraycopySrcPrefetchDistance > 0) {
  49.349 +          __ prefetch(from, ArraycopySrcPrefetchDistance, Assembler::severalReads);
  49.350 +        }
  49.351 +        if (ArraycopyDstPrefetchDistance > 0) {
  49.352 +          __ prefetch(to, ArraycopyDstPrefetchDistance, Assembler::severalWritesAndPossiblyReads);
  49.353 +        }
  49.354 +      }
  49.355 +      __ ldx(from,  off+0, O4);
  49.356 +      __ ldx(from,  off+8, O5);
  49.357 +      if (use_bis) {
  49.358 +        __ stxa(O4, to,  off+0);
  49.359 +        __ stxa(O5, to,  off+8);
  49.360 +      } else {
  49.361 +        __ stx(O4, to,  off+0);
  49.362 +        __ stx(O5, to,  off+8);
  49.363 +      }
  49.364 +    }
  49.365 +    __ deccc(count, 8);
  49.366 +    __ inc(from, 64);
  49.367 +    __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
  49.368 +    __ delayed()->inc(to, 64);
  49.369 +  }
  49.370 +
  49.371 +  //
  49.372    //  Generate core code for disjoint long copy (and oop copy on 64-bit).
  49.373    //  "aligned" is ignored, because we must make the stronger
  49.374    //  assumption that both addresses are always 64-bit aligned.
  49.375 @@ -2261,38 +2425,28 @@
  49.376      const Register offset0 = O4;  // element offset
  49.377      const Register offset8 = O5;  // next element offset
  49.378  
  49.379 -      __ deccc(count, 2);
  49.380 -      __ mov(G0, offset0);   // offset from start of arrays (0)
  49.381 -      __ brx(Assembler::negative, false, Assembler::pn, L_copy_8_bytes );
  49.382 -      __ delayed()->add(offset0, 8, offset8);
  49.383 +    __ deccc(count, 2);
  49.384 +    __ mov(G0, offset0);   // offset from start of arrays (0)
  49.385 +    __ brx(Assembler::negative, false, Assembler::pn, L_copy_8_bytes );
  49.386 +    __ delayed()->add(offset0, 8, offset8);
  49.387  
  49.388      // Copy by 64 bytes chunks
  49.389 -    Label L_copy_64_bytes;
  49.390 +
  49.391      const Register from64 = O3;  // source address
  49.392      const Register to64   = G3;  // destination address
  49.393 -      __ subcc(count, 6, O3);
  49.394 -      __ brx(Assembler::negative, false, Assembler::pt, L_copy_16_bytes );
  49.395 -      __ delayed()->mov(to,   to64);
  49.396 -      // Now we can use O4(offset0), O5(offset8) as temps
  49.397 -      __ mov(O3, count);
  49.398 -      __ mov(from, from64);
  49.399 -
  49.400 -      __ align(OptoLoopAlignment);
  49.401 -    __ BIND(L_copy_64_bytes);
  49.402 -      for( int off = 0; off < 64; off += 16 ) {
  49.403 -        __ ldx(from64,  off+0, O4);
  49.404 -        __ ldx(from64,  off+8, O5);
  49.405 -        __ stx(O4, to64,  off+0);
  49.406 -        __ stx(O5, to64,  off+8);
  49.407 -      }
  49.408 -      __ deccc(count, 8);
  49.409 -      __ inc(from64, 64);
  49.410 -      __ brx(Assembler::greaterEqual, false, Assembler::pt, L_copy_64_bytes);
  49.411 -      __ delayed()->inc(to64, 64);
  49.412 +    __ subcc(count, 6, O3);
  49.413 +    __ brx(Assembler::negative, false, Assembler::pt, L_copy_16_bytes );
  49.414 +    __ delayed()->mov(to,   to64);
  49.415 +    // Now we can use O4(offset0), O5(offset8) as temps
  49.416 +    __ mov(O3, count);
  49.417 +    // count >= 0 (original count - 8)
  49.418 +    __ mov(from, from64);
  49.419 +
  49.420 +    disjoint_copy_core(from64, to64, count, 3, 64, copy_64_bytes_loop);
  49.421  
  49.422        // Restore O4(offset0), O5(offset8)
  49.423        __ sub(from64, from, offset0);
  49.424 -      __ inccc(count, 6);
  49.425 +      __ inccc(count, 6); // restore count
  49.426        __ brx(Assembler::negative, false, Assembler::pn, L_copy_8_bytes );
  49.427        __ delayed()->add(offset0, 8, offset8);
  49.428  
  49.429 @@ -3069,6 +3223,34 @@
  49.430      return start;
  49.431    }
  49.432  
  49.433 +  //
  49.434 +  //  Generate stub for heap zeroing.
  49.435 +  //  "to" address is aligned to jlong (8 bytes).
  49.436 +  //
  49.437 +  // Arguments for generated stub:
  49.438 +  //      to:    O0
  49.439 +  //      count: O1 treated as signed (count of HeapWord)
  49.440 +  //             count could be 0
  49.441 +  //
  49.442 +  address generate_zero_aligned_words(const char* name) {
  49.443 +    __ align(CodeEntryAlignment);
  49.444 +    StubCodeMark mark(this, "StubRoutines", name);
  49.445 +    address start = __ pc();
  49.446 +
  49.447 +    const Register to    = O0;   // source array address
  49.448 +    const Register count = O1;   // HeapWords count
  49.449 +    const Register temp  = O2;   // scratch
  49.450 +
  49.451 +    Label Ldone;
  49.452 +    __ sllx(count, LogHeapWordSize, count); // to bytes count
  49.453 +    // Use BIS for zeroing
  49.454 +    __ bis_zeroing(to, count, temp, Ldone);
  49.455 +    __ bind(Ldone);
  49.456 +    __ retl();
  49.457 +    __ delayed()->nop();
  49.458 +    return start;
  49.459 +}
  49.460 +
  49.461    void generate_arraycopy_stubs() {
  49.462      address entry;
  49.463      address entry_jbyte_arraycopy;
  49.464 @@ -3195,6 +3377,10 @@
  49.465      StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
  49.466      StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
  49.467      StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
  49.468 +
  49.469 +    if (UseBlockZeroing) {
  49.470 +      StubRoutines::_zero_aligned_words = generate_zero_aligned_words("zero_aligned_words");
  49.471 +    }
  49.472    }
  49.473  
  49.474    void generate_initial() {
    50.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp	Thu Sep 08 16:59:27 2011 -0700
    50.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp	Fri Sep 09 16:17:16 2011 -0700
    50.3 @@ -3374,7 +3374,7 @@
    50.4  
    50.5    if(UseTLAB) {
    50.6      Register RoldTopValue = RallocatedObject;
    50.7 -    Register RtopAddr = G3_scratch, RtlabWasteLimitValue = G3_scratch;
    50.8 +    Register RtlabWasteLimitValue = G3_scratch;
    50.9      Register RnewTopValue = G1_scratch;
   50.10      Register RendValue = Rscratch;
   50.11      Register RfreeValue = RnewTopValue;
   50.12 @@ -3455,7 +3455,11 @@
   50.13      __ delayed()->add(RallocatedObject, sizeof(oopDesc), G3_scratch);
   50.14  
   50.15      // initialize remaining object fields
   50.16 -    { Label loop;
   50.17 +    if (UseBlockZeroing) {
   50.18 +      // Use BIS for zeroing
   50.19 +      __ bis_zeroing(G3_scratch, Roffset, G1_scratch, initialize_header);
   50.20 +    } else {
   50.21 +      Label loop;
   50.22        __ subcc(Roffset, wordSize, Roffset);
   50.23        __ bind(loop);
   50.24        //__ subcc(Roffset, wordSize, Roffset);      // executed above loop or in delay slot
    51.1 --- a/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Sep 08 16:59:27 2011 -0700
    51.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp	Fri Sep 09 16:17:16 2011 -0700
    51.3 @@ -75,6 +75,24 @@
    51.4      FLAG_SET_DEFAULT(AllocatePrefetchStyle, 1);
    51.5    }
    51.6  
    51.7 +  if (has_v9()) {
    51.8 +    assert(ArraycopySrcPrefetchDistance < 4096, "invalid value");
    51.9 +    if (ArraycopySrcPrefetchDistance >= 4096)
   51.10 +      ArraycopySrcPrefetchDistance = 4064;
   51.11 +    assert(ArraycopyDstPrefetchDistance < 4096, "invalid value");
   51.12 +    if (ArraycopyDstPrefetchDistance >= 4096)
   51.13 +      ArraycopyDstPrefetchDistance = 4064;
   51.14 +  } else {
   51.15 +    if (ArraycopySrcPrefetchDistance > 0) {
   51.16 +      warning("prefetch instructions are not available on this CPU");
   51.17 +      FLAG_SET_DEFAULT(ArraycopySrcPrefetchDistance, 0);
   51.18 +    }
   51.19 +    if (ArraycopyDstPrefetchDistance > 0) {
   51.20 +      warning("prefetch instructions are not available on this CPU");
   51.21 +      FLAG_SET_DEFAULT(ArraycopyDstPrefetchDistance, 0);
   51.22 +    }
   51.23 +  }
   51.24 +
   51.25    UseSSE = 0; // Only on x86 and x64
   51.26  
   51.27    _supports_cx8 = has_v9();
   51.28 @@ -170,6 +188,26 @@
   51.29      FLAG_SET_DEFAULT(UseCBCond, false);
   51.30    }
   51.31  
   51.32 +  assert(BlockZeroingLowLimit > 0, "invalid value");
   51.33 +  if (has_block_zeroing()) {
   51.34 +    if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
   51.35 +      FLAG_SET_DEFAULT(UseBlockZeroing, true);
   51.36 +    }
   51.37 +  } else if (UseBlockZeroing) {
   51.38 +    warning("BIS zeroing instructions are not available on this CPU");
   51.39 +    FLAG_SET_DEFAULT(UseBlockZeroing, false);
   51.40 +  }
   51.41 +
   51.42 +  assert(BlockCopyLowLimit > 0, "invalid value");
   51.43 +  if (has_block_zeroing()) { // has_blk_init() && is_T4(): core's local L2 cache
   51.44 +    if (FLAG_IS_DEFAULT(UseBlockCopy)) {
   51.45 +      FLAG_SET_DEFAULT(UseBlockCopy, true);
   51.46 +    }
   51.47 +  } else if (UseBlockCopy) {
   51.48 +    warning("BIS instructions are not available or expensive on this CPU");
   51.49 +    FLAG_SET_DEFAULT(UseBlockCopy, false);
   51.50 +  }
   51.51 +
   51.52  #ifdef COMPILER2
   51.53    // T4 and newer Sparc cpus have fast RDPC.
   51.54    if (has_fast_rdpc() && FLAG_IS_DEFAULT(UseRDPCForConstantTableBase)) {
    52.1 --- a/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Sep 08 16:59:27 2011 -0700
    52.2 +++ b/src/cpu/sparc/vm/vm_version_sparc.hpp	Fri Sep 09 16:17:16 2011 -0700
    52.3 @@ -135,8 +135,8 @@
    52.4    // T4 and newer Sparc have fast RDPC instruction.
    52.5    static bool has_fast_rdpc()           { return is_T4(); }
    52.6  
    52.7 -  // T4 and newer Sparc have Most-Recently-Used (MRU) BIS.
    52.8 -  static bool has_mru_blk_init()        { return has_blk_init() && is_T4(); }
    52.9 +  // On T4 and newer Sparc BIS to the beginning of cache line always zeros it.
   52.10 +  static bool has_block_zeroing()       { return has_blk_init() && is_T4(); }
   52.11  
   52.12    static const char* cpu_features()     { return _features_str; }
   52.13  
    53.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Thu Sep 08 16:59:27 2011 -0700
    53.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Fri Sep 09 16:17:16 2011 -0700
    53.3 @@ -129,10 +129,6 @@
    53.4    return FrameMap::receiver_opr;
    53.5  }
    53.6  
    53.7 -LIR_Opr LIR_Assembler::incomingReceiverOpr() {
    53.8 -  return receiverOpr();
    53.9 -}
   53.10 -
   53.11  LIR_Opr LIR_Assembler::osrBufferPointer() {
   53.12    return FrameMap::as_pointer_opr(receiverOpr()->as_register());
   53.13  }
   53.14 @@ -371,55 +367,6 @@
   53.15  }
   53.16  
   53.17  
   53.18 -void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_hdr, int monitor_no, Register exception) {
   53.19 -  if (exception->is_valid()) {
   53.20 -    // preserve exception
   53.21 -    // note: the monitor_exit runtime call is a leaf routine
   53.22 -    //       and cannot block => no GC can happen
   53.23 -    // The slow case (MonitorAccessStub) uses the first two stack slots
   53.24 -    // ([esp+0] and [esp+4]), therefore we store the exception at [esp+8]
   53.25 -    __ movptr (Address(rsp, 2*wordSize), exception);
   53.26 -  }
   53.27 -
   53.28 -  Register obj_reg  = obj_opr->as_register();
   53.29 -  Register lock_reg = lock_opr->as_register();
   53.30 -
   53.31 -  // setup registers (lock_reg must be rax, for lock_object)
   53.32 -  assert(obj_reg != SYNC_header && lock_reg != SYNC_header, "rax, must be available here");
   53.33 -  Register hdr = lock_reg;
   53.34 -  assert(new_hdr == SYNC_header, "wrong register");
   53.35 -  lock_reg = new_hdr;
   53.36 -  // compute pointer to BasicLock
   53.37 -  Address lock_addr = frame_map()->address_for_monitor_lock(monitor_no);
   53.38 -  __ lea(lock_reg, lock_addr);
   53.39 -  // unlock object
   53.40 -  MonitorAccessStub* slow_case = new MonitorExitStub(lock_opr, true, monitor_no);
   53.41 -  // _slow_case_stubs->append(slow_case);
   53.42 -  // temporary fix: must be created after exceptionhandler, therefore as call stub
   53.43 -  _slow_case_stubs->append(slow_case);
   53.44 -  if (UseFastLocking) {
   53.45 -    // try inlined fast unlocking first, revert to slow locking if it fails
   53.46 -    // note: lock_reg points to the displaced header since the displaced header offset is 0!
   53.47 -    assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
   53.48 -    __ unlock_object(hdr, obj_reg, lock_reg, *slow_case->entry());
   53.49 -  } else {
   53.50 -    // always do slow unlocking
   53.51 -    // note: the slow unlocking code could be inlined here, however if we use
   53.52 -    //       slow unlocking, speed doesn't matter anyway and this solution is
   53.53 -    //       simpler and requires less duplicated code - additionally, the
   53.54 -    //       slow unlocking code is the same in either case which simplifies
   53.55 -    //       debugging
   53.56 -    __ jmp(*slow_case->entry());
   53.57 -  }
   53.58 -  // done
   53.59 -  __ bind(*slow_case->continuation());
   53.60 -
   53.61 -  if (exception->is_valid()) {
   53.62 -    // restore exception
   53.63 -    __ movptr (exception, Address(rsp, 2 * wordSize));
   53.64 -  }
   53.65 -}
   53.66 -
   53.67  // This specifies the rsp decrement needed to build the frame
   53.68  int LIR_Assembler::initial_frame_size_in_bytes() {
   53.69    // if rounding, must let FrameMap know!
    54.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp	Thu Sep 08 16:59:27 2011 -0700
    54.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.hpp	Fri Sep 09 16:17:16 2011 -0700
    54.3 @@ -29,8 +29,6 @@
    54.4  
    54.5    Address::ScaleFactor array_element_size(BasicType type) const;
    54.6  
    54.7 -  void monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register new_hdr, int monitor_no, Register exception);
    54.8 -
    54.9    void arith_fpu_implementation(LIR_Code code, int left_index, int right_index, int dest_index, bool pop_fpu_stack);
   54.10  
   54.11    // helper functions which checks for overflow and sets bailout if it
    55.1 --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Thu Sep 08 16:59:27 2011 -0700
    55.2 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Sep 09 16:17:16 2011 -0700
    55.3 @@ -1465,19 +1465,6 @@
    55.4        }
    55.5        break;
    55.6  
    55.7 -    case jvmti_exception_throw_id:
    55.8 -      { // rax,: exception oop
    55.9 -        StubFrame f(sasm, "jvmti_exception_throw", dont_gc_arguments);
   55.10 -        // Preserve all registers across this potentially blocking call
   55.11 -        const int num_rt_args = 2;  // thread, exception oop
   55.12 -        OopMap* map = save_live_registers(sasm, num_rt_args);
   55.13 -        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, Runtime1::post_jvmti_exception_throw), rax);
   55.14 -        oop_maps = new OopMapSet();
   55.15 -        oop_maps->add_gc_map(call_offset, map);
   55.16 -        restore_live_registers(sasm);
   55.17 -      }
   55.18 -      break;
   55.19 -
   55.20      case dtrace_object_alloc_id:
   55.21        { // rax,: object
   55.22          StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
    56.1 --- a/src/cpu/x86/vm/methodHandles_x86.cpp	Thu Sep 08 16:59:27 2011 -0700
    56.2 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp	Fri Sep 09 16:17:16 2011 -0700
    56.3 @@ -1343,6 +1343,13 @@
    56.4      }
    56.5      break;
    56.6  
    56.7 +  case _adapter_opt_profiling:
    56.8 +    if (java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes() != 0) {
    56.9 +      Address rcx_mh_vmcount(rcx_recv, java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes());
   56.10 +      __ incrementl(rcx_mh_vmcount);
   56.11 +    }
   56.12 +    // fall through
   56.13 +
   56.14    case _adapter_retype_only:
   56.15    case _adapter_retype_raw:
   56.16      // immediately jump to the next MH layer:
    57.1 --- a/src/cpu/x86/vm/methodHandles_x86.hpp	Thu Sep 08 16:59:27 2011 -0700
    57.2 +++ b/src/cpu/x86/vm/methodHandles_x86.hpp	Fri Sep 09 16:17:16 2011 -0700
    57.3 @@ -110,6 +110,7 @@
    57.4  
    57.5  class RicochetFrame {
    57.6    friend class MethodHandles;
    57.7 +  friend class VMStructs;
    57.8  
    57.9   private:
   57.10    intptr_t* _continuation;          // what to do when control gets back here
    58.1 --- a/src/os/linux/vm/os_linux.cpp	Thu Sep 08 16:59:27 2011 -0700
    58.2 +++ b/src/os/linux/vm/os_linux.cpp	Fri Sep 09 16:17:16 2011 -0700
    58.3 @@ -125,10 +125,6 @@
    58.4  # include <inttypes.h>
    58.5  # include <sys/ioctl.h>
    58.6  
    58.7 -#ifdef AMD64
    58.8 -#include <asm/vsyscall.h>
    58.9 -#endif
   58.10 -
   58.11  #define MAX_PATH    (2 * K)
   58.12  
   58.13  // for timer info max values which include all bits
   58.14 @@ -2502,7 +2498,13 @@
   58.15    int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
   58.16    uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
   58.17                                     MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
   58.18 -  return res != (uintptr_t) MAP_FAILED;
   58.19 +  if (res != (uintptr_t) MAP_FAILED) {
   58.20 +    if (UseNUMAInterleaving) {
   58.21 +      numa_make_global(addr, size);
   58.22 +    }
   58.23 +    return true;
   58.24 +  }
   58.25 +  return false;
   58.26  }
   58.27  
   58.28  // Define MAP_HUGETLB here so we can build HotSpot on old systems.
   58.29 @@ -2523,10 +2525,20 @@
   58.30        (uintptr_t) ::mmap(addr, size, prot,
   58.31                           MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
   58.32                           -1, 0);
   58.33 -    return res != (uintptr_t) MAP_FAILED;
   58.34 -  }
   58.35 -
   58.36 -  return commit_memory(addr, size, exec);
   58.37 +    if (res != (uintptr_t) MAP_FAILED) {
   58.38 +      if (UseNUMAInterleaving) {
   58.39 +        numa_make_global(addr, size);
   58.40 +      }
   58.41 +      return true;
   58.42 +    }
   58.43 +    // Fall through and try to use small pages
   58.44 +  }
   58.45 +
   58.46 +  if (commit_memory(addr, size, exec)) {
   58.47 +    realign_memory(addr, size, alignment_hint);
   58.48 +    return true;
   58.49 +  }
   58.50 +  return false;
   58.51  }
   58.52  
   58.53  void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
   58.54 @@ -2588,8 +2600,17 @@
   58.55    int retval = -1;
   58.56  
   58.57  #if defined(IA32)
   58.58 +# ifndef SYS_getcpu
   58.59 +# define SYS_getcpu 318
   58.60 +# endif
   58.61    retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
   58.62  #elif defined(AMD64)
   58.63 +// Unfortunately we have to bring all these macros here from vsyscall.h
   58.64 +// to be able to compile on old linuxes.
   58.65 +# define __NR_vgetcpu 2
   58.66 +# define VSYSCALL_START (-10UL << 20)
   58.67 +# define VSYSCALL_SIZE 1024
   58.68 +# define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr))
   58.69    typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache);
   58.70    vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu);
   58.71    retval = vgetcpu(&cpu, NULL, NULL);
   58.72 @@ -3115,6 +3136,10 @@
   58.73       return NULL;
   58.74    }
   58.75  
   58.76 +  if ((addr != NULL) && UseNUMAInterleaving) {
   58.77 +    numa_make_global(addr, bytes);
   58.78 +  }
   58.79 +
   58.80    return addr;
   58.81  }
   58.82  
    59.1 --- a/src/os/solaris/vm/os_solaris.cpp	Thu Sep 08 16:59:27 2011 -0700
    59.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Fri Sep 09 16:17:16 2011 -0700
    59.3 @@ -2777,8 +2777,14 @@
    59.4  bool os::commit_memory(char* addr, size_t bytes, bool exec) {
    59.5    int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
    59.6    size_t size = bytes;
    59.7 -  return
    59.8 -     NULL != Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
    59.9 +  char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
   59.10 +  if (res != NULL) {
   59.11 +    if (UseNUMAInterleaving) {
   59.12 +      numa_make_global(addr, bytes);
   59.13 +    }
   59.14 +    return true;
   59.15 +  }
   59.16 +  return false;
   59.17  }
   59.18  
   59.19  bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint,
   59.20 @@ -3389,12 +3395,11 @@
   59.21    return true;
   59.22  }
   59.23  
   59.24 -char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
   59.25 +char* os::reserve_memory_special(size_t size, char* addr, bool exec) {
   59.26    // "exec" is passed in but not used.  Creating the shared image for
   59.27    // the code cache doesn't have an SHM_X executable permission to check.
   59.28    assert(UseLargePages && UseISM, "only for ISM large pages");
   59.29  
   59.30 -  size_t size = bytes;
   59.31    char* retAddr = NULL;
   59.32    int shmid;
   59.33    key_t ismKey;
   59.34 @@ -3436,7 +3441,9 @@
   59.35      }
   59.36      return NULL;
   59.37    }
   59.38 -
   59.39 +  if ((retAddr != NULL) && UseNUMAInterleaving) {
   59.40 +    numa_make_global(retAddr, size);
   59.41 +  }
   59.42    return retAddr;
   59.43  }
   59.44  
    60.1 --- a/src/os/windows/vm/os_windows.cpp	Thu Sep 08 16:59:27 2011 -0700
    60.2 +++ b/src/os/windows/vm/os_windows.cpp	Fri Sep 09 16:17:16 2011 -0700
    60.3 @@ -2614,6 +2614,57 @@
    60.4  static HANDLE    _hProcess;
    60.5  static HANDLE    _hToken;
    60.6  
    60.7 +// Container for NUMA node list info
    60.8 +class NUMANodeListHolder {
    60.9 +private:
   60.10 +  int *_numa_used_node_list;  // allocated below
   60.11 +  int _numa_used_node_count;
   60.12 +
   60.13 +  void free_node_list() {
   60.14 +    if (_numa_used_node_list != NULL) {
   60.15 +      FREE_C_HEAP_ARRAY(int, _numa_used_node_list);
   60.16 +    }
   60.17 +  }
   60.18 +
   60.19 +public:
   60.20 +  NUMANodeListHolder() {
   60.21 +    _numa_used_node_count = 0;
   60.22 +    _numa_used_node_list = NULL;
   60.23 +    // do rest of initialization in build routine (after function pointers are set up)
   60.24 +  }
   60.25 +
   60.26 +  ~NUMANodeListHolder() {
   60.27 +    free_node_list();
   60.28 +  }
   60.29 +
   60.30 +  bool build() {
   60.31 +    DWORD_PTR proc_aff_mask;
   60.32 +    DWORD_PTR sys_aff_mask;
   60.33 +    if (!GetProcessAffinityMask(GetCurrentProcess(), &proc_aff_mask, &sys_aff_mask)) return false;
   60.34 +    ULONG highest_node_number;
   60.35 +    if (!os::Kernel32Dll::GetNumaHighestNodeNumber(&highest_node_number)) return false;
   60.36 +    free_node_list();
   60.37 +    _numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number);
   60.38 +    for (unsigned int i = 0; i <= highest_node_number; i++) {
   60.39 +      ULONGLONG proc_mask_numa_node;
   60.40 +      if (!os::Kernel32Dll::GetNumaNodeProcessorMask(i, &proc_mask_numa_node)) return false;
   60.41 +      if ((proc_aff_mask & proc_mask_numa_node)!=0) {
   60.42 +        _numa_used_node_list[_numa_used_node_count++] = i;
   60.43 +      }
   60.44 +    }
   60.45 +    return (_numa_used_node_count > 1);
   60.46 +  }
   60.47 +
   60.48 +  int get_count() {return _numa_used_node_count;}
   60.49 +  int get_node_list_entry(int n) {
   60.50 +    // for indexes out of range, returns -1
   60.51 +    return (n < _numa_used_node_count ? _numa_used_node_list[n] : -1);
   60.52 +  }
   60.53 +
   60.54 +} numa_node_list_holder;
   60.55 +
   60.56 +
   60.57 +
   60.58  static size_t _large_page_size = 0;
   60.59  
   60.60  static bool resolve_functions_for_large_page_init() {
   60.61 @@ -2653,6 +2704,153 @@
   60.62    _hToken = NULL;
   60.63  }
   60.64  
   60.65 +static bool numa_interleaving_init() {
   60.66 +  bool success = false;
   60.67 +  bool use_numa_interleaving_specified = !FLAG_IS_DEFAULT(UseNUMAInterleaving);
   60.68 +
   60.69 +  // print a warning if UseNUMAInterleaving flag is specified on command line
   60.70 +  bool warn_on_failure = use_numa_interleaving_specified;
   60.71 +# define WARN(msg) if (warn_on_failure) { warning(msg); }
   60.72 +
   60.73 +  // NUMAInterleaveGranularity cannot be less than vm_allocation_granularity (or _large_page_size if using large pages)
   60.74 +  size_t min_interleave_granularity = UseLargePages ? _large_page_size : os::vm_allocation_granularity();
   60.75 +  NUMAInterleaveGranularity = align_size_up(NUMAInterleaveGranularity, min_interleave_granularity);
   60.76 +
   60.77 +  if (os::Kernel32Dll::NumaCallsAvailable()) {
   60.78 +    if (numa_node_list_holder.build()) {
   60.79 +      if (PrintMiscellaneous && Verbose) {
   60.80 +        tty->print("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());
   60.81 +        for (int i = 0; i < numa_node_list_holder.get_count(); i++) {
   60.82 +          tty->print("%d ", numa_node_list_holder.get_node_list_entry(i));
   60.83 +        }
   60.84 +        tty->print("\n");
   60.85 +      }
   60.86 +      success = true;
   60.87 +    } else {
   60.88 +      WARN("Process does not cover multiple NUMA nodes.");
   60.89 +    }
   60.90 +  } else {
   60.91 +    WARN("NUMA Interleaving is not supported by the operating system.");
   60.92 +  }
   60.93 +  if (!success) {
   60.94 +    if (use_numa_interleaving_specified) WARN("...Ignoring UseNUMAInterleaving flag.");
   60.95 +  }
   60.96 +  return success;
   60.97 +#undef WARN
   60.98 +}
   60.99 +
  60.100 +// this routine is used whenever we need to reserve a contiguous VA range
  60.101 +// but we need to make separate VirtualAlloc calls for each piece of the range
  60.102 +// Reasons for doing this:
  60.103 +//  * UseLargePagesIndividualAllocation was set (normally only needed on WS2003 but possible to be set otherwise)
  60.104 +//  * UseNUMAInterleaving requires a separate node for each piece
  60.105 +static char* allocate_pages_individually(size_t bytes, char* addr, DWORD flags, DWORD prot,
  60.106 +                                         bool should_inject_error=false) {
  60.107 +  char * p_buf;
  60.108 +  // note: at setup time we guaranteed that NUMAInterleaveGranularity was aligned up to a page size
  60.109 +  size_t page_size = UseLargePages ? _large_page_size : os::vm_allocation_granularity();
  60.110 +  size_t chunk_size = UseNUMAInterleaving ? NUMAInterleaveGranularity : page_size;
  60.111 +
  60.112 +  // first reserve enough address space in advance since we want to be
  60.113 +  // able to break a single contiguous virtual address range into multiple
  60.114 +  // large page commits but WS2003 does not allow reserving large page space
  60.115 +  // so we just use 4K pages for reserve, this gives us a legal contiguous
  60.116 +  // address space. then we will deallocate that reservation, and re alloc
  60.117 +  // using large pages
  60.118 +  const size_t size_of_reserve = bytes + chunk_size;
  60.119 +  if (bytes > size_of_reserve) {
  60.120 +    // Overflowed.
  60.121 +    return NULL;
  60.122 +  }
  60.123 +  p_buf = (char *) VirtualAlloc(addr,
  60.124 +                                size_of_reserve,  // size of Reserve
  60.125 +                                MEM_RESERVE,
  60.126 +                                PAGE_READWRITE);
  60.127 +  // If reservation failed, return NULL
  60.128 +  if (p_buf == NULL) return NULL;
  60.129 +
  60.130 +  os::release_memory(p_buf, bytes + chunk_size);
  60.131 +
  60.132 +  // we still need to round up to a page boundary (in case we are using large pages)
  60.133 +  // but not to a chunk boundary (in case InterleavingGranularity doesn't align with page size)
  60.134 +  // instead we handle this in the bytes_to_rq computation below
  60.135 +  p_buf = (char *) align_size_up((size_t)p_buf, page_size);
  60.136 +
  60.137 +  // now go through and allocate one chunk at a time until all bytes are
  60.138 +  // allocated
  60.139 +  size_t  bytes_remaining = bytes;
  60.140 +  // An overflow of align_size_up() would have been caught above
  60.141 +  // in the calculation of size_of_reserve.
  60.142 +  char * next_alloc_addr = p_buf;
  60.143 +  HANDLE hProc = GetCurrentProcess();
  60.144 +
  60.145 +#ifdef ASSERT
  60.146 +  // Variable for the failure injection
  60.147 +  long ran_num = os::random();
  60.148 +  size_t fail_after = ran_num % bytes;
  60.149 +#endif
  60.150 +
  60.151 +  int count=0;
  60.152 +  while (bytes_remaining) {
  60.153 +    // select bytes_to_rq to get to the next chunk_size boundary
  60.154 +
  60.155 +    size_t bytes_to_rq = MIN2(bytes_remaining, chunk_size - ((size_t)next_alloc_addr % chunk_size));
  60.156 +    // Note allocate and commit
  60.157 +    char * p_new;
  60.158 +
  60.159 +#ifdef ASSERT
  60.160 +    bool inject_error_now = should_inject_error && (bytes_remaining <= fail_after);
  60.161 +#else
  60.162 +    const bool inject_error_now = false;
  60.163 +#endif
  60.164 +
  60.165 +    if (inject_error_now) {
  60.166 +      p_new = NULL;
  60.167 +    } else {
  60.168 +      if (!UseNUMAInterleaving) {
  60.169 +        p_new = (char *) VirtualAlloc(next_alloc_addr,
  60.170 +                                      bytes_to_rq,
  60.171 +                                      flags,
  60.172 +                                      prot);
  60.173 +      } else {
  60.174 +        // get the next node to use from the used_node_list
  60.175 +        assert(numa_node_list_holder.get_count() > 0, "Multiple NUMA nodes expected");
  60.176 +        DWORD node = numa_node_list_holder.get_node_list_entry(count % numa_node_list_holder.get_count());
  60.177 +        p_new = (char *)os::Kernel32Dll::VirtualAllocExNuma(hProc,
  60.178 +                                                            next_alloc_addr,
  60.179 +                                                            bytes_to_rq,
  60.180 +                                                            flags,
  60.181 +                                                            prot,
  60.182 +                                                            node);
  60.183 +      }
  60.184 +    }
  60.185 +
  60.186 +    if (p_new == NULL) {
  60.187 +      // Free any allocated pages
  60.188 +      if (next_alloc_addr > p_buf) {
  60.189 +        // Some memory was committed so release it.
  60.190 +        size_t bytes_to_release = bytes - bytes_remaining;
  60.191 +        os::release_memory(p_buf, bytes_to_release);
  60.192 +      }
  60.193 +#ifdef ASSERT
  60.194 +      if (should_inject_error) {
  60.195 +        if (TracePageSizes && Verbose) {
  60.196 +          tty->print_cr("Reserving pages individually failed.");
  60.197 +        }
  60.198 +      }
  60.199 +#endif
  60.200 +      return NULL;
  60.201 +    }
  60.202 +    bytes_remaining -= bytes_to_rq;
  60.203 +    next_alloc_addr += bytes_to_rq;
  60.204 +    count++;
  60.205 +  }
  60.206 +  // made it this far, success
  60.207 +  return p_buf;
  60.208 +}
  60.209 +
  60.210 +
  60.211 +
  60.212  void os::large_page_init() {
  60.213    if (!UseLargePages) return;
  60.214  
  60.215 @@ -2722,9 +2920,30 @@
  60.216    assert((size_t)addr % os::vm_allocation_granularity() == 0,
  60.217           "reserve alignment");
  60.218    assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
  60.219 -  char* res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
  60.220 +  char* res;
  60.221 +  // note that if UseLargePages is on, all the areas that require interleaving
  60.222 +  // will go thru reserve_memory_special rather than thru here.
  60.223 +  bool use_individual = (UseNUMAInterleaving && !UseLargePages);
  60.224 +  if (!use_individual) {
  60.225 +    res = (char*)VirtualAlloc(addr, bytes, MEM_RESERVE, PAGE_READWRITE);
  60.226 +  } else {
  60.227 +    elapsedTimer reserveTimer;
  60.228 +    if( Verbose && PrintMiscellaneous ) reserveTimer.start();
  60.229 +    // in numa interleaving, we have to allocate pages individually
  60.230 +    // (well really chunks of NUMAInterleaveGranularity size)
  60.231 +    res = allocate_pages_individually(bytes, addr, MEM_RESERVE, PAGE_READWRITE);
  60.232 +    if (res == NULL) {
  60.233 +      warning("NUMA page allocation failed");
  60.234 +    }
  60.235 +    if( Verbose && PrintMiscellaneous ) {
  60.236 +      reserveTimer.stop();
  60.237 +      tty->print_cr("reserve_memory of %Ix bytes took %ld ms (%ld ticks)", bytes,
  60.238 +                    reserveTimer.milliseconds(), reserveTimer.ticks());
  60.239 +    }
  60.240 +  }
  60.241    assert(res == NULL || addr == NULL || addr == res,
  60.242           "Unexpected address from reserve.");
  60.243 +
  60.244    return res;
  60.245  }
  60.246  
  60.247 @@ -2754,92 +2973,27 @@
  60.248  char* os::reserve_memory_special(size_t bytes, char* addr, bool exec) {
  60.249  
  60.250    const DWORD prot = exec ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
  60.251 -
  60.252 -  if (UseLargePagesIndividualAllocation) {
  60.253 +  const DWORD flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
  60.254 +
  60.255 +  // with large pages, there are two cases where we need to use Individual Allocation
  60.256 +  // 1) the UseLargePagesIndividualAllocation flag is set (set by default on WS2003)
  60.257 +  // 2) NUMA Interleaving is enabled, in which case we use a different node for each page
  60.258 +  if (UseLargePagesIndividualAllocation || UseNUMAInterleaving) {
  60.259      if (TracePageSizes && Verbose) {
  60.260         tty->print_cr("Reserving large pages individually.");
  60.261      }
  60.262 -    char * p_buf;
  60.263 -    // first reserve enough address space in advance since we want to be
  60.264 -    // able to break a single contiguous virtual address range into multiple
  60.265 -    // large page commits but WS2003 does not allow reserving large page space
  60.266 -    // so we just use 4K pages for reserve, this gives us a legal contiguous
  60.267 -    // address space. then we will deallocate that reservation, and re alloc
  60.268 -    // using large pages
  60.269 -    const size_t size_of_reserve = bytes + _large_page_size;
  60.270 -    if (bytes > size_of_reserve) {
  60.271 -      // Overflowed.
  60.272 -      warning("Individually allocated large pages failed, "
  60.273 -        "use -XX:-UseLargePagesIndividualAllocation to turn off");
  60.274 +    char * p_buf = allocate_pages_individually(bytes, addr, flags, prot, LargePagesIndividualAllocationInjectError);
  60.275 +    if (p_buf == NULL) {
  60.276 +      // give an appropriate warning message
  60.277 +      if (UseNUMAInterleaving) {
  60.278 +        warning("NUMA large page allocation failed, UseLargePages flag ignored");
  60.279 +      }
  60.280 +      if (UseLargePagesIndividualAllocation) {
  60.281 +        warning("Individually allocated large pages failed, "
  60.282 +                "use -XX:-UseLargePagesIndividualAllocation to turn off");
  60.283 +      }
  60.284        return NULL;
  60.285      }
  60.286 -    p_buf = (char *) VirtualAlloc(addr,
  60.287 -                                 size_of_reserve,  // size of Reserve
  60.288 -                                 MEM_RESERVE,
  60.289 -                                 PAGE_READWRITE);
  60.290 -    // If reservation failed, return NULL
  60.291 -    if (p_buf == NULL) return NULL;
  60.292 -
  60.293 -    release_memory(p_buf, bytes + _large_page_size);
  60.294 -    // round up to page boundary.  If the size_of_reserve did not
  60.295 -    // overflow and the reservation did not fail, this align up
  60.296 -    // should not overflow.
  60.297 -    p_buf = (char *) align_size_up((size_t)p_buf, _large_page_size);
  60.298 -
  60.299 -    // now go through and allocate one page at a time until all bytes are
  60.300 -    // allocated
  60.301 -    size_t  bytes_remaining = align_size_up(bytes, _large_page_size);
  60.302 -    // An overflow of align_size_up() would have been caught above
  60.303 -    // in the calculation of size_of_reserve.
  60.304 -    char * next_alloc_addr = p_buf;
  60.305 -
  60.306 -#ifdef ASSERT
  60.307 -    // Variable for the failure injection
  60.308 -    long ran_num = os::random();
  60.309 -    size_t fail_after = ran_num % bytes;
  60.310 -#endif
  60.311 -
  60.312 -    while (bytes_remaining) {
  60.313 -      size_t bytes_to_rq = MIN2(bytes_remaining, _large_page_size);
  60.314 -      // Note allocate and commit
  60.315 -      char * p_new;
  60.316 -
  60.317 -#ifdef ASSERT
  60.318 -      bool inject_error = LargePagesIndividualAllocationInjectError &&
  60.319 -          (bytes_remaining <= fail_after);
  60.320 -#else
  60.321 -      const bool inject_error = false;
  60.322 -#endif
  60.323 -
  60.324 -      if (inject_error) {
  60.325 -        p_new = NULL;
  60.326 -      } else {
  60.327 -        p_new = (char *) VirtualAlloc(next_alloc_addr,
  60.328 -                                    bytes_to_rq,
  60.329 -                                    MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES,
  60.330 -                                    prot);
  60.331 -      }
  60.332 -
  60.333 -      if (p_new == NULL) {
  60.334 -        // Free any allocated pages
  60.335 -        if (next_alloc_addr > p_buf) {
  60.336 -          // Some memory was committed so release it.
  60.337 -          size_t bytes_to_release = bytes - bytes_remaining;
  60.338 -          release_memory(p_buf, bytes_to_release);
  60.339 -        }
  60.340 -#ifdef ASSERT
  60.341 -        if (UseLargePagesIndividualAllocation &&
  60.342 -            LargePagesIndividualAllocationInjectError) {
  60.343 -          if (TracePageSizes && Verbose) {
  60.344 -             tty->print_cr("Reserving large pages individually failed.");
  60.345 -          }
  60.346 -        }
  60.347 -#endif
  60.348 -        return NULL;
  60.349 -      }
  60.350 -      bytes_remaining -= bytes_to_rq;
  60.351 -      next_alloc_addr += bytes_to_rq;
  60.352 -    }
  60.353  
  60.354      return p_buf;
  60.355  
  60.356 @@ -2867,14 +3021,43 @@
  60.357    assert(bytes % os::vm_page_size() == 0, "commit in page-sized chunks");
  60.358    // Don't attempt to print anything if the OS call fails. We're
  60.359    // probably low on resources, so the print itself may cause crashes.
  60.360 -  bool result = VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) != 0;
  60.361 -  if (result != NULL && exec) {
  60.362 -    DWORD oldprot;
  60.363 -    // Windows doc says to use VirtualProtect to get execute permissions
  60.364 -    return VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot) != 0;
  60.365 +
  60.366 +  // unless we have NUMAInterleaving enabled, the range of a commit
  60.367 +  // is always within a reserve covered by a single VirtualAlloc
  60.368 +  // in that case we can just do a single commit for the requested size
  60.369 +  if (!UseNUMAInterleaving) {
  60.370 +    if (VirtualAlloc(addr, bytes, MEM_COMMIT, PAGE_READWRITE) == NULL) return false;
  60.371 +    if (exec) {
  60.372 +      DWORD oldprot;
  60.373 +      // Windows doc says to use VirtualProtect to get execute permissions
  60.374 +      if (!VirtualProtect(addr, bytes, PAGE_EXECUTE_READWRITE, &oldprot)) return false;
  60.375 +    }
  60.376 +    return true;
  60.377    } else {
  60.378 -    return result;
  60.379 -  }
  60.380 +
  60.381 +    // when NUMAInterleaving is enabled, the commit might cover a range that
  60.382 +    // came from multiple VirtualAlloc reserves (using allocate_pages_individually).
  60.383 +    // VirtualQuery can help us determine that.  The RegionSize that VirtualQuery
  60.384 +    // returns represents the number of bytes that can be committed in one step.
  60.385 +    size_t bytes_remaining = bytes;
  60.386 +    char * next_alloc_addr = addr;
  60.387 +    while (bytes_remaining > 0) {
  60.388 +      MEMORY_BASIC_INFORMATION alloc_info;
  60.389 +      VirtualQuery(next_alloc_addr, &alloc_info, sizeof(alloc_info));
  60.390 +      size_t bytes_to_rq = MIN2(bytes_remaining, (size_t)alloc_info.RegionSize);
  60.391 +      if (VirtualAlloc(next_alloc_addr, bytes_to_rq, MEM_COMMIT, PAGE_READWRITE) == NULL)
  60.392 +        return false;
  60.393 +      if (exec) {
  60.394 +        DWORD oldprot;
  60.395 +        if (!VirtualProtect(next_alloc_addr, bytes_to_rq, PAGE_EXECUTE_READWRITE, &oldprot))
  60.396 +          return false;
  60.397 +      }
  60.398 +      bytes_remaining -= bytes_to_rq;
  60.399 +      next_alloc_addr += bytes_to_rq;
  60.400 +    }
  60.401 +  }
  60.402 +  // if we made it this far, return true
  60.403 +  return true;
  60.404  }
  60.405  
  60.406  bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
  60.407 @@ -2948,14 +3131,21 @@
  60.408  void os::numa_make_global(char *addr, size_t bytes)    { }
  60.409  void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
  60.410  bool os::numa_topology_changed()                       { return false; }
  60.411 -size_t os::numa_get_groups_num()                       { return 1; }
  60.412 +size_t os::numa_get_groups_num()                       { return MAX2(numa_node_list_holder.get_count(), 1); }
  60.413  int os::numa_get_group_id()                            { return 0; }
  60.414  size_t os::numa_get_leaf_groups(int *ids, size_t size) {
  60.415 -  if (size > 0) {
  60.416 +  if (numa_node_list_holder.get_count() == 0 && size > 0) {
  60.417 +    // Provide an answer for UMA systems
  60.418      ids[0] = 0;
  60.419      return 1;
  60.420 -  }
  60.421 -  return 0;
  60.422 +  } else {
  60.423 +    // check for size bigger than actual groups_num
  60.424 +    size = MIN2(size, numa_get_groups_num());
  60.425 +    for (int i = 0; i < (int)size; i++) {
  60.426 +      ids[i] = numa_node_list_holder.get_node_list_entry(i);
  60.427 +    }
  60.428 +    return size;
  60.429 +  }
  60.430  }
  60.431  
  60.432  bool os::get_page_info(char *start, page_info* info) {
  60.433 @@ -3480,7 +3670,7 @@
  60.434      if(Verbose && PrintMiscellaneous)
  60.435        tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
  60.436  #endif
  60.437 -}
  60.438 +  }
  60.439  
  60.440    os::large_page_init();
  60.441  
  60.442 @@ -3584,7 +3774,13 @@
  60.443    prio_init();
  60.444  
  60.445    if (UseNUMA && !ForceNUMA) {
  60.446 -    UseNUMA = false; // Currently unsupported.
  60.447 +    UseNUMA = false; // We don't fully support this yet
  60.448 +  }
  60.449 +
  60.450 +  if (UseNUMAInterleaving) {
  60.451 +    // first check whether this Windows OS supports VirtualAllocExNuma, if not ignore this flag
  60.452 +    bool success = numa_interleaving_init();
  60.453 +    if (!success) UseNUMAInterleaving = false;
  60.454    }
  60.455  
  60.456    return JNI_OK;
  60.457 @@ -4758,7 +4954,14 @@
  60.458  
  60.459  // Kernel32 API
  60.460  typedef SIZE_T (WINAPI* GetLargePageMinimum_Fn)(void);
  60.461 +typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
  60.462 +typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG);
  60.463 +typedef BOOL (WINAPI *GetNumaNodeProcessorMask_Fn) (UCHAR, PULONGLONG);
  60.464 +
  60.465  GetLargePageMinimum_Fn      os::Kernel32Dll::_GetLargePageMinimum = NULL;
  60.466 +VirtualAllocExNuma_Fn       os::Kernel32Dll::_VirtualAllocExNuma = NULL;
  60.467 +GetNumaHighestNodeNumber_Fn os::Kernel32Dll::_GetNumaHighestNodeNumber = NULL;
  60.468 +GetNumaNodeProcessorMask_Fn os::Kernel32Dll::_GetNumaNodeProcessorMask = NULL;
  60.469  BOOL                        os::Kernel32Dll::initialized = FALSE;
  60.470  SIZE_T os::Kernel32Dll::GetLargePageMinimum() {
  60.471    assert(initialized && _GetLargePageMinimum != NULL,
  60.472 @@ -4773,19 +4976,56 @@
  60.473    return _GetLargePageMinimum != NULL;
  60.474  }
  60.475  
  60.476 -
  60.477 -#ifndef JDK6_OR_EARLIER
  60.478 -
  60.479 -void os::Kernel32Dll::initialize() {
  60.480 +BOOL os::Kernel32Dll::NumaCallsAvailable() {
  60.481 +  if (!initialized) {
  60.482 +    initialize();
  60.483 +  }
  60.484 +  return _VirtualAllocExNuma != NULL;
  60.485 +}
  60.486 +
  60.487 +LPVOID os::Kernel32Dll::VirtualAllocExNuma(HANDLE hProc, LPVOID addr, SIZE_T bytes, DWORD flags, DWORD prot, DWORD node) {
  60.488 +  assert(initialized && _VirtualAllocExNuma != NULL,
  60.489 +    "NUMACallsAvailable() not yet called");
  60.490 +
  60.491 +  return _VirtualAllocExNuma(hProc, addr, bytes, flags, prot, node);
  60.492 +}
  60.493 +
  60.494 +BOOL os::Kernel32Dll::GetNumaHighestNodeNumber(PULONG ptr_highest_node_number) {
  60.495 +  assert(initialized && _GetNumaHighestNodeNumber != NULL,
  60.496 +    "NUMACallsAvailable() not yet called");
  60.497 +
  60.498 +  return _GetNumaHighestNodeNumber(ptr_highest_node_number);
  60.499 +}
  60.500 +
  60.501 +BOOL os::Kernel32Dll::GetNumaNodeProcessorMask(UCHAR node, PULONGLONG proc_mask) {
  60.502 +  assert(initialized && _GetNumaNodeProcessorMask != NULL,
  60.503 +    "NUMACallsAvailable() not yet called");
  60.504 +
  60.505 +  return _GetNumaNodeProcessorMask(node, proc_mask);
  60.506 +}
  60.507 +
  60.508 +
  60.509 +void os::Kernel32Dll::initializeCommon() {
  60.510    if (!initialized) {
  60.511      HMODULE handle = ::GetModuleHandle("Kernel32.dll");
  60.512      assert(handle != NULL, "Just check");
  60.513      _GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");
  60.514 +    _VirtualAllocExNuma = (VirtualAllocExNuma_Fn)::GetProcAddress(handle, "VirtualAllocExNuma");
  60.515 +    _GetNumaHighestNodeNumber = (GetNumaHighestNodeNumber_Fn)::GetProcAddress(handle, "GetNumaHighestNodeNumber");
  60.516 +    _GetNumaNodeProcessorMask = (GetNumaNodeProcessorMask_Fn)::GetProcAddress(handle, "GetNumaNodeProcessorMask");
  60.517      initialized = TRUE;
  60.518    }
  60.519  }
  60.520  
  60.521  
  60.522 +
  60.523 +#ifndef JDK6_OR_EARLIER
  60.524 +
  60.525 +void os::Kernel32Dll::initialize() {
  60.526 +  initializeCommon();
  60.527 +}
  60.528 +
  60.529 +
  60.530  // Kernel32 API
  60.531  inline BOOL os::Kernel32Dll::SwitchToThread() {
  60.532    return ::SwitchToThread();
  60.533 @@ -4887,18 +5127,19 @@
  60.534  Module32Next_Fn             os::Kernel32Dll::_Module32Next = NULL;
  60.535  GetNativeSystemInfo_Fn      os::Kernel32Dll::_GetNativeSystemInfo = NULL;
  60.536  
  60.537 +
  60.538  void os::Kernel32Dll::initialize() {
  60.539    if (!initialized) {
  60.540      HMODULE handle = ::GetModuleHandle("Kernel32.dll");
  60.541      assert(handle != NULL, "Just check");
  60.542  
  60.543      _SwitchToThread = (SwitchToThread_Fn)::GetProcAddress(handle, "SwitchToThread");
  60.544 -    _GetLargePageMinimum = (GetLargePageMinimum_Fn)::GetProcAddress(handle, "GetLargePageMinimum");
  60.545      _CreateToolhelp32Snapshot = (CreateToolhelp32Snapshot_Fn)
  60.546        ::GetProcAddress(handle, "CreateToolhelp32Snapshot");
  60.547      _Module32First = (Module32First_Fn)::GetProcAddress(handle, "Module32First");
  60.548      _Module32Next = (Module32Next_Fn)::GetProcAddress(handle, "Module32Next");
  60.549      _GetNativeSystemInfo = (GetNativeSystemInfo_Fn)::GetProcAddress(handle, "GetNativeSystemInfo");
  60.550 +    initializeCommon();  // resolve the functions that always need resolving
  60.551  
  60.552      initialized = TRUE;
  60.553    }
  60.554 @@ -4964,6 +5205,8 @@
  60.555    _GetNativeSystemInfo(lpSystemInfo);
  60.556  }
  60.557  
  60.558 +
  60.559 +
  60.560  // PSAPI API
  60.561  
  60.562  
    61.1 --- a/src/os/windows/vm/os_windows.hpp	Thu Sep 08 16:59:27 2011 -0700
    61.2 +++ b/src/os/windows/vm/os_windows.hpp	Fri Sep 09 16:17:16 2011 -0700
    61.3 @@ -173,13 +173,25 @@
    61.4    static BOOL GetNativeSystemInfoAvailable();
    61.5    static void GetNativeSystemInfo(LPSYSTEM_INFO);
    61.6  
    61.7 +  // NUMA calls
    61.8 +  static BOOL NumaCallsAvailable();
    61.9 +  static LPVOID VirtualAllocExNuma(HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
   61.10 +  static BOOL GetNumaHighestNodeNumber(PULONG);
   61.11 +  static BOOL GetNumaNodeProcessorMask(UCHAR, PULONGLONG);
   61.12 +
   61.13  private:
   61.14    // GetLargePageMinimum available on Windows Vista/Windows Server 2003
   61.15    // and later
   61.16 +  // NUMA calls available Windows Vista/WS2008 and later
   61.17 +
   61.18    static SIZE_T (WINAPI *_GetLargePageMinimum)(void);
   61.19 +  static LPVOID (WINAPI *_VirtualAllocExNuma) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
   61.20 +  static BOOL (WINAPI *_GetNumaHighestNodeNumber) (PULONG);
   61.21 +  static BOOL (WINAPI *_GetNumaNodeProcessorMask) (UCHAR, PULONGLONG);
   61.22    static BOOL initialized;
   61.23  
   61.24    static void initialize();
   61.25 +  static void initializeCommon();
   61.26  
   61.27  #ifdef JDK6_OR_EARLIER
   61.28  private:
    62.1 --- a/src/share/vm/c1/c1_Compilation.cpp	Thu Sep 08 16:59:27 2011 -0700
    62.2 +++ b/src/share/vm/c1/c1_Compilation.cpp	Fri Sep 09 16:17:16 2011 -0700
    62.3 @@ -346,7 +346,6 @@
    62.4      implicit_exception_table(),
    62.5      compiler(),
    62.6      _env->comp_level(),
    62.7 -    true,
    62.8      has_unsafe_access()
    62.9    );
   62.10  }
    63.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Sep 08 16:59:27 2011 -0700
    63.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Fri Sep 09 16:17:16 2011 -0700
    63.3 @@ -28,8 +28,10 @@
    63.4  #include "c1/c1_Compilation.hpp"
    63.5  #include "c1/c1_GraphBuilder.hpp"
    63.6  #include "c1/c1_InstructionPrinter.hpp"
    63.7 +#include "ci/ciCallSite.hpp"
    63.8  #include "ci/ciField.hpp"
    63.9  #include "ci/ciKlass.hpp"
   63.10 +#include "ci/ciMethodHandle.hpp"
   63.11  #include "compiler/compileBroker.hpp"
   63.12  #include "interpreter/bytecode.hpp"
   63.13  #include "runtime/sharedRuntime.hpp"
   63.14 @@ -1424,7 +1426,7 @@
   63.15      // See whether this is the first return; if so, store off some
   63.16      // of the state for later examination
   63.17      if (num_returns() == 0) {
   63.18 -      set_inline_cleanup_info(_block, _last, state());
   63.19 +      set_inline_cleanup_info();
   63.20      }
   63.21  
   63.22      // The current bci() is in the wrong scope, so use the bci() of
   63.23 @@ -1582,6 +1584,8 @@
   63.24      code = Bytecodes::_invokespecial;
   63.25    }
   63.26  
   63.27 +  bool is_invokedynamic = code == Bytecodes::_invokedynamic;
   63.28 +
   63.29    // NEEDS_CLEANUP
   63.30    // I've added the target-is_loaded() test below but I don't really understand
   63.31    // how klass->is_loaded() can be true and yet target->is_loaded() is false.
   63.32 @@ -1693,26 +1697,31 @@
   63.33        && target->will_link(klass, callee_holder, code)) {
   63.34      // callee is known => check if we have static binding
   63.35      assert(target->is_loaded(), "callee must be known");
   63.36 -    if (code == Bytecodes::_invokestatic
   63.37 -     || code == Bytecodes::_invokespecial
   63.38 -     || code == Bytecodes::_invokevirtual && target->is_final_method()
   63.39 -    ) {
   63.40 -      // static binding => check if callee is ok
   63.41 -      ciMethod* inline_target = (cha_monomorphic_target != NULL)
   63.42 -                                  ? cha_monomorphic_target
   63.43 -                                  : target;
   63.44 -      bool res = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL));
   63.45 +    if (code == Bytecodes::_invokestatic  ||
   63.46 +        code == Bytecodes::_invokespecial ||
   63.47 +        code == Bytecodes::_invokevirtual && target->is_final_method() ||
   63.48 +        code == Bytecodes::_invokedynamic) {
   63.49 +      ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
   63.50 +      bool success = false;
   63.51 +      if (target->is_method_handle_invoke()) {
   63.52 +        // method handle invokes
   63.53 +        success = !is_invokedynamic ? for_method_handle_inline(target) : for_invokedynamic_inline(target);
   63.54 +      }
   63.55 +      if (!success) {
   63.56 +        // static binding => check if callee is ok
   63.57 +        success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL));
   63.58 +      }
   63.59        CHECK_BAILOUT();
   63.60  
   63.61  #ifndef PRODUCT
   63.62        // printing
   63.63 -      if (PrintInlining && !res) {
   63.64 +      if (PrintInlining && !success) {
   63.65          // if it was successfully inlined, then it was already printed.
   63.66 -        print_inline_result(inline_target, res);
   63.67 +        print_inline_result(inline_target, success);
   63.68        }
   63.69  #endif
   63.70        clear_inline_bailout();
   63.71 -      if (res) {
   63.72 +      if (success) {
   63.73          // Register dependence if JVMTI has either breakpoint
   63.74          // setting or hotswapping of methods capabilities since they may
   63.75          // cause deoptimization.
   63.76 @@ -1740,7 +1749,6 @@
   63.77      code == Bytecodes::_invokespecial   ||
   63.78      code == Bytecodes::_invokevirtual   ||
   63.79      code == Bytecodes::_invokeinterface;
   63.80 -  bool is_invokedynamic = code == Bytecodes::_invokedynamic;
   63.81    ValueType* result_type = as_ValueType(target->return_type());
   63.82  
   63.83    // We require the debug info to be the "state before" because
   63.84 @@ -3038,7 +3046,7 @@
   63.85      INLINE_BAILOUT("disallowed by CompilerOracle")
   63.86    } else if (!callee->can_be_compiled()) {
   63.87      // callee is not compilable (prob. has breakpoints)
   63.88 -    INLINE_BAILOUT("not compilable")
   63.89 +    INLINE_BAILOUT("not compilable (disabled)")
   63.90    } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) {
   63.91      // intrinsics can be native or not
   63.92      return true;
   63.93 @@ -3397,7 +3405,7 @@
   63.94  }
   63.95  
   63.96  
   63.97 -bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
   63.98 +bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, BlockBegin* cont_block) {
   63.99    assert(!callee->is_native(), "callee must not be native");
  63.100    if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
  63.101      INLINE_BAILOUT("inlining prohibited by policy");
  63.102 @@ -3430,7 +3438,7 @@
  63.103    } else {
  63.104      if (inline_level() > MaxInlineLevel                         ) INLINE_BAILOUT("too-deep inlining");
  63.105      if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
  63.106 -    if (callee->code_size() > max_inline_size()                 ) INLINE_BAILOUT("callee is too large");
  63.107 +    if (callee->code_size_for_inlining() > max_inline_size()    ) INLINE_BAILOUT("callee is too large");
  63.108  
  63.109      // don't inline throwable methods unless the inlining tree is rooted in a throwable class
  63.110      if (callee->name() == ciSymbol::object_initializer_name() &&
  63.111 @@ -3468,7 +3476,8 @@
  63.112  
  63.113    // Insert null check if necessary
  63.114    Value recv = NULL;
  63.115 -  if (code() != Bytecodes::_invokestatic) {
  63.116 +  if (code() != Bytecodes::_invokestatic &&
  63.117 +      code() != Bytecodes::_invokedynamic) {
  63.118      // note: null check must happen even if first instruction of callee does
  63.119      //       an implicit null check since the callee is in a different scope
  63.120      //       and we must make sure exception handling does the right thing
  63.121 @@ -3496,7 +3505,7 @@
  63.122    // fall-through of control flow, all return instructions of the
  63.123    // callee will need to be replaced by Goto's pointing to this
  63.124    // continuation point.
  63.125 -  BlockBegin* cont = block_at(next_bci());
  63.126 +  BlockBegin* cont = cont_block != NULL ? cont_block : block_at(next_bci());
  63.127    bool continuation_existed = true;
  63.128    if (cont == NULL) {
  63.129      cont = new BlockBegin(next_bci());
  63.130 @@ -3608,27 +3617,29 @@
  63.131    // block merging. This allows load elimination and CSE to take place
  63.132    // across multiple callee scopes if they are relatively simple, and
  63.133    // is currently essential to making inlining profitable.
  63.134 -  if (   num_returns() == 1
  63.135 -      && block() == orig_block
  63.136 -      && block() == inline_cleanup_block()) {
  63.137 -    _last = inline_cleanup_return_prev();
  63.138 -    _state = inline_cleanup_state();
  63.139 -  } else if (continuation_preds == cont->number_of_preds()) {
  63.140 -    // Inlining caused that the instructions after the invoke in the
  63.141 -    // caller are not reachable any more. So skip filling this block
  63.142 -    // with instructions!
  63.143 -    assert (cont == continuation(), "");
  63.144 -    assert(_last && _last->as_BlockEnd(), "");
  63.145 -    _skip_block = true;
  63.146 -  } else {
  63.147 -    // Resume parsing in continuation block unless it was already parsed.
  63.148 -    // Note that if we don't change _last here, iteration in
  63.149 -    // iterate_bytecodes_for_block will stop when we return.
  63.150 -    if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
  63.151 -      // add continuation to work list instead of parsing it immediately
  63.152 +  if (cont_block == NULL) {
  63.153 +    if (num_returns() == 1
  63.154 +        && block() == orig_block
  63.155 +        && block() == inline_cleanup_block()) {
  63.156 +      _last  = inline_cleanup_return_prev();
  63.157 +      _state = inline_cleanup_state();
  63.158 +    } else if (continuation_preds == cont->number_of_preds()) {
  63.159 +      // Inlining caused that the instructions after the invoke in the
  63.160 +      // caller are not reachable any more. So skip filling this block
  63.161 +      // with instructions!
  63.162 +      assert(cont == continuation(), "");
  63.163        assert(_last && _last->as_BlockEnd(), "");
  63.164 -      scope_data()->parent()->add_to_work_list(continuation());
  63.165        _skip_block = true;
  63.166 +    } else {
  63.167 +      // Resume parsing in continuation block unless it was already parsed.
  63.168 +      // Note that if we don't change _last here, iteration in
  63.169 +      // iterate_bytecodes_for_block will stop when we return.
  63.170 +      if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
  63.171 +        // add continuation to work list instead of parsing it immediately
  63.172 +        assert(_last && _last->as_BlockEnd(), "");
  63.173 +        scope_data()->parent()->add_to_work_list(continuation());
  63.174 +        _skip_block = true;
  63.175 +      }
  63.176      }
  63.177    }
  63.178  
  63.179 @@ -3645,6 +3656,114 @@
  63.180  }
  63.181  
  63.182  
  63.183 +bool GraphBuilder::for_method_handle_inline(ciMethod* callee) {
  63.184 +  assert(!callee->is_static(), "change next line");
  63.185 +  int index = state()->stack_size() - (callee->arg_size_no_receiver() + 1);
  63.186 +  Value receiver = state()->stack_at(index);
  63.187 +
  63.188 +  if (receiver->type()->is_constant()) {
  63.189 +    ciMethodHandle* method_handle = receiver->type()->as_ObjectType()->constant_value()->as_method_handle();
  63.190 +
  63.191 +    // Set the callee to have access to the class and signature in
  63.192 +    // the MethodHandleCompiler.
  63.193 +    method_handle->set_callee(callee);
  63.194 +    method_handle->set_caller(method());
  63.195 +
  63.196 +    // Get an adapter for the MethodHandle.
  63.197 +    ciMethod* method_handle_adapter = method_handle->get_method_handle_adapter();
  63.198 +    if (method_handle_adapter != NULL) {
  63.199 +      return try_inline(method_handle_adapter, /*holder_known=*/ true);
  63.200 +    }
  63.201 +  } else if (receiver->as_CheckCast()) {
  63.202 +    // Match MethodHandle.selectAlternative idiom
  63.203 +    Phi* phi = receiver->as_CheckCast()->obj()->as_Phi();
  63.204 +
  63.205 +    if (phi != NULL && phi->operand_count() == 2) {
  63.206 +      // Get the two MethodHandle inputs from the Phi.
  63.207 +      Value op1 = phi->operand_at(0);
  63.208 +      Value op2 = phi->operand_at(1);
  63.209 +      ciMethodHandle* mh1 = op1->type()->as_ObjectType()->constant_value()->as_method_handle();
  63.210 +      ciMethodHandle* mh2 = op2->type()->as_ObjectType()->constant_value()->as_method_handle();
  63.211 +
  63.212 +      // Set the callee to have access to the class and signature in
  63.213 +      // the MethodHandleCompiler.
  63.214 +      mh1->set_callee(callee);
  63.215 +      mh1->set_caller(method());
  63.216 +      mh2->set_callee(callee);
  63.217 +      mh2->set_caller(method());
  63.218 +
  63.219 +      // Get adapters for the MethodHandles.
  63.220 +      ciMethod* mh1_adapter = mh1->get_method_handle_adapter();
  63.221 +      ciMethod* mh2_adapter = mh2->get_method_handle_adapter();
  63.222 +
  63.223 +      if (mh1_adapter != NULL && mh2_adapter != NULL) {
  63.224 +        set_inline_cleanup_info();
  63.225 +
  63.226 +        // Build the If guard
  63.227 +        BlockBegin* one = new BlockBegin(next_bci());
  63.228 +        BlockBegin* two = new BlockBegin(next_bci());
  63.229 +        BlockBegin* end = new BlockBegin(next_bci());
  63.230 +        Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false));
  63.231 +        block()->set_end(iff->as_BlockEnd());
  63.232 +
  63.233 +        // Connect up the states
  63.234 +        one->merge(block()->end()->state());
  63.235 +        two->merge(block()->end()->state());
  63.236 +
  63.237 +        // Save the state for the second inlinee
  63.238 +        ValueStack* state_before = copy_state_before();
  63.239 +
  63.240 +        // Parse first adapter
  63.241 +        _last = _block = one;
  63.242 +        if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end)) {
  63.243 +          restore_inline_cleanup_info();
  63.244 +          block()->clear_end();  // remove appended iff
  63.245 +          return false;
  63.246 +        }
  63.247 +
  63.248 +        // Parse second adapter
  63.249 +        _last = _block = two;
  63.250 +        _state = state_before;
  63.251 +        if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end)) {
  63.252 +          restore_inline_cleanup_info();
  63.253 +          block()->clear_end();  // remove appended iff
  63.254 +          return false;
  63.255 +        }
  63.256 +
  63.257 +        connect_to_end(end);
  63.258 +        return true;
  63.259 +      }
  63.260 +    }
  63.261 +  }
  63.262 +  return false;
  63.263 +}
  63.264 +
  63.265 +
  63.266 +bool GraphBuilder::for_invokedynamic_inline(ciMethod* callee) {
  63.267 +  // Get the MethodHandle from the CallSite.
  63.268 +  ciCallSite*     call_site     = stream()->get_call_site();
  63.269 +  ciMethodHandle* method_handle = call_site->get_target();
  63.270 +
  63.271 +  // Set the callee to have access to the class and signature in the
  63.272 +  // MethodHandleCompiler.
  63.273 +  method_handle->set_callee(callee);
  63.274 +  method_handle->set_caller(method());
  63.275 +
  63.276 +  // Get an adapter for the MethodHandle.
  63.277 +  ciMethod* method_handle_adapter = method_handle->get_invokedynamic_adapter();
  63.278 +  if (method_handle_adapter != NULL) {
  63.279 +    if (try_inline(method_handle_adapter, /*holder_known=*/ true)) {
  63.280 +      // Add a dependence for invalidation of the optimization.
  63.281 +      if (!call_site->is_constant_call_site()) {
  63.282 +        dependency_recorder()->assert_call_site_target_value(call_site, method_handle);
  63.283 +      }
  63.284 +      return true;
  63.285 +    }
  63.286 +  }
  63.287 +  return false;
  63.288 +}
  63.289 +
  63.290 +
  63.291  void GraphBuilder::inline_bailout(const char* msg) {
  63.292    assert(msg != NULL, "inline bailout msg must exist");
  63.293    _inline_bailout_msg = msg;
    64.1 --- a/src/share/vm/c1/c1_GraphBuilder.hpp	Thu Sep 08 16:59:27 2011 -0700
    64.2 +++ b/src/share/vm/c1/c1_GraphBuilder.hpp	Fri Sep 09 16:17:16 2011 -0700
    64.3 @@ -1,5 +1,5 @@
    64.4  /*
    64.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
    64.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
    64.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    64.8   *
    64.9   * This code is free software; you can redistribute it and/or modify it
   64.10 @@ -315,9 +315,17 @@
   64.11                                 ValueStack* return_state) { scope_data()->set_inline_cleanup_info(block,
   64.12                                                                                                    return_prev,
   64.13                                                                                                    return_state); }
   64.14 +  void set_inline_cleanup_info() {
   64.15 +    set_inline_cleanup_info(_block, _last, _state);
   64.16 +  }
   64.17    BlockBegin*  inline_cleanup_block() const              { return scope_data()->inline_cleanup_block();  }
   64.18    Instruction* inline_cleanup_return_prev() const        { return scope_data()->inline_cleanup_return_prev(); }
   64.19    ValueStack*  inline_cleanup_state() const              { return scope_data()->inline_cleanup_state();  }
   64.20 +  void restore_inline_cleanup_info() {
   64.21 +    _block = inline_cleanup_block();
   64.22 +    _last  = inline_cleanup_return_prev();
   64.23 +    _state = inline_cleanup_state();
   64.24 +  }
   64.25    void incr_num_returns()                                { scope_data()->incr_num_returns();             }
   64.26    int  num_returns() const                               { return scope_data()->num_returns();           }
   64.27    intx max_inline_size() const                           { return scope_data()->max_inline_size();       }
   64.28 @@ -329,11 +337,15 @@
   64.29    void fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler = false);
   64.30  
   64.31    // inliners
   64.32 -  bool try_inline(ciMethod* callee, bool holder_known);
   64.33 +  bool try_inline(           ciMethod* callee, bool holder_known);
   64.34    bool try_inline_intrinsics(ciMethod* callee);
   64.35 -  bool try_inline_full      (ciMethod* callee, bool holder_known);
   64.36 +  bool try_inline_full(      ciMethod* callee, bool holder_known, BlockBegin* cont_block = NULL);
   64.37    bool try_inline_jsr(int jsr_dest_bci);
   64.38  
   64.39 +  // JSR 292 support
   64.40 +  bool for_method_handle_inline(ciMethod* callee);
   64.41 +  bool for_invokedynamic_inline(ciMethod* callee);
   64.42 +
   64.43    // helpers
   64.44    void inline_bailout(const char* msg);
   64.45    BlockBegin* header_block(BlockBegin* entry, BlockBegin::Flag f, ValueStack* state);
    65.1 --- a/src/share/vm/c1/c1_Instruction.cpp	Thu Sep 08 16:59:27 2011 -0700
    65.2 +++ b/src/share/vm/c1/c1_Instruction.cpp	Fri Sep 09 16:17:16 2011 -0700
    65.3 @@ -514,28 +514,17 @@
    65.4  
    65.5  void BlockBegin::set_end(BlockEnd* end) {
    65.6    assert(end != NULL, "should not reset block end to NULL");
    65.7 -  BlockEnd* old_end = _end;
    65.8 -  if (end == old_end) {
    65.9 +  if (end == _end) {
   65.10      return;
   65.11    }
   65.12 -  // Must make the predecessors/successors match up with the
   65.13 -  // BlockEnd's notion.
   65.14 -  int i, n;
   65.15 -  if (old_end != NULL) {
   65.16 -    // disconnect from the old end
   65.17 -    old_end->set_begin(NULL);
   65.18 +  clear_end();
   65.19  
   65.20 -    // disconnect this block from it's current successors
   65.21 -    for (i = 0; i < _successors.length(); i++) {
   65.22 -      _successors.at(i)->remove_predecessor(this);
   65.23 -    }
   65.24 -  }
   65.25 +  // Set the new end
   65.26    _end = end;
   65.27  
   65.28    _successors.clear();
   65.29    // Now reset successors list based on BlockEnd
   65.30 -  n = end->number_of_sux();
   65.31 -  for (i = 0; i < n; i++) {
   65.32 +  for (int i = 0; i < end->number_of_sux(); i++) {
   65.33      BlockBegin* sux = end->sux_at(i);
   65.34      _successors.append(sux);
   65.35      sux->_predecessors.append(this);
   65.36 @@ -544,6 +533,22 @@
   65.37  }
   65.38  
   65.39  
   65.40 +void BlockBegin::clear_end() {
   65.41 +  // Must make the predecessors/successors match up with the
   65.42 +  // BlockEnd's notion.
   65.43 +  if (_end != NULL) {
   65.44 +    // disconnect from the old end
   65.45 +    _end->set_begin(NULL);
   65.46 +
   65.47 +    // disconnect this block from it's current successors
   65.48 +    for (int i = 0; i < _successors.length(); i++) {
   65.49 +      _successors.at(i)->remove_predecessor(this);
   65.50 +    }
   65.51 +    _end = NULL;
   65.52 +  }
   65.53 +}
   65.54 +
   65.55 +
   65.56  void BlockBegin::disconnect_edge(BlockBegin* from, BlockBegin* to) {
   65.57    // disconnect any edges between from and to
   65.58  #ifndef PRODUCT
    66.1 --- a/src/share/vm/c1/c1_Instruction.hpp	Thu Sep 08 16:59:27 2011 -0700
    66.2 +++ b/src/share/vm/c1/c1_Instruction.hpp	Fri Sep 09 16:17:16 2011 -0700
    66.3 @@ -1601,6 +1601,7 @@
    66.4    void set_depth_first_number(int dfn)           { _depth_first_number = dfn; }
    66.5    void set_linear_scan_number(int lsn)           { _linear_scan_number = lsn; }
    66.6    void set_end(BlockEnd* end);
    66.7 +  void clear_end();
    66.8    void disconnect_from_graph();
    66.9    static void disconnect_edge(BlockBegin* from, BlockBegin* to);
   66.10    BlockBegin* insert_block_between(BlockBegin* sux);
    67.1 --- a/src/share/vm/c1/c1_LIRAssembler.cpp	Thu Sep 08 16:59:27 2011 -0700
    67.2 +++ b/src/share/vm/c1/c1_LIRAssembler.cpp	Fri Sep 09 16:17:16 2011 -0700
    67.3 @@ -121,7 +121,7 @@
    67.4  
    67.5  void LIR_Assembler::check_codespace() {
    67.6    CodeSection* cs = _masm->code_section();
    67.7 -  if (cs->remaining() < (int)(1*K)) {
    67.8 +  if (cs->remaining() < (int)(NOT_LP64(1*K)LP64_ONLY(2*K))) {
    67.9      BAILOUT("CodeBuffer overflow");
   67.10    }
   67.11  }
    68.1 --- a/src/share/vm/c1/c1_LIRAssembler.hpp	Thu Sep 08 16:59:27 2011 -0700
    68.2 +++ b/src/share/vm/c1/c1_LIRAssembler.hpp	Fri Sep 09 16:17:16 2011 -0700
    68.3 @@ -133,7 +133,6 @@
    68.4    static bool is_small_constant(LIR_Opr opr);
    68.5  
    68.6    static LIR_Opr receiverOpr();
    68.7 -  static LIR_Opr incomingReceiverOpr();
    68.8    static LIR_Opr osrBufferPointer();
    68.9  
   68.10    // stubs
    69.1 --- a/src/share/vm/c1/c1_LinearScan.cpp	Thu Sep 08 16:59:27 2011 -0700
    69.2 +++ b/src/share/vm/c1/c1_LinearScan.cpp	Fri Sep 09 16:17:16 2011 -0700
    69.3 @@ -2404,7 +2404,7 @@
    69.4        assert(!is_call_site || assigned_reg >= nof_regs || !is_caller_save(assigned_reg), "interval is in a caller-save register at a call -> register will be overwritten");
    69.5  
    69.6        VMReg name = vm_reg_for_interval(interval);
    69.7 -      map->set_oop(name);
    69.8 +      set_oop(map, name);
    69.9  
   69.10        // Spill optimization: when the stack value is guaranteed to be always correct,
   69.11        // then it must be added to the oop map even if the interval is currently in a register
   69.12 @@ -2415,7 +2415,7 @@
   69.13          assert(interval->canonical_spill_slot() >= LinearScan::nof_regs, "no spill slot assigned");
   69.14          assert(interval->assigned_reg() < LinearScan::nof_regs, "interval is on stack, so stack slot is registered twice");
   69.15  
   69.16 -        map->set_oop(frame_map()->slot_regname(interval->canonical_spill_slot() - LinearScan::nof_regs));
   69.17 +        set_oop(map, frame_map()->slot_regname(interval->canonical_spill_slot() - LinearScan::nof_regs));
   69.18        }
   69.19      }
   69.20    }
   69.21 @@ -2424,7 +2424,7 @@
   69.22    assert(info->stack() != NULL, "CodeEmitInfo must always have a stack");
   69.23    int locks_count = info->stack()->total_locks_size();
   69.24    for (int i = 0; i < locks_count; i++) {
   69.25 -    map->set_oop(frame_map()->monitor_object_regname(i));
   69.26 +    set_oop(map, frame_map()->monitor_object_regname(i));
   69.27    }
   69.28  
   69.29    return map;
    70.1 --- a/src/share/vm/c1/c1_LinearScan.hpp	Thu Sep 08 16:59:27 2011 -0700
    70.2 +++ b/src/share/vm/c1/c1_LinearScan.hpp	Fri Sep 09 16:17:16 2011 -0700
    70.3 @@ -352,6 +352,13 @@
    70.4  
    70.5    MonitorValue*  location_for_monitor_index(int monitor_index);
    70.6    LocationValue* location_for_name(int name, Location::Type loc_type);
    70.7 +  void set_oop(OopMap* map, VMReg name) {
    70.8 +    if (map->legal_vm_reg_name(name)) {
    70.9 +      map->set_oop(name);
   70.10 +    } else {
   70.11 +      bailout("illegal oopMap register name");
   70.12 +    }
   70.13 +  }
   70.14  
   70.15    int append_scope_value_for_constant(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values);
   70.16    int append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values);
    71.1 --- a/src/share/vm/c1/c1_Runtime1.cpp	Thu Sep 08 16:59:27 2011 -0700
    71.2 +++ b/src/share/vm/c1/c1_Runtime1.cpp	Fri Sep 09 16:17:16 2011 -0700
    71.3 @@ -375,14 +375,6 @@
    71.4  JRT_END
    71.5  
    71.6  
    71.7 -JRT_ENTRY(void, Runtime1::post_jvmti_exception_throw(JavaThread* thread))
    71.8 -  if (JvmtiExport::can_post_on_exceptions()) {
    71.9 -    vframeStream vfst(thread, true);
   71.10 -    address bcp = vfst.method()->bcp_from(vfst.bci());
   71.11 -    JvmtiExport::post_exception_throw(thread, vfst.method(), bcp, thread->exception_oop());
   71.12 -  }
   71.13 -JRT_END
   71.14 -
   71.15  // counter_overflow() is called from within C1-compiled methods. The enclosing method is the method
   71.16  // associated with the top activation record. The inlinee (that is possibly included in the enclosing
   71.17  // method) method oop is passed as an argument. In order to do that it is embedded in the code as
    72.1 --- a/src/share/vm/c1/c1_Runtime1.hpp	Thu Sep 08 16:59:27 2011 -0700
    72.2 +++ b/src/share/vm/c1/c1_Runtime1.hpp	Fri Sep 09 16:17:16 2011 -0700
    72.3 @@ -65,7 +65,6 @@
    72.4    stub(monitorexit_nofpu)              /* optimized version that does not preserve fpu registers */ \
    72.5    stub(access_field_patching)        \
    72.6    stub(load_klass_patching)          \
    72.7 -  stub(jvmti_exception_throw)        \
    72.8    stub(g1_pre_barrier_slow)          \
    72.9    stub(g1_post_barrier_slow)         \
   72.10    stub(fpu2long_stub)                \
   72.11 @@ -141,7 +140,6 @@
   72.12    static void unimplemented_entry   (JavaThread* thread, StubID id);
   72.13  
   72.14    static address exception_handler_for_pc(JavaThread* thread);
   72.15 -  static void post_jvmti_exception_throw(JavaThread* thread);
   72.16  
   72.17    static void throw_range_check_exception(JavaThread* thread, int index);
   72.18    static void throw_index_exception(JavaThread* thread, int index);
    73.1 --- a/src/share/vm/c1/c1_globals.hpp	Thu Sep 08 16:59:27 2011 -0700
    73.2 +++ b/src/share/vm/c1/c1_globals.hpp	Fri Sep 09 16:17:16 2011 -0700
    73.3 @@ -278,7 +278,7 @@
    73.4    product(intx, CompilationRepeat, 0,                                       \
    73.5            "Number of times to recompile method before returning result")    \
    73.6                                                                              \
    73.7 -  develop(intx, NMethodSizeLimit, (32*K)*wordSize,                          \
    73.8 +  develop(intx, NMethodSizeLimit, (64*K)*wordSize,                          \
    73.9            "Maximum size of a compiled method.")                             \
   73.10                                                                              \
   73.11    develop(bool, TraceFPUStack, false,                                       \
    74.1 --- a/src/share/vm/ci/ciCallProfile.hpp	Thu Sep 08 16:59:27 2011 -0700
    74.2 +++ b/src/share/vm/ci/ciCallProfile.hpp	Fri Sep 09 16:17:16 2011 -0700
    74.3 @@ -79,6 +79,17 @@
    74.4      assert(i < _limit, "out of Call Profile MorphismLimit");
    74.5      return _receiver[i];
    74.6    }
    74.7 +
    74.8 +  // Rescale the current profile based on the incoming scale
    74.9 +  ciCallProfile rescale(double scale) {
   74.10 +    assert(scale >= 0 && scale <= 1.0, "out of range");
   74.11 +    ciCallProfile call = *this;
   74.12 +    call._count = (int)(call._count * scale);
   74.13 +    for (int i = 0; i < _morphism; i++) {
   74.14 +      call._receiver_count[i] = (int)(call._receiver_count[i] * scale);
   74.15 +    }
   74.16 +    return call;
   74.17 +  }
   74.18  };
   74.19  
   74.20  #endif // SHARE_VM_CI_CICALLPROFILE_HPP
    75.1 --- a/src/share/vm/ci/ciConstant.hpp	Thu Sep 08 16:59:27 2011 -0700
    75.2 +++ b/src/share/vm/ci/ciConstant.hpp	Fri Sep 09 16:17:16 2011 -0700
    75.3 @@ -46,9 +46,6 @@
    75.4      ciObject* _object;
    75.5    } _value;
    75.6  
    75.7 -  // Implementation of the print method.
    75.8 -  void print_impl(outputStream* st);
    75.9 -
   75.10  public:
   75.11  
   75.12    ciConstant() {
    76.1 --- a/src/share/vm/ci/ciEnv.cpp	Thu Sep 08 16:59:27 2011 -0700
    76.2 +++ b/src/share/vm/ci/ciEnv.cpp	Fri Sep 09 16:17:16 2011 -0700
    76.3 @@ -884,19 +884,31 @@
    76.4  }
    76.5  
    76.6  // ------------------------------------------------------------------
    76.7 -// ciEnv::check_for_system_dictionary_modification
    76.8 -// Check for changes to the system dictionary during compilation
    76.9 -// class loads, evolution, breakpoints
   76.10 -void ciEnv::check_for_system_dictionary_modification(ciMethod* target) {
   76.11 +// ciEnv::validate_compile_task_dependencies
   76.12 +//
   76.13 +// Check for changes during compilation (e.g. class loads, evolution,
   76.14 +// breakpoints, call site invalidation).
   76.15 +void ciEnv::validate_compile_task_dependencies(ciMethod* target) {
   76.16    if (failing())  return;  // no need for further checks
   76.17  
   76.18 -  // Dependencies must be checked when the system dictionary changes.
   76.19 -  // If logging is enabled all violated dependences will be recorded in
   76.20 -  // the log.  In debug mode check dependencies even if the system
   76.21 -  // dictionary hasn't changed to verify that no invalid dependencies
   76.22 -  // were inserted.  Any violated dependences in this case are dumped to
   76.23 -  // the tty.
   76.24 +  // First, check non-klass dependencies as we might return early and
   76.25 +  // not check klass dependencies if the system dictionary
   76.26 +  // modification counter hasn't changed (see below).
   76.27 +  for (Dependencies::DepStream deps(dependencies()); deps.next(); ) {
   76.28 +    if (deps.is_klass_type())  continue;  // skip klass dependencies
   76.29 +    klassOop witness = deps.check_dependency();
   76.30 +    if (witness != NULL) {
   76.31 +      record_failure("invalid non-klass dependency");
   76.32 +      return;
   76.33 +    }
   76.34 +  }
   76.35  
   76.36 +  // Klass dependencies must be checked when the system dictionary
   76.37 +  // changes.  If logging is enabled all violated dependences will be
   76.38 +  // recorded in the log.  In debug mode check dependencies even if
   76.39 +  // the system dictionary hasn't changed to verify that no invalid
   76.40 +  // dependencies were inserted.  Any violated dependences in this
   76.41 +  // case are dumped to the tty.
   76.42    bool counter_changed = system_dictionary_modification_counter_changed();
   76.43    bool test_deps = counter_changed;
   76.44    DEBUG_ONLY(test_deps = true);
   76.45 @@ -904,22 +916,21 @@
   76.46  
   76.47    bool print_failures = false;
   76.48    DEBUG_ONLY(print_failures = !counter_changed);
   76.49 -
   76.50    bool keep_going = (print_failures || xtty != NULL);
   76.51 -
   76.52 -  int violated = 0;
   76.53 +  int klass_violations = 0;
   76.54  
   76.55    for (Dependencies::DepStream deps(dependencies()); deps.next(); ) {
   76.56 +    if (!deps.is_klass_type())  continue;  // skip non-klass dependencies
   76.57      klassOop witness = deps.check_dependency();
   76.58      if (witness != NULL) {
   76.59 -      ++violated;
   76.60 +      klass_violations++;
   76.61        if (print_failures)  deps.print_dependency(witness, /*verbose=*/ true);
   76.62 -      // If there's no log and we're not sanity-checking, we're done.
   76.63 -      if (!keep_going)     break;
   76.64      }
   76.65 +    // If there's no log and we're not sanity-checking, we're done.
   76.66 +    if (!keep_going)  break;
   76.67    }
   76.68  
   76.69 -  if (violated != 0) {
   76.70 +  if (klass_violations != 0) {
   76.71      assert(counter_changed, "failed dependencies, but counter didn't change");
   76.72      record_failure("concurrent class loading");
   76.73    }
   76.74 @@ -938,7 +949,6 @@
   76.75                              ImplicitExceptionTable* inc_table,
   76.76                              AbstractCompiler* compiler,
   76.77                              int comp_level,
   76.78 -                            bool has_debug_info,
   76.79                              bool has_unsafe_access) {
   76.80    VM_ENTRY_MARK;
   76.81    nmethod* nm = NULL;
   76.82 @@ -978,8 +988,8 @@
   76.83        // Encode the dependencies now, so we can check them right away.
   76.84        dependencies()->encode_content_bytes();
   76.85  
   76.86 -      // Check for {class loads, evolution, breakpoints} during compilation
   76.87 -      check_for_system_dictionary_modification(target);
   76.88 +      // Check for {class loads, evolution, breakpoints, ...} during compilation
   76.89 +      validate_compile_task_dependencies(target);
   76.90      }
   76.91  
   76.92      methodHandle method(THREAD, target->get_methodOop());
   76.93 @@ -1033,7 +1043,6 @@
   76.94          CompileBroker::handle_full_code_cache();
   76.95        }
   76.96      } else {
   76.97 -      NOT_PRODUCT(nm->set_has_debug_info(has_debug_info); )
   76.98        nm->set_has_unsafe_access(has_unsafe_access);
   76.99  
  76.100        // Record successful registration.
    77.1 --- a/src/share/vm/ci/ciEnv.hpp	Thu Sep 08 16:59:27 2011 -0700
    77.2 +++ b/src/share/vm/ci/ciEnv.hpp	Fri Sep 09 16:17:16 2011 -0700
    77.3 @@ -247,9 +247,9 @@
    77.4    // Is this thread currently in the VM state?
    77.5    static bool is_in_vm();
    77.6  
    77.7 -  // Helper routine for determining the validity of a compilation
    77.8 -  // with respect to concurrent class loading.
    77.9 -  void check_for_system_dictionary_modification(ciMethod* target);
   77.10 +  // Helper routine for determining the validity of a compilation with
   77.11 +  // respect to method dependencies (e.g. concurrent class loading).
   77.12 +  void validate_compile_task_dependencies(ciMethod* target);
   77.13  
   77.14  public:
   77.15    enum {
   77.16 @@ -317,8 +317,7 @@
   77.17                         ImplicitExceptionTable*   inc_table,
   77.18                         AbstractCompiler*         compiler,
   77.19                         int                       comp_level,
   77.20 -                       bool                      has_debug_info = true,
   77.21 -                       bool                      has_unsafe_access = false);
   77.22 +                       bool                      has_unsafe_access);
   77.23  
   77.24  
   77.25    // Access to certain well known ciObjects.
    78.1 --- a/src/share/vm/ci/ciField.hpp	Thu Sep 08 16:59:27 2011 -0700
    78.2 +++ b/src/share/vm/ci/ciField.hpp	Fri Sep 09 16:17:16 2011 -0700
    78.3 @@ -64,9 +64,6 @@
    78.4    // shared constructor code
    78.5    void initialize_from(fieldDescriptor* fd);
    78.6  
    78.7 -  // The implementation of the print method.
    78.8 -  void print_impl(outputStream* st);
    78.9 -
   78.10  public:
   78.11    ciFlags flags() { return _flags; }
   78.12  
   78.13 @@ -178,7 +175,12 @@
   78.14    bool is_volatile    () { return flags().is_volatile(); }
   78.15    bool is_transient   () { return flags().is_transient(); }
   78.16  
   78.17 -  bool is_call_site_target() { return ((holder() == CURRENT_ENV->CallSite_klass()) && (name() == ciSymbol::target_name())); }
   78.18 +  bool is_call_site_target() {
   78.19 +    ciInstanceKlass* callsite_klass = CURRENT_ENV->CallSite_klass();
   78.20 +    if (callsite_klass == NULL)
   78.21 +      return false;
   78.22 +    return (holder()->is_subclass_of(callsite_klass) && (name() == ciSymbol::target_name()));
   78.23 +  }
   78.24  
   78.25    // Debugging output
   78.26    void print();
    79.1 --- a/src/share/vm/ci/ciMethod.cpp	Thu Sep 08 16:59:27 2011 -0700
    79.2 +++ b/src/share/vm/ci/ciMethod.cpp	Fri Sep 09 16:17:16 2011 -0700
    79.3 @@ -1017,6 +1017,34 @@
    79.4  }
    79.5  
    79.6  // ------------------------------------------------------------------
    79.7 +// ciMethod::code_size_for_inlining
    79.8 +//
    79.9 +// Code size for inlining decisions.
   79.10 +//
   79.11 +// Don't fully count method handle adapters against inlining budgets:
   79.12 +// the metric we use here is the number of call sites in the adapter
   79.13 +// as they are probably the instructions which generate some code.
   79.14 +int ciMethod::code_size_for_inlining() {
   79.15 +  check_is_loaded();
   79.16 +
   79.17 +  // Method handle adapters
   79.18 +  if (is_method_handle_adapter()) {
   79.19 +    // Count call sites
   79.20 +    int call_site_count = 0;
   79.21 +    ciBytecodeStream iter(this);
   79.22 +    while (iter.next() != ciBytecodeStream::EOBC()) {
   79.23 +      if (Bytecodes::is_invoke(iter.cur_bc())) {
   79.24 +        call_site_count++;
   79.25 +      }
   79.26 +    }
   79.27 +    return call_site_count;
   79.28 +  }
   79.29 +
   79.30 +  // Normal method
   79.31 +  return code_size();
   79.32 +}
   79.33 +
   79.34 +// ------------------------------------------------------------------
   79.35  // ciMethod::instructions_size
   79.36  //
   79.37  // This is a rough metric for "fat" methods, compared before inlining
    80.1 --- a/src/share/vm/ci/ciMethod.hpp	Thu Sep 08 16:59:27 2011 -0700
    80.2 +++ b/src/share/vm/ci/ciMethod.hpp	Fri Sep 09 16:17:16 2011 -0700
    80.3 @@ -157,6 +157,9 @@
    80.4    int interpreter_invocation_count() const       { check_is_loaded(); return _interpreter_invocation_count; }
    80.5    int interpreter_throwout_count() const         { check_is_loaded(); return _interpreter_throwout_count; }
    80.6  
    80.7 +  // Code size for inlining decisions.
    80.8 +  int code_size_for_inlining();
    80.9 +
   80.10    int comp_level();
   80.11    int highest_osr_comp_level();
   80.12  
    81.1 --- a/src/share/vm/ci/ciMethodHandle.cpp	Thu Sep 08 16:59:27 2011 -0700
    81.2 +++ b/src/share/vm/ci/ciMethodHandle.cpp	Fri Sep 09 16:17:16 2011 -0700
    81.3 @@ -37,7 +37,7 @@
    81.4  // ciMethodHandle::get_adapter
    81.5  //
    81.6  // Return an adapter for this MethodHandle.
    81.7 -ciMethod* ciMethodHandle::get_adapter_impl(bool is_invokedynamic) const {
    81.8 +ciMethod* ciMethodHandle::get_adapter_impl(bool is_invokedynamic) {
    81.9    VM_ENTRY_MARK;
   81.10    Handle h(get_oop());
   81.11    methodHandle callee(_callee->get_methodOop());
   81.12 @@ -73,7 +73,7 @@
   81.13  // ciMethodHandle::get_adapter
   81.14  //
   81.15  // Return an adapter for this MethodHandle.
   81.16 -ciMethod* ciMethodHandle::get_adapter(bool is_invokedynamic) const {
   81.17 +ciMethod* ciMethodHandle::get_adapter(bool is_invokedynamic) {
   81.18    ciMethod* result = get_adapter_impl(is_invokedynamic);
   81.19    if (result) {
   81.20      // Fake up the MDO maturity.
   81.21 @@ -86,11 +86,22 @@
   81.22  }
   81.23  
   81.24  
   81.25 +#ifndef PRODUCT
   81.26  // ------------------------------------------------------------------
   81.27 -// ciMethodHandle::print_impl
   81.28 +// ciMethodHandle::print_chain_impl
   81.29  //
   81.30  // Implementation of the print method.
   81.31 -void ciMethodHandle::print_impl(outputStream* st) {
   81.32 -  st->print(" type=");
   81.33 -  get_oop()->print();
   81.34 +void ciMethodHandle::print_chain_impl(outputStream* st) {
   81.35 +  ASSERT_IN_VM;
   81.36 +  MethodHandleChain::print(get_oop());
   81.37  }
   81.38 +
   81.39 +
   81.40 +// ------------------------------------------------------------------
   81.41 +// ciMethodHandle::print_chain
   81.42 +//
   81.43 +// Implementation of the print_chain method.
   81.44 +void ciMethodHandle::print_chain(outputStream* st) {
   81.45 +  GUARDED_VM_ENTRY(print_chain_impl(st););
   81.46 +}
   81.47 +#endif
    82.1 --- a/src/share/vm/ci/ciMethodHandle.hpp	Thu Sep 08 16:59:27 2011 -0700
    82.2 +++ b/src/share/vm/ci/ciMethodHandle.hpp	Fri Sep 09 16:17:16 2011 -0700
    82.3 @@ -37,19 +37,23 @@
    82.4    ciMethod*      _callee;
    82.5    ciMethod*      _caller;
    82.6    ciCallProfile  _profile;
    82.7 +  ciMethod*      _method_handle_adapter;
    82.8 +  ciMethod*      _invokedynamic_adapter;
    82.9  
   82.10    // Return an adapter for this MethodHandle.
   82.11 -  ciMethod* get_adapter_impl(bool is_invokedynamic) const;
   82.12 -  ciMethod* get_adapter(     bool is_invokedynamic) const;
   82.13 +  ciMethod* get_adapter_impl(bool is_invokedynamic);
   82.14 +  ciMethod* get_adapter(     bool is_invokedynamic);
   82.15  
   82.16  protected:
   82.17 -  void print_impl(outputStream* st);
   82.18 +  void print_chain_impl(outputStream* st) PRODUCT_RETURN;
   82.19  
   82.20  public:
   82.21    ciMethodHandle(instanceHandle h_i) :
   82.22      ciInstance(h_i),
   82.23      _callee(NULL),
   82.24 -    _caller(NULL)
   82.25 +    _caller(NULL),
   82.26 +    _method_handle_adapter(NULL),
   82.27 +    _invokedynamic_adapter(NULL)
   82.28    {}
   82.29  
   82.30    // What kind of ciObject is this?
   82.31 @@ -60,10 +64,22 @@
   82.32    void set_call_profile(ciCallProfile profile)  { _profile = profile; }
   82.33  
   82.34    // Return an adapter for a MethodHandle call.
   82.35 -  ciMethod* get_method_handle_adapter() const { return get_adapter(false); }
   82.36 +  ciMethod* get_method_handle_adapter() {
   82.37 +    if (_method_handle_adapter == NULL) {
   82.38 +      _method_handle_adapter = get_adapter(false);
   82.39 +    }
   82.40 +    return _method_handle_adapter;
   82.41 +  }
   82.42  
   82.43    // Return an adapter for an invokedynamic call.
   82.44 -  ciMethod* get_invokedynamic_adapter() const { return get_adapter(true);  }
   82.45 +  ciMethod* get_invokedynamic_adapter() {
   82.46 +    if (_invokedynamic_adapter == NULL) {
   82.47 +      _invokedynamic_adapter = get_adapter(true);
   82.48 +    }
   82.49 +    return _invokedynamic_adapter;
   82.50 +  }
   82.51 +
   82.52 +  void print_chain(outputStream* st = tty) PRODUCT_RETURN;
   82.53  };
   82.54  
   82.55  #endif // SHARE_VM_CI_CIMETHODHANDLE_HPP
    83.1 --- a/src/share/vm/ci/ciObject.cpp	Thu Sep 08 16:59:27 2011 -0700
    83.2 +++ b/src/share/vm/ci/ciObject.cpp	Fri Sep 09 16:17:16 2011 -0700
    83.3 @@ -194,16 +194,26 @@
    83.4  // ciObject::should_be_constant()
    83.5  bool ciObject::should_be_constant() {
    83.6    if (ScavengeRootsInCode >= 2)  return true;  // force everybody to be a constant
    83.7 -  if (!JavaObjectsInPerm && !is_null_object()) {
    83.8 +  if (is_null_object()) return true;
    83.9 +
   83.10 +  ciEnv* env = CURRENT_ENV;
   83.11 +  if (!JavaObjectsInPerm) {
   83.12      // We want Strings and Classes to be embeddable by default since
   83.13      // they used to be in the perm world.  Not all Strings used to be
   83.14      // embeddable but there's no easy way to distinguish the interned
   83.15      // from the regulars ones so just treat them all that way.
   83.16 -    ciEnv* env = CURRENT_ENV;
   83.17      if (klass() == env->String_klass() || klass() == env->Class_klass()) {
   83.18        return true;
   83.19      }
   83.20    }
   83.21 +  if (EnableInvokeDynamic &&
   83.22 +      (klass()->is_subclass_of(env->MethodHandle_klass()) ||
   83.23 +       klass()->is_subclass_of(env->CallSite_klass()))) {
   83.24 +    assert(ScavengeRootsInCode >= 1, "must be");
   83.25 +    // We want to treat these aggressively.
   83.26 +    return true;
   83.27 +  }
   83.28 +
   83.29    return handle() == NULL || is_perm();
   83.30  }
   83.31  
    84.1 --- a/src/share/vm/ci/ciStreams.hpp	Thu Sep 08 16:59:27 2011 -0700
    84.2 +++ b/src/share/vm/ci/ciStreams.hpp	Fri Sep 09 16:17:16 2011 -0700
    84.3 @@ -129,7 +129,8 @@
    84.4    // Return current ByteCode and increment PC to next bytecode, skipping all
    84.5    // intermediate constants.  Returns EOBC at end.
    84.6    // Expected usage:
    84.7 -  //     while( (bc = iter.next()) != EOBC() ) { ... }
    84.8 +  //     ciBytecodeStream iter(m);
    84.9 +  //     while (iter.next() != ciBytecodeStream::EOBC()) { ... }
   84.10    Bytecodes::Code next() {
   84.11      _bc_start = _pc;                        // Capture start of bc
   84.12      if( _pc >= _end ) return EOBC();        // End-Of-Bytecodes
    85.1 --- a/src/share/vm/classfile/javaClasses.cpp	Thu Sep 08 16:59:27 2011 -0700
    85.2 +++ b/src/share/vm/classfile/javaClasses.cpp	Fri Sep 09 16:17:16 2011 -0700
    85.3 @@ -28,6 +28,7 @@
    85.4  #include "classfile/vmSymbols.hpp"
    85.5  #include "code/debugInfo.hpp"
    85.6  #include "code/pcDesc.hpp"
    85.7 +#include "compiler/compilerOracle.hpp"
    85.8  #include "interpreter/interpreter.hpp"
    85.9  #include "memory/oopFactory.hpp"
   85.10  #include "memory/resourceArea.hpp"
   85.11 @@ -2323,6 +2324,8 @@
   85.12  
   85.13  int java_lang_invoke_AdapterMethodHandle::_conversion_offset;
   85.14  
   85.15 +int java_lang_invoke_CountingMethodHandle::_vmcount_offset;
   85.16 +
   85.17  void java_lang_invoke_MethodHandle::compute_offsets() {
   85.18    klassOop k = SystemDictionary::MethodHandle_klass();
   85.19    if (k != NULL && EnableInvokeDynamic) {
   85.20 @@ -2371,6 +2374,23 @@
   85.21    }
   85.22  }
   85.23  
   85.24 +void java_lang_invoke_CountingMethodHandle::compute_offsets() {
   85.25 +  klassOop k = SystemDictionary::CountingMethodHandle_klass();
   85.26 +  if (k != NULL && EnableInvokeDynamic) {
   85.27 +    compute_offset(_vmcount_offset, k, vmSymbols::vmcount_name(), vmSymbols::int_signature(), true);
   85.28 +  }
   85.29 +}
   85.30 +
   85.31 +int java_lang_invoke_CountingMethodHandle::vmcount(oop mh) {
   85.32 +  assert(is_instance(mh), "CMH only");
   85.33 +  return mh->int_field(_vmcount_offset);
   85.34 +}
   85.35 +
   85.36 +void java_lang_invoke_CountingMethodHandle::set_vmcount(oop mh, int count) {
   85.37 +  assert(is_instance(mh), "CMH only");
   85.38 +  mh->int_field_put(_vmcount_offset, count);
   85.39 +}
   85.40 +
   85.41  oop java_lang_invoke_MethodHandle::type(oop mh) {
   85.42    return mh->obj_field(_type_offset);
   85.43  }
   85.44 @@ -2674,6 +2694,17 @@
   85.45    if (k != NULL) {
   85.46      compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
   85.47    }
   85.48 +
   85.49 +  // Disallow compilation of CallSite.setTargetNormal and CallSite.setTargetVolatile
   85.50 +  // (For C2:  keep this until we have throttling logic for uncommon traps.)
   85.51 +  if (k != NULL) {
   85.52 +    instanceKlass* ik = instanceKlass::cast(k);
   85.53 +    methodOop m_normal   = ik->lookup_method(vmSymbols::setTargetNormal_name(),   vmSymbols::setTarget_signature());
   85.54 +    methodOop m_volatile = ik->lookup_method(vmSymbols::setTargetVolatile_name(), vmSymbols::setTarget_signature());
   85.55 +    guarantee(m_normal && m_volatile, "must exist");
   85.56 +    m_normal->set_not_compilable_quietly();
   85.57 +    m_volatile->set_not_compilable_quietly();
   85.58 +  }
   85.59  }
   85.60  
   85.61  oop java_lang_invoke_CallSite::target(oop site) {
   85.62 @@ -3031,6 +3062,7 @@
   85.63      java_lang_invoke_MethodType::compute_offsets();
   85.64      java_lang_invoke_MethodTypeForm::compute_offsets();
   85.65      java_lang_invoke_CallSite::compute_offsets();
   85.66 +    java_lang_invoke_CountingMethodHandle::compute_offsets();
   85.67    }
   85.68    java_security_AccessControlContext::compute_offsets();
   85.69    // Initialize reflection classes. The layouts of these classes
    86.1 --- a/src/share/vm/classfile/javaClasses.hpp	Thu Sep 08 16:59:27 2011 -0700
    86.2 +++ b/src/share/vm/classfile/javaClasses.hpp	Fri Sep 09 16:17:16 2011 -0700
    86.3 @@ -981,6 +981,34 @@
    86.4  };
    86.5  
    86.6  
    86.7 +// A simple class that maintains an invocation count
    86.8 +class java_lang_invoke_CountingMethodHandle: public java_lang_invoke_MethodHandle {
    86.9 +  friend class JavaClasses;
   86.10 +
   86.11 + private:
   86.12 +  static int _vmcount_offset;
   86.13 +  static void compute_offsets();
   86.14 +
   86.15 + public:
   86.16 +  // Accessors
   86.17 +  static int            vmcount(oop mh);
   86.18 +  static void       set_vmcount(oop mh, int count);
   86.19 +
   86.20 +  // Testers
   86.21 +  static bool is_subclass(klassOop klass) {
   86.22 +    return SystemDictionary::CountingMethodHandle_klass() != NULL &&
   86.23 +      Klass::cast(klass)->is_subclass_of(SystemDictionary::CountingMethodHandle_klass());
   86.24 +  }
   86.25 +  static bool is_instance(oop obj) {
   86.26 +    return obj != NULL && is_subclass(obj->klass());
   86.27 +  }
   86.28 +
   86.29 +  // Accessors for code generation:
   86.30 +  static int vmcount_offset_in_bytes()          { return _vmcount_offset; }
   86.31 +};
   86.32 +
   86.33 +
   86.34 +
   86.35  // Interface to java.lang.invoke.MemberName objects
   86.36  // (These are a private interface for Java code to query the class hierarchy.)
   86.37  
    87.1 --- a/src/share/vm/classfile/systemDictionary.hpp	Thu Sep 08 16:59:27 2011 -0700
    87.2 +++ b/src/share/vm/classfile/systemDictionary.hpp	Fri Sep 09 16:17:16 2011 -0700
    87.3 @@ -133,14 +133,14 @@
    87.4    template(reflect_Method_klass,         java_lang_reflect_Method,       Pre) \
    87.5    template(reflect_Constructor_klass,    java_lang_reflect_Constructor,  Pre) \
    87.6                                                                                \
    87.7 -  /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
    87.8 -  /* Universe::is_gte_jdk14x_version() is not set up by this point. */        \
    87.9 -  /* It's okay if this turns out to be NULL in non-1.4 JDKs. */               \
   87.10 -  template(reflect_MagicAccessorImpl_klass,          sun_reflect_MagicAccessorImpl,  Opt) \
   87.11 -  template(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
   87.12 -  template(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
   87.13 -  template(reflect_DelegatingClassLoader_klass, sun_reflect_DelegatingClassLoader, Opt) \
   87.14 -  template(reflect_ConstantPool_klass,  sun_reflect_ConstantPool,       Opt_Only_JDK15) \
   87.15 +  /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */                        \
   87.16 +  /* Universe::is_gte_jdk14x_version() is not set up by this point. */                                             \
   87.17 +  /* It's okay if this turns out to be NULL in non-1.4 JDKs. */                                                    \
   87.18 +  template(reflect_MagicAccessorImpl_klass,          sun_reflect_MagicAccessorImpl,  Opt)                          \
   87.19 +  template(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef)                 \
   87.20 +  template(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef)       \
   87.21 +  template(reflect_DelegatingClassLoader_klass, sun_reflect_DelegatingClassLoader, Opt)                            \
   87.22 +  template(reflect_ConstantPool_klass,  sun_reflect_ConstantPool,       Opt_Only_JDK15)                            \
   87.23    template(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15) \
   87.24                                                                                \
   87.25    /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
   87.26 @@ -155,6 +155,7 @@
   87.27    template(BootstrapMethodError_klass,     java_lang_BootstrapMethodError,            Pre_JSR292) \
   87.28    template(WrongMethodTypeException_klass, java_lang_invoke_WrongMethodTypeException, Pre_JSR292) \
   87.29    template(CallSite_klass,                 java_lang_invoke_CallSite,                 Pre_JSR292) \
   87.30 +  template(CountingMethodHandle_klass,     java_lang_invoke_CountingMethodHandle,     Opt)        \
   87.31    template(ConstantCallSite_klass,         java_lang_invoke_ConstantCallSite,         Pre_JSR292) \
   87.32    template(MutableCallSite_klass,          java_lang_invoke_MutableCallSite,          Pre_JSR292) \
   87.33    template(VolatileCallSite_klass,         java_lang_invoke_VolatileCallSite,         Pre_JSR292) \
    88.1 --- a/src/share/vm/classfile/vmSymbols.hpp	Thu Sep 08 16:59:27 2011 -0700
    88.2 +++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Sep 09 16:17:16 2011 -0700
    88.3 @@ -218,6 +218,7 @@
    88.4    template(returnType_name,                           "returnType")                               \
    88.5    template(signature_name,                            "signature")                                \
    88.6    template(slot_name,                                 "slot")                                     \
    88.7 +  template(selectAlternative_name,                    "selectAlternative")                        \
    88.8                                                                                                    \
    88.9    /* Support for annotations (JDK 1.5 and above) */                                               \
   88.10                                                                                                    \
   88.11 @@ -246,9 +247,11 @@
   88.12    template(java_lang_invoke_MethodTypeForm_signature, "Ljava/lang/invoke/MethodTypeForm;")        \
   88.13    template(java_lang_invoke_MemberName,               "java/lang/invoke/MemberName")              \
   88.14    template(java_lang_invoke_MethodHandleNatives,      "java/lang/invoke/MethodHandleNatives")     \
   88.15 +  template(java_lang_invoke_MethodHandleImpl,         "java/lang/invoke/MethodHandleImpl")        \
   88.16    template(java_lang_invoke_AdapterMethodHandle,      "java/lang/invoke/AdapterMethodHandle")     \
   88.17    template(java_lang_invoke_BoundMethodHandle,        "java/lang/invoke/BoundMethodHandle")       \
   88.18    template(java_lang_invoke_DirectMethodHandle,       "java/lang/invoke/DirectMethodHandle")      \
   88.19 +  template(java_lang_invoke_CountingMethodHandle,     "java/lang/invoke/CountingMethodHandle")    \
   88.20    /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */         \
   88.21    template(findMethodHandleType_name,                 "findMethodHandleType")                     \
   88.22    template(findMethodHandleType_signature,       "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
   88.23 @@ -258,8 +261,12 @@
   88.24    template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;") \
   88.25    template(makeDynamicCallSite_name,                  "makeDynamicCallSite")                      \
   88.26    template(makeDynamicCallSite_signature, "(Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/invoke/MemberName;I)Ljava/lang/invoke/CallSite;") \
   88.27 +  template(setTargetNormal_name,                      "setTargetNormal")                          \
   88.28 +  template(setTargetVolatile_name,                    "setTargetVolatile")                        \
   88.29 +  template(setTarget_signature,                       "(Ljava/lang/invoke/MethodHandle;)V")       \
   88.30    NOT_LP64(  do_alias(machine_word_signature,         int_signature)  )                           \
   88.31    LP64_ONLY( do_alias(machine_word_signature,         long_signature) )                           \
   88.32 +  template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
   88.33                                                                                                    \
   88.34    /* common method and field names */                                                             \
   88.35    template(object_initializer_name,                   "<init>")                                   \
   88.36 @@ -344,6 +351,7 @@
   88.37    template(vmmethod_name,                             "vmmethod")                                 \
   88.38    template(vmtarget_name,                             "vmtarget")                                 \
   88.39    template(vmentry_name,                              "vmentry")                                  \
   88.40 +  template(vmcount_name,                              "vmcount")                                  \
   88.41    template(vmslots_name,                              "vmslots")                                  \
   88.42    template(vmlayout_name,                             "vmlayout")                                 \
   88.43    template(vmindex_name,                              "vmindex")                                  \
   88.44 @@ -907,6 +915,8 @@
   88.45    do_intrinsic(_invokeVarargs,            java_lang_invoke_MethodHandle, invokeVarargs_name, object_array_object_signature, F_R)  \
   88.46    do_intrinsic(_invokeDynamic,            java_lang_invoke_InvokeDynamic, star_name,         object_array_object_signature, F_SN) \
   88.47                                                                                                                          \
   88.48 +  do_intrinsic(_selectAlternative,        java_lang_invoke_MethodHandleImpl, selectAlternative_name, selectAlternative_signature, F_S)  \
   88.49 +                                                                                                                        \
   88.50    /* unboxing methods: */                                                                                               \
   88.51    do_intrinsic(_booleanValue,             java_lang_Boolean,      booleanValue_name, void_boolean_signature, F_R)       \
   88.52     do_name(     booleanValue_name,       "booleanValue")                                                                \
    89.1 --- a/src/share/vm/code/dependencies.cpp	Thu Sep 08 16:59:27 2011 -0700
    89.2 +++ b/src/share/vm/code/dependencies.cpp	Fri Sep 09 16:17:16 2011 -0700
    89.3 @@ -113,9 +113,9 @@
    89.4    assert_common_1(no_finalizable_subclasses, ctxk);
    89.5  }
    89.6  
    89.7 -void Dependencies::assert_call_site_target_value(ciKlass* ctxk, ciCallSite* call_site, ciMethodHandle* method_handle) {
    89.8 -  check_ctxk(ctxk);
    89.9 -  assert_common_3(call_site_target_value, ctxk, call_site, method_handle);
   89.10 +void Dependencies::assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle) {
   89.11 +  check_ctxk(call_site->klass());
   89.12 +  assert_common_2(call_site_target_value, call_site, method_handle);
   89.13  }
   89.14  
   89.15  // Helper function.  If we are adding a new dep. under ctxk2,
   89.16 @@ -135,7 +135,7 @@
   89.17    }
   89.18  }
   89.19  
   89.20 -void Dependencies::assert_common_1(Dependencies::DepType dept, ciObject* x) {
   89.21 +void Dependencies::assert_common_1(DepType dept, ciObject* x) {
   89.22    assert(dep_args(dept) == 1, "sanity");
   89.23    log_dependency(dept, x);
   89.24    GrowableArray<ciObject*>* deps = _deps[dept];
   89.25 @@ -148,21 +148,37 @@
   89.26    }
   89.27  }
   89.28  
   89.29 -void Dependencies::assert_common_2(Dependencies::DepType dept,
   89.30 -                                   ciKlass* ctxk, ciObject* x) {
   89.31 -  assert(dep_context_arg(dept) == 0, "sanity");
   89.32 +void Dependencies::assert_common_2(DepType dept,
   89.33 +                                   ciObject* x0, ciObject* x1) {
   89.34    assert(dep_args(dept) == 2, "sanity");
   89.35 -  log_dependency(dept, ctxk, x);
   89.36 +  log_dependency(dept, x0, x1);
   89.37    GrowableArray<ciObject*>* deps = _deps[dept];
   89.38  
   89.39    // see if the same (or a similar) dep is already recorded
   89.40 -  if (note_dep_seen(dept, x)) {
   89.41 -    // look in this bucket for redundant assertions
   89.42 -    const int stride = 2;
   89.43 -    for (int i = deps->length(); (i -= stride) >= 0; ) {
   89.44 -      ciObject* x1 = deps->at(i+1);
   89.45 -      if (x == x1) {  // same subject; check the context
   89.46 -        if (maybe_merge_ctxk(deps, i+0, ctxk)) {
   89.47 +  bool has_ctxk = has_explicit_context_arg(dept);
   89.48 +  if (has_ctxk) {
   89.49 +    assert(dep_context_arg(dept) == 0, "sanity");
   89.50 +    if (note_dep_seen(dept, x1)) {
   89.51 +      // look in this bucket for redundant assertions
   89.52 +      const int stride = 2;
   89.53 +      for (int i = deps->length(); (i -= stride) >= 0; ) {
   89.54 +        ciObject* y1 = deps->at(i+1);
   89.55 +        if (x1 == y1) {  // same subject; check the context
   89.56 +          if (maybe_merge_ctxk(deps, i+0, x0->as_klass())) {
   89.57 +            return;
   89.58 +          }
   89.59 +        }
   89.60 +      }
   89.61 +    }
   89.62 +  } else {
   89.63 +    assert(dep_implicit_context_arg(dept) == 0, "sanity");
   89.64 +    if (note_dep_seen(dept, x0) && note_dep_seen(dept, x1)) {
   89.65 +      // look in this bucket for redundant assertions
   89.66 +      const int stride = 2;
   89.67 +      for (int i = deps->length(); (i -= stride) >= 0; ) {
   89.68 +        ciObject* y0 = deps->at(i+0);
   89.69 +        ciObject* y1 = deps->at(i+1);
   89.70 +        if (x0 == y0 && x1 == y1) {
   89.71            return;
   89.72          }
   89.73        }
   89.74 @@ -170,11 +186,11 @@
   89.75    }
   89.76  
   89.77    // append the assertion in the correct bucket:
   89.78 -  deps->append(ctxk);
   89.79 -  deps->append(x);
   89.80 +  deps->append(x0);
   89.81 +  deps->append(x1);
   89.82  }
   89.83  
   89.84 -void Dependencies::assert_common_3(Dependencies::DepType dept,
   89.85 +void Dependencies::assert_common_3(DepType dept,
   89.86                                     ciKlass* ctxk, ciObject* x, ciObject* x2) {
   89.87    assert(dep_context_arg(dept) == 0, "sanity");
   89.88    assert(dep_args(dept) == 3, "sanity");
   89.89 @@ -361,7 +377,7 @@
   89.90    3, // unique_concrete_subtypes_2 ctxk, k1, k2
   89.91    3, // unique_concrete_methods_2 ctxk, m1, m2
   89.92    1, // no_finalizable_subclasses ctxk
   89.93 -  3  // call_site_target_value ctxk, call_site, method_handle
   89.94 +  2  // call_site_target_value call_site, method_handle
   89.95  };
   89.96  
   89.97  const char* Dependencies::dep_name(Dependencies::DepType dept) {
   89.98 @@ -375,10 +391,7 @@
   89.99  }
  89.100  
  89.101  void Dependencies::check_valid_dependency_type(DepType dept) {
  89.102 -  for (int deptv = (int) FIRST_TYPE; deptv < (int) TYPE_LIMIT; deptv++) {
  89.103 -    if (dept == ((DepType) deptv))  return;
  89.104 -  }
  89.105 -  ShouldNotReachHere();
  89.106 +  guarantee(FIRST_TYPE <= dept && dept < TYPE_LIMIT, err_msg("invalid dependency type: %d", (int) dept));
  89.107  }
  89.108  
  89.109  // for the sake of the compiler log, print out current dependencies:
  89.110 @@ -586,8 +599,7 @@
  89.111      code_byte -= ctxk_bit;
  89.112      DepType dept = (DepType)code_byte;
  89.113      _type = dept;
  89.114 -    guarantee((dept - FIRST_TYPE) < (TYPE_LIMIT - FIRST_TYPE),
  89.115 -              "bad dependency type tag");
  89.116 +    Dependencies::check_valid_dependency_type(dept);
  89.117      int stride = _dep_args[dept];
  89.118      assert(stride == dep_args(dept), "sanity");
  89.119      int skipj = -1;
  89.120 @@ -615,18 +627,35 @@
  89.121  
  89.122  klassOop Dependencies::DepStream::context_type() {
  89.123    assert(must_be_in_vm(), "raw oops here");
  89.124 -  int ctxkj = dep_context_arg(_type);  // -1 if no context arg
  89.125 -  if (ctxkj < 0) {
  89.126 -    return NULL;           // for example, evol_method
  89.127 -  } else {
  89.128 -    oop k = recorded_oop_at(_xi[ctxkj]);
  89.129 -    if (k != NULL) {       // context type was not compressed away
  89.130 +
  89.131 +  // Most dependencies have an explicit context type argument.
  89.132 +  {
  89.133 +    int ctxkj = dep_context_arg(_type);  // -1 if no explicit context arg
  89.134 +    if (ctxkj >= 0) {
  89.135 +      oop k = argument(ctxkj);
  89.136 +      if (k != NULL) {       // context type was not compressed away
  89.137 +        assert(k->is_klass(), "type check");
  89.138 +        return (klassOop) k;
  89.139 +      }
  89.140 +      // recompute "default" context type
  89.141 +      return ctxk_encoded_as_null(_type, argument(ctxkj+1));
  89.142 +    }
  89.143 +  }
  89.144 +
  89.145 +  // Some dependencies are using the klass of the first object
  89.146 +  // argument as implicit context type (e.g. call_site_target_value).
  89.147 +  {
  89.148 +    int ctxkj = dep_implicit_context_arg(_type);
  89.149 +    if (ctxkj >= 0) {
  89.150 +      oop k = argument(ctxkj)->klass();
  89.151        assert(k->is_klass(), "type check");
  89.152        return (klassOop) k;
  89.153 -    } else {               // recompute "default" context type
  89.154 -      return ctxk_encoded_as_null(_type, recorded_oop_at(_xi[ctxkj+1]));
  89.155      }
  89.156    }
  89.157 +
  89.158 +  // And some dependencies don't have a context type at all,
  89.159 +  // e.g. evol_method.
  89.160 +  return NULL;
  89.161  }
  89.162  
  89.163  /// Checking dependencies:
  89.164 @@ -1409,21 +1438,20 @@
  89.165  }
  89.166  
  89.167  
  89.168 -klassOop Dependencies::check_call_site_target_value(klassOop ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes) {
  89.169 +klassOop Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
  89.170    assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "sanity");
  89.171    assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
  89.172    if (changes == NULL) {
  89.173      // Validate all CallSites
  89.174      if (java_lang_invoke_CallSite::target(call_site) != method_handle)
  89.175 -      return ctxk;  // assertion failed
  89.176 +      return call_site->klass();  // assertion failed
  89.177    } else {
  89.178      // Validate the given CallSite
  89.179      if (call_site == changes->call_site() && java_lang_invoke_CallSite::target(call_site) != changes->method_handle()) {
  89.180        assert(method_handle != changes->method_handle(), "must be");
  89.181 -      return ctxk;  // assertion failed
  89.182 +      return call_site->klass();  // assertion failed
  89.183      }
  89.184    }
  89.185 -  assert(java_lang_invoke_CallSite::target(call_site) == method_handle, "should still be valid");
  89.186    return NULL;  // assertion still valid
  89.187  }
  89.188  
  89.189 @@ -1488,7 +1516,7 @@
  89.190    klassOop witness = NULL;
  89.191    switch (type()) {
  89.192    case call_site_target_value:
  89.193 -    witness = check_call_site_target_value(context_type(), argument(1), argument(2), changes);
  89.194 +    witness = check_call_site_target_value(argument(0), argument(1), changes);
  89.195      break;
  89.196    default:
  89.197      witness = NULL;
    90.1 --- a/src/share/vm/code/dependencies.hpp	Thu Sep 08 16:59:27 2011 -0700
    90.2 +++ b/src/share/vm/code/dependencies.hpp	Fri Sep 09 16:17:16 2011 -0700
    90.3 @@ -166,9 +166,14 @@
    90.4      LG2_TYPE_LIMIT = 4,  // assert(TYPE_LIMIT <= (1<<LG2_TYPE_LIMIT))
    90.5  
    90.6      // handy categorizations of dependency types:
    90.7 -    all_types      = ((1<<TYPE_LIMIT)-1) & ((-1)<<FIRST_TYPE),
    90.8 -    non_ctxk_types = (1<<evol_method),
    90.9 -    ctxk_types     = all_types & ~non_ctxk_types,
   90.10 +    all_types           = ((1 << TYPE_LIMIT) - 1) & ((-1) << FIRST_TYPE),
   90.11 +
   90.12 +    non_klass_types     = (1 << call_site_target_value),
   90.13 +    klass_types         = all_types & ~non_klass_types,
   90.14 +
   90.15 +    non_ctxk_types      = (1 << evol_method),
   90.16 +    implicit_ctxk_types = (1 << call_site_target_value),
   90.17 +    explicit_ctxk_types = all_types & ~(non_ctxk_types | implicit_ctxk_types),
   90.18  
   90.19      max_arg_count = 3,   // current maximum number of arguments (incl. ctxk)
   90.20  
   90.21 @@ -184,9 +189,15 @@
   90.22  
   90.23    static const char* dep_name(DepType dept);
   90.24    static int         dep_args(DepType dept);
   90.25 -  static int  dep_context_arg(DepType dept) {
   90.26 -    return dept_in_mask(dept, ctxk_types)? 0: -1;
   90.27 -  }
   90.28 +
   90.29 +  static bool is_klass_type(           DepType dept) { return dept_in_mask(dept, klass_types        ); }
   90.30 +
   90.31 +  static bool has_explicit_context_arg(DepType dept) { return dept_in_mask(dept, explicit_ctxk_types); }
   90.32 +  static bool has_implicit_context_arg(DepType dept) { return dept_in_mask(dept, implicit_ctxk_types); }
   90.33 +
   90.34 +  static int           dep_context_arg(DepType dept) { return has_explicit_context_arg(dept) ? 0 : -1; }
   90.35 +  static int  dep_implicit_context_arg(DepType dept) { return has_implicit_context_arg(dept) ? 0 : -1; }
   90.36 +
   90.37    static void check_valid_dependency_type(DepType dept);
   90.38  
   90.39   private:
   90.40 @@ -250,8 +261,8 @@
   90.41    }
   90.42  
   90.43    void assert_common_1(DepType dept, ciObject* x);
   90.44 -  void assert_common_2(DepType dept, ciKlass* ctxk, ciObject* x);
   90.45 -  void assert_common_3(DepType dept, ciKlass* ctxk, ciObject* x, ciObject* x2);
   90.46 +  void assert_common_2(DepType dept, ciObject* x0, ciObject* x1);
   90.47 +  void assert_common_3(DepType dept, ciKlass* ctxk, ciObject* x1, ciObject* x2);
   90.48  
   90.49   public:
   90.50    // Adding assertions to a new dependency set at compile time:
   90.51 @@ -264,7 +275,7 @@
   90.52    void assert_abstract_with_exclusive_concrete_subtypes(ciKlass* ctxk, ciKlass* k1, ciKlass* k2);
   90.53    void assert_exclusive_concrete_methods(ciKlass* ctxk, ciMethod* m1, ciMethod* m2);
   90.54    void assert_has_no_finalizable_subclasses(ciKlass* ctxk);
   90.55 -  void assert_call_site_target_value(ciKlass* ctxk, ciCallSite* call_site, ciMethodHandle* method_handle);
   90.56 +  void assert_call_site_target_value(ciCallSite* call_site, ciMethodHandle* method_handle);
   90.57  
   90.58    // Define whether a given method or type is concrete.
   90.59    // These methods define the term "concrete" as used in this module.
   90.60 @@ -318,7 +329,7 @@
   90.61    static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2,
   90.62                                                     KlassDepChange* changes = NULL);
   90.63    static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes = NULL);
   90.64 -  static klassOop check_call_site_target_value(klassOop ctxk, oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
   90.65 +  static klassOop check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes = NULL);
   90.66    // A returned klassOop is NULL if the dependency assertion is still
   90.67    // valid.  A non-NULL klassOop is a 'witness' to the assertion
   90.68    // failure, a point in the class hierarchy where the assertion has
   90.69 @@ -455,6 +466,8 @@
   90.70      oop argument(int i);         // => recorded_oop_at(argument_index(i))
   90.71      klassOop context_type();
   90.72  
   90.73 +    bool is_klass_type()         { return Dependencies::is_klass_type(type()); }
   90.74 +
   90.75      methodOop method_argument(int i) {
   90.76        oop x = argument(i);
   90.77        assert(x->is_method(), "type");
    91.1 --- a/src/share/vm/code/nmethod.cpp	Thu Sep 08 16:59:27 2011 -0700
    91.2 +++ b/src/share/vm/code/nmethod.cpp	Fri Sep 09 16:17:16 2011 -0700
    91.3 @@ -451,7 +451,6 @@
    91.4    _stack_traversal_mark       = 0;
    91.5    _unload_reported            = false;           // jvmti state
    91.6  
    91.7 -  NOT_PRODUCT(_has_debug_info = false);
    91.8  #ifdef ASSERT
    91.9    _oops_are_stale             = false;
   91.10  #endif
    92.1 --- a/src/share/vm/code/nmethod.hpp	Thu Sep 08 16:59:27 2011 -0700
    92.2 +++ b/src/share/vm/code/nmethod.hpp	Fri Sep 09 16:17:16 2011 -0700
    92.3 @@ -191,8 +191,6 @@
    92.4  
    92.5    jbyte _scavenge_root_state;
    92.6  
    92.7 -  NOT_PRODUCT(bool _has_debug_info; )
    92.8 -
    92.9    // Nmethod Flushing lock. If non-zero, then the nmethod is not removed
   92.10    // and is not made into a zombie. However, once the nmethod is made into
   92.11    // a zombie, it will be locked one final time if CompiledMethodUnload
   92.12 @@ -329,11 +327,6 @@
   92.13    methodOop method() const                        { return _method; }
   92.14    AbstractCompiler* compiler() const              { return _compiler; }
   92.15  
   92.16 -#ifndef PRODUCT
   92.17 -  bool has_debug_info() const                     { return _has_debug_info; }
   92.18 -  void set_has_debug_info(bool f)                 { _has_debug_info = false; }
   92.19 -#endif // NOT PRODUCT
   92.20 -
   92.21    // type info
   92.22    bool is_nmethod() const                         { return true; }
   92.23    bool is_java_method() const                     { return !method()->is_native(); }
    93.1 --- a/src/share/vm/code/pcDesc.cpp	Thu Sep 08 16:59:27 2011 -0700
    93.2 +++ b/src/share/vm/code/pcDesc.cpp	Fri Sep 09 16:17:16 2011 -0700
    93.3 @@ -30,11 +30,10 @@
    93.4  #include "memory/resourceArea.hpp"
    93.5  
    93.6  PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) {
    93.7 -  assert(sizeof(PcDescFlags) <= 4, "occupies more than a word");
    93.8    _pc_offset           = pc_offset;
    93.9    _scope_decode_offset = scope_decode_offset;
   93.10    _obj_decode_offset   = obj_decode_offset;
   93.11 -  _flags.word          = 0;
   93.12 +  _flags               = 0;
   93.13  }
   93.14  
   93.15  address PcDesc::real_pc(const nmethod* code) const {
   93.16 @@ -44,7 +43,7 @@
   93.17  void PcDesc::print(nmethod* code) {
   93.18  #ifndef PRODUCT
   93.19    ResourceMark rm;
   93.20 -  tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags.bits);
   93.21 +  tty->print_cr("PcDesc(pc=0x%lx offset=%x bits=%x):", real_pc(code), pc_offset(), _flags);
   93.22  
   93.23    if (scope_decode_offset() == DebugInformationRecorder::serialized_null) {
   93.24      return;
    94.1 --- a/src/share/vm/code/pcDesc.hpp	Thu Sep 08 16:59:27 2011 -0700
    94.2 +++ b/src/share/vm/code/pcDesc.hpp	Fri Sep 09 16:17:16 2011 -0700
    94.3 @@ -39,15 +39,17 @@
    94.4    int _scope_decode_offset; // offset for scope in nmethod
    94.5    int _obj_decode_offset;
    94.6  
    94.7 -  union PcDescFlags {
    94.8 -    int word;
    94.9 -    struct {
   94.10 -      unsigned int reexecute: 1;
   94.11 -      unsigned int is_method_handle_invoke: 1;
   94.12 -      unsigned int return_oop: 1;
   94.13 -    } bits;
   94.14 -    bool operator ==(const PcDescFlags& other) { return word == other.word; }
   94.15 -  } _flags;
   94.16 +  enum {
   94.17 +    PCDESC_reexecute               = 1 << 0,
   94.18 +    PCDESC_is_method_handle_invoke = 1 << 1,
   94.19 +    PCDESC_return_oop              = 1 << 2
   94.20 +  };
   94.21 +
   94.22 +  int _flags;
   94.23 +
   94.24 +  void set_flag(int mask, bool z) {
   94.25 +    _flags = z ? (_flags | mask) : (_flags & ~mask);
   94.26 +  }
   94.27  
   94.28   public:
   94.29    int pc_offset() const           { return _pc_offset;   }
   94.30 @@ -69,8 +71,8 @@
   94.31    };
   94.32  
   94.33    // Flags
   94.34 -  bool     should_reexecute()              const { return _flags.bits.reexecute; }
   94.35 -  void set_should_reexecute(bool z)              { _flags.bits.reexecute = z;    }
   94.36 +  bool     should_reexecute()              const { return (_flags & PCDESC_reexecute) != 0; }
   94.37 +  void set_should_reexecute(bool z)              { set_flag(PCDESC_reexecute, z); }
   94.38  
   94.39    // Does pd refer to the same information as pd?
   94.40    bool is_same_info(const PcDesc* pd) {
   94.41 @@ -79,11 +81,11 @@
   94.42        _flags == pd->_flags;
   94.43    }
   94.44  
   94.45 -  bool     is_method_handle_invoke()       const { return _flags.bits.is_method_handle_invoke;     }
   94.46 -  void set_is_method_handle_invoke(bool z)       {        _flags.bits.is_method_handle_invoke = z; }
   94.47 +  bool     is_method_handle_invoke()       const { return (_flags & PCDESC_is_method_handle_invoke) != 0;     }
   94.48 +  void set_is_method_handle_invoke(bool z)       { set_flag(PCDESC_is_method_handle_invoke, z); }
   94.49  
   94.50 -  bool     return_oop()                    const { return _flags.bits.return_oop;     }
   94.51 -  void set_return_oop(bool z)                    {        _flags.bits.return_oop = z; }
   94.52 +  bool     return_oop()                    const { return (_flags & PCDESC_return_oop) != 0;     }
   94.53 +  void set_return_oop(bool z)                    { set_flag(PCDESC_return_oop, z); }
   94.54  
   94.55    // Returns the real pc
   94.56    address real_pc(const nmethod* code) const;
    95.1 --- a/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Thu Sep 08 16:59:27 2011 -0700
    95.2 +++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp	Fri Sep 09 16:17:16 2011 -0700
    95.3 @@ -1,5 +1,5 @@
    95.4  /*
    95.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
    95.6 + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
    95.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    95.8   *
    95.9   * This code is free software; you can redistribute it and/or modify it
   95.10 @@ -26,6 +26,7 @@
   95.11  #include "gc_implementation/g1/collectionSetChooser.hpp"
   95.12  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
   95.13  #include "gc_implementation/g1/g1CollectorPolicy.hpp"
   95.14 +#include "gc_implementation/g1/g1ErgoVerbose.hpp"
   95.15  #include "memory/space.inline.hpp"
   95.16  
   95.17  CSetChooserCache::CSetChooserCache() {
   95.18 @@ -358,6 +359,9 @@
   95.19    if (_cache.is_empty()) {
   95.20      assert(_curMarkedIndex == _numMarkedRegions,
   95.21             "if cache is empty, list should also be empty");
   95.22 +    ergo_verbose0(ErgoCSetConstruction,
   95.23 +                  "stop adding old regions to CSet",
   95.24 +                  ergo_format_reason("cache is empty"));
   95.25      return NULL;
   95.26    }
   95.27  
   95.28 @@ -368,10 +372,23 @@
   95.29    if (g1p->adaptive_young_list_length()) {
   95.30      if (time_remaining - predicted_time < 0.0) {
   95.31        g1h->check_if_region_is_too_expensive(predicted_time);
   95.32 +      ergo_verbose2(ErgoCSetConstruction,
   95.33 +                    "stop adding old regions to CSet",
   95.34 +                    ergo_format_reason("predicted old region time higher than remaining time")
   95.35 +                    ergo_format_ms("predicted old region time")
   95.36 +                    ergo_format_ms("remaining time"),
   95.37 +                    predicted_time, time_remaining);
   95.38        return NULL;
   95.39      }
   95.40    } else {
   95.41 -    if (predicted_time > 2.0 * avg_prediction) {
   95.42 +    double threshold = 2.0 * avg_prediction;
   95.43 +    if (predicted_time > threshold) {
   95.44 +      ergo_verbose2(ErgoCSetConstruction,
   95.45 +                    "stop adding old regions to CSet",
   95.46 +                    ergo_format_reason("predicted old region time higher than threshold")
   95.47 +                    ergo_format_ms("predicted old region time")
   95.48 +                    ergo_format_ms("threshold"),
   95.49 +                    predicted_time, threshold);
   95.50        return NULL;
   95.51      }
   95.52    }
    96.1 --- a/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp	Thu Sep 08 16:59:27 2011 -0700
    96.2 +++ b/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp	Fri Sep 09 16:17:16 2011 -0700
    96.3 @@ -91,7 +91,7 @@
    96.4        }
    96.5      }
    96.6  
    96.7 -    g1p->check_prediction_validity();
    96.8 +    g1p->revise_young_list_target_length_if_necessary();
    96.9    }
   96.10  }
   96.11  
    97.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Thu Sep 08 16:59:27 2011 -0700
    97.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Fri Sep 09 16:17:16 2011 -0700
    97.3 @@ -28,6 +28,7 @@
    97.4  #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
    97.5  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
    97.6  #include "gc_implementation/g1/g1CollectorPolicy.hpp"
    97.7 +#include "gc_implementation/g1/g1ErgoVerbose.hpp"
    97.8  #include "gc_implementation/g1/g1OopClosures.inline.hpp"
    97.9  #include "gc_implementation/g1/g1RemSet.hpp"
   97.10  #include "gc_implementation/g1/heapRegionRemSet.hpp"
   97.11 @@ -1727,18 +1728,21 @@
   97.12  
   97.13    size_t known_garbage_bytes =
   97.14      g1_par_count_task.used_bytes() - g1_par_count_task.live_bytes();
   97.15 -#if 0
   97.16 -  gclog_or_tty->print_cr("used %1.2lf, live %1.2lf, garbage %1.2lf",
   97.17 -                         (double) g1_par_count_task.used_bytes() / (double) (1024 * 1024),
   97.18 -                         (double) g1_par_count_task.live_bytes() / (double) (1024 * 1024),
   97.19 -                         (double) known_garbage_bytes / (double) (1024 * 1024));
   97.20 -#endif // 0
   97.21    g1p->set_known_garbage_bytes(known_garbage_bytes);
   97.22  
   97.23    size_t start_used_bytes = g1h->used();
   97.24    _at_least_one_mark_complete = true;
   97.25    g1h->set_marking_complete();
   97.26  
   97.27 +  ergo_verbose4(ErgoConcCycles,
   97.28 +           "finish cleanup",
   97.29 +           ergo_format_byte("occupancy")
   97.30 +           ergo_format_byte("capacity")
   97.31 +           ergo_format_byte_perc("known garbage"),
   97.32 +           start_used_bytes, g1h->capacity(),
   97.33 +           known_garbage_bytes,
   97.34 +           ((double) known_garbage_bytes / (double) g1h->capacity()) * 100.0);
   97.35 +
   97.36    double count_end = os::elapsedTime();
   97.37    double this_final_counting_time = (count_end - start);
   97.38    if (G1PrintParCleanupStats) {
    98.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Sep 08 16:59:27 2011 -0700
    98.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Sep 09 16:17:16 2011 -0700
    98.3 @@ -31,6 +31,7 @@
    98.4  #include "gc_implementation/g1/g1AllocRegion.inline.hpp"
    98.5  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
    98.6  #include "gc_implementation/g1/g1CollectorPolicy.hpp"
    98.7 +#include "gc_implementation/g1/g1ErgoVerbose.hpp"
    98.8  #include "gc_implementation/g1/g1MarkSweep.hpp"
    98.9  #include "gc_implementation/g1/g1OopClosures.inline.hpp"
   98.10  #include "gc_implementation/g1/g1RemSet.inline.hpp"
   98.11 @@ -577,6 +578,11 @@
   98.12      res = new_region_try_secondary_free_list();
   98.13    }
   98.14    if (res == NULL && do_expand) {
   98.15 +    ergo_verbose1(ErgoHeapSizing,
   98.16 +                  "attempt heap expansion",
   98.17 +                  ergo_format_reason("region allocation request failed")
   98.18 +                  ergo_format_byte("allocation request"),
   98.19 +                  word_size * HeapWordSize);
   98.20      if (expand(word_size * HeapWordSize)) {
   98.21        // Even though the heap was expanded, it might not have reached
   98.22        // the desired size. So, we cannot assume that the allocation
   98.23 @@ -790,6 +796,11 @@
   98.24        // room available.
   98.25        assert(num_regions > fs, "earlier allocation should have succeeded");
   98.26  
   98.27 +      ergo_verbose1(ErgoHeapSizing,
   98.28 +                    "attempt heap expansion",
   98.29 +                    ergo_format_reason("humongous allocation request failed")
   98.30 +                    ergo_format_byte("allocation request"),
   98.31 +                    word_size * HeapWordSize);
   98.32        if (expand((num_regions - fs) * HeapRegion::GrainBytes)) {
   98.33          // Even though the heap was expanded, it might not have
   98.34          // reached the desired size. So, we cannot assume that the
   98.35 @@ -906,6 +917,8 @@
   98.36  
   98.37        if (GC_locker::is_active_and_needs_gc()) {
   98.38          if (g1_policy()->can_expand_young_list()) {
   98.39 +          // No need for an ergo verbose message here,
   98.40 +          // can_expand_young_list() does this when it returns true.
   98.41            result = _mutator_alloc_region.attempt_allocation_force(word_size,
   98.42                                                        false /* bot_updates */);
   98.43            if (result != NULL) {
   98.44 @@ -1477,63 +1490,34 @@
   98.45    // we'll try to make the capacity smaller than it, not greater).
   98.46    maximum_desired_capacity =  MAX2(maximum_desired_capacity, min_heap_size);
   98.47  
   98.48 -  if (PrintGC && Verbose) {
   98.49 -    const double free_percentage =
   98.50 -      (double) free_after_gc / (double) capacity_after_gc;
   98.51 -    gclog_or_tty->print_cr("Computing new size after full GC ");
   98.52 -    gclog_or_tty->print_cr("  "
   98.53 -                           "  minimum_free_percentage: %6.2f",
   98.54 -                           minimum_free_percentage);
   98.55 -    gclog_or_tty->print_cr("  "
   98.56 -                           "  maximum_free_percentage: %6.2f",
   98.57 -                           maximum_free_percentage);
   98.58 -    gclog_or_tty->print_cr("  "
   98.59 -                           "  capacity: %6.1fK"
   98.60 -                           "  minimum_desired_capacity: %6.1fK"
   98.61 -                           "  maximum_desired_capacity: %6.1fK",
   98.62 -                           (double) capacity_after_gc / (double) K,
   98.63 -                           (double) minimum_desired_capacity / (double) K,
   98.64 -                           (double) maximum_desired_capacity / (double) K);
   98.65 -    gclog_or_tty->print_cr("  "
   98.66 -                           "  free_after_gc: %6.1fK"
   98.67 -                           "  used_after_gc: %6.1fK",
   98.68 -                           (double) free_after_gc / (double) K,
   98.69 -                           (double) used_after_gc / (double) K);
   98.70 -    gclog_or_tty->print_cr("  "
   98.71 -                           "   free_percentage: %6.2f",
   98.72 -                           free_percentage);
   98.73 -  }
   98.74    if (capacity_after_gc < minimum_desired_capacity) {
   98.75      // Don't expand unless it's significant
   98.76      size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
   98.77 -    if (expand(expand_bytes)) {
   98.78 -      if (PrintGC && Verbose) {
   98.79 -        gclog_or_tty->print_cr("  "
   98.80 -                               "  expanding:"
   98.81 -                               "  max_heap_size: %6.1fK"
   98.82 -                               "  minimum_desired_capacity: %6.1fK"
   98.83 -                               "  expand_bytes: %6.1fK",
   98.84 -                               (double) max_heap_size / (double) K,
   98.85 -                               (double) minimum_desired_capacity / (double) K,
   98.86 -                               (double) expand_bytes / (double) K);
   98.87 -      }
   98.88 -    }
   98.89 +    ergo_verbose4(ErgoHeapSizing,
   98.90 +                  "attempt heap expansion",
   98.91 +                  ergo_format_reason("capacity lower than "
   98.92 +                                     "min desired capacity after Full GC")
   98.93 +                  ergo_format_byte("capacity")
   98.94 +                  ergo_format_byte("occupancy")
   98.95 +                  ergo_format_byte_perc("min desired capacity"),
   98.96 +                  capacity_after_gc, used_after_gc,
   98.97 +                  minimum_desired_capacity, (double) MinHeapFreeRatio);
   98.98 +    expand(expand_bytes);
   98.99  
  98.100      // No expansion, now see if we want to shrink
  98.101    } else if (capacity_after_gc > maximum_desired_capacity) {
  98.102      // Capacity too large, compute shrinking size
  98.103      size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity;
  98.104 +    ergo_verbose4(ErgoHeapSizing,
  98.105 +                  "attempt heap shrinking",
  98.106 +                  ergo_format_reason("capacity higher than "
  98.107 +                                     "max desired capacity after Full GC")
  98.108 +                  ergo_format_byte("capacity")
  98.109 +                  ergo_format_byte("occupancy")
  98.110 +                  ergo_format_byte_perc("max desired capacity"),
  98.111 +                  capacity_after_gc, used_after_gc,
  98.112 +                  maximum_desired_capacity, (double) MaxHeapFreeRatio);
  98.113      shrink(shrink_bytes);
  98.114 -    if (PrintGC && Verbose) {
  98.115 -      gclog_or_tty->print_cr("  "
  98.116 -                             "  shrinking:"
  98.117 -                             "  min_heap_size: %6.1fK"
  98.118 -                             "  maximum_desired_capacity: %6.1fK"
  98.119 -                             "  shrink_bytes: %6.1fK",
  98.120 -                             (double) min_heap_size / (double) K,
  98.121 -                             (double) maximum_desired_capacity / (double) K,
  98.122 -                             (double) shrink_bytes / (double) K);
  98.123 -    }
  98.124    }
  98.125  }
  98.126  
  98.127 @@ -1619,6 +1603,11 @@
  98.128    verify_region_sets_optional();
  98.129  
  98.130    size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes);
  98.131 +  ergo_verbose1(ErgoHeapSizing,
  98.132 +                "attempt heap expansion",
  98.133 +                ergo_format_reason("allocation request failed")
  98.134 +                ergo_format_byte("allocation request"),
  98.135 +                word_size * HeapWordSize);
  98.136    if (expand(expand_bytes)) {
  98.137      _hrs.verify_optional();
  98.138      verify_region_sets_optional();
  98.139 @@ -1646,11 +1635,11 @@
  98.140    size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
  98.141    aligned_expand_bytes = align_size_up(aligned_expand_bytes,
  98.142                                         HeapRegion::GrainBytes);
  98.143 -
  98.144 -  if (Verbose && PrintGC) {
  98.145 -    gclog_or_tty->print("Expanding garbage-first heap from %ldK by %ldK",
  98.146 -                           old_mem_size/K, aligned_expand_bytes/K);
  98.147 -  }
  98.148 +  ergo_verbose2(ErgoHeapSizing,
  98.149 +                "expand the heap",
  98.150 +                ergo_format_byte("requested expansion amount")
  98.151 +                ergo_format_byte("attempted expansion amount"),
  98.152 +                expand_bytes, aligned_expand_bytes);
  98.153  
  98.154    // First commit the memory.
  98.155    HeapWord* old_end = (HeapWord*) _g1_storage.high();
  98.156 @@ -1693,7 +1682,11 @@
  98.157        }
  98.158        assert(curr == mr.end(), "post-condition");
  98.159      }
  98.160 +    g1_policy()->record_new_heap_size(n_regions());
  98.161    } else {
  98.162 +    ergo_verbose0(ErgoHeapSizing,
  98.163 +                  "did not expand the heap",
  98.164 +                  ergo_format_reason("heap expansion operation failed"));
  98.165      // The expansion of the virtual storage space was unsuccessful.
  98.166      // Let's see if it was because we ran out of swap.
  98.167      if (G1ExitOnExpansionFailure &&
  98.168 @@ -1702,13 +1695,6 @@
  98.169        vm_exit_out_of_memory(aligned_expand_bytes, "G1 heap expansion");
  98.170      }
  98.171    }
  98.172 -
  98.173 -  if (Verbose && PrintGC) {
  98.174 -    size_t new_mem_size = _g1_storage.committed_size();
  98.175 -    gclog_or_tty->print_cr("...%s, expanded to %ldK",
  98.176 -                           (successful ? "Successful" : "Failed"),
  98.177 -                           new_mem_size/K);
  98.178 -  }
  98.179    return successful;
  98.180  }
  98.181  
  98.182 @@ -1722,6 +1708,13 @@
  98.183    MemRegion mr = _hrs.shrink_by(aligned_shrink_bytes, &num_regions_deleted);
  98.184    HeapWord* old_end = (HeapWord*) _g1_storage.high();
  98.185    assert(mr.end() == old_end, "post-condition");
  98.186 +
  98.187 +  ergo_verbose3(ErgoHeapSizing,
  98.188 +                "shrink the heap",
  98.189 +                ergo_format_byte("requested shrinking amount")
  98.190 +                ergo_format_byte("aligned shrinking amount")
  98.191 +                ergo_format_byte("attempted shrinking amount"),
  98.192 +                shrink_bytes, aligned_shrink_bytes, mr.byte_size());
  98.193    if (mr.byte_size() > 0) {
  98.194      if (_hr_printer.is_active()) {
  98.195        HeapWord* curr = mr.end();
  98.196 @@ -1740,13 +1733,11 @@
  98.197      _expansion_regions += num_regions_deleted;
  98.198      update_committed_space(old_end, new_end);
  98.199      HeapRegionRemSet::shrink_heap(n_regions());
  98.200 -
  98.201 -    if (Verbose && PrintGC) {
  98.202 -      size_t new_mem_size = _g1_storage.committed_size();
  98.203 -      gclog_or_tty->print_cr("Shrinking garbage-first heap from %ldK by %ldK to %ldK",
  98.204 -                             old_mem_size/K, aligned_shrink_bytes/K,
  98.205 -                             new_mem_size/K);
  98.206 -    }
  98.207 +    g1_policy()->record_new_heap_size(n_regions());
  98.208 +  } else {
  98.209 +    ergo_verbose0(ErgoHeapSizing,
  98.210 +                  "did not shrink the heap",
  98.211 +                  ergo_format_reason("heap shrinking operation failed"));
  98.212    }
  98.213  }
  98.214  
  98.215 @@ -3534,6 +3525,19 @@
  98.216  
  98.217        init_mutator_alloc_region();
  98.218  
  98.219 +      {
  98.220 +        size_t expand_bytes = g1_policy()->expansion_amount();
  98.221 +        if (expand_bytes > 0) {
  98.222 +          size_t bytes_before = capacity();
  98.223 +          if (!expand(expand_bytes)) {
  98.224 +            // We failed to expand the heap so let's verify that
  98.225 +            // committed/uncommitted amount match the backing store
  98.226 +            assert(capacity() == _g1_storage.committed_size(), "committed size mismatch");
  98.227 +            assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch");
  98.228 +          }
  98.229 +        }
  98.230 +      }
  98.231 +
  98.232        double end_time_sec = os::elapsedTime();
  98.233        double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
  98.234        g1_policy()->record_pause_time_ms(pause_time_ms);
  98.235 @@ -3579,6 +3583,8 @@
  98.236          size_t expand_bytes = g1_policy()->expansion_amount();
  98.237          if (expand_bytes > 0) {
  98.238            size_t bytes_before = capacity();
  98.239 +          // No need for an ergo verbose message here,
  98.240 +          // expansion_amount() does this when it returns a value > 0.
  98.241            if (!expand(expand_bytes)) {
  98.242              // We failed to expand the heap so let's verify that
  98.243              // committed/uncommitted amount match the backing store
  98.244 @@ -3732,13 +3738,6 @@
  98.245    bool do_object_b(oop p) {
  98.246      // It is reachable if it is outside the collection set, or is inside
  98.247      // and forwarded.
  98.248 -
  98.249 -#ifdef G1_DEBUG
  98.250 -    gclog_or_tty->print_cr("is alive "PTR_FORMAT" in CS %d forwarded %d overall %d",
  98.251 -                           (void*) p, _g1->obj_in_cs(p), p->is_forwarded(),
  98.252 -                           !_g1->obj_in_cs(p) || p->is_forwarded());
  98.253 -#endif // G1_DEBUG
  98.254 -
  98.255      return !_g1->obj_in_cs(p) || p->is_forwarded();
  98.256    }
  98.257  };
  98.258 @@ -3750,20 +3749,9 @@
  98.259    void do_oop(narrowOop* p) { guarantee(false, "Not needed"); }
  98.260    void do_oop(      oop* p) {
  98.261      oop obj = *p;
  98.262 -#ifdef G1_DEBUG
  98.263 -    if (PrintGC && Verbose) {
  98.264 -      gclog_or_tty->print_cr("keep alive *"PTR_FORMAT" = "PTR_FORMAT" "PTR_FORMAT,
  98.265 -                             p, (void*) obj, (void*) *p);
  98.266 -    }
  98.267 -#endif // G1_DEBUG
  98.268 -
  98.269      if (_g1->obj_in_cs(obj)) {
  98.270        assert( obj->is_forwarded(), "invariant" );
  98.271        *p = obj->forwardee();
  98.272 -#ifdef G1_DEBUG
  98.273 -      gclog_or_tty->print_cr("     in CSet: moved "PTR_FORMAT" -> "PTR_FORMAT,
  98.274 -                             (void*) obj, (void*) *p);
  98.275 -#endif // G1_DEBUG
  98.276      }
  98.277    }
  98.278  };
  98.279 @@ -4069,6 +4057,23 @@
  98.280  }
  98.281  #endif // PRODUCT
  98.282  
  98.283 +G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
  98.284 +  ParGCAllocBuffer(gclab_word_size),
  98.285 +  _should_mark_objects(false),
  98.286 +  _bitmap(G1CollectedHeap::heap()->reserved_region().start(), gclab_word_size),
  98.287 +  _retired(false)
  98.288 +{
  98.289 +  //_should_mark_objects is set to true when G1ParCopyHelper needs to
  98.290 +  // mark the forwarded location of an evacuated object.
  98.291 +  // We set _should_mark_objects to true if marking is active, i.e. when we
  98.292 +  // need to propagate a mark, or during an initial mark pause, i.e. when we
  98.293 +  // need to mark objects immediately reachable by the roots.
  98.294 +  if (G1CollectedHeap::heap()->mark_in_progress() ||
  98.295 +      G1CollectedHeap::heap()->g1_policy()->during_initial_mark_pause()) {
  98.296 +    _should_mark_objects = true;
  98.297 +  }
  98.298 +}
  98.299 +
  98.300  G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num)
  98.301    : _g1h(g1h),
  98.302      _refs(g1h->task_queue(queue_num)),
  98.303 @@ -4184,12 +4189,14 @@
  98.304  
  98.305  G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) :
  98.306    _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()),
  98.307 -  _par_scan_state(par_scan_state) { }
  98.308 -
  98.309 -template <class T> void G1ParCopyHelper::mark_forwardee(T* p) {
  98.310 -  // This is called _after_ do_oop_work has been called, hence after
  98.311 -  // the object has been relocated to its new location and *p points
  98.312 -  // to its new location.
  98.313 +  _par_scan_state(par_scan_state),
  98.314 +  _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()),
  98.315 +  _mark_in_progress(_g1->mark_in_progress()) { }
  98.316 +
  98.317 +template <class T> void G1ParCopyHelper::mark_object(T* p) {
  98.318 +  // This is called from do_oop_work for objects that are not
  98.319 +  // in the collection set. Objects in the collection set
  98.320 +  // are marked after they have been evacuated.
  98.321  
  98.322    T heap_oop = oopDesc::load_heap_oop(p);
  98.323    if (!oopDesc::is_null(heap_oop)) {
  98.324 @@ -4201,7 +4208,7 @@
  98.325    }
  98.326  }
  98.327  
  98.328 -oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
  98.329 +oop G1ParCopyHelper::copy_to_survivor_space(oop old, bool should_mark_copy) {
  98.330    size_t    word_sz = old->size();
  98.331    HeapRegion* from_region = _g1->heap_region_containing_raw(old);
  98.332    // +1 to make the -1 indexes valid...
  98.333 @@ -4257,8 +4264,8 @@
  98.334        obj->set_mark(m);
  98.335      }
  98.336  
  98.337 -    // preserve "next" mark bit
  98.338 -    if (_g1->mark_in_progress() && !_g1->is_obj_ill(old)) {
  98.339 +    // Mark the evacuated object or propagate "next" mark bit
  98.340 +    if (should_mark_copy) {
  98.341        if (!use_local_bitmaps ||
  98.342            !_par_scan_state->alloc_buffer(alloc_purpose)->mark(obj_ptr)) {
  98.343          // if we couldn't mark it on the local bitmap (this happens when
  98.344 @@ -4266,11 +4273,12 @@
  98.345          // the bullet and do the standard parallel mark
  98.346          _cm->markAndGrayObjectIfNecessary(obj);
  98.347        }
  98.348 -#if 1
  98.349 +
  98.350        if (_g1->isMarkedNext(old)) {
  98.351 +        // Unmark the object's old location so that marking
  98.352 +        // doesn't think the old object is alive.
  98.353          _cm->nextMarkBitMap()->parClear((HeapWord*)old);
  98.354        }
  98.355 -#endif
  98.356      }
  98.357  
  98.358      size_t* surv_young_words = _par_scan_state->surviving_young_words();
  98.359 @@ -4293,26 +4301,62 @@
  98.360    return obj;
  98.361  }
  98.362  
  98.363 -template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_forwardee>
  98.364 +template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
  98.365  template <class T>
  98.366 -void G1ParCopyClosure <do_gen_barrier, barrier, do_mark_forwardee>
  98.367 +void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object>
  98.368  ::do_oop_work(T* p) {
  98.369    oop obj = oopDesc::load_decode_heap_oop(p);
  98.370    assert(barrier != G1BarrierRS || obj != NULL,
  98.371           "Precondition: G1BarrierRS implies obj is nonNull");
  98.372  
  98.373 +  // Marking:
  98.374 +  // If the object is in the collection set, then the thread
  98.375 +  // that copies the object should mark, or propagate the
  98.376 +  // mark to, the evacuated object.
  98.377 +  // If the object is not in the collection set then we
  98.378 +  // should call the mark_object() method depending on the
  98.379 +  // value of the template parameter do_mark_object (which will
  98.380 +  // be true for root scanning closures during an initial mark
  98.381 +  // pause).
  98.382 +  // The mark_object() method first checks whether the object
  98.383 +  // is marked and, if not, attempts to mark the object.
  98.384 +
  98.385    // here the null check is implicit in the cset_fast_test() test
  98.386    if (_g1->in_cset_fast_test(obj)) {
  98.387      if (obj->is_forwarded()) {
  98.388        oopDesc::encode_store_heap_oop(p, obj->forwardee());
  98.389 +      // If we are a root scanning closure during an initial
  98.390 +      // mark pause (i.e. do_mark_object will be true) then
  98.391 +      // we also need to handle marking of roots in the
  98.392 +      // event of an evacuation failure. In the event of an
  98.393 +      // evacuation failure, the object is forwarded to itself
  98.394 +      // and not copied so let's mark it here.
  98.395 +      if (do_mark_object && obj->forwardee() == obj) {
  98.396 +        mark_object(p);
  98.397 +      }
  98.398      } else {
  98.399 -      oop copy_oop = copy_to_survivor_space(obj);
  98.400 +      // We need to mark the copied object if we're a root scanning
  98.401 +      // closure during an initial mark pause (i.e. do_mark_object
  98.402 +      // will be true), or the object is already marked and we need
  98.403 +      // to propagate the mark to the evacuated copy.
  98.404 +      bool should_mark_copy = do_mark_object ||
  98.405 +                              _during_initial_mark ||
  98.406 +                              (_mark_in_progress && !_g1->is_obj_ill(obj));
  98.407 +
  98.408 +      oop copy_oop = copy_to_survivor_space(obj, should_mark_copy);
  98.409        oopDesc::encode_store_heap_oop(p, copy_oop);
  98.410      }
  98.411      // When scanning the RS, we only care about objs in CS.
  98.412      if (barrier == G1BarrierRS) {
  98.413        _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num());
  98.414      }
  98.415 +  } else {
  98.416 +    // The object is not in collection set. If we're a root scanning
  98.417 +    // closure during an initial mark pause (i.e. do_mark_object will
  98.418 +    // be true) then attempt to mark the object.
  98.419 +    if (do_mark_object) {
  98.420 +      mark_object(p);
  98.421 +    }
  98.422    }
  98.423  
  98.424    if (barrier == G1BarrierEvac && obj != NULL) {
  98.425 @@ -4557,7 +4601,6 @@
  98.426      // keep entries (which are added by the marking threads) on them
  98.427      // live until they can be processed at the end of marking.
  98.428      ref_processor()->weak_oops_do(&buf_scan_non_heap_roots);
  98.429 -    ref_processor()->oops_do(&buf_scan_non_heap_roots);
  98.430    }
  98.431  
  98.432    // Finish up any enqueued closure apps (attributed as object copy time).
    99.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Thu Sep 08 16:59:27 2011 -0700
    99.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Sep 09 16:17:16 2011 -0700
    99.3 @@ -1715,26 +1715,22 @@
    99.4  class G1ParGCAllocBuffer: public ParGCAllocBuffer {
    99.5  private:
    99.6    bool        _retired;
    99.7 -  bool        _during_marking;
    99.8 +  bool        _should_mark_objects;
    99.9    GCLabBitMap _bitmap;
   99.10  
   99.11  public:
   99.12 -  G1ParGCAllocBuffer(size_t gclab_word_size) :
   99.13 -    ParGCAllocBuffer(gclab_word_size),
   99.14 -    _during_marking(G1CollectedHeap::heap()->mark_in_progress()),
   99.15 -    _bitmap(G1CollectedHeap::heap()->reserved_region().start(), gclab_word_size),
   99.16 -    _retired(false)
   99.17 -  { }
   99.18 +  G1ParGCAllocBuffer(size_t gclab_word_size);
   99.19  
   99.20    inline bool mark(HeapWord* addr) {
   99.21      guarantee(use_local_bitmaps, "invariant");
   99.22 -    assert(_during_marking, "invariant");
   99.23 +    assert(_should_mark_objects, "invariant");
   99.24      return _bitmap.mark(addr);
   99.25    }
   99.26  
   99.27    inline void set_buf(HeapWord* buf) {
   99.28 -    if (use_local_bitmaps && _during_marking)
   99.29 +    if (use_local_bitmaps && _should_mark_objects) {
   99.30        _bitmap.set_buffer(buf);
   99.31 +    }
   99.32      ParGCAllocBuffer::set_buf(buf);
   99.33      _retired = false;
   99.34    }
   99.35 @@ -1742,7 +1738,7 @@
   99.36    inline void retire(bool end_of_gc, bool retain) {
   99.37      if (_retired)
   99.38        return;
   99.39 -    if (use_local_bitmaps && _during_marking) {
   99.40 +    if (use_local_bitmaps && _should_mark_objects) {
   99.41        _bitmap.retire();
   99.42      }
   99.43      ParGCAllocBuffer::retire(end_of_gc, retain);
   100.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Thu Sep 08 16:59:27 2011 -0700
   100.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Sep 09 16:17:16 2011 -0700
   100.3 @@ -28,6 +28,7 @@
   100.4  #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
   100.5  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
   100.6  #include "gc_implementation/g1/g1CollectorPolicy.hpp"
   100.7 +#include "gc_implementation/g1/g1ErgoVerbose.hpp"
   100.8  #include "gc_implementation/g1/heapRegionRemSet.hpp"
   100.9  #include "gc_implementation/shared/gcPolicyCounters.hpp"
  100.10  #include "runtime/arguments.hpp"
  100.11 @@ -145,6 +146,7 @@
  100.12    _stop_world_start(0.0),
  100.13    _all_stop_world_times_ms(new NumberSeq()),
  100.14    _all_yield_times_ms(new NumberSeq()),
  100.15 +  _using_new_ratio_calculations(false),
  100.16  
  100.17    _all_mod_union_times_ms(new NumberSeq()),
  100.18  
  100.19 @@ -271,15 +273,26 @@
  100.20    _recorded_survivor_tail(NULL),
  100.21    _survivors_age_table(true),
  100.22  
  100.23 -  _gc_overhead_perc(0.0)
  100.24 -
  100.25 -{
  100.26 +  _gc_overhead_perc(0.0) {
  100.27 +
  100.28    // Set up the region size and associated fields. Given that the
  100.29    // policy is created before the heap, we have to set this up here,
  100.30    // so it's done as soon as possible.
  100.31    HeapRegion::setup_heap_region_size(Arguments::min_heap_size());
  100.32    HeapRegionRemSet::setup_remset_size();
  100.33  
  100.34 +  G1ErgoVerbose::initialize();
  100.35 +  if (PrintAdaptiveSizePolicy) {
  100.36 +    // Currently, we only use a single switch for all the heuristics.
  100.37 +    G1ErgoVerbose::set_enabled(true);
  100.38 +    // Given that we don't currently have a verboseness level
  100.39 +    // parameter, we'll hardcode this to high. This can be easily
  100.40 +    // changed in the future.
  100.41 +    G1ErgoVerbose::set_level(ErgoHigh);
  100.42 +  } else {
  100.43 +    G1ErgoVerbose::set_enabled(false);
  100.44 +  }
  100.45 +
  100.46    // Verify PLAB sizes
  100.47    const uint region_size = HeapRegion::GrainWords;
  100.48    if (YoungPLABSize > region_size || OldPLABSize > region_size) {
  100.49 @@ -402,7 +415,7 @@
  100.50    _concurrent_mark_cleanup_times_ms->add(0.20);
  100.51    _tenuring_threshold = MaxTenuringThreshold;
  100.52    // _max_survivor_regions will be calculated by
  100.53 -  // calculate_young_list_target_length() during initialization.
  100.54 +  // update_young_list_target_length() during initialization.
  100.55    _max_survivor_regions = 0;
  100.56  
  100.57    assert(GCTimeRatio > 0,
  100.58 @@ -410,6 +423,18 @@
  100.59           "if a user set it to 0");
  100.60    _gc_overhead_perc = 100.0 * (1.0 / (1.0 + GCTimeRatio));
  100.61  
  100.62 +  uintx reserve_perc = G1ReservePercent;
  100.63 +  // Put an artificial ceiling on this so that it's not set to a silly value.
  100.64 +  if (reserve_perc > 50) {
  100.65 +    reserve_perc = 50;
  100.66 +    warning("G1ReservePercent is set to a value that is too large, "
  100.67 +            "it's been updated to %u", reserve_perc);
  100.68 +  }
  100.69 +  _reserve_factor = (double) reserve_perc / 100.0;
  100.70 +  // This will be set when the heap is expanded
  100.71 +  // for the first time during initialization.
  100.72 +  _reserve_regions = 0;
  100.73 +
  100.74    initialize_all();
  100.75  }
  100.76  
  100.77 @@ -434,16 +459,15 @@
  100.78  // ParallelScavengeHeap::initialize()). We might change this in the
  100.79  // future, but it's a good start.
  100.80  class G1YoungGenSizer : public TwoGenerationCollectorPolicy {
  100.81 -  size_t size_to_region_num(size_t byte_size) {
  100.82 -    return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
  100.83 -  }
  100.84  
  100.85  public:
  100.86    G1YoungGenSizer() {
  100.87      initialize_flags();
  100.88      initialize_size_info();
  100.89    }
  100.90 -
  100.91 +  size_t size_to_region_num(size_t byte_size) {
  100.92 +    return MAX2((size_t) 1, byte_size / HeapRegion::GrainBytes);
  100.93 +  }
  100.94    size_t min_young_region_num() {
  100.95      return size_to_region_num(_min_gen0_size);
  100.96    }
  100.97 @@ -455,6 +479,13 @@
  100.98    }
  100.99  };
 100.100  
 100.101 +void G1CollectorPolicy::update_young_list_size_using_newratio(size_t number_of_heap_regions) {
 100.102 +  assert(number_of_heap_regions > 0, "Heap must be initialized");
 100.103 +  size_t young_size = number_of_heap_regions / (NewRatio + 1);
 100.104 +  _min_desired_young_length = young_size;
 100.105 +  _max_desired_young_length = young_size;
 100.106 +}
 100.107 +
 100.108  void G1CollectorPolicy::init() {
 100.109    // Set aside an initial future to_space.
 100.110    _g1 = G1CollectedHeap::heap();
 100.111 @@ -465,18 +496,35 @@
 100.112  
 100.113    G1YoungGenSizer sizer;
 100.114    size_t initial_region_num = sizer.initial_young_region_num();
 100.115 -
 100.116 -  if (UseAdaptiveSizePolicy) {
 100.117 -    set_adaptive_young_list_length(true);
 100.118 +  _min_desired_young_length = sizer.min_young_region_num();
 100.119 +  _max_desired_young_length = sizer.max_young_region_num();
 100.120 +
 100.121 +  if (FLAG_IS_CMDLINE(NewRatio)) {
 100.122 +    if (FLAG_IS_CMDLINE(NewSize) || FLAG_IS_CMDLINE(MaxNewSize)) {
 100.123 +      gclog_or_tty->print_cr("-XX:NewSize and -XX:MaxNewSize overrides -XX:NewRatio");
 100.124 +    } else {
 100.125 +      // Treat NewRatio as a fixed size that is only recalculated when the heap size changes
 100.126 +      size_t heap_regions = sizer.size_to_region_num(_g1->n_regions());
 100.127 +      update_young_list_size_using_newratio(heap_regions);
 100.128 +      _using_new_ratio_calculations = true;
 100.129 +    }
 100.130 +  }
 100.131 +
 100.132 +  // GenCollectorPolicy guarantees that min <= initial <= max.
 100.133 +  // Asserting here just to state that we rely on this property.
 100.134 +  assert(_min_desired_young_length <= _max_desired_young_length, "Invalid min/max young gen size values");
 100.135 +  assert(initial_region_num <= _max_desired_young_length, "Initial young gen size too large");
 100.136 +  assert(_min_desired_young_length <= initial_region_num, "Initial young gen size too small");
 100.137 +
 100.138 +  set_adaptive_young_list_length(_min_desired_young_length < _max_desired_young_length);
 100.139 +  if (adaptive_young_list_length()) {
 100.140      _young_list_fixed_length = 0;
 100.141    } else {
 100.142 -    set_adaptive_young_list_length(false);
 100.143      _young_list_fixed_length = initial_region_num;
 100.144    }
 100.145    _free_regions_at_end_of_collection = _g1->free_regions();
 100.146 -  calculate_young_list_min_length();
 100.147 -  guarantee( _young_list_min_length == 0, "invariant, not enough info" );
 100.148 -  calculate_young_list_target_length();
 100.149 +  update_young_list_target_length();
 100.150 +  _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes;
 100.151  
 100.152    // We may immediately start allocating regions and placing them on the
 100.153    // collection set list. Initialize the per-collection set info
 100.154 @@ -484,236 +532,259 @@
 100.155  }
 100.156  
 100.157  // Create the jstat counters for the policy.
 100.158 -void G1CollectorPolicy::initialize_gc_policy_counters()
 100.159 -{
 100.160 +void G1CollectorPolicy::initialize_gc_policy_counters() {
 100.161    _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3);
 100.162  }
 100.163  
 100.164 -void G1CollectorPolicy::calculate_young_list_min_length() {
 100.165 -  _young_list_min_length = 0;
 100.166 -
 100.167 -  if (!adaptive_young_list_length())
 100.168 -    return;
 100.169 -
 100.170 -  if (_alloc_rate_ms_seq->num() > 3) {
 100.171 -    double now_sec = os::elapsedTime();
 100.172 -    double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
 100.173 -    double alloc_rate_ms = predict_alloc_rate_ms();
 100.174 -    size_t min_regions = (size_t) ceil(alloc_rate_ms * when_ms);
 100.175 -    size_t current_region_num = _g1->young_list()->length();
 100.176 -    _young_list_min_length = min_regions + current_region_num;
 100.177 +bool G1CollectorPolicy::predict_will_fit(size_t young_length,
 100.178 +                                         double base_time_ms,
 100.179 +                                         size_t base_free_regions,
 100.180 +                                         double target_pause_time_ms) {
 100.181 +  if (young_length >= base_free_regions) {
 100.182 +    // end condition 1: not enough space for the young regions
 100.183 +    return false;
 100.184 +  }
 100.185 +
 100.186 +  double accum_surv_rate = accum_yg_surv_rate_pred((int)(young_length - 1));
 100.187 +  size_t bytes_to_copy =
 100.188 +               (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes);
 100.189 +  double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy);
 100.190 +  double young_other_time_ms = predict_young_other_time_ms(young_length);
 100.191 +  double pause_time_ms = base_time_ms + copy_time_ms + young_other_time_ms;
 100.192 +  if (pause_time_ms > target_pause_time_ms) {
 100.193 +    // end condition 2: prediction is over the target pause time
 100.194 +    return false;
 100.195 +  }
 100.196 +
 100.197 +  size_t free_bytes =
 100.198 +                  (base_free_regions - young_length) * HeapRegion::GrainBytes;
 100.199 +  if ((2.0 * sigma()) * (double) bytes_to_copy > (double) free_bytes) {
 100.200 +    // end condition 3: out-of-space (conservatively!)
 100.201 +    return false;
 100.202 +  }
 100.203 +
 100.204 +  // success!
 100.205 +  return true;
 100.206 +}
 100.207 +
 100.208 +void G1CollectorPolicy::record_new_heap_size(size_t new_number_of_regions) {
 100.209 +  // re-calculate the necessary reserve
 100.210 +  double reserve_regions_d = (double) new_number_of_regions * _reserve_factor;
 100.211 +  // We use ceiling so that if reserve_regions_d is > 0.0 (but
 100.212 +  // smaller than 1.0) we'll get 1.
 100.213 +  _reserve_regions = (size_t) ceil(reserve_regions_d);
 100.214 +
 100.215 +  if (_using_new_ratio_calculations) {
 100.216 +    // -XX:NewRatio was specified so we need to update the
 100.217 +    // young gen length when the heap size has changed.
 100.218 +    update_young_list_size_using_newratio(new_number_of_regions);
 100.219    }
 100.220  }
 100.221  
 100.222 -void G1CollectorPolicy::calculate_young_list_target_length() {
 100.223 +size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
 100.224 +                                                     size_t base_min_length) {
 100.225 +  size_t desired_min_length = 0;
 100.226    if (adaptive_young_list_length()) {
 100.227 -    size_t rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq);
 100.228 -    calculate_young_list_target_length(rs_lengths);
 100.229 -  } else {
 100.230 -    if (full_young_gcs())
 100.231 -      _young_list_target_length = _young_list_fixed_length;
 100.232 -    else
 100.233 -      _young_list_target_length = _young_list_fixed_length / 2;
 100.234 +    if (_alloc_rate_ms_seq->num() > 3) {
 100.235 +      double now_sec = os::elapsedTime();
 100.236 +      double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
 100.237 +      double alloc_rate_ms = predict_alloc_rate_ms();
 100.238 +      desired_min_length = (size_t) ceil(alloc_rate_ms * when_ms);
 100.239 +    } else {
 100.240 +      // otherwise we don't have enough info to make the prediction
 100.241 +    }
 100.242    }
 100.243 -
 100.244 -  // Make sure we allow the application to allocate at least one
 100.245 -  // region before we need to do a collection again.
 100.246 -  size_t min_length = _g1->young_list()->length() + 1;
 100.247 -  _young_list_target_length = MAX2(_young_list_target_length, min_length);
 100.248 -  calculate_max_gc_locker_expansion();
 100.249 -  calculate_survivors_policy();
 100.250 +  desired_min_length += base_min_length;
 100.251 +  // make sure we don't go below any user-defined minimum bound
 100.252 +  return MAX2(_min_desired_young_length, desired_min_length);
 100.253  }
 100.254  
 100.255 -void G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths) {
 100.256 -  guarantee( adaptive_young_list_length(), "pre-condition" );
 100.257 -  guarantee( !_in_marking_window || !_last_full_young_gc, "invariant" );
 100.258 -
 100.259 -  double start_time_sec = os::elapsedTime();
 100.260 -  size_t min_reserve_perc = MAX2((size_t)2, (size_t)G1ReservePercent);
 100.261 -  min_reserve_perc = MIN2((size_t) 50, min_reserve_perc);
 100.262 -  size_t reserve_regions =
 100.263 -    (size_t) ((double) min_reserve_perc * (double) _g1->n_regions() / 100.0);
 100.264 -
 100.265 -  if (full_young_gcs() && _free_regions_at_end_of_collection > 0) {
 100.266 -    // we are in fully-young mode and there are free regions in the heap
 100.267 -
 100.268 -    double survivor_regions_evac_time =
 100.269 -        predict_survivor_regions_evac_time();
 100.270 -
 100.271 -    double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
 100.272 -    size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq);
 100.273 -    size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff();
 100.274 -    size_t scanned_cards = predict_young_card_num(adj_rs_lengths);
 100.275 -    double base_time_ms = predict_base_elapsed_time_ms(pending_cards, scanned_cards)
 100.276 -                          + survivor_regions_evac_time;
 100.277 -
 100.278 -    // the result
 100.279 -    size_t final_young_length = 0;
 100.280 -
 100.281 -    size_t init_free_regions =
 100.282 -      MAX2((size_t)0, _free_regions_at_end_of_collection - reserve_regions);
 100.283 -
 100.284 -    // if we're still under the pause target...
 100.285 -    if (base_time_ms <= target_pause_time_ms) {
 100.286 -      // We make sure that the shortest young length that makes sense
 100.287 -      // fits within the target pause time.
 100.288 -      size_t min_young_length = 1;
 100.289 -
 100.290 -      if (predict_will_fit(min_young_length, base_time_ms,
 100.291 -                                     init_free_regions, target_pause_time_ms)) {
 100.292 -        // The shortest young length will fit within the target pause time;
 100.293 -        // we'll now check whether the absolute maximum number of young
 100.294 -        // regions will fit in the target pause time. If not, we'll do
 100.295 -        // a binary search between min_young_length and max_young_length
 100.296 -        size_t abs_max_young_length = _free_regions_at_end_of_collection - 1;
 100.297 -        size_t max_young_length = abs_max_young_length;
 100.298 -
 100.299 -        if (max_young_length > min_young_length) {
 100.300 -          // Let's check if the initial max young length will fit within the
 100.301 -          // target pause. If so then there is no need to search for a maximal
 100.302 -          // young length - we'll return the initial maximum
 100.303 -
 100.304 -          if (predict_will_fit(max_young_length, base_time_ms,
 100.305 -                                init_free_regions, target_pause_time_ms)) {
 100.306 -            // The maximum young length will satisfy the target pause time.
 100.307 -            // We are done so set min young length to this maximum length.
 100.308 -            // The code after the loop will then set final_young_length using
 100.309 -            // the value cached in the minimum length.
 100.310 -            min_young_length = max_young_length;
 100.311 -          } else {
 100.312 -            // The maximum possible number of young regions will not fit within
 100.313 -            // the target pause time so let's search....
 100.314 -
 100.315 -            size_t diff = (max_young_length - min_young_length) / 2;
 100.316 -            max_young_length = min_young_length + diff;
 100.317 -
 100.318 -            while (max_young_length > min_young_length) {
 100.319 -              if (predict_will_fit(max_young_length, base_time_ms,
 100.320 -                                        init_free_regions, target_pause_time_ms)) {
 100.321 -
 100.322 -                // The current max young length will fit within the target
 100.323 -                // pause time. Note we do not exit the loop here. By setting
 100.324 -                // min = max, and then increasing the max below means that
 100.325 -                // we will continue searching for an upper bound in the
 100.326 -                // range [max..max+diff]
 100.327 -                min_young_length = max_young_length;
 100.328 -              }
 100.329 -              diff = (max_young_length - min_young_length) / 2;
 100.330 -              max_young_length = min_young_length + diff;
 100.331 -            }
 100.332 -            // the above loop found a maximal young length that will fit
 100.333 -            // within the target pause time.
 100.334 -          }
 100.335 -          assert(min_young_length <= abs_max_young_length, "just checking");
 100.336 -        }
 100.337 -        final_young_length = min_young_length;
 100.338 -      }
 100.339 -    }
 100.340 -    // and we're done!
 100.341 -
 100.342 -    // we should have at least one region in the target young length
 100.343 -    _young_list_target_length =
 100.344 -                              final_young_length + _recorded_survivor_regions;
 100.345 -
 100.346 -    // let's keep an eye of how long we spend on this calculation
 100.347 -    // right now, I assume that we'll print it when we need it; we
 100.348 -    // should really adde it to the breakdown of a pause
 100.349 -    double end_time_sec = os::elapsedTime();
 100.350 -    double elapsed_time_ms = (end_time_sec - start_time_sec) * 1000.0;
 100.351 -
 100.352 -#ifdef TRACE_CALC_YOUNG_LENGTH
 100.353 -    // leave this in for debugging, just in case
 100.354 -    gclog_or_tty->print_cr("target = %1.1lf ms, young = " SIZE_FORMAT ", "
 100.355 -                           "elapsed %1.2lf ms, (%s%s) " SIZE_FORMAT SIZE_FORMAT,
 100.356 -                           target_pause_time_ms,
 100.357 -                           _young_list_target_length
 100.358 -                           elapsed_time_ms,
 100.359 -                           full_young_gcs() ? "full" : "partial",
 100.360 -                           during_initial_mark_pause() ? " i-m" : "",
 100.361 -                           _in_marking_window,
 100.362 -                           _in_marking_window_im);
 100.363 -#endif // TRACE_CALC_YOUNG_LENGTH
 100.364 -
 100.365 -    if (_young_list_target_length < _young_list_min_length) {
 100.366 -      // bummer; this means that, if we do a pause when the maximal
 100.367 -      // length dictates, we'll violate the pause spacing target (the
 100.368 -      // min length was calculate based on the application's current
 100.369 -      // alloc rate);
 100.370 -
 100.371 -      // so, we have to bite the bullet, and allocate the minimum
 100.372 -      // number. We'll violate our target, but we just can't meet it.
 100.373 -
 100.374 -#ifdef TRACE_CALC_YOUNG_LENGTH
 100.375 -      // leave this in for debugging, just in case
 100.376 -      gclog_or_tty->print_cr("adjusted target length from "
 100.377 -                             SIZE_FORMAT " to " SIZE_FORMAT,
 100.378 -                             _young_list_target_length, _young_list_min_length);
 100.379 -#endif // TRACE_CALC_YOUNG_LENGTH
 100.380 -
 100.381 -      _young_list_target_length = _young_list_min_length;
 100.382 +size_t G1CollectorPolicy::calculate_young_list_desired_max_length() {
 100.383 +  // Here, we might want to also take into account any additional
 100.384 +  // constraints (i.e., user-defined minimum bound). Currently, we
 100.385 +  // effectively don't set this bound.
 100.386 +  return _max_desired_young_length;
 100.387 +}
 100.388 +
 100.389 +void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {
 100.390 +  if (rs_lengths == (size_t) -1) {
 100.391 +    // if it's set to the default value (-1), we should predict it;
 100.392 +    // otherwise, use the given value.
 100.393 +    rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq);
 100.394 +  }
 100.395 +
 100.396 +  // Calculate the absolute and desired min bounds.
 100.397 +
 100.398 +  // This is how many young regions we already have (currently: the survivors).
 100.399 +  size_t base_min_length = recorded_survivor_regions();
 100.400 +  // This is the absolute minimum young length, which ensures that we
 100.401 +  // can allocate one eden region in the worst-case.
 100.402 +  size_t absolute_min_length = base_min_length + 1;
 100.403 +  size_t desired_min_length =
 100.404 +                     calculate_young_list_desired_min_length(base_min_length);
 100.405 +  if (desired_min_length < absolute_min_length) {
 100.406 +    desired_min_length = absolute_min_length;
 100.407 +  }
 100.408 +
 100.409 +  // Calculate the absolute and desired max bounds.
 100.410 +
 100.411 +  // We will try our best not to "eat" into the reserve.
 100.412 +  size_t absolute_max_length = 0;
 100.413 +  if (_free_regions_at_end_of_collection > _reserve_regions) {
 100.414 +    absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
 100.415 +  }
 100.416 +  size_t desired_max_length = calculate_young_list_desired_max_length();
 100.417 +  if (desired_max_length > absolute_max_length) {
 100.418 +    desired_max_length = absolute_max_length;
 100.419 +  }
 100.420 +
 100.421 +  size_t young_list_target_length = 0;
 100.422 +  if (adaptive_young_list_length()) {
 100.423 +    if (full_young_gcs()) {
 100.424 +      young_list_target_length =
 100.425 +                        calculate_young_list_target_length(rs_lengths,
 100.426 +                                                           base_min_length,
 100.427 +                                                           desired_min_length,
 100.428 +                                                           desired_max_length);
 100.429 +      _rs_lengths_prediction = rs_lengths;
 100.430 +    } else {
 100.431 +      // Don't calculate anything and let the code below bound it to
 100.432 +      // the desired_min_length, i.e., do the next GC as soon as
 100.433 +      // possible to maximize how many old regions we can add to it.
 100.434      }
 100.435    } else {
 100.436 -    // we are in a partially-young mode or we've run out of regions (due
 100.437 -    // to evacuation failure)
 100.438 -
 100.439 -#ifdef TRACE_CALC_YOUNG_LENGTH
 100.440 -    // leave this in for debugging, just in case
 100.441 -    gclog_or_tty->print_cr("(partial) setting target to " SIZE_FORMAT
 100.442 -                           _young_list_min_length);
 100.443 -#endif // TRACE_CALC_YOUNG_LENGTH
 100.444 -    // we'll do the pause as soon as possible by choosing the minimum
 100.445 -    _young_list_target_length = _young_list_min_length;
 100.446 +    if (full_young_gcs()) {
 100.447 +      young_list_target_length = _young_list_fixed_length;
 100.448 +    } else {
 100.449 +      // A bit arbitrary: during partially-young GCs we allocate half
 100.450 +      // the young regions to try to add old regions to the CSet.
 100.451 +      young_list_target_length = _young_list_fixed_length / 2;
 100.452 +      // We choose to accept that we might go under the desired min
 100.453 +      // length given that we intentionally ask for a smaller young gen.
 100.454 +      desired_min_length = absolute_min_length;
 100.455 +    }
 100.456    }
 100.457  
 100.458 -  _rs_lengths_prediction = rs_lengths;
 100.459 +  // Make sure we don't go over the desired max length, nor under the
 100.460 +  // desired min length. In case they clash, desired_min_length wins
 100.461 +  // which is why that test is second.
 100.462 +  if (young_list_target_length > desired_max_length) {
 100.463 +    young_list_target_length = desired_max_length;
 100.464 +  }
 100.465 +  if (young_list_target_length < desired_min_length) {
 100.466 +    young_list_target_length = desired_min_length;
 100.467 +  }
 100.468 +
 100.469 +  assert(young_list_target_length > recorded_survivor_regions(),
 100.470 +         "we should be able to allocate at least one eden region");
 100.471 +  assert(young_list_target_length >= absolute_min_length, "post-condition");
 100.472 +  _young_list_target_length = young_list_target_length;
 100.473 +
 100.474 +  update_max_gc_locker_expansion();
 100.475  }
 100.476  
 100.477 -// This is used by: calculate_young_list_target_length(rs_length). It
 100.478 -// returns true iff:
 100.479 -//   the predicted pause time for the given young list will not overflow
 100.480 -//   the target pause time
 100.481 -// and:
 100.482 -//   the predicted amount of surviving data will not overflow the
 100.483 -//   the amount of free space available for survivor regions.
 100.484 -//
 100.485 -bool
 100.486 -G1CollectorPolicy::predict_will_fit(size_t young_length,
 100.487 -                                    double base_time_ms,
 100.488 -                                    size_t init_free_regions,
 100.489 -                                    double target_pause_time_ms) {
 100.490 -
 100.491 -  if (young_length >= init_free_regions)
 100.492 -    // end condition 1: not enough space for the young regions
 100.493 -    return false;
 100.494 -
 100.495 -  double accum_surv_rate_adj = 0.0;
 100.496 -  double accum_surv_rate =
 100.497 -    accum_yg_surv_rate_pred((int)(young_length - 1)) - accum_surv_rate_adj;
 100.498 -
 100.499 -  size_t bytes_to_copy =
 100.500 -    (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes);
 100.501 -
 100.502 -  double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy);
 100.503 -
 100.504 -  double young_other_time_ms =
 100.505 -                       predict_young_other_time_ms(young_length);
 100.506 -
 100.507 -  double pause_time_ms =
 100.508 -                   base_time_ms + copy_time_ms + young_other_time_ms;
 100.509 -
 100.510 -  if (pause_time_ms > target_pause_time_ms)
 100.511 -    // end condition 2: over the target pause time
 100.512 -    return false;
 100.513 -
 100.514 -  size_t free_bytes =
 100.515 -                 (init_free_regions - young_length) * HeapRegion::GrainBytes;
 100.516 -
 100.517 -  if ((2.0 + sigma()) * (double) bytes_to_copy > (double) free_bytes)
 100.518 -    // end condition 3: out of to-space (conservatively)
 100.519 -    return false;
 100.520 -
 100.521 -  // success!
 100.522 -  return true;
 100.523 +size_t
 100.524 +G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths,
 100.525 +                                                   size_t base_min_length,
 100.526 +                                                   size_t desired_min_length,
 100.527 +                                                   size_t desired_max_length) {
 100.528 +  assert(adaptive_young_list_length(), "pre-condition");
 100.529 +  assert(full_young_gcs(), "only call this for fully-young GCs");
 100.530 +
 100.531 +  // In case some edge-condition makes the desired max length too small...
 100.532 +  if (desired_max_length <= desired_min_length) {
 100.533 +    return desired_min_length;
 100.534 +  }
 100.535 +
 100.536 +  // We'll adjust min_young_length and max_young_length not to include
 100.537 +  // the already allocated young regions (i.e., so they reflect the
 100.538 +  // min and max eden regions we'll allocate). The base_min_length
 100.539 +  // will be reflected in the predictions by the
 100.540 +  // survivor_regions_evac_time prediction.
 100.541 +  assert(desired_min_length > base_min_length, "invariant");
 100.542 +  size_t min_young_length = desired_min_length - base_min_length;
 100.543 +  assert(desired_max_length > base_min_length, "invariant");
 100.544 +  size_t max_young_length = desired_max_length - base_min_length;
 100.545 +
 100.546 +  double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
 100.547 +  double survivor_regions_evac_time = predict_survivor_regions_evac_time();
 100.548 +  size_t pending_cards = (size_t) get_new_prediction(_pending_cards_seq);
 100.549 +  size_t adj_rs_lengths = rs_lengths + predict_rs_length_diff();
 100.550 +  size_t scanned_cards = predict_young_card_num(adj_rs_lengths);
 100.551 +  double base_time_ms =
 100.552 +    predict_base_elapsed_time_ms(pending_cards, scanned_cards) +
 100.553 +    survivor_regions_evac_time;
 100.554 +  size_t available_free_regions = _free_regions_at_end_of_collection;
 100.555 +  size_t base_free_regions = 0;
 100.556 +  if (available_free_regions > _reserve_regions) {
 100.557 +    base_free_regions = available_free_regions - _reserve_regions;
 100.558 +  }
 100.559 +
 100.560 +  // Here, we will make sure that the shortest young length that
 100.561 +  // makes sense fits within the target pause time.
 100.562 +
 100.563 +  if (predict_will_fit(min_young_length, base_time_ms,
 100.564 +                       base_free_regions, target_pause_time_ms)) {
 100.565 +    // The shortest young length will fit into the target pause time;
 100.566 +    // we'll now check whether the absolute maximum number of young
 100.567 +    // regions will fit in the target pause time. If not, we'll do
 100.568 +    // a binary search between min_young_length and max_young_length.
 100.569 +    if (predict_will_fit(max_young_length, base_time_ms,
 100.570 +                         base_free_regions, target_pause_time_ms)) {
 100.571 +      // The maximum young length will fit into the target pause time.
 100.572 +      // We are done so set min young length to the maximum length (as
 100.573 +      // the result is assumed to be returned in min_young_length).
 100.574 +      min_young_length = max_young_length;
 100.575 +    } else {
 100.576 +      // The maximum possible number of young regions will not fit within
 100.577 +      // the target pause time so we'll search for the optimal
 100.578 +      // length. The loop invariants are:
 100.579 +      //
 100.580 +      // min_young_length < max_young_length
 100.581 +      // min_young_length is known to fit into the target pause time
 100.582 +      // max_young_length is known not to fit into the target pause time
 100.583 +      //
 100.584 +      // Going into the loop we know the above hold as we've just
 100.585 +      // checked them. Every time around the loop we check whether
 100.586 +      // the middle value between min_young_length and
 100.587 +      // max_young_length fits into the target pause time. If it
 100.588 +      // does, it becomes the new min. If it doesn't, it becomes
 100.589 +      // the new max. This way we maintain the loop invariants.
 100.590 +
 100.591 +      assert(min_young_length < max_young_length, "invariant");
 100.592 +      size_t diff = (max_young_length - min_young_length) / 2;
 100.593 +      while (diff > 0) {
 100.594 +        size_t young_length = min_young_length + diff;
 100.595 +        if (predict_will_fit(young_length, base_time_ms,
 100.596 +                             base_free_regions, target_pause_time_ms)) {
 100.597 +          min_young_length = young_length;
 100.598 +        } else {
 100.599 +          max_young_length = young_length;
 100.600 +        }
 100.601 +        assert(min_young_length <  max_young_length, "invariant");
 100.602 +        diff = (max_young_length - min_young_length) / 2;
 100.603 +      }
 100.604 +      // The results is min_young_length which, according to the
 100.605 +      // loop invariants, should fit within the target pause time.
 100.606 +
 100.607 +      // These are the post-conditions of the binary search above:
 100.608 +      assert(min_young_length < max_young_length,
 100.609 +             "otherwise we should have discovered that max_young_length "
 100.610 +             "fits into the pause target and not done the binary search");
 100.611 +      assert(predict_will_fit(min_young_length, base_time_ms,
 100.612 +                              base_free_regions, target_pause_time_ms),
 100.613 +             "min_young_length, the result of the binary search, should "
 100.614 +             "fit into the pause target");
 100.615 +      assert(!predict_will_fit(min_young_length + 1, base_time_ms,
 100.616 +                               base_free_regions, target_pause_time_ms),
 100.617 +             "min_young_length, the result of the binary search, should be "
 100.618 +             "optimal, so no larger length should fit into the pause target");
 100.619 +    }
 100.620 +  } else {
 100.621 +    // Even the minimum length doesn't fit into the pause time
 100.622 +    // target, return it as the result nevertheless.
 100.623 +  }
 100.624 +  return base_min_length + min_young_length;
 100.625  }
 100.626  
 100.627  double G1CollectorPolicy::predict_survivor_regions_evac_time() {
 100.628 @@ -726,17 +797,19 @@
 100.629    return survivor_regions_evac_time;
 100.630  }
 100.631  
 100.632 -void G1CollectorPolicy::check_prediction_validity() {
 100.633 +void G1CollectorPolicy::revise_young_list_target_length_if_necessary() {
 100.634    guarantee( adaptive_young_list_length(), "should not call this otherwise" );
 100.635  
 100.636    size_t rs_lengths = _g1->young_list()->sampled_rs_lengths();
 100.637    if (rs_lengths > _rs_lengths_prediction) {
 100.638      // add 10% to avoid having to recalculate often
 100.639      size_t rs_lengths_prediction = rs_lengths * 1100 / 1000;
 100.640 -    calculate_young_list_target_length(rs_lengths_prediction);
 100.641 +    update_young_list_target_length(rs_lengths_prediction);
 100.642    }
 100.643  }
 100.644  
 100.645 +
 100.646 +
 100.647  HeapWord* G1CollectorPolicy::mem_allocate_work(size_t size,
 100.648                                                 bool is_tlab,
 100.649                                                 bool* gc_overhead_limit_was_exceeded) {
 100.650 @@ -843,8 +916,7 @@
 100.651    _free_regions_at_end_of_collection = _g1->free_regions();
 100.652    // Reset survivors SurvRateGroup.
 100.653    _survivor_surv_rate_group->reset();
 100.654 -  calculate_young_list_min_length();
 100.655 -  calculate_young_list_target_length();
 100.656 +  update_young_list_target_length();
 100.657  }
 100.658  
 100.659  void G1CollectorPolicy::record_stop_world_start() {
 100.660 @@ -859,6 +931,11 @@
 100.661      gclog_or_tty->print(" (%s)", full_young_gcs() ? "young" : "partial");
 100.662    }
 100.663  
 100.664 +  // We only need to do this here as the policy will only be applied
 100.665 +  // to the GC we're about to start. so, no point is calculating this
 100.666 +  // every time we calculate / recalculate the target young length.
 100.667 +  update_survivors_policy();
 100.668 +
 100.669    assert(_g1->used() == _g1->recalculate_used(),
 100.670           err_msg("sanity, used: "SIZE_FORMAT" recalculate_used: "SIZE_FORMAT,
 100.671                   _g1->used(), _g1->recalculate_used()));
 100.672 @@ -959,11 +1036,9 @@
 100.673  G1CollectorPolicy::
 100.674  record_concurrent_mark_cleanup_end_work1(size_t freed_bytes,
 100.675                                           size_t max_live_bytes) {
 100.676 -  if (_n_marks < 2) _n_marks++;
 100.677 -  if (G1PolicyVerbose > 0)
 100.678 -    gclog_or_tty->print_cr("At end of marking, max_live is " SIZE_FORMAT " MB "
 100.679 -                           " (of " SIZE_FORMAT " MB heap).",
 100.680 -                           max_live_bytes/M, _g1->capacity()/M);
 100.681 +  if (_n_marks < 2) {
 100.682 +    _n_marks++;
 100.683 +  }
 100.684  }
 100.685  
 100.686  // The important thing about this is that it includes "os::elapsedTime".
 100.687 @@ -977,14 +1052,6 @@
 100.688    _mmu_tracker->add_pause(_mark_cleanup_start_sec, end_time_sec, true);
 100.689  
 100.690    _num_markings++;
 100.691 -
 100.692 -  // We did a marking, so reset the "since_last_mark" variables.
 100.693 -  double considerConcMarkCost = 1.0;
 100.694 -  // If there are available processors, concurrent activity is free...
 100.695 -  if (Threads::number_of_non_daemon_threads() * 2 <
 100.696 -      os::active_processor_count()) {
 100.697 -    considerConcMarkCost = 0.0;
 100.698 -  }
 100.699    _n_pauses_at_mark_end = _n_pauses;
 100.700    _n_marks_since_last_pause++;
 100.701  }
 100.702 @@ -994,8 +1061,6 @@
 100.703    _should_revert_to_full_young_gcs = false;
 100.704    _last_full_young_gc = true;
 100.705    _in_marking_window = false;
 100.706 -  if (adaptive_young_list_length())
 100.707 -    calculate_young_list_target_length();
 100.708  }
 100.709  
 100.710  void G1CollectorPolicy::record_concurrent_pause() {
 100.711 @@ -1148,20 +1213,37 @@
 100.712    if (last_pause_included_initial_mark)
 100.713      record_concurrent_mark_init_end(0.0);
 100.714  
 100.715 -  size_t min_used_targ =
 100.716 +  size_t marking_initiating_used_threshold =
 100.717      (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent;
 100.718  
 100.719 -
 100.720    if (!_g1->mark_in_progress() && !_last_full_young_gc) {
 100.721      assert(!last_pause_included_initial_mark, "invariant");
 100.722 -    if (cur_used_bytes > min_used_targ &&
 100.723 -      cur_used_bytes > _prev_collection_pause_used_at_end_bytes) {
 100.724 +    if (cur_used_bytes > marking_initiating_used_threshold) {
 100.725 +      if (cur_used_bytes > _prev_collection_pause_used_at_end_bytes) {
 100.726          assert(!during_initial_mark_pause(), "we should not see this here");
 100.727  
 100.728 +        ergo_verbose3(ErgoConcCycles,
 100.729 +                      "request concurrent cycle initiation",
 100.730 +                      ergo_format_reason("occupancy higher than threshold")
 100.731 +                      ergo_format_byte("occupancy")
 100.732 +                      ergo_format_byte_perc("threshold"),
 100.733 +                      cur_used_bytes,
 100.734 +                      marking_initiating_used_threshold,
 100.735 +                      (double) InitiatingHeapOccupancyPercent);
 100.736 +
 100.737          // Note: this might have already been set, if during the last
 100.738          // pause we decided to start a cycle but at the beginning of
 100.739          // this pause we decided to postpone it. That's OK.
 100.740          set_initiate_conc_mark_if_possible();
 100.741 +      } else {
 100.742 +        ergo_verbose2(ErgoConcCycles,
 100.743 +                  "do not request concurrent cycle initiation",
 100.744 +                  ergo_format_reason("occupancy lower than previous occupancy")
 100.745 +                  ergo_format_byte("occupancy")
 100.746 +                  ergo_format_byte("previous occupancy"),
 100.747 +                  cur_used_bytes,
 100.748 +                  _prev_collection_pause_used_at_end_bytes);
 100.749 +      }
 100.750      }
 100.751    }
 100.752  
 100.753 @@ -1437,16 +1519,45 @@
 100.754    }
 100.755  
 100.756    if (_last_full_young_gc) {
 100.757 +    ergo_verbose2(ErgoPartiallyYoungGCs,
 100.758 +                  "start partially-young GCs",
 100.759 +                  ergo_format_byte_perc("known garbage"),
 100.760 +                  _known_garbage_bytes, _known_garbage_ratio * 100.0);
 100.761      set_full_young_gcs(false);
 100.762      _last_full_young_gc = false;
 100.763    }
 100.764  
 100.765    if ( !_last_young_gc_full ) {
 100.766 -    if ( _should_revert_to_full_young_gcs ||
 100.767 -      _known_garbage_ratio < 0.05 ||
 100.768 -      (adaptive_young_list_length() &&
 100.769 -      (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) ) {
 100.770 -        set_full_young_gcs(true);
 100.771 +    if (_should_revert_to_full_young_gcs) {
 100.772 +      ergo_verbose2(ErgoPartiallyYoungGCs,
 100.773 +                    "end partially-young GCs",
 100.774 +                    ergo_format_reason("partially-young GCs end requested")
 100.775 +                    ergo_format_byte_perc("known garbage"),
 100.776 +                    _known_garbage_bytes, _known_garbage_ratio * 100.0);
 100.777 +      set_full_young_gcs(true);
 100.778 +    } else if (_known_garbage_ratio < 0.05) {
 100.779 +      ergo_verbose3(ErgoPartiallyYoungGCs,
 100.780 +               "end partially-young GCs",
 100.781 +               ergo_format_reason("known garbage percent lower than threshold")
 100.782 +               ergo_format_byte_perc("known garbage")
 100.783 +               ergo_format_perc("threshold"),
 100.784 +               _known_garbage_bytes, _known_garbage_ratio * 100.0,
 100.785 +               0.05 * 100.0);
 100.786 +      set_full_young_gcs(true);
 100.787 +    } else if (adaptive_young_list_length() &&
 100.788 +              (get_gc_eff_factor() * cur_efficiency < predict_young_gc_eff())) {
 100.789 +      ergo_verbose5(ErgoPartiallyYoungGCs,
 100.790 +                    "end partially-young GCs",
 100.791 +                    ergo_format_reason("current GC efficiency lower than "
 100.792 +                                       "predicted fully-young GC efficiency")
 100.793 +                    ergo_format_double("GC efficiency factor")
 100.794 +                    ergo_format_double("current GC efficiency")
 100.795 +                    ergo_format_double("predicted fully-young GC efficiency")
 100.796 +                    ergo_format_byte_perc("known garbage"),
 100.797 +                    get_gc_eff_factor(), cur_efficiency,
 100.798 +                    predict_young_gc_eff(),
 100.799 +                    _known_garbage_bytes, _known_garbage_ratio * 100.0);
 100.800 +      set_full_young_gcs(true);
 100.801      }
 100.802    }
 100.803    _should_revert_to_full_young_gcs = false;
 100.804 @@ -1600,8 +1711,7 @@
 100.805    _in_marking_window = new_in_marking_window;
 100.806    _in_marking_window_im = new_in_marking_window_im;
 100.807    _free_regions_at_end_of_collection = _g1->free_regions();
 100.808 -  calculate_young_list_min_length();
 100.809 -  calculate_young_list_target_length();
 100.810 +  update_young_list_target_length();
 100.811  
 100.812    // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
 100.813    double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
 100.814 @@ -1622,20 +1732,26 @@
 100.815      size_t used_before_gc = _cur_collection_pause_used_at_start_bytes;
 100.816      size_t used = _g1->used();
 100.817      size_t capacity = _g1->capacity();
 100.818 +    size_t eden_capacity =
 100.819 +      (_young_list_target_length * HeapRegion::GrainBytes) - survivor_bytes;
 100.820  
 100.821      gclog_or_tty->print_cr(
 100.822 -         "   [Eden: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
 100.823 -             "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
 100.824 -             "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
 100.825 -                     EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
 100.826 -             EXT_SIZE_PARAMS(_eden_bytes_before_gc),
 100.827 -               EXT_SIZE_PARAMS(eden_bytes),
 100.828 -             EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
 100.829 -               EXT_SIZE_PARAMS(survivor_bytes),
 100.830 -             EXT_SIZE_PARAMS(used_before_gc),
 100.831 -             EXT_SIZE_PARAMS(_capacity_before_gc),
 100.832 -               EXT_SIZE_PARAMS(used),
 100.833 -               EXT_SIZE_PARAMS(capacity));
 100.834 +      "   [Eden: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT") "
 100.835 +      "Survivors: "EXT_SIZE_FORMAT"->"EXT_SIZE_FORMAT" "
 100.836 +      "Heap: "EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")->"
 100.837 +      EXT_SIZE_FORMAT"("EXT_SIZE_FORMAT")]",
 100.838 +      EXT_SIZE_PARAMS(_eden_bytes_before_gc),
 100.839 +      EXT_SIZE_PARAMS(_prev_eden_capacity),
 100.840 +      EXT_SIZE_PARAMS(eden_bytes),
 100.841 +      EXT_SIZE_PARAMS(eden_capacity),
 100.842 +      EXT_SIZE_PARAMS(_survivor_bytes_before_gc),
 100.843 +      EXT_SIZE_PARAMS(survivor_bytes),
 100.844 +      EXT_SIZE_PARAMS(used_before_gc),
 100.845 +      EXT_SIZE_PARAMS(_capacity_before_gc),
 100.846 +      EXT_SIZE_PARAMS(used),
 100.847 +      EXT_SIZE_PARAMS(capacity));
 100.848 +
 100.849 +    _prev_eden_capacity = eden_capacity;
 100.850    } else if (PrintGC) {
 100.851      _g1->print_size_transition(gclog_or_tty,
 100.852                                 _cur_collection_pause_used_at_start_bytes,
 100.853 @@ -1877,6 +1993,12 @@
 100.854    // I don't think we need to do this when in young GC mode since
 100.855    // marking will be initiated next time we hit the soft limit anyway...
 100.856    if (predicted_time_ms > _expensive_region_limit_ms) {
 100.857 +    ergo_verbose2(ErgoPartiallyYoungGCs,
 100.858 +              "request partially-young GCs end",
 100.859 +              ergo_format_reason("predicted region time higher than threshold")
 100.860 +              ergo_format_ms("predicted region time")
 100.861 +              ergo_format_ms("threshold"),
 100.862 +              predicted_time_ms, _expensive_region_limit_ms);
 100.863      // no point in doing another partial one
 100.864      _should_revert_to_full_young_gcs = true;
 100.865    }
 100.866 @@ -1986,7 +2108,9 @@
 100.867  }
 100.868  
 100.869  size_t G1CollectorPolicy::expansion_amount() {
 100.870 -  if ((recent_avg_pause_time_ratio() * 100.0) > _gc_overhead_perc) {
 100.871 +  double recent_gc_overhead = recent_avg_pause_time_ratio() * 100.0;
 100.872 +  double threshold = _gc_overhead_perc;
 100.873 +  if (recent_gc_overhead > threshold) {
 100.874      // We will double the existing space, or take
 100.875      // G1ExpandByPercentOfAvailable % of the available expansion
 100.876      // space, whichever is smaller, bounded below by a minimum
 100.877 @@ -2001,20 +2125,19 @@
 100.878      expand_bytes = MIN2(expand_bytes_via_pct, committed_bytes);
 100.879      expand_bytes = MAX2(expand_bytes, min_expand_bytes);
 100.880      expand_bytes = MIN2(expand_bytes, uncommitted_bytes);
 100.881 -    if (G1PolicyVerbose > 1) {
 100.882 -      gclog_or_tty->print("Decided to expand: ratio = %5.2f, "
 100.883 -                 "committed = %d%s, uncommited = %d%s, via pct = %d%s.\n"
 100.884 -                 "                   Answer = %d.\n",
 100.885 -                 recent_avg_pause_time_ratio(),
 100.886 -                 byte_size_in_proper_unit(committed_bytes),
 100.887 -                 proper_unit_for_byte_size(committed_bytes),
 100.888 -                 byte_size_in_proper_unit(uncommitted_bytes),
 100.889 -                 proper_unit_for_byte_size(uncommitted_bytes),
 100.890 -                 byte_size_in_proper_unit(expand_bytes_via_pct),
 100.891 -                 proper_unit_for_byte_size(expand_bytes_via_pct),
 100.892 -                 byte_size_in_proper_unit(expand_bytes),
 100.893 -                 proper_unit_for_byte_size(expand_bytes));
 100.894 -    }
 100.895 +
 100.896 +    ergo_verbose5(ErgoHeapSizing,
 100.897 +                  "attempt heap expansion",
 100.898 +                  ergo_format_reason("recent GC overhead higher than "
 100.899 +                                     "threshold after GC")
 100.900 +                  ergo_format_perc("recent GC overhead")
 100.901 +                  ergo_format_perc("threshold")
 100.902 +                  ergo_format_byte("uncommitted")
 100.903 +                  ergo_format_byte_perc("calculated expansion amount"),
 100.904 +                  recent_gc_overhead, threshold,
 100.905 +                  uncommitted_bytes,
 100.906 +                  expand_bytes_via_pct, (double) G1ExpandByPercentOfAvailable);
 100.907 +
 100.908      return expand_bytes;
 100.909    } else {
 100.910      return 0;
 100.911 @@ -2237,8 +2360,7 @@
 100.912  #endif // PRODUCT
 100.913  }
 100.914  
 100.915 -void
 100.916 -G1CollectorPolicy::update_region_num(bool young) {
 100.917 +void G1CollectorPolicy::update_region_num(bool young) {
 100.918    if (young) {
 100.919      ++_region_num_young;
 100.920    } else {
 100.921 @@ -2270,7 +2392,7 @@
 100.922    };
 100.923  }
 100.924  
 100.925 -void G1CollectorPolicy::calculate_max_gc_locker_expansion() {
 100.926 +void G1CollectorPolicy::update_max_gc_locker_expansion() {
 100.927    size_t expansion_region_num = 0;
 100.928    if (GCLockerEdenExpansionPercent > 0) {
 100.929      double perc = (double) GCLockerEdenExpansionPercent / 100.0;
 100.930 @@ -2286,9 +2408,13 @@
 100.931  }
 100.932  
 100.933  // Calculates survivor space parameters.
 100.934 -void G1CollectorPolicy::calculate_survivors_policy()
 100.935 -{
 100.936 -  _max_survivor_regions = _young_list_target_length / SurvivorRatio;
 100.937 +void G1CollectorPolicy::update_survivors_policy() {
 100.938 +  double max_survivor_regions_d =
 100.939 +                 (double) _young_list_target_length / (double) SurvivorRatio;
 100.940 +  // We use ceiling so that if max_survivor_regions_d is > 0.0 (but
 100.941 +  // smaller than 1.0) we'll get 1.
 100.942 +  _max_survivor_regions = (size_t) ceil(max_survivor_regions_d);
 100.943 +
 100.944    _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
 100.945          HeapRegion::GrainWords * _max_survivor_regions);
 100.946  }
 100.947 @@ -2315,13 +2441,23 @@
 100.948  }
 100.949  #endif
 100.950  
 100.951 -bool
 100.952 -G1CollectorPolicy::force_initial_mark_if_outside_cycle() {
 100.953 +bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(
 100.954 +                                                     GCCause::Cause gc_cause) {
 100.955    bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
 100.956    if (!during_cycle) {
 100.957 +    ergo_verbose1(ErgoConcCycles,
 100.958 +                  "request concurrent cycle initiation",
 100.959 +                  ergo_format_reason("requested by GC cause")
 100.960 +                  ergo_format_str("GC cause"),
 100.961 +                  GCCause::to_string(gc_cause));
 100.962      set_initiate_conc_mark_if_possible();
 100.963      return true;
 100.964    } else {
 100.965 +    ergo_verbose1(ErgoConcCycles,
 100.966 +                  "do not request concurrent cycle initiation",
 100.967 +                  ergo_format_reason("concurrent cycle already in progress")
 100.968 +                  ergo_format_str("GC cause"),
 100.969 +                  GCCause::to_string(gc_cause));
 100.970      return false;
 100.971    }
 100.972  }
 100.973 @@ -2353,6 +2489,10 @@
 100.974        // And we can now clear initiate_conc_mark_if_possible() as
 100.975        // we've already acted on it.
 100.976        clear_initiate_conc_mark_if_possible();
 100.977 +
 100.978 +      ergo_verbose0(ErgoConcCycles,
 100.979 +                  "initiate concurrent cycle",
 100.980 +                  ergo_format_reason("concurrent cycle initiation requested"));
 100.981      } else {
 100.982        // The concurrent marking thread is still finishing up the
 100.983        // previous cycle. If we start one right now the two cycles
 100.984 @@ -2366,6 +2506,9 @@
 100.985        // and, if it's in a yield point, it's waiting for us to
 100.986        // finish. So, at this point we will not start a cycle and we'll
 100.987        // let the concurrent marking thread complete the last one.
 100.988 +      ergo_verbose0(ErgoConcCycles,
 100.989 +                    "do not initiate concurrent cycle",
 100.990 +                    ergo_format_reason("concurrent cycle already in progress"));
 100.991      }
 100.992    }
 100.993  }
 100.994 @@ -2756,6 +2899,8 @@
 100.995    // Set this here - in case we're not doing young collections.
 100.996    double non_young_start_time_sec = os::elapsedTime();
 100.997  
 100.998 +  YoungList* young_list = _g1->young_list();
 100.999 +
100.1000    start_recording_regions();
100.1001  
100.1002    guarantee(target_pause_time_ms > 0.0,
100.1003 @@ -2768,61 +2913,62 @@
100.1004  
100.1005    double time_remaining_ms = target_pause_time_ms - base_time_ms;
100.1006  
100.1007 +  ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
100.1008 +                "start choosing CSet",
100.1009 +                ergo_format_ms("predicted base time")
100.1010 +                ergo_format_ms("remaining time")
100.1011 +                ergo_format_ms("target pause time"),
100.1012 +                base_time_ms, time_remaining_ms, target_pause_time_ms);
100.1013 +
100.1014    // the 10% and 50% values are arbitrary...
100.1015 -  if (time_remaining_ms < 0.10 * target_pause_time_ms) {
100.1016 +  double threshold = 0.10 * target_pause_time_ms;
100.1017 +  if (time_remaining_ms < threshold) {
100.1018 +    double prev_time_remaining_ms = time_remaining_ms;
100.1019      time_remaining_ms = 0.50 * target_pause_time_ms;
100.1020      _within_target = false;
100.1021 +    ergo_verbose3(ErgoCSetConstruction,
100.1022 +                  "adjust remaining time",
100.1023 +                  ergo_format_reason("remaining time lower than threshold")
100.1024 +                  ergo_format_ms("remaining time")
100.1025 +                  ergo_format_ms("threshold")
100.1026 +                  ergo_format_ms("adjusted remaining time"),
100.1027 +                  prev_time_remaining_ms, threshold, time_remaining_ms);
100.1028    } else {
100.1029      _within_target = true;
100.1030    }
100.1031  
100.1032 -  // We figure out the number of bytes available for future to-space.
100.1033 -  // For new regions without marking information, we must assume the
100.1034 -  // worst-case of complete survival.  If we have marking information for a
100.1035 -  // region, we can bound the amount of live data.  We can add a number of
100.1036 -  // such regions, as long as the sum of the live data bounds does not
100.1037 -  // exceed the available evacuation space.
100.1038 -  size_t max_live_bytes = _g1->free_regions() * HeapRegion::GrainBytes;
100.1039 -
100.1040 -  size_t expansion_bytes =
100.1041 -    _g1->expansion_regions() * HeapRegion::GrainBytes;
100.1042 +  size_t expansion_bytes = _g1->expansion_regions() * HeapRegion::GrainBytes;
100.1043 +
100.1044 +  HeapRegion* hr;
100.1045 +  double young_start_time_sec = os::elapsedTime();
100.1046  
100.1047    _collection_set_bytes_used_before = 0;
100.1048    _collection_set_size = 0;
100.1049 -
100.1050 -  // Adjust for expansion and slop.
100.1051 -  max_live_bytes = max_live_bytes + expansion_bytes;
100.1052 -
100.1053 -  HeapRegion* hr;
100.1054 -  double young_start_time_sec = os::elapsedTime();
100.1055 -
100.1056 -  if (G1PolicyVerbose > 0) {
100.1057 -    gclog_or_tty->print_cr("Adding %d young regions to the CSet",
100.1058 -      _g1->young_list()->length());
100.1059 -  }
100.1060 -
100.1061    _young_cset_length  = 0;
100.1062    _last_young_gc_full = full_young_gcs() ? true : false;
100.1063  
100.1064 -  if (_last_young_gc_full)
100.1065 +  if (_last_young_gc_full) {
100.1066      ++_full_young_pause_num;
100.1067 -  else
100.1068 +  } else {
100.1069      ++_partial_young_pause_num;
100.1070 +  }
100.1071  
100.1072    // The young list is laid with the survivor regions from the previous
100.1073    // pause are appended to the RHS of the young list, i.e.
100.1074    //   [Newly Young Regions ++ Survivors from last pause].
100.1075  
100.1076 -  hr = _g1->young_list()->first_survivor_region();
100.1077 +  size_t survivor_region_num = young_list->survivor_length();
100.1078 +  size_t eden_region_num = young_list->length() - survivor_region_num;
100.1079 +  size_t old_region_num = 0;
100.1080 +  hr = young_list->first_survivor_region();
100.1081    while (hr != NULL) {
100.1082      assert(hr->is_survivor(), "badly formed young list");
100.1083      hr->set_young();
100.1084      hr = hr->get_next_young_region();
100.1085    }
100.1086  
100.1087 -  // Clear the fields that point to the survivor list - they are
100.1088 -  // all young now.
100.1089 -  _g1->young_list()->clear_survivors();
100.1090 +  // Clear the fields that point to the survivor list - they are all young now.
100.1091 +  young_list->clear_survivors();
100.1092  
100.1093    if (_g1->mark_in_progress())
100.1094      _g1->concurrent_mark()->register_collection_set_finger(_inc_cset_max_finger);
100.1095 @@ -2831,14 +2977,17 @@
100.1096    _collection_set = _inc_cset_head;
100.1097    _collection_set_size = _inc_cset_size;
100.1098    _collection_set_bytes_used_before = _inc_cset_bytes_used_before;
100.1099 -
100.1100 -  // For young regions in the collection set, we assume the worst
100.1101 -  // case of complete survival
100.1102 -  max_live_bytes -= _inc_cset_size * HeapRegion::GrainBytes;
100.1103 -
100.1104    time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms;
100.1105    predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms;
100.1106  
100.1107 +  ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
100.1108 +                "add young regions to CSet",
100.1109 +                ergo_format_region("eden")
100.1110 +                ergo_format_region("survivors")
100.1111 +                ergo_format_ms("predicted young region time"),
100.1112 +                eden_region_num, survivor_region_num,
100.1113 +                _inc_cset_predicted_elapsed_time_ms);
100.1114 +
100.1115    // The number of recorded young regions is the incremental
100.1116    // collection set's current size
100.1117    set_recorded_young_regions(_inc_cset_size);
100.1118 @@ -2848,14 +2997,7 @@
100.1119    set_predicted_bytes_to_copy(_inc_cset_predicted_bytes_to_copy);
100.1120  #endif // PREDICTIONS_VERBOSE
100.1121  
100.1122 -  if (G1PolicyVerbose > 0) {
100.1123 -    gclog_or_tty->print_cr("  Added " PTR_FORMAT " Young Regions to CS.",
100.1124 -      _inc_cset_size);
100.1125 -    gclog_or_tty->print_cr("    (" SIZE_FORMAT " KB left in heap.)",
100.1126 -      max_live_bytes/K);
100.1127 -  }
100.1128 -
100.1129 -  assert(_inc_cset_size == _g1->young_list()->length(), "Invariant");
100.1130 +  assert(_inc_cset_size == young_list->length(), "Invariant");
100.1131  
100.1132    double young_end_time_sec = os::elapsedTime();
100.1133    _recorded_young_cset_choice_time_ms =
100.1134 @@ -2869,6 +3011,8 @@
100.1135      NumberSeq seq;
100.1136      double avg_prediction = 100000000000000000.0; // something very large
100.1137  
100.1138 +    size_t prev_collection_set_size = _collection_set_size;
100.1139 +    double prev_predicted_pause_time_ms = predicted_pause_time_ms;
100.1140      do {
100.1141        hr = _collectionSetChooser->getNextMarkedRegion(time_remaining_ms,
100.1142                                                        avg_prediction);
100.1143 @@ -2878,23 +3022,58 @@
100.1144          predicted_pause_time_ms += predicted_time_ms;
100.1145          add_to_collection_set(hr);
100.1146          record_non_young_cset_region(hr);
100.1147 -        max_live_bytes -= MIN2(hr->max_live_bytes(), max_live_bytes);
100.1148 -        if (G1PolicyVerbose > 0) {
100.1149 -          gclog_or_tty->print_cr("    (" SIZE_FORMAT " KB left in heap.)",
100.1150 -                        max_live_bytes/K);
100.1151 -        }
100.1152          seq.add(predicted_time_ms);
100.1153          avg_prediction = seq.avg() + seq.sd();
100.1154        }
100.1155 -      should_continue =
100.1156 -        ( hr != NULL) &&
100.1157 -        ( (adaptive_young_list_length()) ? time_remaining_ms > 0.0
100.1158 -          : _collection_set_size < _young_list_fixed_length );
100.1159 +
100.1160 +      should_continue = true;
100.1161 +      if (hr == NULL) {
100.1162 +        // No need for an ergo verbose message here,
100.1163 +        // getNextMarkRegion() does this when it returns NULL.
100.1164 +        should_continue = false;
100.1165 +      } else {
100.1166 +        if (adaptive_young_list_length()) {
100.1167 +          if (time_remaining_ms < 0.0) {
100.1168 +            ergo_verbose1(ErgoCSetConstruction,
100.1169 +                          "stop adding old regions to CSet",
100.1170 +                          ergo_format_reason("remaining time is lower than 0")
100.1171 +                          ergo_format_ms("remaining time"),
100.1172 +                          time_remaining_ms);
100.1173 +            should_continue = false;
100.1174 +          }
100.1175 +        } else {
100.1176 +          if (_collection_set_size < _young_list_fixed_length) {
100.1177 +            ergo_verbose2(ErgoCSetConstruction,
100.1178 +                          "stop adding old regions to CSet",
100.1179 +                          ergo_format_reason("CSet length lower than target")
100.1180 +                          ergo_format_region("CSet")
100.1181 +                          ergo_format_region("young target"),
100.1182 +                          _collection_set_size, _young_list_fixed_length);
100.1183 +            should_continue = false;
100.1184 +          }
100.1185 +        }
100.1186 +      }
100.1187      } while (should_continue);
100.1188  
100.1189      if (!adaptive_young_list_length() &&
100.1190 -        _collection_set_size < _young_list_fixed_length)
100.1191 +        _collection_set_size < _young_list_fixed_length) {
100.1192 +      ergo_verbose2(ErgoCSetConstruction,
100.1193 +                    "request partially-young GCs end",
100.1194 +                    ergo_format_reason("CSet length lower than target")
100.1195 +                    ergo_format_region("CSet")
100.1196 +                    ergo_format_region("young target"),
100.1197 +                    _collection_set_size, _young_list_fixed_length);
100.1198        _should_revert_to_full_young_gcs  = true;
100.1199 +    }
100.1200 +
100.1201 +    old_region_num = _collection_set_size - prev_collection_set_size;
100.1202 +
100.1203 +    ergo_verbose2(ErgoCSetConstruction | ErgoHigh,
100.1204 +                  "add old regions to CSet",
100.1205 +                  ergo_format_region("old")
100.1206 +                  ergo_format_ms("predicted old region time"),
100.1207 +                  old_region_num,
100.1208 +                  predicted_pause_time_ms - prev_predicted_pause_time_ms);
100.1209    }
100.1210  
100.1211    stop_incremental_cset_building();
100.1212 @@ -2903,6 +3082,16 @@
100.1213  
100.1214    end_recording_regions();
100.1215  
100.1216 +  ergo_verbose5(ErgoCSetConstruction,
100.1217 +                "finish choosing CSet",
100.1218 +                ergo_format_region("eden")
100.1219 +                ergo_format_region("survivors")
100.1220 +                ergo_format_region("old")
100.1221 +                ergo_format_ms("predicted pause time")
100.1222 +                ergo_format_ms("target pause time"),
100.1223 +                eden_region_num, survivor_region_num, old_region_num,
100.1224 +                predicted_pause_time_ms, target_pause_time_ms);
100.1225 +
100.1226    double non_young_end_time_sec = os::elapsedTime();
100.1227    _recorded_non_young_cset_choice_time_ms =
100.1228      (non_young_end_time_sec - non_young_start_time_sec) * 1000.0;
100.1229 @@ -2914,12 +3103,6 @@
100.1230  }
100.1231  
100.1232  void G1CollectorPolicy_BestRegionsFirst::
100.1233 -expand_if_possible(size_t numRegions) {
100.1234 -  size_t expansion_bytes = numRegions * HeapRegion::GrainBytes;
100.1235 -  _g1->expand(expansion_bytes);
100.1236 -}
100.1237 -
100.1238 -void G1CollectorPolicy_BestRegionsFirst::
100.1239  record_collection_pause_end() {
100.1240    G1CollectorPolicy::record_collection_pause_end();
100.1241    assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
   101.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Thu Sep 08 16:59:27 2011 -0700
   101.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp	Fri Sep 09 16:17:16 2011 -0700
   101.3 @@ -183,9 +183,9 @@
   101.4    // if true, then it tries to dynamically adjust the length of the
   101.5    // young list
   101.6    bool _adaptive_young_list_length;
   101.7 -  size_t _young_list_min_length;
   101.8    size_t _young_list_target_length;
   101.9    size_t _young_list_fixed_length;
  101.10 +  size_t _prev_eden_capacity; // used for logging
  101.11  
  101.12    // The max number of regions we can extend the eden by while the GC
  101.13    // locker is active. This should be >= _young_list_target_length;
  101.14 @@ -207,6 +207,9 @@
  101.15  
  101.16    double                _gc_overhead_perc;
  101.17  
  101.18 +  double _reserve_factor;
  101.19 +  size_t _reserve_regions;
  101.20 +
  101.21    bool during_marking() {
  101.22      return _during_marking;
  101.23    }
  101.24 @@ -243,6 +246,10 @@
  101.25  
  101.26    TruncatedSeq* _max_conc_overhead_seq;
  101.27  
  101.28 +  bool   _using_new_ratio_calculations;
  101.29 +  size_t _min_desired_young_length; // as set on the command line or default calculations
  101.30 +  size_t _max_desired_young_length; // as set on the command line or default calculations
  101.31 +
  101.32    size_t _recorded_young_regions;
  101.33    size_t _recorded_non_young_regions;
  101.34    size_t _recorded_region_num;
  101.35 @@ -456,12 +463,6 @@
  101.36    size_t predict_bytes_to_copy(HeapRegion* hr);
  101.37    double predict_region_elapsed_time_ms(HeapRegion* hr, bool young);
  101.38  
  101.39 -    // for use by: calculate_young_list_target_length(rs_length)
  101.40 -  bool predict_will_fit(size_t young_region_num,
  101.41 -                        double base_time_ms,
  101.42 -                        size_t init_free_regions,
  101.43 -                        double target_pause_time_ms);
  101.44 -
  101.45    void start_recording_regions();
  101.46    void record_cset_region_info(HeapRegion* hr, bool young);
  101.47    void record_non_young_cset_region(HeapRegion* hr);
  101.48 @@ -493,7 +494,6 @@
  101.49  
  101.50    // </NEW PREDICTION>
  101.51  
  101.52 -public:
  101.53    void cset_regions_freed() {
  101.54      bool propagate = _last_young_gc_full && !_in_marking_window;
  101.55      _short_lived_surv_rate_group->all_surviving_words_recorded(propagate);
  101.56 @@ -772,9 +772,41 @@
  101.57    double _mark_cleanup_start_sec;
  101.58    double _mark_closure_time_ms;
  101.59  
  101.60 -  void   calculate_young_list_min_length();
  101.61 -  void   calculate_young_list_target_length();
  101.62 -  void   calculate_young_list_target_length(size_t rs_lengths);
  101.63 +  // Update the young list target length either by setting it to the
  101.64 +  // desired fixed value or by calculating it using G1's pause
  101.65 +  // prediction model. If no rs_lengths parameter is passed, predict
  101.66 +  // the RS lengths using the prediction model, otherwise use the
  101.67 +  // given rs_lengths as the prediction.
  101.68 +  void update_young_list_target_length(size_t rs_lengths = (size_t) -1);
  101.69 +
  101.70 +  // Calculate and return the minimum desired young list target
  101.71 +  // length. This is the minimum desired young list length according
  101.72 +  // to the user's inputs.
  101.73 +  size_t calculate_young_list_desired_min_length(size_t base_min_length);
  101.74 +
  101.75 +  // Calculate and return the maximum desired young list target
  101.76 +  // length. This is the maximum desired young list length according
  101.77 +  // to the user's inputs.
  101.78 +  size_t calculate_young_list_desired_max_length();
  101.79 +
  101.80 +  // Calculate and return the maximum young list target length that
  101.81 +  // can fit into the pause time goal. The parameters are: rs_lengths
  101.82 +  // represent the prediction of how large the young RSet lengths will
  101.83 +  // be, base_min_length is the alreay existing number of regions in
  101.84 +  // the young list, min_length and max_length are the desired min and
  101.85 +  // max young list length according to the user's inputs.
  101.86 +  size_t calculate_young_list_target_length(size_t rs_lengths,
  101.87 +                                            size_t base_min_length,
  101.88 +                                            size_t desired_min_length,
  101.89 +                                            size_t desired_max_length);
  101.90 +
  101.91 +  // Check whether a given young length (young_length) fits into the
  101.92 +  // given target pause time and whether the prediction for the amount
  101.93 +  // of objects to be copied for the given length will fit into the
  101.94 +  // given free space (expressed by base_free_regions).  It is used by
  101.95 +  // calculate_young_list_target_length().
  101.96 +  bool predict_will_fit(size_t young_length, double base_time_ms,
  101.97 +                        size_t base_free_regions, double target_pause_time_ms);
  101.98  
  101.99  public:
 101.100  
 101.101 @@ -786,7 +818,10 @@
 101.102      return CollectorPolicy::G1CollectorPolicyKind;
 101.103    }
 101.104  
 101.105 -  void check_prediction_validity();
 101.106 +  // Check the current value of the young list RSet lengths and
 101.107 +  // compare it against the last prediction. If the current value is
 101.108 +  // higher, recalculate the young list target length prediction.
 101.109 +  void revise_young_list_target_length_if_necessary();
 101.110  
 101.111    size_t bytes_in_collection_set() {
 101.112      return _bytes_in_collection_set_before_gc;
 101.113 @@ -796,6 +831,9 @@
 101.114      return _all_pause_times_ms->num() + 1;
 101.115    }
 101.116  
 101.117 +  // This should be called after the heap is resized.
 101.118 +  void record_new_heap_size(size_t new_number_of_regions);
 101.119 +
 101.120  protected:
 101.121  
 101.122    // Count the number of bytes used in the CS.
 101.123 @@ -807,6 +845,8 @@
 101.124                                                  size_t max_live_bytes);
 101.125    void record_concurrent_mark_cleanup_end_work2();
 101.126  
 101.127 +  void update_young_list_size_using_newratio(size_t number_of_heap_regions);
 101.128 +
 101.129  public:
 101.130  
 101.131    virtual void init();
 101.132 @@ -1045,7 +1085,7 @@
 101.133    // new cycle, as long as we are not already in one. It's best if it
 101.134    // is called during a safepoint when the test whether a cycle is in
 101.135    // progress or not is stable.
 101.136 -  bool force_initial_mark_if_outside_cycle();
 101.137 +  bool force_initial_mark_if_outside_cycle(GCCause::Cause gc_cause);
 101.138  
 101.139    // This is called at the very beginning of an evacuation pause (it
 101.140    // has to be the first thing that the pause does). If
 101.141 @@ -1204,10 +1244,10 @@
 101.142      _survivors_age_table.merge_par(age_table);
 101.143    }
 101.144  
 101.145 -  void calculate_max_gc_locker_expansion();
 101.146 +  void update_max_gc_locker_expansion();
 101.147  
 101.148    // Calculates survivor space parameters.
 101.149 -  void calculate_survivors_policy();
 101.150 +  void update_survivors_policy();
 101.151  
 101.152  };
 101.153  
 101.154 @@ -1234,8 +1274,6 @@
 101.155  
 101.156  class G1CollectorPolicy_BestRegionsFirst: public G1CollectorPolicy {
 101.157    CollectionSetChooser* _collectionSetChooser;
 101.158 -  // If the estimated is less then desirable, resize if possible.
 101.159 -  void expand_if_possible(size_t numRegions);
 101.160  
 101.161    virtual void choose_collection_set(double target_pause_time_ms);
 101.162    virtual void record_collection_pause_start(double start_time_sec,
 101.163 @@ -1269,8 +1307,4 @@
 101.164    return (sum_of_squares - 2.0 * avg * sum + n_d * avg * avg) / n_d;
 101.165  }
 101.166  
 101.167 -// Local Variables: ***
 101.168 -// c-indentation-style: gnu ***
 101.169 -// End: ***
 101.170 -
 101.171  #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTORPOLICY_HPP
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/src/share/vm/gc_implementation/g1/g1ErgoVerbose.cpp	Fri Sep 09 16:17:16 2011 -0700
   102.3 @@ -0,0 +1,65 @@
   102.4 +/*
   102.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
   102.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   102.7 + *
   102.8 + * This code is free software; you can redistribute it and/or modify it
   102.9 + * under the terms of the GNU General Public License version 2 only, as
  102.10 + * published by the Free Software Foundation.
  102.11 + *
  102.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  102.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  102.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  102.15 + * version 2 for more details (a copy is included in the LICENSE file that
  102.16 + * accompanied this code).
  102.17 + *
  102.18 + * You should have received a copy of the GNU General Public License version
  102.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  102.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  102.21 + *
  102.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  102.23 + * or visit www.oracle.com if you need additional information or have any
  102.24 + * questions.
  102.25 + *
  102.26 + */
  102.27 +
  102.28 +#include "precompiled.hpp"
  102.29 +#include "gc_implementation/g1/g1ErgoVerbose.hpp"
  102.30 +#include "utilities/ostream.hpp"
  102.31 +
  102.32 +ErgoLevel G1ErgoVerbose::_level;
  102.33 +bool G1ErgoVerbose::_enabled[ErgoHeuristicNum];
  102.34 +
  102.35 +void G1ErgoVerbose::initialize() {
  102.36 +  set_level(ErgoLow);
  102.37 +  set_enabled(false);
  102.38 +}
  102.39 +
  102.40 +void G1ErgoVerbose::set_level(ErgoLevel level) {
  102.41 +  _level = level;
  102.42 +}
  102.43 +
  102.44 +void G1ErgoVerbose::set_enabled(ErgoHeuristic n, bool enabled) {
  102.45 +  assert(0 <= n && n < ErgoHeuristicNum, "pre-condition");
  102.46 +  _enabled[n] = enabled;
  102.47 +}
  102.48 +
  102.49 +void G1ErgoVerbose::set_enabled(bool enabled) {
  102.50 +  for (int n = 0; n < ErgoHeuristicNum; n += 1) {
  102.51 +    set_enabled((ErgoHeuristic) n, enabled);
  102.52 +  }
  102.53 +}
  102.54 +
  102.55 +const char* G1ErgoVerbose::to_string(int tag) {
  102.56 +  ErgoHeuristic n = extract_heuristic(tag);
  102.57 +  switch (n) {
  102.58 +  case ErgoHeapSizing:            return "Heap Sizing";
  102.59 +  case ErgoCSetConstruction:      return "CSet Construction";
  102.60 +  case ErgoConcCycles:            return "Concurrent Cycles";
  102.61 +  case ErgoPartiallyYoungGCs:     return "Partially-Young GCs";
  102.62 +  default:
  102.63 +    ShouldNotReachHere();
  102.64 +    // Keep the Windows compiler happy
  102.65 +    return NULL;
  102.66 +  }
  102.67 +}
  102.68 +
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp	Fri Sep 09 16:17:16 2011 -0700
   103.3 @@ -0,0 +1,197 @@
   103.4 +/*
   103.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
   103.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   103.7 + *
   103.8 + * This code is free software; you can redistribute it and/or modify it
   103.9 + * under the terms of the GNU General Public License version 2 only, as
  103.10 + * published by the Free Software Foundation.
  103.11 + *
  103.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  103.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  103.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  103.15 + * version 2 for more details (a copy is included in the LICENSE file that
  103.16 + * accompanied this code).
  103.17 + *
  103.18 + * You should have received a copy of the GNU General Public License version
  103.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  103.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  103.21 + *
  103.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  103.23 + * or visit www.oracle.com if you need additional information or have any
  103.24 + * questions.
  103.25 + *
  103.26 + */
  103.27 +
  103.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP
  103.29 +#define SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP
  103.30 +
  103.31 +#include "memory/allocation.hpp"
  103.32 +#include "utilities/debug.hpp"
  103.33 +
  103.34 +// The log of G1's heuristic decisions comprises of a series of
  103.35 +// records which have a similar format in order to maintain
  103.36 +// consistency across records and ultimately easier parsing of the
  103.37 +// output, if we ever choose to do that. Each record consists of:
  103.38 +// * A time stamp to be able to easily correlate each record with
  103.39 +// other events.
  103.40 +// * A unique string to allow us to easily identify such records.
  103.41 +// * The name of the heuristic the record corresponds to.
  103.42 +// * An action string which describes the action that G1 did or is
  103.43 +// about to do.
  103.44 +// * An optional reason string which describes the reason for the
  103.45 +// action.
  103.46 +// * An optional number of name/value pairs which contributed to the
  103.47 +// decision to take the action described in the record.
  103.48 +//
  103.49 +// Each record is associated with a "tag" which is the combination of
  103.50 +// the heuristic the record corresponds to, as well as the min level
  103.51 +// of verboseness at which the record should be printed. The tag is
  103.52 +// checked against the current settings to determine whether the record
  103.53 +// should be printed or not.
  103.54 +
  103.55 +// The available verboseness levels.
  103.56 +typedef enum {
  103.57 +  // Determine which part of the tag is occupied by the level.
  103.58 +  ErgoLevelShift = 8,
  103.59 +  ErgoLevelMask = ~((1 << ErgoLevelShift) - 1),
  103.60 +
  103.61 +  // ErgoLow is 0 so that we don't have to explicitly or a heuristic
  103.62 +  // id with ErgoLow to keep its use simpler.
  103.63 +  ErgoLow = 0,
  103.64 +  ErgoHigh = 1 << ErgoLevelShift,
  103.65 +} ErgoLevel;
  103.66 +
  103.67 +// The available heuristics.
  103.68 +typedef enum {
  103.69 +  // Determines which part of the tag is occupied by the heuristic id.
  103.70 +  ErgoHeuristicMask = ~ErgoLevelMask,
  103.71 +
  103.72 +  ErgoHeapSizing = 0,
  103.73 +  ErgoCSetConstruction,
  103.74 +  ErgoConcCycles,
  103.75 +  ErgoPartiallyYoungGCs,
  103.76 +
  103.77 +  ErgoHeuristicNum
  103.78 +} ErgoHeuristic;
  103.79 +
  103.80 +class G1ErgoVerbose : AllStatic {
  103.81 +private:
  103.82 +  // Determines the minimum verboseness level at which records will be
  103.83 +  // printed.
  103.84 +  static ErgoLevel _level;
  103.85 +  // Determines which heuristics are currently enabled.
  103.86 +  static bool _enabled[ErgoHeuristicNum];
  103.87 +
  103.88 +  static ErgoLevel extract_level(int tag) {
  103.89 +    return (ErgoLevel) (tag & ErgoLevelMask);
  103.90 +  }
  103.91 +
  103.92 +  static ErgoHeuristic extract_heuristic(int tag) {
  103.93 +    return (ErgoHeuristic) (tag & ErgoHeuristicMask);
  103.94 +  }
  103.95 +
  103.96 +public:
  103.97 +  // Needs to be explicitly called at GC initialization.
  103.98 +  static void initialize();
  103.99 +
 103.100 +  static void set_level(ErgoLevel level);
 103.101 +  static void set_enabled(ErgoHeuristic h, bool enabled);
 103.102 +  // It is applied to all heuristics.
 103.103 +  static void set_enabled(bool enabled);
 103.104 +
 103.105 +  static bool enabled(int tag) {
 103.106 +    ErgoLevel level = extract_level(tag);
 103.107 +    ErgoHeuristic n = extract_heuristic(tag);
 103.108 +    return level <= _level && _enabled[n];
 103.109 +  }
 103.110 +
 103.111 +  // Extract the heuristic id from the tag and return a string with
 103.112 +  // its name.
 103.113 +  static const char* to_string(int tag);
 103.114 +};
 103.115 +
 103.116 +// The macros below generate the format string for values of different
 103.117 +// types and/or metrics.
 103.118 +
 103.119 +// The reason for the action is optional and is handled specially: the
 103.120 +// reason string is concatenated here so it's not necessary to pass it
 103.121 +// as a parameter.
 103.122 +#define ergo_format_reason(_reason_) ", reason: " _reason_
 103.123 +
 103.124 +// Single parameter format strings
 103.125 +#define ergo_format_str(_name_)      ", " _name_ ": %s"
 103.126 +#define ergo_format_region(_name_)   ", " _name_ ": "SIZE_FORMAT" regions"
 103.127 +#define ergo_format_byte(_name_)     ", " _name_ ": "SIZE_FORMAT" bytes"
 103.128 +#define ergo_format_double(_name_)   ", " _name_ ": %1.2f"
 103.129 +#define ergo_format_perc(_name_)     ", " _name_ ": %1.2f %%"
 103.130 +#define ergo_format_ms(_name_)       ", " _name_ ": %1.2f ms"
 103.131 +
 103.132 +// Double parameter format strings
 103.133 +#define ergo_format_byte_perc(_name_)                                   \
 103.134 +                             ", " _name_ ": "SIZE_FORMAT" bytes (%1.2f %%)"
 103.135 +
 103.136 +// Generates the format string
 103.137 +#define ergo_format(_action_, _extra_format_)                   \
 103.138 +  " %1.3f: [G1Ergonomics (%s) " _action_ _extra_format_ "]"
 103.139 +
 103.140 +// Conditionally, prints an ergonomic decision record. _extra_format_
 103.141 +// is the format string for the optional items we'd like to print
 103.142 +// (i.e., the decision's reason and any associated values). This
 103.143 +// string should be built up using the ergo_*_format macros (see
 103.144 +// above) to ensure consistency.
 103.145 +//
 103.146 +// Since we cannot rely on the compiler supporting variable argument
 103.147 +// macros, this macro accepts a fixed number of arguments and passes
 103.148 +// them to the print method. For convenience, we have wrapper macros
 103.149 +// below which take a specific number of arguments and set the rest to
 103.150 +// a default value.
 103.151 +#define ergo_verbose_common(_tag_, _action_, _extra_format_,            \
 103.152 +                            _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_) \
 103.153 +  do {                                                                  \
 103.154 +    if (G1ErgoVerbose::enabled((_tag_))) {                              \
 103.155 +      gclog_or_tty->print_cr(ergo_format(_action_, _extra_format_),     \
 103.156 +                             os::elapsedTime(),                         \
 103.157 +                             G1ErgoVerbose::to_string((_tag_)),         \
 103.158 +                             (_arg0_), (_arg1_), (_arg2_),              \
 103.159 +                             (_arg3_), (_arg4_), (_arg5_));             \
 103.160 +    }                                                                   \
 103.161 +  } while (0)
 103.162 +
 103.163 +
 103.164 +#define ergo_verbose(_tag_, _action_)                           \
 103.165 +  ergo_verbose_common(_tag_, _action_, "", 0, 0, 0, 0, 0, 0)
 103.166 +
 103.167 +#define ergo_verbose0(_tag_, _action_, _extra_format_)                  \
 103.168 +  ergo_verbose_common(_tag_, _action_, _extra_format_, 0, 0, 0, 0, 0, 0)
 103.169 +
 103.170 +#define ergo_verbose1(_tag_, _action_, _extra_format_,                  \
 103.171 +                      _arg0_)                                           \
 103.172 +  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
 103.173 +                      _arg0_, 0, 0, 0, 0, 0)
 103.174 +
 103.175 +#define ergo_verbose2(_tag_, _action_, _extra_format_,                  \
 103.176 +                      _arg0_, _arg1_)                                   \
 103.177 +  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
 103.178 +                      _arg0_, _arg1_, 0, 0, 0, 0)
 103.179 +
 103.180 +#define ergo_verbose3(_tag_, _action_, _extra_format_,                  \
 103.181 +                      _arg0_, _arg1_, _arg2_)                           \
 103.182 +  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
 103.183 +                      _arg0_, _arg1_, _arg2_, 0, 0, 0)
 103.184 +
 103.185 +#define ergo_verbose4(_tag_, _action_, _extra_format_,                  \
 103.186 +                      _arg0_, _arg1_, _arg2_, _arg3_)                   \
 103.187 +  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
 103.188 +                      _arg0_, _arg1_, _arg2_, _arg3_, 0, 0)
 103.189 +
 103.190 +#define ergo_verbose5(_tag_, _action_, _extra_format_,                  \
 103.191 +                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_)           \
 103.192 +  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
 103.193 +                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, 0)
 103.194 +
 103.195 +#define ergo_verbose6(_tag_, _action_, _extra_format_,                  \
 103.196 +                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)   \
 103.197 +  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
 103.198 +                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)
 103.199 +
 103.200 +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP
   104.1 --- a/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp	Thu Sep 08 16:59:27 2011 -0700
   104.2 +++ b/src/share/vm/gc_implementation/g1/g1MMUTracker.cpp	Fri Sep 09 16:17:16 2011 -0700
   104.3 @@ -1,5 +1,5 @@
   104.4  /*
   104.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
   104.6 + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
   104.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   104.8   *
   104.9   * This code is free software; you can redistribute it and/or modify it
  104.10 @@ -97,10 +97,6 @@
  104.11      // or performance (we are GC'ing most of the time anyway!),
  104.12      // simply overwrite the oldest entry in the tracker.
  104.13  
  104.14 -    if (G1PolicyVerbose > 1) {
  104.15 -      warning("MMU Tracker Queue overflow. Replacing earliest entry.");
  104.16 -    }
  104.17 -
  104.18      _head_index = trim_index(_head_index + 1);
  104.19      assert(_head_index == _tail_index, "Because we have a full circular buffer");
  104.20      _tail_index = trim_index(_tail_index + 1);
   105.1 --- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Thu Sep 08 16:59:27 2011 -0700
   105.2 +++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp	Fri Sep 09 16:17:16 2011 -0700
   105.3 @@ -50,6 +50,8 @@
   105.4    G1RemSet* _g1_rem;
   105.5    ConcurrentMark* _cm;
   105.6    G1ParScanThreadState* _par_scan_state;
   105.7 +  bool _during_initial_mark;
   105.8 +  bool _mark_in_progress;
   105.9  public:
  105.10    G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state);
  105.11    bool apply_to_weak_ref_discovered_field() { return true; }
  105.12 @@ -102,8 +104,8 @@
  105.13  class G1ParCopyHelper : public G1ParClosureSuper {
  105.14    G1ParScanClosure *_scanner;
  105.15  protected:
  105.16 -  template <class T> void mark_forwardee(T* p);
  105.17 -  oop copy_to_survivor_space(oop obj);
  105.18 +  template <class T> void mark_object(T* p);
  105.19 +  oop copy_to_survivor_space(oop obj, bool should_mark_copy);
  105.20  public:
  105.21    G1ParCopyHelper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state,
  105.22                    G1ParScanClosure *scanner) :
  105.23 @@ -111,7 +113,7 @@
  105.24  };
  105.25  
  105.26  template<bool do_gen_barrier, G1Barrier barrier,
  105.27 -         bool do_mark_forwardee>
  105.28 +         bool do_mark_object>
  105.29  class G1ParCopyClosure : public G1ParCopyHelper {
  105.30    G1ParScanClosure _scanner;
  105.31    template <class T> void do_oop_work(T* p);
  105.32 @@ -120,8 +122,6 @@
  105.33      _scanner(g1, par_scan_state), G1ParCopyHelper(g1, par_scan_state, &_scanner) { }
  105.34    template <class T> void do_oop_nv(T* p) {
  105.35      do_oop_work(p);
  105.36 -    if (do_mark_forwardee)
  105.37 -      mark_forwardee(p);
  105.38    }
  105.39    virtual void do_oop(oop* p)       { do_oop_nv(p); }
  105.40    virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
   106.1 --- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Thu Sep 08 16:59:27 2011 -0700
   106.2 +++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Sep 09 16:17:16 2011 -0700
   106.3 @@ -124,9 +124,6 @@
   106.4    develop(bool, G1RSBarrierNullFilter, true,                                \
   106.5            "If true, generate null-pointer filtering code in RS barrier")    \
   106.6                                                                              \
   106.7 -  develop(bool, G1PrintCTFilterStats, false,                                \
   106.8 -          "If true, print stats on RS filtering effectiveness")             \
   106.9 -                                                                            \
  106.10    develop(bool, G1DeferredRSUpdate, true,                                   \
  106.11            "If true, use deferred RS updates")                               \
  106.12                                                                              \
  106.13 @@ -137,9 +134,9 @@
  106.14    develop(bool, G1RSCountHisto, false,                                      \
  106.15            "If true, print a histogram of RS occupancies after each pause")  \
  106.16                                                                              \
  106.17 -  product(bool, G1PrintRegionLivenessInfo, false,                           \
  106.18 -          "Prints the liveness information for all regions in the heap "    \
  106.19 -          "at the end of a marking cycle.")                                 \
  106.20 +  diagnostic(bool, G1PrintRegionLivenessInfo, false,                        \
  106.21 +            "Prints the liveness information for all regions in the heap "  \
  106.22 +            "at the end of a marking cycle.")                               \
  106.23                                                                              \
  106.24    develop(bool, G1PrintParCleanupStats, false,                              \
  106.25            "When true, print extra stats about parallel cleanup.")           \
  106.26 @@ -231,7 +228,7 @@
  106.27            "the number of regions for which we'll print a surv rate "        \
  106.28            "summary.")                                                       \
  106.29                                                                              \
  106.30 -  product(intx, G1ReservePercent, 10,                                       \
  106.31 +  product(uintx, G1ReservePercent, 10,                                      \
  106.32            "It determines the minimum reserve we should have in the heap "   \
  106.33            "to minimize the probability of promotion failure.")              \
  106.34                                                                              \
   107.1 --- a/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp	Thu Sep 08 16:59:27 2011 -0700
   107.2 +++ b/src/share/vm/gc_implementation/g1/g1_specialized_oop_closures.hpp	Fri Sep 09 16:17:16 2011 -0700
   107.3 @@ -36,7 +36,7 @@
   107.4  };
   107.5  
   107.6  template<bool do_gen_barrier, G1Barrier barrier,
   107.7 -         bool do_mark_forwardee>
   107.8 +         bool do_mark_object>
   107.9  class G1ParCopyClosure;
  107.10  class G1ParScanClosure;
  107.11  class G1ParPushHeapRSClosure;
   108.1 --- a/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Thu Sep 08 16:59:27 2011 -0700
   108.2 +++ b/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp	Fri Sep 09 16:17:16 2011 -0700
   108.3 @@ -98,7 +98,7 @@
   108.4  
   108.5      // At this point we are supposed to start a concurrent cycle. We
   108.6      // will do so if one is not already in progress.
   108.7 -    bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle();
   108.8 +    bool res = g1h->g1_policy()->force_initial_mark_if_outside_cycle(_gc_cause);
   108.9  
  108.10      // The above routine returns true if we were able to force the
  108.11      // next GC pause to be an initial mark; it returns false if a
   109.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu Sep 08 16:59:27 2011 -0700
   109.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Fri Sep 09 16:17:16 2011 -0700
   109.3 @@ -909,10 +909,6 @@
   109.4      }
   109.5      young_gen()->verify(allow_dirty);
   109.6    }
   109.7 -  if (!silent) {
   109.8 -    gclog_or_tty->print("ref_proc ");
   109.9 -  }
  109.10 -  ReferenceProcessor::verify();
  109.11  }
  109.12  
  109.13  void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
   110.1 --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Thu Sep 08 16:59:27 2011 -0700
   110.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp	Fri Sep 09 16:17:16 2011 -0700
   110.3 @@ -80,10 +80,6 @@
   110.4        Universe::oops_do(&mark_and_push_closure);
   110.5        break;
   110.6  
   110.7 -    case reference_processing:
   110.8 -      ReferenceProcessor::oops_do(&mark_and_push_closure);
   110.9 -      break;
  110.10 -
  110.11      case jni_handles:
  110.12        JNIHandles::oops_do(&mark_and_push_closure);
  110.13        break;
   111.1 --- a/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Thu Sep 08 16:59:27 2011 -0700
   111.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp	Fri Sep 09 16:17:16 2011 -0700
   111.3 @@ -98,8 +98,7 @@
   111.4      management            = 6,
   111.5      jvmti                 = 7,
   111.6      system_dictionary     = 8,
   111.7 -    reference_processing  = 9,
   111.8 -    code_cache            = 10
   111.9 +    code_cache            = 9
  111.10    };
  111.11   private:
  111.12    RootType _root_type;
   112.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Thu Sep 08 16:59:27 2011 -0700
   112.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp	Fri Sep 09 16:17:16 2011 -0700
   112.3 @@ -516,7 +516,6 @@
   112.4    {
   112.5      ParallelScavengeHeap::ParStrongRootsScope psrs;
   112.6      Universe::oops_do(mark_and_push_closure());
   112.7 -    ReferenceProcessor::oops_do(mark_and_push_closure());
   112.8      JNIHandles::oops_do(mark_and_push_closure());   // Global (strong) JNI handles
   112.9      CodeBlobToOopClosure each_active_code_blob(mark_and_push_closure(), /*do_marking=*/ true);
  112.10      Threads::oops_do(mark_and_push_closure(), &each_active_code_blob);
  112.11 @@ -623,7 +622,6 @@
  112.12  
  112.13    // General strong roots.
  112.14    Universe::oops_do(adjust_root_pointer_closure());
  112.15 -  ReferenceProcessor::oops_do(adjust_root_pointer_closure());
  112.16    JNIHandles::oops_do(adjust_root_pointer_closure());   // Global (strong) JNI handles
  112.17    Threads::oops_do(adjust_root_pointer_closure(), NULL);
  112.18    ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
   113.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Sep 08 16:59:27 2011 -0700
   113.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Sep 09 16:17:16 2011 -0700
   113.3 @@ -2445,7 +2445,6 @@
   113.4  
   113.5    // General strong roots.
   113.6    Universe::oops_do(adjust_root_pointer_closure());
   113.7 -  ReferenceProcessor::oops_do(adjust_root_pointer_closure());
   113.8    JNIHandles::oops_do(adjust_root_pointer_closure());   // Global (strong) JNI handles
   113.9    Threads::oops_do(adjust_root_pointer_closure(), NULL);
  113.10    ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
   114.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Thu Sep 08 16:59:27 2011 -0700
   114.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp	Fri Sep 09 16:17:16 2011 -0700
   114.3 @@ -55,7 +55,6 @@
   114.4    switch (_root_type) {
   114.5      case universe:
   114.6        Universe::oops_do(&roots_closure);
   114.7 -      ReferenceProcessor::oops_do(&roots_closure);
   114.8        break;
   114.9  
  114.10      case jni_handles:
   115.1 --- a/src/share/vm/gc_interface/collectedHeap.cpp	Thu Sep 08 16:59:27 2011 -0700
   115.2 +++ b/src/share/vm/gc_interface/collectedHeap.cpp	Fri Sep 09 16:17:16 2011 -0700
   115.3 @@ -157,8 +157,14 @@
   115.4      // ..and clear it.
   115.5      Copy::zero_to_words(obj, new_tlab_size);
   115.6    } else {
   115.7 -    // ...and clear just the allocated object.
   115.8 -    Copy::zero_to_words(obj, size);
   115.9 +    // ...and zap just allocated object.
  115.10 +#ifdef ASSERT
  115.11 +    // Skip mangling the space corresponding to the object header to
  115.12 +    // ensure that the returned space is not considered parsable by
  115.13 +    // any concurrent GC thread.
  115.14 +    size_t hdr_size = oopDesc::header_size();
  115.15 +    Copy::fill_to_words(obj + hdr_size, new_tlab_size - hdr_size, badHeapWordVal);
  115.16 +#endif // ASSERT
  115.17    }
  115.18    thread->tlab().fill(obj, obj + size, new_tlab_size);
  115.19    return obj;
   116.1 --- a/src/share/vm/gc_interface/collectedHeap.inline.hpp	Thu Sep 08 16:59:27 2011 -0700
   116.2 +++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp	Fri Sep 09 16:17:16 2011 -0700
   116.3 @@ -287,7 +287,10 @@
   116.4    assert(size >= 0, "int won't convert to size_t");
   116.5    HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
   116.6    post_allocation_setup_no_klass_install(klass, obj, size);
   116.7 -  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   116.8 +#ifndef PRODUCT
   116.9 +  const size_t hs = oopDesc::header_size();
  116.10 +  Universe::heap()->check_for_bad_heap_word_value(obj+hs, size-hs);
  116.11 +#endif
  116.12    return (oop)obj;
  116.13  }
  116.14  
   117.1 --- a/src/share/vm/interpreter/bytecodes.hpp	Thu Sep 08 16:59:27 2011 -0700
   117.2 +++ b/src/share/vm/interpreter/bytecodes.hpp	Fri Sep 09 16:17:16 2011 -0700
   117.3 @@ -419,6 +419,8 @@
   117.4  
   117.5    static bool        is_zero_const  (Code code)    { return (code == _aconst_null || code == _iconst_0
   117.6                                                             || code == _fconst_0 || code == _dconst_0); }
   117.7 +  static bool        is_invoke      (Code code)    { return (_invokevirtual <= code && code <= _invokedynamic); }
   117.8 +
   117.9    static int         compute_flags  (const char* format, int more_flags = 0);  // compute the flags
  117.10    static int         flags          (int code, bool is_wide) {
  117.11      assert(code == (u_char)code, "must be a byte");
   118.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp	Thu Sep 08 16:59:27 2011 -0700
   118.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Sep 09 16:17:16 2011 -0700
   118.3 @@ -555,7 +555,7 @@
   118.4      assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
   118.5  
   118.6      {
   118.7 -      // Walk all nmethods depending on CallSite
   118.8 +      // Walk all nmethods depending on this call site.
   118.9        MutexLocker mu(Compile_lock, thread);
  118.10        Universe::flush_dependents_on(call_site, method_handle);
  118.11      }
  118.12 @@ -1244,7 +1244,7 @@
  118.13    // preparing the same method will be sure to see non-null entry & mirror.
  118.14  IRT_END
  118.15  
  118.16 -#if defined(IA32) || defined(AMD64)
  118.17 +#if defined(IA32) || defined(AMD64) || defined(ARM)
  118.18  IRT_LEAF(void, InterpreterRuntime::popframe_move_outgoing_args(JavaThread* thread, void* src_address, void* dest_address))
  118.19    if (src_address == dest_address) {
  118.20      return;
   119.1 --- a/src/share/vm/interpreter/interpreterRuntime.hpp	Thu Sep 08 16:59:27 2011 -0700
   119.2 +++ b/src/share/vm/interpreter/interpreterRuntime.hpp	Fri Sep 09 16:17:16 2011 -0700
   119.3 @@ -141,8 +141,8 @@
   119.4                                          methodOopDesc* method,
   119.5                                          intptr_t* from, intptr_t* to);
   119.6  
   119.7 -#if defined(IA32) || defined(AMD64)
   119.8 -  // Popframe support (only needed on x86 and AMD64)
   119.9 +#if defined(IA32) || defined(AMD64) || defined(ARM)
  119.10 +  // Popframe support (only needed on x86, AMD64 and ARM)
  119.11    static void popframe_move_outgoing_args(JavaThread* thread, void* src_address, void* dest_address);
  119.12  #endif
  119.13  
   120.1 --- a/src/share/vm/memory/genCollectedHeap.cpp	Thu Sep 08 16:59:27 2011 -0700
   120.2 +++ b/src/share/vm/memory/genCollectedHeap.cpp	Fri Sep 09 16:17:16 2011 -0700
   120.3 @@ -1269,10 +1269,6 @@
   120.4      gclog_or_tty->print("remset ");
   120.5    }
   120.6    rem_set()->verify();
   120.7 -  if (!silent) {
   120.8 -     gclog_or_tty->print("ref_proc ");
   120.9 -  }
  120.10 -  ReferenceProcessor::verify();
  120.11  }
  120.12  
  120.13  void GenCollectedHeap::print() const { print_on(tty); }
   121.1 --- a/src/share/vm/memory/referenceProcessor.cpp	Thu Sep 08 16:59:27 2011 -0700
   121.2 +++ b/src/share/vm/memory/referenceProcessor.cpp	Fri Sep 09 16:17:16 2011 -0700
   121.3 @@ -35,15 +35,15 @@
   121.4  
   121.5  ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
   121.6  ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy      = NULL;
   121.7 -oop              ReferenceProcessor::_sentinelRef = NULL;
   121.8  const int        subclasses_of_ref                = REF_PHANTOM - REF_OTHER;
   121.9 +bool             ReferenceProcessor::_pending_list_uses_discovered_field = false;
  121.10  
  121.11  // List of discovered references.
  121.12  class DiscoveredList {
  121.13  public:
  121.14    DiscoveredList() : _len(0), _compressed_head(0), _oop_head(NULL) { }
  121.15    oop head() const     {
  121.16 -     return UseCompressedOops ?  oopDesc::decode_heap_oop_not_null(_compressed_head) :
  121.17 +     return UseCompressedOops ?  oopDesc::decode_heap_oop(_compressed_head) :
  121.18                                  _oop_head;
  121.19    }
  121.20    HeapWord* adr_head() {
  121.21 @@ -53,12 +53,12 @@
  121.22    void   set_head(oop o) {
  121.23      if (UseCompressedOops) {
  121.24        // Must compress the head ptr.
  121.25 -      _compressed_head = oopDesc::encode_heap_oop_not_null(o);
  121.26 +      _compressed_head = oopDesc::encode_heap_oop(o);
  121.27      } else {
  121.28        _oop_head = o;
  121.29      }
  121.30    }
  121.31 -  bool   empty() const          { return head() == ReferenceProcessor::sentinel_ref(); }
  121.32 +  bool   empty() const          { return head() == NULL; }
  121.33    size_t length()               { return _len; }
  121.34    void   set_length(size_t len) { _len = len;  }
  121.35    void   inc_length(size_t inc) { _len += inc; assert(_len > 0, "Error"); }
  121.36 @@ -76,21 +76,9 @@
  121.37  }
  121.38  
  121.39  void ReferenceProcessor::init_statics() {
  121.40 -  assert(_sentinelRef == NULL, "should be initialized precisely once");
  121.41 -  EXCEPTION_MARK;
  121.42 -  _sentinelRef = instanceKlass::cast(
  121.43 -                    SystemDictionary::Reference_klass())->
  121.44 -                      allocate_permanent_instance(THREAD);
  121.45 -
  121.46    // Initialize the master soft ref clock.
  121.47    java_lang_ref_SoftReference::set_clock(os::javaTimeMillis());
  121.48  
  121.49 -  if (HAS_PENDING_EXCEPTION) {
  121.50 -      Handle ex(THREAD, PENDING_EXCEPTION);
  121.51 -      vm_exit_during_initialization(ex);
  121.52 -  }
  121.53 -  assert(_sentinelRef != NULL && _sentinelRef->is_oop(),
  121.54 -         "Just constructed it!");
  121.55    _always_clear_soft_ref_policy = new AlwaysClearPolicy();
  121.56    _default_soft_ref_policy      = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
  121.57                                        NOT_COMPILER2(LRUCurrentHeapPolicy());
  121.58 @@ -100,6 +88,7 @@
  121.59    guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
  121.60              RefDiscoveryPolicy == ReferentBasedDiscovery,
  121.61              "Unrecongnized RefDiscoveryPolicy");
  121.62 +  _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
  121.63  }
  121.64  
  121.65  ReferenceProcessor::ReferenceProcessor(MemRegion span,
  121.66 @@ -130,13 +119,12 @@
  121.67    _discoveredWeakRefs    = &_discoveredSoftRefs[_max_num_q];
  121.68    _discoveredFinalRefs   = &_discoveredWeakRefs[_max_num_q];
  121.69    _discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q];
  121.70 -  assert(sentinel_ref() != NULL, "_sentinelRef is NULL");
  121.71 -  // Initialized all entries to _sentinelRef
  121.72 +  // Initialized all entries to NULL
  121.73    for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
  121.74 -        _discoveredSoftRefs[i].set_head(sentinel_ref());
  121.75 +    _discoveredSoftRefs[i].set_head(NULL);
  121.76      _discoveredSoftRefs[i].set_length(0);
  121.77    }
  121.78 -  // If we do barreirs, cache a copy of the barrier set.
  121.79 +  // If we do barriers, cache a copy of the barrier set.
  121.80    if (discovered_list_needs_barrier) {
  121.81      _bs = Universe::heap()->barrier_set();
  121.82    }
  121.83 @@ -167,10 +155,6 @@
  121.84    }
  121.85  }
  121.86  
  121.87 -void ReferenceProcessor::oops_do(OopClosure* f) {
  121.88 -  f->do_oop(adr_sentinel_ref());
  121.89 -}
  121.90 -
  121.91  void ReferenceProcessor::update_soft_ref_master_clock() {
  121.92    // Update (advance) the soft ref master clock field. This must be done
  121.93    // after processing the soft ref list.
  121.94 @@ -283,8 +267,6 @@
  121.95    }
  121.96  #endif
  121.97    JNIHandles::weak_oops_do(is_alive, keep_alive);
  121.98 -  // Finally remember to keep sentinel around
  121.99 -  keep_alive->do_oop(adr_sentinel_ref());
 121.100    complete_gc->do_void();
 121.101  }
 121.102  
 121.103 @@ -327,46 +309,77 @@
 121.104  void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
 121.105                                                      HeapWord* pending_list_addr) {
 121.106    // Given a list of refs linked through the "discovered" field
 121.107 -  // (java.lang.ref.Reference.discovered) chain them through the
 121.108 -  // "next" field (java.lang.ref.Reference.next) and prepend
 121.109 -  // to the pending list.
 121.110 +  // (java.lang.ref.Reference.discovered), self-loop their "next" field
 121.111 +  // thus distinguishing them from active References, then
 121.112 +  // prepend them to the pending list.
 121.113 +  // BKWRD COMPATIBILITY NOTE: For older JDKs (prior to the fix for 4956777),
 121.114 +  // the "next" field is used to chain the pending list, not the discovered
 121.115 +  // field.
 121.116 +
 121.117    if (TraceReferenceGC && PrintGCDetails) {
 121.118      gclog_or_tty->print_cr("ReferenceProcessor::enqueue_discovered_reflist list "
 121.119                             INTPTR_FORMAT, (address)refs_list.head());
 121.120    }
 121.121 -  oop obj = refs_list.head();
 121.122 -  // Walk down the list, copying the discovered field into
 121.123 -  // the next field and clearing it (except for the last
 121.124 -  // non-sentinel object which is treated specially to avoid
 121.125 -  // confusion with an active reference).
 121.126 -  while (obj != sentinel_ref()) {
 121.127 -    assert(obj->is_instanceRef(), "should be reference object");
 121.128 -    oop next = java_lang_ref_Reference::discovered(obj);
 121.129 -    if (TraceReferenceGC && PrintGCDetails) {
 121.130 -      gclog_or_tty->print_cr("        obj " INTPTR_FORMAT "/next " INTPTR_FORMAT,
 121.131 -                             obj, next);
 121.132 +
 121.133 +  oop obj = NULL;
 121.134 +  oop next_d = refs_list.head();
 121.135 +  if (pending_list_uses_discovered_field()) { // New behaviour
 121.136 +    // Walk down the list, self-looping the next field
 121.137 +    // so that the References are not considered active.
 121.138 +    while (obj != next_d) {
 121.139 +      obj = next_d;
 121.140 +      assert(obj->is_instanceRef(), "should be reference object");
 121.141 +      next_d = java_lang_ref_Reference::discovered(obj);
 121.142 +      if (TraceReferenceGC && PrintGCDetails) {
 121.143 +        gclog_or_tty->print_cr("        obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
 121.144 +                               obj, next_d);
 121.145 +      }
 121.146 +      assert(java_lang_ref_Reference::next(obj) == NULL,
 121.147 +             "Reference not active; should not be discovered");
 121.148 +      // Self-loop next, so as to make Ref not active.
 121.149 +      java_lang_ref_Reference::set_next(obj, obj);
 121.150 +      if (next_d == obj) {  // obj is last
 121.151 +        // Swap refs_list into pendling_list_addr and
 121.152 +        // set obj's discovered to what we read from pending_list_addr.
 121.153 +        oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
 121.154 +        // Need oop_check on pending_list_addr above;
 121.155 +        // see special oop-check code at the end of
 121.156 +        // enqueue_discovered_reflists() further below.
 121.157 +        java_lang_ref_Reference::set_discovered(obj, old); // old may be NULL
 121.158 +      }
 121.159      }
 121.160 -    assert(java_lang_ref_Reference::next(obj) == NULL,
 121.161 -           "The reference should not be enqueued");
 121.162 -    if (next == sentinel_ref()) {  // obj is last
 121.163 -      // Swap refs_list into pendling_list_addr and
 121.164 -      // set obj's next to what we read from pending_list_addr.
 121.165 -      oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
 121.166 -      // Need oop_check on pending_list_addr above;
 121.167 -      // see special oop-check code at the end of
 121.168 -      // enqueue_discovered_reflists() further below.
 121.169 -      if (old == NULL) {
 121.170 -        // obj should be made to point to itself, since
 121.171 -        // pending list was empty.
 121.172 -        java_lang_ref_Reference::set_next(obj, obj);
 121.173 +  } else { // Old behaviour
 121.174 +    // Walk down the list, copying the discovered field into
 121.175 +    // the next field and clearing the discovered field.
 121.176 +    while (obj != next_d) {
 121.177 +      obj = next_d;
 121.178 +      assert(obj->is_instanceRef(), "should be reference object");
 121.179 +      next_d = java_lang_ref_Reference::discovered(obj);
 121.180 +      if (TraceReferenceGC && PrintGCDetails) {
 121.181 +        gclog_or_tty->print_cr("        obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
 121.182 +                               obj, next_d);
 121.183 +      }
 121.184 +      assert(java_lang_ref_Reference::next(obj) == NULL,
 121.185 +             "The reference should not be enqueued");
 121.186 +      if (next_d == obj) {  // obj is last
 121.187 +        // Swap refs_list into pendling_list_addr and
 121.188 +        // set obj's next to what we read from pending_list_addr.
 121.189 +        oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
 121.190 +        // Need oop_check on pending_list_addr above;
 121.191 +        // see special oop-check code at the end of
 121.192 +        // enqueue_discovered_reflists() further below.
 121.193 +        if (old == NULL) {
 121.194 +          // obj should be made to point to itself, since
 121.195 +          // pending list was empty.
 121.196 +          java_lang_ref_Reference::set_next(obj, obj);
 121.197 +        } else {
 121.198 +          java_lang_ref_Reference::set_next(obj, old);
 121.199 +        }
 121.200        } else {
 121.201 -        java_lang_ref_Reference::set_next(obj, old);
 121.202 +        java_lang_ref_Reference::set_next(obj, next_d);
 121.203        }
 121.204 -    } else {
 121.205 -      java_lang_ref_Reference::set_next(obj, next);
 121.206 +      java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
 121.207      }
 121.208 -    java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
 121.209 -    obj = next;
 121.210    }
 121.211  }
 121.212  
 121.213 @@ -376,10 +389,9 @@
 121.214    RefProcEnqueueTask(ReferenceProcessor& ref_processor,
 121.215                       DiscoveredList      discovered_refs[],
 121.216                       HeapWord*           pending_list_addr,
 121.217 -                     oop                 sentinel_ref,
 121.218                       int                 n_queues)
 121.219      : EnqueueTask(ref_processor, discovered_refs,
 121.220 -                  pending_list_addr, sentinel_ref, n_queues)
 121.221 +                  pending_list_addr, n_queues)
 121.222    { }
 121.223  
 121.224    virtual void work(unsigned int work_id) {
 121.225 @@ -396,7 +408,7 @@
 121.226           j++, index += _n_queues) {
 121.227        _ref_processor.enqueue_discovered_reflist(
 121.228          _refs_lists[index], _pending_list_addr);
 121.229 -      _refs_lists[index].set_head(_sentinel_ref);
 121.230 +      _refs_lists[index].set_head(NULL);
 121.231        _refs_lists[index].set_length(0);
 121.232      }
 121.233    }
 121.234 @@ -408,13 +420,13 @@
 121.235    if (_processing_is_mt && task_executor != NULL) {
 121.236      // Parallel code
 121.237      RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
 121.238 -                           pending_list_addr, sentinel_ref(), _max_num_q);
 121.239 +                           pending_list_addr, _max_num_q);
 121.240      task_executor->execute(tsk);
 121.241    } else {
 121.242      // Serial code: call the parent class's implementation
 121.243      for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
 121.244        enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr);
 121.245 -      _discoveredSoftRefs[i].set_head(sentinel_ref());
 121.246 +      _discoveredSoftRefs[i].set_head(NULL);
 121.247        _discoveredSoftRefs[i].set_length(0);
 121.248      }
 121.249    }
 121.250 @@ -428,7 +440,7 @@
 121.251                                  BoolObjectClosure* is_alive);
 121.252  
 121.253    // End Of List.
 121.254 -  inline bool has_next() const { return _next != ReferenceProcessor::sentinel_ref(); }
 121.255 +  inline bool has_next() const { return _ref != NULL; }
 121.256  
 121.257    // Get oop to the Reference object.
 121.258    inline oop obj() const { return _ref; }
 121.259 @@ -468,9 +480,13 @@
 121.260    inline void update_discovered() {
 121.261      // First _prev_next ref actually points into DiscoveredList (gross).
 121.262      if (UseCompressedOops) {
 121.263 -      _keep_alive->do_oop((narrowOop*)_prev_next);
 121.264 +      if (!oopDesc::is_null(*(narrowOop*)_prev_next)) {
 121.265 +        _keep_alive->do_oop((narrowOop*)_prev_next);
 121.266 +      }
 121.267      } else {
 121.268 -      _keep_alive->do_oop((oop*)_prev_next);
 121.269 +      if (!oopDesc::is_null(*(oop*)_prev_next)) {
 121.270 +        _keep_alive->do_oop((oop*)_prev_next);
 121.271 +      }
 121.272      }
 121.273    }
 121.274  
 121.275 @@ -488,6 +504,7 @@
 121.276  private:
 121.277    DiscoveredList&    _refs_list;
 121.278    HeapWord*          _prev_next;
 121.279 +  oop                _prev;
 121.280    oop                _ref;
 121.281    HeapWord*          _discovered_addr;
 121.282    oop                _next;
 121.283 @@ -509,6 +526,7 @@
 121.284                                                        BoolObjectClosure* is_alive)
 121.285    : _refs_list(refs_list),
 121.286      _prev_next(refs_list.adr_head()),
 121.287 +    _prev(NULL),
 121.288      _ref(refs_list.head()),
 121.289  #ifdef ASSERT
 121.290      _first_seen(refs_list.head()),
 121.291 @@ -517,7 +535,7 @@
 121.292      _processed(0),
 121.293      _removed(0),
 121.294  #endif
 121.295 -    _next(refs_list.head()),
 121.296 +    _next(NULL),
 121.297      _keep_alive(keep_alive),
 121.298      _is_alive(is_alive)
 121.299  { }
 121.300 @@ -544,26 +562,43 @@
 121.301  
 121.302  inline void DiscoveredListIterator::next() {
 121.303    _prev_next = _discovered_addr;
 121.304 +  _prev = _ref;
 121.305    move_to_next();
 121.306  }
 121.307  
 121.308  inline void DiscoveredListIterator::remove() {
 121.309    assert(_ref->is_oop(), "Dropping a bad reference");
 121.310    oop_store_raw(_discovered_addr, NULL);
 121.311 +
 121.312    // First _prev_next ref actually points into DiscoveredList (gross).
 121.313 +  oop new_next;
 121.314 +  if (_next == _ref) {
 121.315 +    // At the end of the list, we should make _prev point to itself.
 121.316 +    // If _ref is the first ref, then _prev_next will be in the DiscoveredList,
 121.317 +    // and _prev will be NULL.
 121.318 +    new_next = _prev;
 121.319 +  } else {
 121.320 +    new_next = _next;
 121.321 +  }
 121.322 +
 121.323    if (UseCompressedOops) {
 121.324      // Remove Reference object from list.
 121.325 -    oopDesc::encode_store_heap_oop_not_null((narrowOop*)_prev_next, _next);
 121.326 +    oopDesc::encode_store_heap_oop((narrowOop*)_prev_next, new_next);
 121.327    } else {
 121.328      // Remove Reference object from list.
 121.329 -    oopDesc::store_heap_oop((oop*)_prev_next, _next);
 121.330 +    oopDesc::store_heap_oop((oop*)_prev_next, new_next);
 121.331    }
 121.332    NOT_PRODUCT(_removed++);
 121.333    _refs_list.dec_length(1);
 121.334  }
 121.335  
 121.336  inline void DiscoveredListIterator::move_to_next() {
 121.337 -  _ref = _next;
 121.338 +  if (_ref == _next) {
 121.339 +    // End of the list.
 121.340 +    _ref = NULL;
 121.341 +  } else {
 121.342 +    _ref = _next;
 121.343 +  }
 121.344    assert(_ref != _first_seen, "cyclic ref_list found");
 121.345    NOT_PRODUCT(_processed++);
 121.346  }
 121.347 @@ -613,7 +648,7 @@
 121.348    NOT_PRODUCT(
 121.349      if (PrintGCDetails && TraceReferenceGC) {
 121.350        gclog_or_tty->print_cr(" Dropped %d dead Refs out of %d "
 121.351 -        "discovered Refs by policy  list " INTPTR_FORMAT,
 121.352 +        "discovered Refs by policy, from list " INTPTR_FORMAT,
 121.353          iter.removed(), iter.processed(), (address)refs_list.head());
 121.354      }
 121.355    )
 121.356 @@ -725,22 +760,28 @@
 121.357      assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
 121.358      iter.next();
 121.359    }
 121.360 -  // Remember to keep sentinel pointer around
 121.361 +  // Remember to update the next pointer of the last ref.
 121.362    iter.update_discovered();
 121.363    // Close the reachable set
 121.364    complete_gc->do_void();
 121.365  }
 121.366  
 121.367  void
 121.368 +ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) {
 121.369 +  oop obj = NULL;
 121.370 +  oop next = refs_list.head();
 121.371 +  while (next != obj) {
 121.372 +    obj = next;
 121.373 +    next = java_lang_ref_Reference::discovered(obj);
 121.374 +    java_lang_ref_Reference::set_discovered_raw(obj, NULL);
 121.375 +  }
 121.376 +  refs_list.set_head(NULL);
 121.377 +  refs_list.set_length(0);
 121.378 +}
 121.379 +
 121.380 +void
 121.381  ReferenceProcessor::abandon_partial_discovered_list(DiscoveredList& refs_list) {
 121.382 -  oop obj = refs_list.head();
 121.383 -  while (obj != sentinel_ref()) {
 121.384 -    oop discovered = java_lang_ref_Reference::discovered(obj);
 121.385 -    java_lang_ref_Reference::set_discovered_raw(obj, NULL);
 121.386 -    obj = discovered;
 121.387 -  }
 121.388 -  refs_list.set_head(sentinel_ref());
 121.389 -  refs_list.set_length(0);
 121.390 +  clear_discovered_references(refs_list);
 121.391  }
 121.392  
 121.393  void ReferenceProcessor::abandon_partial_discovery() {
 121.394 @@ -859,6 +900,9 @@
 121.395            refs_to_move = MIN2(ref_lists[from_idx].length() - avg_refs,
 121.396                                avg_refs - ref_lists[to_idx].length());
 121.397          }
 121.398 +
 121.399 +        assert(refs_to_move > 0, "otherwise the code below will fail");
 121.400 +
 121.401          oop move_head = ref_lists[from_idx].head();
 121.402          oop move_tail = move_head;
 121.403          oop new_head  = move_head;
 121.404 @@ -867,10 +911,24 @@
 121.405            move_tail = new_head;
 121.406            new_head = java_lang_ref_Reference::discovered(new_head);
 121.407          }
 121.408 -        java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
 121.409 +
 121.410 +        // Add the chain to the to list.
 121.411 +        if (ref_lists[to_idx].head() == NULL) {
 121.412 +          // to list is empty. Make a loop at the end.
 121.413 +          java_lang_ref_Reference::set_discovered(move_tail, move_tail);
 121.414 +        } else {
 121.415 +          java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
 121.416 +        }
 121.417          ref_lists[to_idx].set_head(move_head);
 121.418          ref_lists[to_idx].inc_length(refs_to_move);
 121.419 -        ref_lists[from_idx].set_head(new_head);
 121.420 +
 121.421 +        // Remove the chain from the from list.
 121.422 +        if (move_tail == new_head) {
 121.423 +          // We found the end of the from list.
 121.424 +          ref_lists[from_idx].set_head(NULL);
 121.425 +        } else {
 121.426 +          ref_lists[from_idx].set_head(new_head);
 121.427 +        }
 121.428          ref_lists[from_idx].dec_length(refs_to_move);
 121.429          if (ref_lists[from_idx].length() == 0) {
 121.430            break;
 121.431 @@ -1082,42 +1140,40 @@
 121.432    // First we must make sure this object is only enqueued once. CAS in a non null
 121.433    // discovered_addr.
 121.434    oop current_head = refs_list.head();
 121.435 +  // The last ref must have its discovered field pointing to itself.
 121.436 +  oop next_discovered = (current_head != NULL) ? current_head : obj;
 121.437  
 121.438    // Note: In the case of G1, this specific pre-barrier is strictly
 121.439    // not necessary because the only case we are interested in
 121.440    // here is when *discovered_addr is NULL (see the CAS further below),
 121.441    // so this will expand to nothing. As a result, we have manually
 121.442    // elided this out for G1, but left in the test for some future
 121.443 -  // collector that might have need for a pre-barrier here.
 121.444 -  if (_discovered_list_needs_barrier && !UseG1GC) {
 121.445 -    if (UseCompressedOops) {
 121.446 -      _bs->write_ref_field_pre((narrowOop*)discovered_addr, current_head);
 121.447 -    } else {
 121.448 -      _bs->write_ref_field_pre((oop*)discovered_addr, current_head);
 121.449 -    }
 121.450 -    guarantee(false, "Need to check non-G1 collector");
 121.451 -  }
 121.452 -  oop retest = oopDesc::atomic_compare_exchange_oop(current_head, discovered_addr,
 121.453 +  // collector that might have need for a pre-barrier here, e.g.:-
 121.454 +  // _bs->write_ref_field_pre((oop* or narrowOop*)discovered_addr, next_discovered);
 121.455 +  assert(!_discovered_list_needs_barrier || UseG1GC,
 121.456 +         "Need to check non-G1 collector: "
 121.457 +         "may need a pre-write-barrier for CAS from NULL below");
 121.458 +  oop retest = oopDesc::atomic_compare_exchange_oop(next_discovered, discovered_addr,
 121.459                                                      NULL);
 121.460    if (retest == NULL) {
 121.461      // This thread just won the right to enqueue the object.
 121.462 -    // We have separate lists for enqueueing so no synchronization
 121.463 +    // We have separate lists for enqueueing, so no synchronization
 121.464      // is necessary.
 121.465      refs_list.set_head(obj);
 121.466      refs_list.inc_length(1);
 121.467      if (_discovered_list_needs_barrier) {
 121.468 -      _bs->write_ref_field((void*)discovered_addr, current_head);
 121.469 +      _bs->write_ref_field((void*)discovered_addr, next_discovered);
 121.470      }
 121.471  
 121.472      if (TraceReferenceGC) {
 121.473 -      gclog_or_tty->print_cr("Enqueued reference (mt) (" INTPTR_FORMAT ": %s)",
 121.474 +      gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
 121.475                               obj, obj->blueprint()->internal_name());
 121.476      }
 121.477    } else {
 121.478      // If retest was non NULL, another thread beat us to it:
 121.479      // The reference has already been discovered...
 121.480      if (TraceReferenceGC) {
 121.481 -      gclog_or_tty->print_cr("Already enqueued reference (" INTPTR_FORMAT ": %s)",
 121.482 +      gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
 121.483                               obj, obj->blueprint()->internal_name());
 121.484      }
 121.485    }
 121.486 @@ -1142,7 +1198,7 @@
 121.487  //     (or part of the heap being collected, indicated by our "span"
 121.488  //     we don't treat it specially (i.e. we scan it as we would
 121.489  //     a normal oop, treating its references as strong references).
 121.490 -//     This means that references can't be enqueued unless their
 121.491 +//     This means that references can't be discovered unless their
 121.492  //     referent is also in the same span. This is the simplest,
 121.493  //     most "local" and most conservative approach, albeit one
 121.494  //     that may cause weak references to be enqueued least promptly.
 121.495 @@ -1164,14 +1220,13 @@
 121.496  //     and complexity in processing these references.
 121.497  //     We call this choice the "RefeferentBasedDiscovery" policy.
 121.498  bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
 121.499 -  // We enqueue references only if we are discovering refs
 121.500 -  // (rather than processing discovered refs).
 121.501 +  // Make sure we are discovering refs (rather than processing discovered refs).
 121.502    if (!_discovering_refs || !RegisterReferences) {
 121.503      return false;
 121.504    }
 121.505 -  // We only enqueue active references.
 121.506 +  // We only discover active references.
 121.507    oop next = java_lang_ref_Reference::next(obj);
 121.508 -  if (next != NULL) {
 121.509 +  if (next != NULL) {   // Ref is no longer active
 121.510      return false;
 121.511    }
 121.512  
 121.513 @@ -1184,8 +1239,8 @@
 121.514      return false;
 121.515    }
 121.516  
 121.517 -  // We only enqueue references whose referents are not (yet) strongly
 121.518 -  // reachable.
 121.519 +  // We only discover references whose referents are not (yet)
 121.520 +  // known to be strongly reachable.
 121.521    if (is_alive_non_header() != NULL) {
 121.522      verify_referent(obj);
 121.523      if (is_alive_non_header()->do_object_b(java_lang_ref_Reference::referent(obj))) {
 121.524 @@ -1211,7 +1266,7 @@
 121.525    if (discovered != NULL) {
 121.526      // The reference has already been discovered...
 121.527      if (TraceReferenceGC) {
 121.528 -      gclog_or_tty->print_cr("Already enqueued reference (" INTPTR_FORMAT ": %s)",
 121.529 +      gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
 121.530                               obj, obj->blueprint()->internal_name());
 121.531      }
 121.532      if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
 121.533 @@ -1233,9 +1288,9 @@
 121.534  
 121.535    if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
 121.536      verify_referent(obj);
 121.537 -    // enqueue if and only if either:
 121.538 -    // reference is in our span or
 121.539 -    // we are an atomic collector and referent is in our span
 121.540 +    // Discover if and only if EITHER:
 121.541 +    // .. reference is in our span, OR
 121.542 +    // .. we are an atomic collector and referent is in our span
 121.543      if (_span.contains(obj_addr) ||
 121.544          (discovery_is_atomic() &&
 121.545           _span.contains(java_lang_ref_Reference::referent(obj)))) {
 121.546 @@ -1262,30 +1317,28 @@
 121.547      // here: the field will be visited later when processing the discovered
 121.548      // references.
 121.549      oop current_head = list->head();
 121.550 +    // The last ref must have its discovered field pointing to itself.
 121.551 +    oop next_discovered = (current_head != NULL) ? current_head : obj;
 121.552 +
 121.553      // As in the case further above, since we are over-writing a NULL
 121.554      // pre-value, we can safely elide the pre-barrier here for the case of G1.
 121.555 +    // e.g.:- _bs->write_ref_field_pre((oop* or narrowOop*)discovered_addr, next_discovered);
 121.556      assert(discovered == NULL, "control point invariant");
 121.557 -    if (_discovered_list_needs_barrier && !UseG1GC) { // safe to elide for G1
 121.558 -      if (UseCompressedOops) {
 121.559 -        _bs->write_ref_field_pre((narrowOop*)discovered_addr, current_head);
 121.560 -      } else {
 121.561 -        _bs->write_ref_field_pre((oop*)discovered_addr, current_head);
 121.562 -      }
 121.563 -      guarantee(false, "Need to check non-G1 collector");
 121.564 -    }
 121.565 -    oop_store_raw(discovered_addr, current_head);
 121.566 +    assert(!_discovered_list_needs_barrier || UseG1GC,
 121.567 +           "For non-G1 collector, may need a pre-write-barrier for CAS from NULL below");
 121.568 +    oop_store_raw(discovered_addr, next_discovered);
 121.569      if (_discovered_list_needs_barrier) {
 121.570 -      _bs->write_ref_field((void*)discovered_addr, current_head);
 121.571 +      _bs->write_ref_field((void*)discovered_addr, next_discovered);
 121.572      }
 121.573      list->set_head(obj);
 121.574      list->inc_length(1);
 121.575  
 121.576      if (TraceReferenceGC) {
 121.577 -      gclog_or_tty->print_cr("Enqueued reference (" INTPTR_FORMAT ": %s)",
 121.578 +      gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
 121.579                                  obj, obj->blueprint()->internal_name());
 121.580      }
 121.581    }
 121.582 -  assert(obj->is_oop(), "Enqueued a bad reference");
 121.583 +  assert(obj->is_oop(), "Discovered a bad reference");
 121.584    verify_referent(obj);
 121.585    return true;
 121.586  }
 121.587 @@ -1437,22 +1490,12 @@
 121.588  }
 121.589  #endif
 121.590  
 121.591 -void ReferenceProcessor::verify() {
 121.592 -  guarantee(sentinel_ref() != NULL && sentinel_ref()->is_oop(), "Lost _sentinelRef");
 121.593 -}
 121.594 -
 121.595  #ifndef PRODUCT
 121.596  void ReferenceProcessor::clear_discovered_references() {
 121.597    guarantee(!_discovering_refs, "Discovering refs?");
 121.598    for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
 121.599 -    oop obj = _discoveredSoftRefs[i].head();
 121.600 -    while (obj != sentinel_ref()) {
 121.601 -      oop next = java_lang_ref_Reference::discovered(obj);
 121.602 -      java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
 121.603 -      obj = next;
 121.604 -    }
 121.605 -    _discoveredSoftRefs[i].set_head(sentinel_ref());
 121.606 -    _discoveredSoftRefs[i].set_length(0);
 121.607 +    clear_discovered_references(_discoveredSoftRefs[i]);
 121.608    }
 121.609  }
 121.610 +
 121.611  #endif // PRODUCT
   122.1 --- a/src/share/vm/memory/referenceProcessor.hpp	Thu Sep 08 16:59:27 2011 -0700
   122.2 +++ b/src/share/vm/memory/referenceProcessor.hpp	Fri Sep 09 16:17:16 2011 -0700
   122.3 @@ -52,8 +52,8 @@
   122.4  
   122.5  class ReferenceProcessor : public CHeapObj {
   122.6   protected:
   122.7 -  // End of list marker
   122.8 -  static oop  _sentinelRef;
   122.9 +  // Compatibility with pre-4965777 JDK's
  122.10 +  static bool _pending_list_uses_discovered_field;
  122.11    MemRegion   _span; // (right-open) interval of heap
  122.12                       // subject to wkref discovery
  122.13    bool        _discovering_refs;      // true when discovery enabled
  122.14 @@ -106,8 +106,6 @@
  122.15    int max_num_q()                        { return _max_num_q; }
  122.16    void set_active_mt_degree(int v)       { _num_q = v; }
  122.17    DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; }
  122.18 -  static oop  sentinel_ref()             { return _sentinelRef; }
  122.19 -  static oop* adr_sentinel_ref()         { return &_sentinelRef; }
  122.20    ReferencePolicy* setup_policy(bool always_clear) {
  122.21      _current_soft_ref_policy = always_clear ?
  122.22        _always_clear_soft_ref_policy : _default_soft_ref_policy;
  122.23 @@ -115,7 +113,6 @@
  122.24      return _current_soft_ref_policy;
  122.25    }
  122.26  
  122.27 - public:
  122.28    // Process references with a certain reachability level.
  122.29    void process_discovered_reflist(DiscoveredList               refs_lists[],
  122.30                                    ReferencePolicy*             policy,
  122.31 @@ -230,6 +227,7 @@
  122.32                                          HeapWord* discovered_addr);
  122.33    void verify_ok_to_handle_reflists() PRODUCT_RETURN;
  122.34  
  122.35 +  void clear_discovered_references(DiscoveredList& refs_list);
  122.36    void abandon_partial_discovered_list(DiscoveredList& refs_list);
  122.37  
  122.38    // Calculate the number of jni handles.
  122.39 @@ -300,6 +298,13 @@
  122.40    bool discovery_is_atomic() const { return _discovery_is_atomic; }
  122.41    void set_atomic_discovery(bool atomic) { _discovery_is_atomic = atomic; }
  122.42  
  122.43 +  // whether the JDK in which we are embedded is a pre-4965777 JDK,
  122.44 +  // and thus whether or not it uses the discovered field to chain
  122.45 +  // the entries in the pending list.
  122.46 +  static bool pending_list_uses_discovered_field() {
  122.47 +    return _pending_list_uses_discovered_field;
  122.48 +  }
  122.49 +
  122.50    // whether discovery is done by multiple threads same-old-timeously
  122.51    bool discovery_is_mt() const { return _discovery_is_mt; }
  122.52    void set_mt_discovery(bool mt) { _discovery_is_mt = mt; }
  122.53 @@ -314,7 +319,6 @@
  122.54  
  122.55    // iterate over oops
  122.56    void weak_oops_do(OopClosure* f);       // weak roots
  122.57 -  static void oops_do(OopClosure* f);     // strong root(s)
  122.58  
  122.59    // Balance each of the discovered lists.
  122.60    void balance_all_queues();
  122.61 @@ -340,7 +344,6 @@
  122.62    // debugging
  122.63    void verify_no_references_recorded() PRODUCT_RETURN;
  122.64    void verify_referent(oop obj)        PRODUCT_RETURN;
  122.65 -  static void verify();
  122.66  
  122.67    // clear the discovered lists (unlinking each entry).
  122.68    void clear_discovered_references() PRODUCT_RETURN;
  122.69 @@ -524,12 +527,10 @@
  122.70    EnqueueTask(ReferenceProcessor& ref_processor,
  122.71                DiscoveredList      refs_lists[],
  122.72                HeapWord*           pending_list_addr,
  122.73 -              oop                 sentinel_ref,
  122.74                int                 n_queues)
  122.75      : _ref_processor(ref_processor),
  122.76        _refs_lists(refs_lists),
  122.77        _pending_list_addr(pending_list_addr),
  122.78 -      _sentinel_ref(sentinel_ref),
  122.79        _n_queues(n_queues)
  122.80    { }
  122.81  
  122.82 @@ -540,7 +541,6 @@
  122.83    ReferenceProcessor& _ref_processor;
  122.84    DiscoveredList*     _refs_lists;
  122.85    HeapWord*           _pending_list_addr;
  122.86 -  oop                 _sentinel_ref;
  122.87    int                 _n_queues;
  122.88  };
  122.89  
   123.1 --- a/src/share/vm/memory/sharedHeap.cpp	Thu Sep 08 16:59:27 2011 -0700
   123.2 +++ b/src/share/vm/memory/sharedHeap.cpp	Fri Sep 09 16:17:16 2011 -0700
   123.3 @@ -146,7 +146,6 @@
   123.4    assert(_strong_roots_parity != 0, "must have called prologue code");
   123.5    if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) {
   123.6      Universe::oops_do(roots);
   123.7 -    ReferenceProcessor::oops_do(roots);
   123.8      // Consider perm-gen discovered lists to be strong.
   123.9      perm_gen()->ref_processor()->weak_oops_do(roots);
  123.10    }
   124.1 --- a/src/share/vm/memory/universe.cpp	Thu Sep 08 16:59:27 2011 -0700
   124.2 +++ b/src/share/vm/memory/universe.cpp	Fri Sep 09 16:17:16 2011 -0700
   124.3 @@ -1203,12 +1203,12 @@
   124.4    // Compute the dependent nmethods that have a reference to a
   124.5    // CallSite object.  We use instanceKlass::mark_dependent_nmethod
   124.6    // directly instead of CodeCache::mark_for_deoptimization because we
   124.7 -  // want dependents on the class CallSite only not all classes in the
   124.8 -  // ContextStream.
   124.9 +  // want dependents on the call site class only not all classes in
  124.10 +  // the ContextStream.
  124.11    int marked = 0;
  124.12    {
  124.13      MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
  124.14 -    instanceKlass* call_site_klass = instanceKlass::cast(SystemDictionary::CallSite_klass());
  124.15 +    instanceKlass* call_site_klass = instanceKlass::cast(call_site->klass());
  124.16      marked = call_site_klass->mark_dependent_nmethods(changes);
  124.17    }
  124.18    if (marked > 0) {
   125.1 --- a/src/share/vm/oops/constMethodKlass.cpp	Thu Sep 08 16:59:27 2011 -0700
   125.2 +++ b/src/share/vm/oops/constMethodKlass.cpp	Fri Sep 09 16:17:16 2011 -0700
   125.3 @@ -172,11 +172,6 @@
   125.4  int constMethodKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
   125.5    assert(obj->is_constMethod(), "should be constMethod");
   125.6    constMethodOop cm_oop = constMethodOop(obj);
   125.7 -#if 0
   125.8 -  PSParallelCompact::adjust_pointer(cm_oop->adr_method());
   125.9 -  PSParallelCompact::adjust_pointer(cm_oop->adr_exception_table());
  125.10 -  PSParallelCompact::adjust_pointer(cm_oop->adr_stackmap_data());
  125.11 -#endif
  125.12    oop* const beg_oop = cm_oop->oop_block_beg();
  125.13    oop* const end_oop = cm_oop->oop_block_end();
  125.14    for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
   126.1 --- a/src/share/vm/oops/cpCacheKlass.cpp	Thu Sep 08 16:59:27 2011 -0700
   126.2 +++ b/src/share/vm/oops/cpCacheKlass.cpp	Fri Sep 09 16:17:16 2011 -0700
   126.3 @@ -63,8 +63,10 @@
   126.4    //   CollectedHeap::permanent_obj_allocate(klass, size, CHECK_NULL);
   126.5  
   126.6    oop obj = CollectedHeap::permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
   126.7 -  NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
   126.8 -                                                              size));
   126.9 +#ifndef PRODUCT
  126.10 +  const size_t hs = oopDesc::header_size();
  126.11 +  Universe::heap()->check_for_bad_heap_word_value(((HeapWord*) obj)+hs, size-hs);
  126.12 +#endif
  126.13    constantPoolCacheOop cache = (constantPoolCacheOop) obj;
  126.14    assert(!UseConcMarkSweepGC || obj->klass_or_null() == NULL,
  126.15           "klass should be NULL here when using CMS");
   127.1 --- a/src/share/vm/oops/instanceRefKlass.cpp	Thu Sep 08 16:59:27 2011 -0700
   127.2 +++ b/src/share/vm/oops/instanceRefKlass.cpp	Fri Sep 09 16:17:16 2011 -0700
   127.3 @@ -56,9 +56,8 @@
   127.4    if (!oopDesc::is_null(heap_oop)) {
   127.5      oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
   127.6      if (!referent->is_gc_marked() &&
   127.7 -        MarkSweep::ref_processor()->
   127.8 -          discover_reference(obj, ref->reference_type())) {
   127.9 -      // reference already enqueued, referent will be traversed later
  127.10 +        MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) {
  127.11 +      // reference was discovered, referent will be traversed later
  127.12        ref->instanceKlass::oop_follow_contents(obj);
  127.13        debug_only(
  127.14          if(TraceReferenceGC && PrintGCDetails) {
  127.15 @@ -76,8 +75,34 @@
  127.16        MarkSweep::mark_and_push(referent_addr);
  127.17      }
  127.18    }
  127.19 -  // treat next as normal oop.  next is a link in the pending list.
  127.20    T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  127.21 +  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
  127.22 +    // Treat discovered as normal oop, if ref is not "active",
  127.23 +    // i.e. if next is non-NULL.
  127.24 +    T  next_oop = oopDesc::load_heap_oop(next_addr);
  127.25 +    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
  127.26 +      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
  127.27 +      debug_only(
  127.28 +        if(TraceReferenceGC && PrintGCDetails) {
  127.29 +          gclog_or_tty->print_cr("   Process discovered as normal "
  127.30 +                                 INTPTR_FORMAT, discovered_addr);
  127.31 +        }
  127.32 +      )
  127.33 +      MarkSweep::mark_and_push(discovered_addr);
  127.34 +    }
  127.35 +  } else {
  127.36 +#ifdef ASSERT
  127.37 +    // In the case of older JDKs which do not use the discovered
  127.38 +    // field for the pending list, an inactive ref (next != NULL)
  127.39 +    // must always have a NULL discovered field.
  127.40 +    oop next = oopDesc::load_decode_heap_oop(next_addr);
  127.41 +    oop discovered = java_lang_ref_Reference::discovered(obj);
  127.42 +    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
  127.43 +           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
  127.44 +                   obj));
  127.45 +#endif
  127.46 +  }
  127.47 +  // treat next as normal oop.  next is a link in the reference queue.
  127.48    debug_only(
  127.49      if(TraceReferenceGC && PrintGCDetails) {
  127.50        gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
  127.51 @@ -130,13 +155,33 @@
  127.52        PSParallelCompact::mark_and_push(cm, referent_addr);
  127.53      }
  127.54    }
  127.55 -  // treat next as normal oop.  next is a link in the pending list.
  127.56    T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
  127.57 -  debug_only(
  127.58 -    if(TraceReferenceGC && PrintGCDetails) {
  127.59 -      gclog_or_tty->print_cr("   Process next as normal " INTPTR_FORMAT, next_addr);
  127.60 +  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
  127.61 +    // Treat discovered as normal oop, if ref is not "active",
  127.62 +    // i.e. if next is non-NULL.
  127.63 +    T  next_oop = oopDesc::load_heap_oop(next_addr);
  127.64 +    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
  127.65 +      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
  127.66 +      debug_only(
  127.67 +        if(TraceReferenceGC && PrintGCDetails) {
  127.68 +          gclog_or_tty->print_cr("   Process discovered as normal "
  127.69 +                                 INTPTR_FORMAT, discovered_addr);
  127.70 +        }
  127.71 +      )
  127.72 +      PSParallelCompact::mark_and_push(cm, discovered_addr);
  127.73      }
  127.74 -  )
  127.75 +  } else {
  127.76 +#ifdef ASSERT
  127.77 +    // In the case of older JDKs which do not use the discovered
  127.78 +    // field for the pending list, an inactive ref (next != NULL)
  127.79 +    // must always have a NULL discovered field.
  127.80 +    T next = oopDesc::load_heap_oop(next_addr);
  127.81 +    oop discovered = java_lang_ref_Reference::discovered(obj);
  127.82 +    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
  127.83 +           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
  127.84 +                   obj));
  127.85 +#endif
  127.86 +  }
  127.87    PSParallelCompact::mark_and_push(cm, next_addr);
  127.88    ref->instanceKlass::oop_follow_contents(cm, obj);
  127.89  }
  127.90 @@ -197,27 +242,53 @@
  127.91  }
  127.92  
  127.93  #define InstanceRefKlass_SPECIALIZED_OOP_ITERATE(T, nv_suffix, contains)        \
  127.94 +  T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);             \
  127.95    if (closure->apply_to_weak_ref_discovered_field()) {                          \
  127.96 -    T* disc_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);           \
  127.97      closure->do_oop##nv_suffix(disc_addr);                                      \
  127.98    }                                                                             \
  127.99                                                                                  \
 127.100    T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);           \
 127.101    T heap_oop = oopDesc::load_heap_oop(referent_addr);                           \
 127.102 -  if (!oopDesc::is_null(heap_oop) && contains(referent_addr)) {                 \
 127.103 -    ReferenceProcessor* rp = closure->_ref_processor;                           \
 127.104 +  ReferenceProcessor* rp = closure->_ref_processor;                             \
 127.105 +  if (!oopDesc::is_null(heap_oop)) {                                            \
 127.106      oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);                 \
 127.107      if (!referent->is_gc_marked() && (rp != NULL) &&                            \
 127.108          rp->discover_reference(obj, reference_type())) {                        \
 127.109        return size;                                                              \
 127.110 -    } else {                                                                    \
 127.111 +    } else if (contains(referent_addr)) {                                       \
 127.112        /* treat referent as normal oop */                                        \
 127.113        SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
 127.114        closure->do_oop##nv_suffix(referent_addr);                                \
 127.115      }                                                                           \
 127.116    }                                                                             \
 127.117 +  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);                   \
 127.118 +  if (ReferenceProcessor::pending_list_uses_discovered_field()) {               \
 127.119 +    T next_oop  = oopDesc::load_heap_oop(next_addr);                            \
 127.120 +    /* Treat discovered as normal oop, if ref is not "active" (next non-NULL) */\
 127.121 +    if (!oopDesc::is_null(next_oop) && contains(disc_addr)) {                   \
 127.122 +        /* i.e. ref is not "active" */                                          \
 127.123 +      debug_only(                                                               \
 127.124 +        if(TraceReferenceGC && PrintGCDetails) {                                \
 127.125 +          gclog_or_tty->print_cr("   Process discovered as normal "             \
 127.126 +                                 INTPTR_FORMAT, disc_addr);                     \
 127.127 +        }                                                                       \
 127.128 +      )                                                                         \
 127.129 +      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk);\
 127.130 +      closure->do_oop##nv_suffix(disc_addr);                                    \
 127.131 +    }                                                                           \
 127.132 +  } else {                                                                      \
 127.133 +    /* In the case of older JDKs which do not use the discovered field for  */  \
 127.134 +    /* the pending list, an inactive ref (next != NULL) must always have a  */  \
 127.135 +    /* NULL discovered field. */                                                \
 127.136 +    debug_only(                                                                 \
 127.137 +      T next_oop = oopDesc::load_heap_oop(next_addr);                           \
 127.138 +      T disc_oop = oopDesc::load_heap_oop(disc_addr);                           \
 127.139 +      assert(oopDesc::is_null(next_oop) || oopDesc::is_null(disc_oop),          \
 127.140 +           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL" \
 127.141 +                   "discovered field", obj));                                   \
 127.142 +    )                                                                           \
 127.143 +  }                                                                             \
 127.144    /* treat next as normal oop */                                                \
 127.145 -  T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);                   \
 127.146    if (contains(next_addr)) {                                                    \
 127.147      SpecializationStats::record_do_oop_call##nv_suffix(SpecializationStats::irk); \
 127.148      closure->do_oop##nv_suffix(next_addr);                                      \
 127.149 @@ -306,8 +377,37 @@
 127.150        pm->claim_or_forward_depth(referent_addr);
 127.151      }
 127.152    }
 127.153 -  // treat next as normal oop
 127.154 +  // Treat discovered as normal oop, if ref is not "active",
 127.155 +  // i.e. if next is non-NULL.
 127.156    T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
 127.157 +  if (ReferenceProcessor::pending_list_uses_discovered_field()) {
 127.158 +    T  next_oop = oopDesc::load_heap_oop(next_addr);
 127.159 +    if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
 127.160 +      T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
 127.161 +      debug_only(
 127.162 +        if(TraceReferenceGC && PrintGCDetails) {
 127.163 +          gclog_or_tty->print_cr("   Process discovered as normal "
 127.164 +                                 INTPTR_FORMAT, discovered_addr);
 127.165 +        }
 127.166 +      )
 127.167 +      if (PSScavenge::should_scavenge(discovered_addr)) {
 127.168 +        pm->claim_or_forward_depth(discovered_addr);
 127.169 +      }
 127.170 +    }
 127.171 +  } else {
 127.172 +#ifdef ASSERT
 127.173 +    // In the case of older JDKs which do not use the discovered
 127.174 +    // field for the pending list, an inactive ref (next != NULL)
 127.175 +    // must always have a NULL discovered field.
 127.176 +    oop next = oopDesc::load_decode_heap_oop(next_addr);
 127.177 +    oop discovered = java_lang_ref_Reference::discovered(obj);
 127.178 +    assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
 127.179 +           err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
 127.180 +                   obj));
 127.181 +#endif
 127.182 +  }
 127.183 +
 127.184 +  // Treat next as normal oop;  next is a link in the reference queue.
 127.185    if (PSScavenge::should_scavenge(next_addr)) {
 127.186      pm->claim_or_forward_depth(next_addr);
 127.187    }
   128.1 --- a/src/share/vm/oops/methodDataOop.hpp	Thu Sep 08 16:59:27 2011 -0700
   128.2 +++ b/src/share/vm/oops/methodDataOop.hpp	Fri Sep 09 16:17:16 2011 -0700
   128.3 @@ -600,6 +600,11 @@
   128.4    uint taken() {
   128.5      return uint_at(taken_off_set);
   128.6    }
   128.7 +
   128.8 +  void set_taken(uint cnt) {
   128.9 +    set_uint_at(taken_off_set, cnt);
  128.10 +  }
  128.11 +
  128.12    // Saturating counter
  128.13    uint inc_taken() {
  128.14      uint cnt = taken() + 1;
  128.15 @@ -926,6 +931,10 @@
  128.16      return uint_at(not_taken_off_set);
  128.17    }
  128.18  
  128.19 +  void set_not_taken(uint cnt) {
  128.20 +    set_uint_at(not_taken_off_set, cnt);
  128.21 +  }
  128.22 +
  128.23    uint inc_not_taken() {
  128.24      uint cnt = not_taken() + 1;
  128.25      // Did we wrap? Will compiler screw us??
   129.1 --- a/src/share/vm/oops/methodOop.cpp	Thu Sep 08 16:59:27 2011 -0700
   129.2 +++ b/src/share/vm/oops/methodOop.cpp	Fri Sep 09 16:17:16 2011 -0700
   129.3 @@ -914,6 +914,7 @@
   129.4                                                 Symbol* name,
   129.5                                                 Symbol* signature,
   129.6                                                 Handle method_type, TRAPS) {
   129.7 +  ResourceMark rm;
   129.8    methodHandle empty;
   129.9  
  129.10    assert(holder() == SystemDictionary::MethodHandle_klass(),
   130.1 --- a/src/share/vm/opto/bytecodeInfo.cpp	Thu Sep 08 16:59:27 2011 -0700
   130.2 +++ b/src/share/vm/opto/bytecodeInfo.cpp	Fri Sep 09 16:17:16 2011 -0700
   130.3 @@ -45,7 +45,7 @@
   130.4    _method(callee),
   130.5    _site_invoke_ratio(site_invoke_ratio),
   130.6    _max_inline_level(max_inline_level),
   130.7 -  _count_inline_bcs(method()->code_size())
   130.8 +  _count_inline_bcs(method()->code_size_for_inlining())
   130.9  {
  130.10    NOT_PRODUCT(_count_inlines = 0;)
  130.11    if (_caller_jvms != NULL) {
  130.12 @@ -107,7 +107,7 @@
  130.13  
  130.14    // positive filter: should send be inlined?  returns NULL (--> yes)
  130.15    // or rejection msg
  130.16 -  int size = callee_method->code_size();
  130.17 +  int size = callee_method->code_size_for_inlining();
  130.18  
  130.19    // Check for too many throws (and not too huge)
  130.20    if(callee_method->interpreter_throwout_count() > InlineThrowCount &&
  130.21 @@ -141,7 +141,21 @@
  130.22      assert(mha_profile, "must exist");
  130.23      CounterData* cd = mha_profile->as_CounterData();
  130.24      invoke_count = cd->count();
  130.25 -    call_site_count = invoke_count;  // use the same value
  130.26 +    if (invoke_count == 0) {
  130.27 +      return "method handle not reached";
  130.28 +    }
  130.29 +
  130.30 +    if (_caller_jvms != NULL && _caller_jvms->method() != NULL &&
  130.31 +        _caller_jvms->method()->method_data() != NULL &&
  130.32 +        !_caller_jvms->method()->method_data()->is_empty()) {
  130.33 +      ciMethodData* mdo = _caller_jvms->method()->method_data();
  130.34 +      ciProfileData* mha_profile = mdo->bci_to_data(_caller_jvms->bci());
  130.35 +      assert(mha_profile, "must exist");
  130.36 +      CounterData* cd = mha_profile->as_CounterData();
  130.37 +      call_site_count = cd->count();
  130.38 +    } else {
  130.39 +      call_site_count = invoke_count;  // use the same value
  130.40 +    }
  130.41    }
  130.42  
  130.43    assert(invoke_count != 0, "require invocation count greater than zero");
  130.44 @@ -244,7 +258,7 @@
  130.45    }
  130.46  
  130.47    // use frequency-based objections only for non-trivial methods
  130.48 -  if (callee_method->code_size() <= MaxTrivialSize) return NULL;
  130.49 +  if (callee_method->code_size_for_inlining() <= MaxTrivialSize) return NULL;
  130.50  
  130.51    // don't use counts with -Xcomp or CTW
  130.52    if (UseInterpreter && !CompileTheWorld) {
  130.53 @@ -305,7 +319,7 @@
  130.54    }
  130.55  
  130.56    // suppress a few checks for accessors and trivial methods
  130.57 -  if (callee_method->code_size() > MaxTrivialSize) {
  130.58 +  if (callee_method->code_size_for_inlining() > MaxTrivialSize) {
  130.59  
  130.60      // don't inline into giant methods
  130.61      if (C->unique() > (uint)NodeCountInliningCutoff) {
  130.62 @@ -349,7 +363,7 @@
  130.63      }
  130.64    }
  130.65  
  130.66 -  int size = callee_method->code_size();
  130.67 +  int size = callee_method->code_size_for_inlining();
  130.68  
  130.69    if (UseOldInlining && ClipInlining
  130.70        && (int)count_inline_bcs() + size >= DesiredMethodLimit) {
  130.71 @@ -394,6 +408,16 @@
  130.72    return true;
  130.73  }
  130.74  
  130.75 +//------------------------------check_can_parse--------------------------------
  130.76 +const char* InlineTree::check_can_parse(ciMethod* callee) {
  130.77 +  // Certain methods cannot be parsed at all:
  130.78 +  if ( callee->is_native())                     return "native method";
  130.79 +  if (!callee->can_be_compiled())               return "not compilable (disabled)";
  130.80 +  if (!callee->has_balanced_monitors())         return "not compilable (unbalanced monitors)";
  130.81 +  if ( callee->get_flow_analysis()->failing())  return "not compilable (flow analysis failed)";
  130.82 +  return NULL;
  130.83 +}
  130.84 +
  130.85  //------------------------------print_inlining---------------------------------
  130.86  // Really, the failure_msg can be a success message also.
  130.87  void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, const char* failure_msg) const {
  130.88 @@ -423,14 +447,22 @@
  130.89    int         caller_bci    = jvms->bci();
  130.90    ciMethod   *caller_method = jvms->method();
  130.91  
  130.92 -  if( !pass_initial_checks(caller_method, caller_bci, callee_method)) {
  130.93 -    if( PrintInlining ) {
  130.94 +  // Do some initial checks.
  130.95 +  if (!pass_initial_checks(caller_method, caller_bci, callee_method)) {
  130.96 +    if (PrintInlining) {
  130.97        failure_msg = "failed_initial_checks";
  130.98 -      print_inlining( callee_method, caller_bci, failure_msg);
  130.99 +      print_inlining(callee_method, caller_bci, failure_msg);
 130.100      }
 130.101      return NULL;
 130.102    }
 130.103  
 130.104 +  // Do some parse checks.
 130.105 +  failure_msg = check_can_parse(callee_method);
 130.106 +  if (failure_msg != NULL) {
 130.107 +    if (PrintInlining)  print_inlining(callee_method, caller_bci, failure_msg);
 130.108 +    return NULL;
 130.109 +  }
 130.110 +
 130.111    // Check if inlining policy says no.
 130.112    WarmCallInfo wci = *(initial_wci);
 130.113    failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci);
 130.114 @@ -471,7 +503,7 @@
 130.115      if (failure_msg == NULL)  failure_msg = "inline (hot)";
 130.116  
 130.117      // Inline!
 130.118 -    if( PrintInlining ) print_inlining( callee_method, caller_bci, failure_msg);
 130.119 +    if (PrintInlining)  print_inlining(callee_method, caller_bci, failure_msg);
 130.120      if (UseOldInlining)
 130.121        build_inline_tree_for_callee(callee_method, jvms, caller_bci);
 130.122      if (InlineWarmCalls && !wci.is_hot())
 130.123 @@ -481,7 +513,7 @@
 130.124  
 130.125    // Do not inline
 130.126    if (failure_msg == NULL)  failure_msg = "too cold to inline";
 130.127 -  if( PrintInlining ) print_inlining( callee_method, caller_bci, failure_msg);
 130.128 +  if (PrintInlining)  print_inlining(callee_method, caller_bci, failure_msg);
 130.129    return NULL;
 130.130  }
 130.131  
   131.1 --- a/src/share/vm/opto/callGenerator.cpp	Thu Sep 08 16:59:27 2011 -0700
   131.2 +++ b/src/share/vm/opto/callGenerator.cpp	Fri Sep 09 16:17:16 2011 -0700
   131.3 @@ -61,12 +61,9 @@
   131.4    {
   131.5      _is_osr        = is_osr;
   131.6      _expected_uses = expected_uses;
   131.7 -    assert(can_parse(method, is_osr), "parse must be possible");
   131.8 +    assert(InlineTree::check_can_parse(method) == NULL, "parse must be possible");
   131.9    }
  131.10  
  131.11 -  // Can we build either an OSR or a regular parser for this method?
  131.12 -  static bool can_parse(ciMethod* method, int is_osr = false);
  131.13 -
  131.14    virtual bool      is_parse() const           { return true; }
  131.15    virtual JVMState* generate(JVMState* jvms);
  131.16    int is_osr() { return _is_osr; }
  131.17 @@ -152,7 +149,6 @@
  131.18      call->set_optimized_virtual(true);
  131.19      if (method()->is_method_handle_invoke()) {
  131.20        call->set_method_handle_invoke(true);
  131.21 -      kit.C->set_has_method_handle_invokes(true);
  131.22      }
  131.23    }
  131.24    kit.set_arguments_for_java_call(call);
  131.25 @@ -210,7 +206,6 @@
  131.26    call->set_optimized_virtual(true);
  131.27    // Take extra care (in the presence of argument motion) not to trash the SP:
  131.28    call->set_method_handle_invoke(true);
  131.29 -  kit.C->set_has_method_handle_invokes(true);
  131.30  
  131.31    // Pass the target MethodHandle as first argument and shift the
  131.32    // other arguments.
  131.33 @@ -303,20 +298,8 @@
  131.34    return kit.transfer_exceptions_into_jvms();
  131.35  }
  131.36  
  131.37 -bool ParseGenerator::can_parse(ciMethod* m, int entry_bci) {
  131.38 -  // Certain methods cannot be parsed at all:
  131.39 -  if (!m->can_be_compiled())              return false;
  131.40 -  if (!m->has_balanced_monitors())        return false;
  131.41 -  if (m->get_flow_analysis()->failing())  return false;
  131.42 -
  131.43 -  // (Methods may bail out for other reasons, after the parser is run.
  131.44 -  // We try to avoid this, but if forced, we must return (Node*)NULL.
  131.45 -  // The user of the CallGenerator must check for this condition.)
  131.46 -  return true;
  131.47 -}
  131.48 -
  131.49  CallGenerator* CallGenerator::for_inline(ciMethod* m, float expected_uses) {
  131.50 -  if (!ParseGenerator::can_parse(m))  return NULL;
  131.51 +  if (InlineTree::check_can_parse(m) != NULL)  return NULL;
  131.52    return new ParseGenerator(m, expected_uses);
  131.53  }
  131.54  
  131.55 @@ -324,7 +307,7 @@
  131.56  // for the method execution already in progress, not just the JVMS
  131.57  // of the caller.  Thus, this CallGenerator cannot be mixed with others!
  131.58  CallGenerator* CallGenerator::for_osr(ciMethod* m, int osr_bci) {
  131.59 -  if (!ParseGenerator::can_parse(m, true))  return NULL;
  131.60 +  if (InlineTree::check_can_parse(m) != NULL)  return NULL;
  131.61    float past_uses = m->interpreter_invocation_count();
  131.62    float expected_uses = past_uses;
  131.63    return new ParseGenerator(m, expected_uses, true);
  131.64 @@ -336,7 +319,7 @@
  131.65  }
  131.66  
  131.67  CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
  131.68 -  assert(m->is_method_handle_invoke(), "for_dynamic_call mismatch");
  131.69 +  assert(m->is_method_handle_invoke() || m->is_method_handle_adapter(), "for_dynamic_call mismatch");
  131.70    return new DynamicCallGenerator(m);
  131.71  }
  131.72  
  131.73 @@ -715,24 +698,36 @@
  131.74      // Get an adapter for the MethodHandle.
  131.75      ciMethod* target_method = method_handle->get_method_handle_adapter();
  131.76      if (target_method != NULL) {
  131.77 -      CallGenerator* hit_cg = Compile::current()->call_generator(target_method, -1, false, jvms, true, 1);
  131.78 -      if (hit_cg != NULL && hit_cg->is_inline())
  131.79 -        return hit_cg;
  131.80 +      CallGenerator* cg = Compile::current()->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
  131.81 +      if (cg != NULL && cg->is_inline())
  131.82 +        return cg;
  131.83      }
  131.84    } else if (method_handle->Opcode() == Op_Phi && method_handle->req() == 3 &&
  131.85               method_handle->in(1)->Opcode() == Op_ConP && method_handle->in(2)->Opcode() == Op_ConP) {
  131.86 +    float prob = PROB_FAIR;
  131.87 +    Node* meth_region = method_handle->in(0);
  131.88 +    if (meth_region->is_Region() &&
  131.89 +        meth_region->in(1)->is_Proj() && meth_region->in(2)->is_Proj() &&
  131.90 +        meth_region->in(1)->in(0) == meth_region->in(2)->in(0) &&
  131.91 +        meth_region->in(1)->in(0)->is_If()) {
  131.92 +      // If diamond, so grab the probability of the test to drive the inlining below
  131.93 +      prob = meth_region->in(1)->in(0)->as_If()->_prob;
  131.94 +      if (meth_region->in(1)->is_IfTrue()) {
  131.95 +        prob = 1 - prob;
  131.96 +      }
  131.97 +    }
  131.98 +
  131.99      // selectAlternative idiom merging two constant MethodHandles.
 131.100      // Generate a guard so that each can be inlined.  We might want to
 131.101      // do more inputs at later point but this gets the most common
 131.102      // case.
 131.103 -    const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr();
 131.104 -    ciObject* const_oop = oop_ptr->const_oop();
 131.105 -    ciMethodHandle* mh = const_oop->as_method_handle();
 131.106 -
 131.107 -    CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile);
 131.108 -    CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile);
 131.109 +    CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile.rescale(1.0 - prob));
 131.110 +    CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile.rescale(prob));
 131.111      if (cg1 != NULL && cg2 != NULL) {
 131.112 -      return new PredictedDynamicCallGenerator(mh, cg2, cg1, PROB_FAIR);
 131.113 +      const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr();
 131.114 +      ciObject* const_oop = oop_ptr->const_oop();
 131.115 +      ciMethodHandle* mh = const_oop->as_method_handle();
 131.116 +      return new PredictedDynamicCallGenerator(mh, cg2, cg1, prob);
 131.117      }
 131.118    }
 131.119    return NULL;
 131.120 @@ -741,7 +736,6 @@
 131.121  
 131.122  CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms,
 131.123                                                         ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
 131.124 -  assert(call_site->is_constant_call_site() || call_site->is_mutable_call_site(), "must be");
 131.125    ciMethodHandle* method_handle = call_site->get_target();
 131.126  
 131.127    // Set the callee to have access to the class and signature in the
 131.128 @@ -754,13 +748,13 @@
 131.129    ciMethod* target_method = method_handle->get_invokedynamic_adapter();
 131.130    if (target_method != NULL) {
 131.131      Compile *C = Compile::current();
 131.132 -    CallGenerator* hit_cg = C->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
 131.133 -    if (hit_cg != NULL && hit_cg->is_inline()) {
 131.134 +    CallGenerator* cg = C->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
 131.135 +    if (cg != NULL && cg->is_inline()) {
 131.136        // Add a dependence for invalidation of the optimization.
 131.137 -      if (call_site->is_mutable_call_site()) {
 131.138 -        C->dependencies()->assert_call_site_target_value(C->env()->CallSite_klass(), call_site, method_handle);
 131.139 +      if (!call_site->is_constant_call_site()) {
 131.140 +        C->dependencies()->assert_call_site_target_value(call_site, method_handle);
 131.141        }
 131.142 -      return hit_cg;
 131.143 +      return cg;
 131.144      }
 131.145    }
 131.146    return NULL;
   132.1 --- a/src/share/vm/opto/compile.cpp	Thu Sep 08 16:59:27 2011 -0700
   132.2 +++ b/src/share/vm/opto/compile.cpp	Fri Sep 09 16:17:16 2011 -0700
   132.3 @@ -817,7 +817,6 @@
   132.4                             &_handler_table, &_inc_table,
   132.5                             compiler,
   132.6                             env()->comp_level(),
   132.7 -                           true, /*has_debug_info*/
   132.8                             has_unsafe_access()
   132.9                             );
  132.10    }
   133.1 --- a/src/share/vm/opto/connode.hpp	Thu Sep 08 16:59:27 2011 -0700
   133.2 +++ b/src/share/vm/opto/connode.hpp	Fri Sep 09 16:17:16 2011 -0700
   133.3 @@ -496,14 +496,6 @@
   133.4    virtual bool depends_only_on_test() const { return false; }
   133.5  };
   133.6  
   133.7 -//------------------------------MemMoveNode------------------------------------
   133.8 -// Memory to memory move.  Inserted very late, after allocation.
   133.9 -class MemMoveNode : public Node {
  133.10 -public:
  133.11 -  MemMoveNode( Node *dst, Node *src ) : Node(0,dst,src) {}
  133.12 -  virtual int Opcode() const;
  133.13 -};
  133.14 -
  133.15  //------------------------------ThreadLocalNode--------------------------------
  133.16  // Ideal Node which returns the base of ThreadLocalStorage.
  133.17  class ThreadLocalNode : public Node {
   134.1 --- a/src/share/vm/opto/doCall.cpp	Thu Sep 08 16:59:27 2011 -0700
   134.2 +++ b/src/share/vm/opto/doCall.cpp	Fri Sep 09 16:17:16 2011 -0700
   134.3 @@ -136,15 +136,9 @@
   134.4        str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
   134.5        ciCallSite* call_site = str.get_call_site();
   134.6  
   134.7 -      // Inline constant and mutable call sites.  We don't inline
   134.8 -      // volatile call sites optimistically since they are specified
   134.9 -      // to change their value often and that would result in a lot of
  134.10 -      // deoptimizations and recompiles.
  134.11 -      if (call_site->is_constant_call_site() || call_site->is_mutable_call_site()) {
  134.12 -        CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile);
  134.13 -        if (cg != NULL) {
  134.14 -          return cg;
  134.15 -        }
  134.16 +      CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile);
  134.17 +      if (cg != NULL) {
  134.18 +        return cg;
  134.19        }
  134.20        // If something failed, generate a normal dynamic call.
  134.21        return CallGenerator::for_dynamic_call(call_method);
   135.1 --- a/src/share/vm/opto/idealGraphPrinter.cpp	Thu Sep 08 16:59:27 2011 -0700
   135.2 +++ b/src/share/vm/opto/idealGraphPrinter.cpp	Fri Sep 09 16:17:16 2011 -0700
   135.3 @@ -375,9 +375,9 @@
   135.4    return (intptr_t)(n);
   135.5  }
   135.6  
   135.7 -void IdealGraphPrinter::visit_node(Node *n, void *param) {
   135.8 +void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
   135.9  
  135.10 -  if(param) {
  135.11 +  if (edges) {
  135.12  
  135.13      // Output edge
  135.14      intptr_t dest_id = get_node_id(n);
  135.15 @@ -599,16 +599,11 @@
  135.16  
  135.17  #ifdef ASSERT
  135.18      if (node->debug_orig() != NULL) {
  135.19 +      temp_set->Clear();
  135.20        stringStream dorigStream;
  135.21        Node* dorig = node->debug_orig();
  135.22 -      if (dorig) {
  135.23 +      while (dorig && temp_set->test_set(dorig->_idx)) {
  135.24          dorigStream.print("%d ", dorig->_idx);
  135.25 -        Node* first = dorig;
  135.26 -        dorig = first->debug_orig();
  135.27 -        while (dorig && dorig != first) {
  135.28 -          dorigStream.print("%d ", dorig->_idx);
  135.29 -          dorig = dorig->debug_orig();
  135.30 -        }
  135.31        }
  135.32        print_prop("debug_orig", dorigStream.as_string());
  135.33      }
  135.34 @@ -629,7 +624,7 @@
  135.35    }
  135.36  }
  135.37  
  135.38 -void IdealGraphPrinter::walk_nodes(Node *start, void *param) {
  135.39 +void IdealGraphPrinter::walk_nodes(Node *start, bool edges, VectorSet* temp_set) {
  135.40  
  135.41  
  135.42    VectorSet visited(Thread::current()->resource_area());
  135.43 @@ -650,7 +645,7 @@
  135.44    while(nodeStack.length() > 0) {
  135.45  
  135.46      Node *n = nodeStack.pop();
  135.47 -    visit_node(n, param);
  135.48 +    visit_node(n, edges, temp_set);
  135.49  
  135.50      if (_traverse_outs) {
  135.51        for (DUIterator i = n->outs(); n->has_out(i); i++) {
  135.52 @@ -689,12 +684,14 @@
  135.53    print_attr(GRAPH_NAME_PROPERTY, (const char *)name);
  135.54    end_head();
  135.55  
  135.56 +  VectorSet temp_set(Thread::current()->resource_area());
  135.57 +
  135.58    head(NODES_ELEMENT);
  135.59 -  walk_nodes(node, NULL);
  135.60 +  walk_nodes(node, false, &temp_set);
  135.61    tail(NODES_ELEMENT);
  135.62  
  135.63    head(EDGES_ELEMENT);
  135.64 -  walk_nodes(node, (void *)1);
  135.65 +  walk_nodes(node, true, &temp_set);
  135.66    tail(EDGES_ELEMENT);
  135.67    if (C->cfg() != NULL) {
  135.68      head(CONTROL_FLOW_ELEMENT);
   136.1 --- a/src/share/vm/opto/idealGraphPrinter.hpp	Thu Sep 08 16:59:27 2011 -0700
   136.2 +++ b/src/share/vm/opto/idealGraphPrinter.hpp	Fri Sep 09 16:17:16 2011 -0700
   136.3 @@ -104,8 +104,8 @@
   136.4    void print_indent();
   136.5    void print_method(ciMethod *method, int bci, InlineTree *tree);
   136.6    void print_inline_tree(InlineTree *tree);
   136.7 -  void visit_node(Node *n, void *param);
   136.8 -  void walk_nodes(Node *start, void *param);
   136.9 +  void visit_node(Node *n, bool edges, VectorSet* temp_set);
  136.10 +  void walk_nodes(Node *start, bool edges, VectorSet* temp_set);
  136.11    void begin_elem(const char *s);
  136.12    void end_elem();
  136.13    void begin_head(const char *s);
   137.1 --- a/src/share/vm/opto/matcher.cpp	Thu Sep 08 16:59:27 2011 -0700
   137.2 +++ b/src/share/vm/opto/matcher.cpp	Fri Sep 09 16:17:16 2011 -0700
   137.3 @@ -501,6 +501,12 @@
   137.4       idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegD]);
   137.5  #else
   137.6       idealreg2spillmask[Op_RegP]->OR(*idealreg2regmask[Op_RegF]);
   137.7 +#ifdef ARM
   137.8 +     // ARM has support for moving 64bit values between a pair of
   137.9 +     // integer registers and a double register
  137.10 +     idealreg2spillmask[Op_RegL]->OR(*idealreg2regmask[Op_RegD]);
  137.11 +     idealreg2spillmask[Op_RegD]->OR(*idealreg2regmask[Op_RegL]);
  137.12 +#endif
  137.13  #endif
  137.14     }
  137.15  
  137.16 @@ -1106,6 +1112,9 @@
  137.17        mcall_java->_optimized_virtual = call_java->is_optimized_virtual();
  137.18        is_method_handle_invoke = call_java->is_method_handle_invoke();
  137.19        mcall_java->_method_handle_invoke = is_method_handle_invoke;
  137.20 +      if (is_method_handle_invoke) {
  137.21 +        C->set_has_method_handle_invokes(true);
  137.22 +      }
  137.23        if( mcall_java->is_MachCallStaticJava() )
  137.24          mcall_java->as_MachCallStaticJava()->_name =
  137.25           call_java->as_CallStaticJava()->_name;
   138.1 --- a/src/share/vm/opto/memnode.cpp	Thu Sep 08 16:59:27 2011 -0700
   138.2 +++ b/src/share/vm/opto/memnode.cpp	Fri Sep 09 16:17:16 2011 -0700
   138.3 @@ -1493,6 +1493,7 @@
   138.4    if (tp == NULL || tp->empty())  return Type::TOP;
   138.5    int off = tp->offset();
   138.6    assert(off != Type::OffsetTop, "case covered by TypePtr::empty");
   138.7 +  Compile* C = phase->C;
   138.8  
   138.9    // Try to guess loaded type from pointer type
  138.10    if (tp->base() == Type::AryPtr) {
  138.11 @@ -1536,7 +1537,7 @@
  138.12            Node* base = adr->in(AddPNode::Base);
  138.13            if (base != NULL &&
  138.14                !phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
  138.15 -            Compile::AliasType* atp = phase->C->alias_type(base->adr_type());
  138.16 +            Compile::AliasType* atp = C->alias_type(base->adr_type());
  138.17              if (is_autobox_cache(atp)) {
  138.18                return jt->join(TypePtr::NOTNULL)->is_ptr();
  138.19              }
  138.20 @@ -1546,22 +1547,23 @@
  138.21        }
  138.22      }
  138.23    } else if (tp->base() == Type::InstPtr) {
  138.24 +    ciEnv* env = C->env();
  138.25      const TypeInstPtr* tinst = tp->is_instptr();
  138.26      ciKlass* klass = tinst->klass();
  138.27      assert( off != Type::OffsetBot ||
  138.28              // arrays can be cast to Objects
  138.29              tp->is_oopptr()->klass()->is_java_lang_Object() ||
  138.30              // unsafe field access may not have a constant offset
  138.31 -            phase->C->has_unsafe_access(),
  138.32 +            C->has_unsafe_access(),
  138.33              "Field accesses must be precise" );
  138.34      // For oop loads, we expect the _type to be precise
  138.35 -    if (klass == phase->C->env()->String_klass() &&
  138.36 +    if (klass == env->String_klass() &&
  138.37          adr->is_AddP() && off != Type::OffsetBot) {
  138.38        // For constant Strings treat the final fields as compile time constants.
  138.39        Node* base = adr->in(AddPNode::Base);
  138.40        const TypeOopPtr* t = phase->type(base)->isa_oopptr();
  138.41        if (t != NULL && t->singleton()) {
  138.42 -        ciField* field = phase->C->env()->String_klass()->get_field_by_offset(off, false);
  138.43 +        ciField* field = env->String_klass()->get_field_by_offset(off, false);
  138.44          if (field != NULL && field->is_final()) {
  138.45            ciObject* string = t->const_oop();
  138.46            ciConstant constant = string->as_instance()->field_value(field);
  138.47 @@ -1577,6 +1579,32 @@
  138.48          }
  138.49        }
  138.50      }
  138.51 +    // Optimizations for constant objects
  138.52 +    ciObject* const_oop = tinst->const_oop();
  138.53 +    if (const_oop != NULL) {
  138.54 +      // For constant CallSites treat the target field as a compile time constant.
  138.55 +      if (const_oop->is_call_site()) {
  138.56 +        ciCallSite* call_site = const_oop->as_call_site();
  138.57 +        ciField* field = call_site->klass()->as_instance_klass()->get_field_by_offset(off, /*is_static=*/ false);
  138.58 +        if (field != NULL && field->is_call_site_target()) {
  138.59 +          ciMethodHandle* target = call_site->get_target();
  138.60 +          if (target != NULL) {  // just in case
  138.61 +            ciConstant constant(T_OBJECT, target);
  138.62 +            const Type* t;
  138.63 +            if (adr->bottom_type()->is_ptr_to_narrowoop()) {
  138.64 +              t = TypeNarrowOop::make_from_constant(constant.as_object(), true);
  138.65 +            } else {
  138.66 +              t = TypeOopPtr::make_from_constant(constant.as_object(), true);
  138.67 +            }
  138.68 +            // Add a dependence for invalidation of the optimization.
  138.69 +            if (!call_site->is_constant_call_site()) {
  138.70 +              C->dependencies()->assert_call_site_target_value(call_site, target);
  138.71 +            }
  138.72 +            return t;
  138.73 +          }
  138.74 +        }
  138.75 +      }
  138.76 +    }
  138.77    } else if (tp->base() == Type::KlassPtr) {
  138.78      assert( off != Type::OffsetBot ||
  138.79              // arrays can be cast to Objects
   139.1 --- a/src/share/vm/opto/parse.hpp	Thu Sep 08 16:59:27 2011 -0700
   139.2 +++ b/src/share/vm/opto/parse.hpp	Fri Sep 09 16:17:16 2011 -0700
   139.3 @@ -78,6 +78,8 @@
   139.4    int         stack_depth()       const { return _caller_jvms ? _caller_jvms->depth() : 0; }
   139.5  
   139.6  public:
   139.7 +  static const char* check_can_parse(ciMethod* callee);
   139.8 +
   139.9    static InlineTree* build_inline_tree_root();
  139.10    static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found = false);
  139.11  
   140.1 --- a/src/share/vm/opto/parse2.cpp	Thu Sep 08 16:59:27 2011 -0700
   140.2 +++ b/src/share/vm/opto/parse2.cpp	Fri Sep 09 16:17:16 2011 -0700
   140.3 @@ -752,20 +752,12 @@
   140.4  // Handle ret bytecode
   140.5  void Parse::do_ret() {
   140.6    // Find to whom we return.
   140.7 -#if 0 // %%%% MAKE THIS WORK
   140.8 -  Node* con = local();
   140.9 -  const TypePtr* tp = con->bottom_type()->isa_ptr();
  140.10 -  assert(tp && tp->singleton(), "");
  140.11 -  int return_bci = (int) tp->get_con();
  140.12 -  merge(return_bci);
  140.13 -#else
  140.14    assert(block()->num_successors() == 1, "a ret can only go one place now");
  140.15    Block* target = block()->successor_at(0);
  140.16    assert(!target->is_ready(), "our arrival must be expected");
  140.17    profile_ret(target->flow()->start());
  140.18    int pnum = target->next_path_num();
  140.19    merge_common(target, pnum);
  140.20 -#endif
  140.21  }
  140.22  
  140.23  //--------------------------dynamic_branch_prediction--------------------------
   141.1 --- a/src/share/vm/opto/parse3.cpp	Thu Sep 08 16:59:27 2011 -0700
   141.2 +++ b/src/share/vm/opto/parse3.cpp	Fri Sep 09 16:17:16 2011 -0700
   141.3 @@ -100,11 +100,11 @@
   141.4      }
   141.5    }
   141.6  
   141.7 -  // Deoptimize on putfield writes to CallSite.target
   141.8 +  // Deoptimize on putfield writes to call site target field.
   141.9    if (!is_get && field->is_call_site_target()) {
  141.10      uncommon_trap(Deoptimization::Reason_unhandled,
  141.11                    Deoptimization::Action_reinterpret,
  141.12 -                  NULL, "put to CallSite.target field");
  141.13 +                  NULL, "put to call site target field");
  141.14      return;
  141.15    }
  141.16  
  141.17 @@ -147,19 +147,21 @@
  141.18  void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) {
  141.19    // Does this field have a constant value?  If so, just push the value.
  141.20    if (field->is_constant()) {
  141.21 +    // final field
  141.22      if (field->is_static()) {
  141.23        // final static field
  141.24        if (push_constant(field->constant_value()))
  141.25          return;
  141.26      }
  141.27      else {
  141.28 -      // final non-static field of a trusted class (classes in
  141.29 -      // java.lang.invoke and sun.invoke packages and subpackages).
  141.30 +      // final non-static field
  141.31 +      // Treat final non-static fields of trusted classes (classes in
  141.32 +      // java.lang.invoke and sun.invoke packages and subpackages) as
  141.33 +      // compile time constants.
  141.34        if (obj->is_Con()) {
  141.35          const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr();
  141.36          ciObject* constant_oop = oop_ptr->const_oop();
  141.37          ciConstant constant = field->constant_value_of(constant_oop);
  141.38 -
  141.39          if (push_constant(constant, true))
  141.40            return;
  141.41        }
   142.1 --- a/src/share/vm/opto/runtime.cpp	Thu Sep 08 16:59:27 2011 -0700
   142.2 +++ b/src/share/vm/opto/runtime.cpp	Fri Sep 09 16:17:16 2011 -0700
   142.3 @@ -978,7 +978,6 @@
   142.4  
   142.5      thread->set_exception_pc(pc);
   142.6      thread->set_exception_handler_pc(handler_address);
   142.7 -    thread->set_exception_stack_size(0);
   142.8  
   142.9      // Check if the exception PC is a MethodHandle call site.
  142.10      thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
   143.1 --- a/src/share/vm/opto/split_if.cpp	Thu Sep 08 16:59:27 2011 -0700
   143.2 +++ b/src/share/vm/opto/split_if.cpp	Fri Sep 09 16:17:16 2011 -0700
   143.3 @@ -500,19 +500,14 @@
   143.4    region_cache.lru_insert( new_false, new_false );
   143.5    region_cache.lru_insert( new_true , new_true  );
   143.6    // Now handle all uses of the splitting block
   143.7 -  for (DUIterator_Last kmin, k = region->last_outs(kmin); k >= kmin; --k) {
   143.8 -    Node* phi = region->last_out(k);
   143.9 -    if( !phi->in(0) ) {         // Dead phi?  Remove it
  143.10 +  for (DUIterator k = region->outs(); region->has_out(k); k++) {
  143.11 +    Node* phi = region->out(k);
  143.12 +    if (!phi->in(0)) {         // Dead phi?  Remove it
  143.13        _igvn.remove_dead_node(phi);
  143.14 -      continue;
  143.15 -    }
  143.16 -    assert( phi->in(0) == region, "" );
  143.17 -    if( phi == region ) {       // Found the self-reference
  143.18 -      phi->set_req(0, NULL);
  143.19 -      continue;                 // Break the self-cycle
  143.20 -    }
  143.21 -    // Expected common case: Phi hanging off of Region
  143.22 -    if( phi->is_Phi() ) {
  143.23 +    } else if (phi == region) { // Found the self-reference
  143.24 +      continue;                 // No roll-back of DUIterator
  143.25 +    } else if (phi->is_Phi()) { // Expected common case: Phi hanging off of Region
  143.26 +      assert(phi->in(0) == region, "Inconsistent graph");
  143.27        // Need a per-def cache.  Phi represents a def, so make a cache
  143.28        small_cache phi_cache;
  143.29  
  143.30 @@ -524,22 +519,24 @@
  143.31          // collection of PHI's merging values from different paths.  The Phis
  143.32          // inserted depend only on the location of the USE.  We use a
  143.33          // 2-element cache to handle multiple uses from the same block.
  143.34 -        handle_use( use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true );
  143.35 +        handle_use(use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true);
  143.36        } // End of while phi has uses
  143.37 -
  143.38 -      // Because handle_use might relocate region->_out,
  143.39 -      // we must refresh the iterator.
  143.40 -      k = region->last_outs(kmin);
  143.41 -
  143.42        // Remove the dead Phi
  143.43        _igvn.remove_dead_node( phi );
  143.44 +    } else {
  143.45 +      assert(phi->in(0) == region, "Inconsistent graph");
  143.46 +      // Random memory op guarded by Region.  Compute new DEF for USE.
  143.47 +      handle_use(phi, region, &region_cache, region_dom, new_false, new_true, old_false, old_true);
  143.48 +    }
  143.49 +    // Every path above deletes a use of the region, except for the region
  143.50 +    // self-cycle (which is needed by handle_use calling find_use_block
  143.51 +    // calling get_ctrl calling get_ctrl_no_update looking for dead
  143.52 +    // regions).  So roll back the DUIterator innards.
  143.53 +    --k;
  143.54 +  } // End of while merge point has phis
  143.55  
  143.56 -    } else {
  143.57 -      // Random memory op guarded by Region.  Compute new DEF for USE.
  143.58 -      handle_use( phi, region, &region_cache, region_dom, new_false, new_true, old_false, old_true );
  143.59 -    }
  143.60 -
  143.61 -  } // End of while merge point has phis
  143.62 +  assert(region->outcnt() == 1, "Only self reference should remain"); // Just Self on the Region
  143.63 +  region->set_req(0, NULL);       // Break the self-cycle
  143.64  
  143.65    // Any leftover bits in the splitting block must not have depended on local
  143.66    // Phi inputs (these have already been split-up).  Hence it's safe to hoist
   144.1 --- a/src/share/vm/precompiled.hpp	Thu Sep 08 16:59:27 2011 -0700
   144.2 +++ b/src/share/vm/precompiled.hpp	Fri Sep 09 16:17:16 2011 -0700
   144.3 @@ -206,7 +206,6 @@
   144.4  # include "runtime/perfMemory.hpp"
   144.5  # include "runtime/prefetch.hpp"
   144.6  # include "runtime/reflection.hpp"
   144.7 -# include "runtime/reflectionCompat.hpp"
   144.8  # include "runtime/reflectionUtils.hpp"
   144.9  # include "runtime/registerMap.hpp"
  144.10  # include "runtime/safepoint.hpp"
   145.1 --- a/src/share/vm/prims/forte.cpp	Thu Sep 08 16:59:27 2011 -0700
   145.2 +++ b/src/share/vm/prims/forte.cpp	Fri Sep 09 16:17:16 2011 -0700
   145.3 @@ -522,25 +522,6 @@
   145.4  extern "C" {
   145.5  JNIEXPORT
   145.6  void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
   145.7 -
   145.8 -// This is if'd out because we no longer use thread suspension.
   145.9 -// However if someone wanted to backport this to a 5.0 jvm then this
  145.10 -// code would be important.
  145.11 -#if 0
  145.12 -  if (SafepointSynchronize::is_synchronizing()) {
  145.13 -    // The safepoint mechanism is trying to synchronize all the threads.
  145.14 -    // Since this can involve thread suspension, it is not safe for us
  145.15 -    // to be here. We can reduce the deadlock risk window by quickly
  145.16 -    // returning to the SIGPROF handler. However, it is still possible
  145.17 -    // for VMThread to catch us here or in the SIGPROF handler. If we
  145.18 -    // are suspended while holding a resource and another thread blocks
  145.19 -    // on that resource in the SIGPROF handler, then we will have a
  145.20 -    // three-thread deadlock (VMThread, this thread, the other thread).
  145.21 -    trace->num_frames = ticks_safepoint; // -10
  145.22 -    return;
  145.23 -  }
  145.24 -#endif
  145.25 -
  145.26    JavaThread* thread;
  145.27  
  145.28    if (trace->env_id == NULL ||
   146.1 --- a/src/share/vm/prims/jvm.cpp	Thu Sep 08 16:59:27 2011 -0700
   146.2 +++ b/src/share/vm/prims/jvm.cpp	Fri Sep 09 16:17:16 2011 -0700
   146.3 @@ -4020,249 +4020,6 @@
   146.4  #endif
   146.5  
   146.6  
   146.7 -//---------------------------------------------------------------------------
   146.8 -//
   146.9 -// Support for old native code-based reflection (pre-JDK 1.4)
  146.10 -// Disabled by default in the product build.
  146.11 -//
  146.12 -// See reflection.hpp for information on SUPPORT_OLD_REFLECTION
  146.13 -//
  146.14 -//---------------------------------------------------------------------------
  146.15 -
  146.16 -#ifdef SUPPORT_OLD_REFLECTION
  146.17 -
  146.18 -JVM_ENTRY(jobjectArray, JVM_GetClassFields(JNIEnv *env, jclass cls, jint which))
  146.19 -  JVMWrapper("JVM_GetClassFields");
  146.20 -  JvmtiVMObjectAllocEventCollector oam;
  146.21 -  oop mirror = JNIHandles::resolve_non_null(cls);
  146.22 -  objArrayOop result = Reflection::reflect_fields(mirror, which, CHECK_NULL);
  146.23 -  return (jobjectArray) JNIHandles::make_local(env, result);
  146.24 -JVM_END
  146.25 -
  146.26 -
  146.27 -JVM_ENTRY(jobjectArray, JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which))
  146.28 -  JVMWrapper("JVM_GetClassMethods");
  146.29 -  JvmtiVMObjectAllocEventCollector oam;
  146.30 -  oop mirror = JNIHandles::resolve_non_null(cls);
  146.31 -  objArrayOop result = Reflection::reflect_methods(mirror, which, CHECK_NULL);
  146.32 -  //%note jvm_r4
  146.33 -  return (jobjectArray) JNIHandles::make_local(env, result);
  146.34 -JVM_END
  146.35 -
  146.36 -
  146.37 -JVM_ENTRY(jobjectArray, JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which))
  146.38 -  JVMWrapper("JVM_GetClassConstructors");
  146.39 -  JvmtiVMObjectAllocEventCollector oam;
  146.40 -  oop mirror = JNIHandles::resolve_non_null(cls);
  146.41 -  objArrayOop result = Reflection::reflect_constructors(mirror, which, CHECK_NULL);
  146.42 -  //%note jvm_r4
  146.43 -  return (jobjectArray) JNIHandles::make_local(env, result);
  146.44 -JVM_END
  146.45 -
  146.46 -
  146.47 -JVM_ENTRY(jobject, JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which))
  146.48 -  JVMWrapper("JVM_GetClassField");
  146.49 -  JvmtiVMObjectAllocEventCollector oam;
  146.50 -  if (name == NULL) return NULL;
  146.51 -  Handle str (THREAD, JNIHandles::resolve_non_null(name));
  146.52 -
  146.53 -  const char* cstr = java_lang_String::as_utf8_string(str());
  146.54 -  TempNewSymbol field_name = SymbolTable::probe(cstr, (int)strlen(cstr));
  146.55 -  if (field_name == NULL) {
  146.56 -    THROW_0(vmSymbols::java_lang_NoSuchFieldException());
  146.57 -  }
  146.58 -
  146.59 -  oop mirror = JNIHandles::resolve_non_null(cls);
  146.60 -  oop result = Reflection::reflect_field(mirror, field_name, which, CHECK_NULL);
  146.61 -  if (result == NULL) {
  146.62 -    THROW_0(vmSymbols::java_lang_NoSuchFieldException());
  146.63 -  }
  146.64 -  return JNIHandles::make_local(env, result);
  146.65 -JVM_END
  146.66 -
  146.67 -
  146.68 -JVM_ENTRY(jobject, JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types, jint which))
  146.69 -  JVMWrapper("JVM_GetClassMethod");
  146.70 -  JvmtiVMObjectAllocEventCollector oam;
  146.71 -  if (name == NULL) {
  146.72 -    THROW_0(vmSymbols::java_lang_NullPointerException());
  146.73 -  }
  146.74 -  Handle str (THREAD, JNIHandles::resolve_non_null(name));
  146.75 -
  146.76 -  const char* cstr = java_lang_String::as_utf8_string(str());
  146.77 -  TempNewSymbol method_name = SymbolTable::probe(cstr, (int)strlen(cstr));
  146.78 -  if (method_name == NULL) {
  146.79 -    THROW_0(vmSymbols::java_lang_NoSuchMethodException());
  146.80 -  }
  146.81 -
  146.82 -  oop mirror = JNIHandles::resolve_non_null(cls);
  146.83 -  objArrayHandle tarray (THREAD, objArrayOop(JNIHandles::resolve(types)));
  146.84 -  oop result = Reflection::reflect_method(mirror, method_name, tarray,
  146.85 -                                          which, CHECK_NULL);
  146.86 -  if (result == NULL) {
  146.87 -    THROW_0(vmSymbols::java_lang_NoSuchMethodException());
  146.88 -  }
  146.89 -  return JNIHandles::make_local(env, result);
  146.90 -JVM_END
  146.91 -
  146.92 -
  146.93 -JVM_ENTRY(jobject, JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jint which))
  146.94 -  JVMWrapper("JVM_GetClassConstructor");
  146.95 -  JvmtiVMObjectAllocEventCollector oam;
  146.96 -  oop mirror = JNIHandles::resolve_non_null(cls);
  146.97 -  objArrayHandle tarray (THREAD, objArrayOop(JNIHandles::resolve(types)));
  146.98 -  oop result = Reflection::reflect_constructor(mirror, tarray, which, CHECK_NULL);
  146.99 -  if (result == NULL) {
 146.100 -    THROW_0(vmSymbols::java_lang_NoSuchMethodException());
 146.101 -  }
 146.102 -  return (jobject) JNIHandles::make_local(env, result);
 146.103 -JVM_END
 146.104 -
 146.105 -
 146.106 -// Instantiation ///////////////////////////////////////////////////////////////////////////////
 146.107 -
 146.108 -JVM_ENTRY(jobject, JVM_NewInstance(JNIEnv *env, jclass cls))
 146.109 -  JVMWrapper("JVM_NewInstance");
 146.110 -  Handle mirror(THREAD, JNIHandles::resolve_non_null(cls));
 146.111 -
 146.112 -  methodOop resolved_constructor = java_lang_Class::resolved_constructor(mirror());
 146.113 -  if (resolved_constructor == NULL) {
 146.114 -    klassOop k = java_lang_Class::as_klassOop(mirror());
 146.115 -    // The java.lang.Class object caches a resolved constructor if all the checks
 146.116 -    // below were done successfully and a constructor was found.
 146.117 -
 146.118 -    // Do class based checks
 146.119 -    if (java_lang_Class::is_primitive(mirror())) {
 146.120 -      const char* msg = "";
 146.121 -      if      (mirror == Universe::bool_mirror())   msg = "java/lang/Boolean";
 146.122 -      else if (mirror == Universe::char_mirror())   msg = "java/lang/Character";
 146.123 -      else if (mirror == Universe::float_mirror())  msg = "java/lang/Float";
 146.124 -      else if (mirror == Universe::double_mirror()) msg = "java/lang/Double";
 146.125 -      else if (mirror == Universe::byte_mirror())   msg = "java/lang/Byte";
 146.126 -      else if (mirror == Universe::short_mirror())  msg = "java/lang/Short";
 146.127 -      else if (mirror == Universe::int_mirror())    msg = "java/lang/Integer";
 146.128 -      else if (mirror == Universe::long_mirror())   msg = "java/lang/Long";
 146.129 -      THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), msg);
 146.130 -    }
 146.131 -
 146.132 -    // Check whether we are allowed to instantiate this class
 146.133 -    Klass::cast(k)->check_valid_for_instantiation(false, CHECK_NULL); // Array classes get caught here
 146.134 -    instanceKlassHandle klass(THREAD, k);
 146.135 -    // Make sure class is initialized (also so all methods are rewritten)
 146.136 -    klass->initialize(CHECK_NULL);
 146.137 -
 146.138 -    // Lookup default constructor
 146.139 -    resolved_constructor = klass->find_method(vmSymbols::object_initializer_name(), vmSymbols::void_method_signature());
 146.140 -    if (resolved_constructor == NULL) {
 146.141 -      ResourceMark rm(THREAD);
 146.142 -      THROW_MSG_0(vmSymbols::java_lang_InstantiationException(), klass->external_name());
 146.143 -    }
 146.144 -
 146.145 -    // Cache result in java.lang.Class object. Does not have to be MT safe.
 146.146 -    java_lang_Class::set_resolved_constructor(mirror(), resolved_constructor);
 146.147 -  }
 146.148 -
 146.149 -  assert(resolved_constructor != NULL, "sanity check");
 146.150 -  methodHandle constructor = methodHandle(THREAD, resolved_constructor);
 146.151 -
 146.152 -  // We have an initialized instanceKlass with a default constructor
 146.153 -  instanceKlassHandle klass(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)));
 146.154 -  assert(klass->is_initialized() || klass->is_being_initialized(), "sanity check");
 146.155 -
 146.156 -  // Do security check
 146.157 -  klassOop caller_klass = NULL;
 146.158 -  if (UsePrivilegedStack) {
 146.159 -    caller_klass = thread->security_get_caller_class(2);
 146.160 -
 146.161 -    if (!Reflection::verify_class_access(caller_klass, klass(), false) ||
 146.162 -        !Reflection::verify_field_access(caller_klass,
 146.163 -                                         klass(),
 146.164 -                                         klass(),
 146.165 -                                         constructor->access_flags(),
 146.166 -                                         false,
 146.167 -                                         true)) {
 146.168 -      ResourceMark rm(THREAD);
 146.169 -      THROW_MSG_0(vmSymbols::java_lang_IllegalAccessException(), klass->external_name());
 146.170 -    }
 146.171 -  }
 146.172 -
 146.173 -  // Allocate object and call constructor
 146.174 -  Handle receiver = klass->allocate_instance_handle(CHECK_NULL);
 146.175 -  JavaCalls::call_default_constructor(thread, constructor, receiver, CHECK_NULL);
 146.176 -
 146.177 -  jobject res = JNIHandles::make_local(env, receiver());
 146.178 -  if (JvmtiExport::should_post_vm_object_alloc()) {
 146.179 -    JvmtiExport::post_vm_object_alloc(JavaThread::current(), receiver());
 146.180 -  }
 146.181 -  return res;
 146.182 -JVM_END
 146.183 -
 146.184 -
 146.185 -// Field ////////////////////////////////////////////////////////////////////////////////////////////
 146.186 -
 146.187 -JVM_ENTRY(jobject, JVM_GetField(JNIEnv *env, jobject field, jobject obj))
 146.188 -  JVMWrapper("JVM_GetField");
 146.189 -  JvmtiVMObjectAllocEventCollector oam;
 146.190 -  Handle field_mirror(thread, JNIHandles::resolve(field));
 146.191 -  Handle receiver    (thread, JNIHandles::resolve(obj));
 146.192 -  fieldDescriptor fd;
 146.193 -  Reflection::resolve_field(field_mirror, receiver, &fd, false, CHECK_NULL);
 146.194 -  jvalue value;
 146.195 -  BasicType type = Reflection::field_get(&value, &fd, receiver);
 146.196 -  oop box = Reflection::box(&value, type, CHECK_NULL);
 146.197 -  return JNIHandles::make_local(env, box);
 146.198 -JVM_END
 146.199 -
 146.200 -
 146.201 -JVM_ENTRY(jvalue, JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj, unsigned char wCode))
 146.202 -  JVMWrapper("JVM_GetPrimitiveField");
 146.203 -  Handle field_mirror(thread, JNIHandles::resolve(field));
 146.204 -  Handle receiver    (thread, JNIHandles::resolve(obj));
 146.205 -  fieldDescriptor fd;
 146.206 -  jvalue value;
 146.207 -  value.j = 0;
 146.208 -  Reflection::resolve_field(field_mirror, receiver, &fd, false, CHECK_(value));
 146.209 -  BasicType type = Reflection::field_get(&value, &fd, receiver);
 146.210 -  BasicType wide_type = (BasicType) wCode;
 146.211 -  if (type != wide_type) {
 146.212 -    Reflection::widen(&value, type, wide_type, CHECK_(value));
 146.213 -  }
 146.214 -  return value;
 146.215 -JVM_END // should really be JVM_END, but that doesn't work for union types!
 146.216 -
 146.217 -
 146.218 -JVM_ENTRY(void, JVM_SetField(JNIEnv *env, jobject field, jobject obj, jobject val))
 146.219 -  JVMWrapper("JVM_SetField");
 146.220 -  Handle field_mirror(thread, JNIHandles::resolve(field));
 146.221 -  Handle receiver    (thread, JNIHandles::resolve(obj));
 146.222 -  oop box = JNIHandles::resolve(val);
 146.223 -  fieldDescriptor fd;
 146.224 -  Reflection::resolve_field(field_mirror, receiver, &fd, true, CHECK);
 146.225 -  BasicType field_type = fd.field_type();
 146.226 -  jvalue value;
 146.227 -  BasicType value_type;
 146.228 -  if (field_type == T_OBJECT || field_type == T_ARRAY) {
 146.229 -    // Make sure we do no unbox e.g. java/lang/Integer instances when storing into an object array
 146.230 -    value_type = Reflection::unbox_for_regular_object(box, &value);
 146.231 -    Reflection::field_set(&value, &fd, receiver, field_type, CHECK);
 146.232 -  } else {
 146.233 -    value_type = Reflection::unbox_for_primitive(box, &value, CHECK);
 146.234 -    Reflection::field_set(&value, &fd, receiver, value_type, CHECK);
 146.235 -  }
 146.236 -JVM_END
 146.237 -
 146.238 -
 146.239 -JVM_ENTRY(void, JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v, unsigned char vCode))
 146.240 -  JVMWrapper("JVM_SetPrimitiveField");
 146.241 -  Handle field_mirror(thread, JNIHandles::resolve(field));
 146.242 -  Handle receiver    (thread, JNIHandles::resolve(obj));
 146.243 -  fieldDescriptor fd;
 146.244 -  Reflection::resolve_field(field_mirror, receiver, &fd, true, CHECK);
 146.245 -  BasicType value_type = (BasicType) vCode;
 146.246 -  Reflection::field_set(&v, &fd, receiver, value_type, CHECK);
 146.247 -JVM_END
 146.248 -
 146.249 -
 146.250  // Method ///////////////////////////////////////////////////////////////////////////////////////////
 146.251  
 146.252  JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0))
 146.253 @@ -4302,8 +4059,6 @@
 146.254    return res;
 146.255  JVM_END
 146.256  
 146.257 -#endif /* SUPPORT_OLD_REFLECTION */
 146.258 -
 146.259  // Atomic ///////////////////////////////////////////////////////////////////////////////////////////
 146.260  
 146.261  JVM_LEAF(jboolean, JVM_SupportsCX8())
   147.1 --- a/src/share/vm/prims/jvm.h	Thu Sep 08 16:59:27 2011 -0700
   147.2 +++ b/src/share/vm/prims/jvm.h	Fri Sep 09 16:17:16 2011 -0700
   147.3 @@ -26,7 +26,6 @@
   147.4  #define SHARE_VM_PRIMS_JVM_H
   147.5  
   147.6  #include "prims/jni.h"
   147.7 -#include "runtime/reflectionCompat.hpp"
   147.8  #ifdef TARGET_OS_FAMILY_linux
   147.9  # include "jvm_linux.h"
  147.10  #endif
  147.11 @@ -43,8 +42,7 @@
  147.12  // HotSpot integration note:
  147.13  //
  147.14  // This file and jvm.h used with the JDK are identical,
  147.15 -// except for the three includes removed below and the
  147.16 -// SUPPORT_OLD_REFLECTION sections cut out of the JDK's jvm.h.
  147.17 +// except for the three includes removed below
  147.18  
  147.19  // #include <sys/stat.h>
  147.20  // #include "jni.h"
  147.21 @@ -443,14 +441,6 @@
  147.22                                jsize len, jobject pd, const char *source,
  147.23                                jboolean verify);
  147.24  
  147.25 -/* Define a class with a source (MLVM) */
  147.26 -JNIEXPORT jclass JNICALL
  147.27 -JVM_DefineClassWithCP(JNIEnv *env, const char *name, jobject loader,
  147.28 -                      const jbyte *buf, jsize len, jobject pd,
  147.29 -                      const char *source,
  147.30 -                      // same args as JVM_DefineClassWithSource to this point
  147.31 -                      jobjectArray constants);
  147.32 -
  147.33  /*
  147.34   * Reflection support functions
  147.35   */
  147.36 @@ -1442,65 +1432,6 @@
  147.37  JNIEXPORT void JNICALL
  147.38  JVM_RawMonitorExit(void *mon);
  147.39  
  147.40 -
  147.41 -#ifdef SUPPORT_OLD_REFLECTION
  147.42 -
  147.43 -/*
  147.44 - * Support for old native code-based (pre-JDK 1.4) reflection implementation.
  147.45 - * Disabled by default in the product build.
  147.46 - *
  147.47 - * See reflection.hpp for information on SUPPORT_OLD_REFLECTION
  147.48 - */
  147.49 -
  147.50 -/*
  147.51 - * reflecting fields and methods.
  147.52 - * which: 0 --- MEMBER_PUBLIC
  147.53 - *        1 --- MEMBER_DECLARED
  147.54 - * NOTE: absent in product build by default
  147.55 - */
  147.56 -
  147.57 -JNIEXPORT jobjectArray JNICALL
  147.58 -JVM_GetClassFields(JNIEnv *env, jclass cls, jint which);
  147.59 -
  147.60 -JNIEXPORT jobjectArray JNICALL
  147.61 -JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which);
  147.62 -
  147.63 -JNIEXPORT jobjectArray JNICALL
  147.64 -JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which);
  147.65 -
  147.66 -JNIEXPORT jobject JNICALL
  147.67 -JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which);
  147.68 -
  147.69 -JNIEXPORT jobject JNICALL
  147.70 -JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types,
  147.71 -                   jint which);
  147.72 -JNIEXPORT jobject JNICALL
  147.73 -JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types,
  147.74 -                        jint which);
  147.75 -
  147.76 -/*
  147.77 - * Implements Class.newInstance
  147.78 - */
  147.79 -JNIEXPORT jobject JNICALL
  147.80 -JVM_NewInstance(JNIEnv *env, jclass cls);
  147.81 -
  147.82 -/*
  147.83 - * java.lang.reflect.Field
  147.84 - */
  147.85 -JNIEXPORT jobject JNICALL
  147.86 -JVM_GetField(JNIEnv *env, jobject field, jobject obj);
  147.87 -
  147.88 -JNIEXPORT jvalue JNICALL
  147.89 -JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj,
  147.90 -                      unsigned char wCode);
  147.91 -
  147.92 -JNIEXPORT void JNICALL
  147.93 -JVM_SetField(JNIEnv *env, jobject field, jobject obj, jobject val);
  147.94 -
  147.95 -JNIEXPORT void JNICALL
  147.96 -JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v,
  147.97 -                      unsigned char vCode);
  147.98 -
  147.99  /*
 147.100   * java.lang.reflect.Method
 147.101   */
 147.102 @@ -1513,8 +1444,6 @@
 147.103  JNIEXPORT jobject JNICALL
 147.104  JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0);
 147.105  
 147.106 -#endif /* SUPPORT_OLD_REFLECTION */
 147.107 -
 147.108  /*
 147.109   * java.lang.management support
 147.110   */
 147.111 @@ -1650,7 +1579,8 @@
 147.112       */
 147.113      unsigned int thread_park_blocker : 1;
 147.114      unsigned int post_vm_init_hook_enabled : 1;
 147.115 -    unsigned int : 30;
 147.116 +    unsigned int pending_list_uses_discovered_field : 1;
 147.117 +    unsigned int : 29;
 147.118      unsigned int : 32;
 147.119      unsigned int : 32;
 147.120  } jdk_version_info;
   148.1 --- a/src/share/vm/prims/methodHandleWalk.cpp	Thu Sep 08 16:59:27 2011 -0700
   148.2 +++ b/src/share/vm/prims/methodHandleWalk.cpp	Fri Sep 09 16:17:16 2011 -0700
   148.3 @@ -182,10 +182,6 @@
   148.4    HandleMark hm;
   148.5    ResourceMark rm;
   148.6    Handle mh(m);
   148.7 -  print(mh);
   148.8 -}
   148.9 -
  148.10 -void MethodHandleChain::print(Handle mh) {
  148.11    EXCEPTION_MARK;
  148.12    MethodHandleChain mhc(mh, THREAD);
  148.13    if (HAS_PENDING_EXCEPTION) {
  148.14 @@ -222,16 +218,33 @@
  148.15        if (o != NULL) {
  148.16          if (o->is_instance()) {
  148.17            tty->print(" instance %s", o->klass()->klass_part()->internal_name());
  148.18 +          if (java_lang_invoke_CountingMethodHandle::is_instance(o)) {
  148.19 +            tty->print(" vmcount: %d", java_lang_invoke_CountingMethodHandle::vmcount(o));
  148.20 +          }
  148.21          } else {
  148.22            o->print();
  148.23          }
  148.24        }
  148.25 +      oop vmt = chain.vmtarget_oop();
  148.26 +      if (vmt != NULL) {
  148.27 +        if (vmt->is_method()) {
  148.28 +          tty->print(" ");
  148.29 +          methodOop(vmt)->print_short_name(tty);
  148.30 +        } else if (java_lang_invoke_MethodHandle::is_instance(vmt)) {
  148.31 +          tty->print(" method handle " INTPTR_FORMAT, vmt);
  148.32 +        } else {
  148.33 +          ShouldNotReachHere();
  148.34 +        }
  148.35 +      }
  148.36      } else if (chain.is_adapter()) {
  148.37        tty->print("adapter: arg_slot %d conversion op %s",
  148.38                   chain.adapter_arg_slot(),
  148.39                   adapter_op_to_string(chain.adapter_conversion_op()));
  148.40        switch (chain.adapter_conversion_op()) {
  148.41          case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY:
  148.42 +          if (java_lang_invoke_CountingMethodHandle::is_instance(chain.method_handle_oop())) {
  148.43 +            tty->print(" vmcount: %d", java_lang_invoke_CountingMethodHandle::vmcount(chain.method_handle_oop()));
  148.44 +          }
  148.45          case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW:
  148.46          case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST:
  148.47          case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM:
  148.48 @@ -907,7 +920,10 @@
  148.49      _non_bcp_klasses(THREAD, 5),
  148.50      _cur_stack(0),
  148.51      _max_stack(0),
  148.52 -    _rtype(T_ILLEGAL)
  148.53 +    _rtype(T_ILLEGAL),
  148.54 +    _selectAlternative_bci(-1),
  148.55 +    _taken_count(0),
  148.56 +    _not_taken_count(0)
  148.57  {
  148.58  
  148.59    // Element zero is always the null constant.
  148.60 @@ -1115,11 +1131,50 @@
  148.61      _bytecode.push(0);
  148.62      break;
  148.63  
  148.64 +  case Bytecodes::_ifeq:
  148.65 +    assert((unsigned short) index == index, "index does not fit in 16-bit");
  148.66 +    _bytecode.push(op);
  148.67 +    _bytecode.push(index >> 8);
  148.68 +    _bytecode.push(index);
  148.69 +    break;
  148.70 +
  148.71    default:
  148.72      ShouldNotReachHere();
  148.73    }
  148.74  }
  148.75  
  148.76 +void MethodHandleCompiler::update_branch_dest(int src, int dst) {
  148.77 +  switch (_bytecode.at(src)) {
  148.78 +    case Bytecodes::_ifeq:
  148.79 +      dst -= src; // compute the offset
  148.80 +      assert((unsigned short) dst == dst, "index does not fit in 16-bit");
  148.81 +      _bytecode.at_put(src + 1, dst >> 8);
  148.82 +      _bytecode.at_put(src + 2, dst);
  148.83 +      break;
  148.84 +    default:
  148.85 +      ShouldNotReachHere();
  148.86 +  }
  148.87 +}
  148.88 +
  148.89 +void MethodHandleCompiler::emit_load(ArgToken arg) {
  148.90 +  TokenType tt = arg.token_type();
  148.91 +  BasicType bt = arg.basic_type();
  148.92 +
  148.93 +  switch (tt) {
  148.94 +    case tt_parameter:
  148.95 +    case tt_temporary:
  148.96 +      emit_load(bt, arg.index());
  148.97 +      break;
  148.98 +    case tt_constant:
  148.99 +      emit_load_constant(arg);
 148.100 +      break;
 148.101 +    case tt_illegal:
 148.102 +    case tt_void:
 148.103 +    default:
 148.104 +      ShouldNotReachHere();
 148.105 +  }
 148.106 +}
 148.107 +
 148.108  
 148.109  void MethodHandleCompiler::emit_load(BasicType bt, int index) {
 148.110    if (index <= 3) {
 148.111 @@ -1318,6 +1373,29 @@
 148.112  jvalue MethodHandleCompiler::zero_jvalue = { 0 };
 148.113  jvalue MethodHandleCompiler::one_jvalue  = { 1 };
 148.114  
 148.115 +// Fetch any values from CountingMethodHandles and capture them for profiles
 148.116 +bool MethodHandleCompiler::fetch_counts(ArgToken arg1, ArgToken arg2) {
 148.117 +  int count1 = -1, count2 = -1;
 148.118 +  if (arg1.token_type() == tt_constant && arg1.basic_type() == T_OBJECT &&
 148.119 +      java_lang_invoke_CountingMethodHandle::is_instance(arg1.object()())) {
 148.120 +    count1 = java_lang_invoke_CountingMethodHandle::vmcount(arg1.object()());
 148.121 +  }
 148.122 +  if (arg2.token_type() == tt_constant && arg2.basic_type() == T_OBJECT &&
 148.123 +      java_lang_invoke_CountingMethodHandle::is_instance(arg2.object()())) {
 148.124 +    count2 = java_lang_invoke_CountingMethodHandle::vmcount(arg2.object()());
 148.125 +  }
 148.126 +  int total = count1 + count2;
 148.127 +  if (count1 != -1 && count2 != -1 && total != 0) {
 148.128 +    // Normalize the collect counts to the invoke_count
 148.129 +    tty->print("counts %d %d scaled by %d = ", count2, count1, _invoke_count);
 148.130 +    if (count1 != 0) _not_taken_count = (int)(_invoke_count * count1 / (double)total);
 148.131 +    if (count2 != 0) _taken_count = (int)(_invoke_count * count2 / (double)total);
 148.132 +    tty->print_cr("%d %d", _taken_count, _not_taken_count);
 148.133 +    return true;
 148.134 +  }
 148.135 +  return false;
 148.136 +}
 148.137 +
 148.138  // Emit bytecodes for the given invoke instruction.
 148.139  MethodHandleWalker::ArgToken
 148.140  MethodHandleCompiler::make_invoke(methodHandle m, vmIntrinsics::ID iid,
 148.141 @@ -1367,6 +1445,29 @@
 148.142      }
 148.143    }
 148.144  
 148.145 +  if (m->intrinsic_id() == vmIntrinsics::_selectAlternative &&
 148.146 +      fetch_counts(argv[1], argv[2])) {
 148.147 +    assert(argc == 3, "three arguments");
 148.148 +    assert(tailcall, "only");
 148.149 +
 148.150 +    // do inline bytecodes so we can drop profile data into it,
 148.151 +    //   0:   iload_0
 148.152 +    emit_load(argv[0]);
 148.153 +    //   1:   ifeq    8
 148.154 +    _selectAlternative_bci = _bytecode.length();
 148.155 +    emit_bc(Bytecodes::_ifeq, 0); // emit placeholder offset
 148.156 +    //   4:   aload_1
 148.157 +    emit_load(argv[1]);
 148.158 +    //   5:   areturn;
 148.159 +    emit_bc(Bytecodes::_areturn);
 148.160 +    //   8:   aload_2
 148.161 +    update_branch_dest(_selectAlternative_bci, cur_bci());
 148.162 +    emit_load(argv[2]);
 148.163 +    //   9:   areturn
 148.164 +    emit_bc(Bytecodes::_areturn);
 148.165 +    return ArgToken();  // Dummy return value.
 148.166 +  }
 148.167 +
 148.168    check_non_bcp_klass(klass, CHECK_(zero));
 148.169    if (m->is_method_handle_invoke()) {
 148.170      check_non_bcp_klasses(m->method_handle_type(), CHECK_(zero));
 148.171 @@ -1377,10 +1478,6 @@
 148.172    assert(argc == asc.size() + ((op == Bytecodes::_invokestatic || op == Bytecodes::_invokedynamic) ? 0 : 1),
 148.173           "argc mismatch");
 148.174  
 148.175 -  // Inline the method.
 148.176 -  InvocationCounter* ic = m->invocation_counter();
 148.177 -  ic->set_carry_flag();
 148.178 -
 148.179    for (int i = 0; i < argc; i++) {
 148.180      ArgToken arg = argv[i];
 148.181      TokenType tt = arg.token_type();
 148.182 @@ -1686,7 +1783,7 @@
 148.183  }
 148.184  
 148.185  
 148.186 -methodHandle MethodHandleCompiler::get_method_oop(TRAPS) const {
 148.187 +methodHandle MethodHandleCompiler::get_method_oop(TRAPS) {
 148.188    methodHandle empty;
 148.189    // Create a method that holds the generated bytecode.  invokedynamic
 148.190    // has no receiver, normal MH calls do.
 148.191 @@ -1765,6 +1862,7 @@
 148.192      assert(m->method_data() == NULL, "there should not be an MDO yet");
 148.193      m->set_method_data(mdo);
 148.194  
 148.195 +    bool found_selectAlternative = false;
 148.196      // Iterate over all profile data and set the count of the counter
 148.197      // data entries to the original call site counter.
 148.198      for (ProfileData* profile_data = mdo->first_data();
 148.199 @@ -1774,7 +1872,15 @@
 148.200          CounterData* counter_data = profile_data->as_CounterData();
 148.201          counter_data->set_count(_invoke_count);
 148.202        }
 148.203 +      if (profile_data->is_BranchData() &&
 148.204 +          profile_data->bci() == _selectAlternative_bci) {
 148.205 +        BranchData* bd = profile_data->as_BranchData();
 148.206 +        bd->set_taken(_taken_count);
 148.207 +        bd->set_not_taken(_not_taken_count);
 148.208 +        found_selectAlternative = true;
 148.209 +      }
 148.210      }
 148.211 +    assert(_selectAlternative_bci == -1 || found_selectAlternative, "must have found profile entry");
 148.212    }
 148.213  
 148.214  #ifndef PRODUCT
   149.1 --- a/src/share/vm/prims/methodHandleWalk.hpp	Thu Sep 08 16:59:27 2011 -0700
   149.2 +++ b/src/share/vm/prims/methodHandleWalk.hpp	Fri Sep 09 16:17:16 2011 -0700
   149.3 @@ -74,6 +74,7 @@
   149.4      set_method_handle(MethodHandle_vmtarget_oop(), THREAD);
   149.5    }
   149.6  
   149.7 +  Handle root()                 { return _root; }
   149.8    Handle method_handle()        { return _method_handle; }
   149.9    oop    method_handle_oop()    { return _method_handle(); }
  149.10    oop    method_type_oop()      { return MethodHandle_type_oop(); }
  149.11 @@ -110,7 +111,6 @@
  149.12    // the signature for each method.  The signatures are printed in
  149.13    // slot order to make it easier to understand.
  149.14    void print();
  149.15 -  static void print(Handle mh);
  149.16    static void print(oopDesc* mh);
  149.17  #endif
  149.18  };
  149.19 @@ -277,6 +277,10 @@
  149.20    KlassHandle  _target_klass;
  149.21    Thread*      _thread;
  149.22  
  149.23 +  int          _selectAlternative_bci; // These are used for capturing profiles from GWTs
  149.24 +  int          _taken_count;
  149.25 +  int          _not_taken_count;
  149.26 +
  149.27    // Values used by the compiler.
  149.28    static jvalue zero_jvalue;
  149.29    static jvalue one_jvalue;
  149.30 @@ -372,6 +376,7 @@
  149.31  
  149.32    unsigned char* bytecode()        const { return _bytecode.adr_at(0); }
  149.33    int            bytecode_length() const { return _bytecode.length(); }
  149.34 +  int            cur_bci()         const { return _bytecode.length(); }
  149.35  
  149.36    // Fake constant pool.
  149.37    int cpool_oop_put(int tag, Handle con) {
  149.38 @@ -436,6 +441,8 @@
  149.39    }
  149.40  
  149.41    void emit_bc(Bytecodes::Code op, int index = 0, int args_size = -1);
  149.42 +  void update_branch_dest(int src, int dst);
  149.43 +  void emit_load(ArgToken arg);
  149.44    void emit_load(BasicType bt, int index);
  149.45    void emit_store(BasicType bt, int index);
  149.46    void emit_load_constant(ArgToken arg);
  149.47 @@ -455,11 +462,14 @@
  149.48    virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS);
  149.49    virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS);
  149.50  
  149.51 +  // Check for profiling information on a GWT and return true if it's found
  149.52 +  bool fetch_counts(ArgToken a1, ArgToken a2);
  149.53 +
  149.54    // Get a real constant pool.
  149.55    constantPoolHandle get_constant_pool(TRAPS) const;
  149.56  
  149.57    // Get a real methodOop.
  149.58 -  methodHandle get_method_oop(TRAPS) const;
  149.59 +  methodHandle get_method_oop(TRAPS);
  149.60  
  149.61  public:
  149.62    MethodHandleCompiler(Handle root, Symbol* name, Symbol* signature, int invoke_count, bool for_invokedynamic, TRAPS);
   150.1 --- a/src/share/vm/prims/methodHandles.cpp	Thu Sep 08 16:59:27 2011 -0700
   150.2 +++ b/src/share/vm/prims/methodHandles.cpp	Fri Sep 09 16:17:16 2011 -0700
   150.3 @@ -158,6 +158,8 @@
   150.4    "adapter_fold/4/ref",
   150.5    "adapter_fold/5/ref",
   150.6  
   150.7 +  "adapter_opt_profiling",
   150.8 +
   150.9    NULL
  150.10  };
  150.11  
  150.12 @@ -2653,6 +2655,11 @@
  150.13    // Finalize the conversion field.  (Note that it is final to Java code.)
  150.14    java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion);
  150.15  
  150.16 +  if (java_lang_invoke_CountingMethodHandle::is_instance(mh())) {
  150.17 +    assert(ek_orig == _adapter_retype_only, "only one handled");
  150.18 +    ek_opt = _adapter_opt_profiling;
  150.19 +  }
  150.20 +
  150.21    // Done!
  150.22    java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt));
  150.23  
  150.24 @@ -2905,8 +2912,12 @@
  150.25      return MethodHandles::stack_move_unit();
  150.26    case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
  150.27      return MethodHandles::adapter_conversion_ops_supported_mask();
  150.28 -  case MethodHandles::GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS:
  150.29 -    return MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS;
  150.30 +  case MethodHandles::GC_COUNT_GWT:
  150.31 +#ifdef COMPILER2
  150.32 +    return true;
  150.33 +#else
  150.34 +    return false;
  150.35 +#endif
  150.36    }
  150.37    return 0;
  150.38  }
   151.1 --- a/src/share/vm/prims/methodHandles.hpp	Thu Sep 08 16:59:27 2011 -0700
   151.2 +++ b/src/share/vm/prims/methodHandles.hpp	Fri Sep 09 16:17:16 2011 -0700
   151.3 @@ -187,6 +187,8 @@
   151.4      _adapter_opt_fold_FIRST = _adapter_opt_fold_ref,
   151.5      _adapter_opt_fold_LAST  = _adapter_opt_fold_5_ref,
   151.6  
   151.7 +    _adapter_opt_profiling,
   151.8 +
   151.9      _EK_LIMIT,
  151.10      _EK_FIRST = 0
  151.11    };
  151.12 @@ -266,6 +268,8 @@
  151.13        return _adapter_fold_args;
  151.14      if (ek >= _adapter_opt_return_FIRST && ek <= _adapter_opt_return_LAST)
  151.15        return _adapter_opt_return_any;
  151.16 +    if (ek == _adapter_opt_profiling)
  151.17 +      return _adapter_retype_only;
  151.18      assert(false, "oob");
  151.19      return _EK_LIMIT;
  151.20    }
  151.21 @@ -582,6 +586,7 @@
  151.22      GC_JVM_STACK_MOVE_UNIT = 1,
  151.23      GC_CONV_OP_IMPLEMENTED_MASK = 2,
  151.24      GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS = 3,
  151.25 +    GC_COUNT_GWT = 4,
  151.26  
  151.27      // format of result from getTarget / encode_target:
  151.28      ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
   152.1 --- a/src/share/vm/prims/unsafe.cpp	Thu Sep 08 16:59:27 2011 -0700
   152.2 +++ b/src/share/vm/prims/unsafe.cpp	Fri Sep 09 16:17:16 2011 -0700
   152.3 @@ -33,7 +33,6 @@
   152.4  #include "runtime/globals.hpp"
   152.5  #include "runtime/interfaceSupport.hpp"
   152.6  #include "runtime/reflection.hpp"
   152.7 -#include "runtime/reflectionCompat.hpp"
   152.8  #include "runtime/synchronizer.hpp"
   152.9  #include "services/threadService.hpp"
  152.10  #include "utilities/copy.hpp"
  152.11 @@ -303,6 +302,19 @@
  152.12    UnsafeWrapper("Unsafe_SetObjectVolatile");
  152.13    oop x = JNIHandles::resolve(x_h);
  152.14    oop p = JNIHandles::resolve(obj);
  152.15 +  // Catch VolatileCallSite.target stores (via
  152.16 +  // CallSite.setTargetVolatile) and check call site dependencies.
  152.17 +  if ((offset == java_lang_invoke_CallSite::target_offset_in_bytes()) && p->is_a(SystemDictionary::CallSite_klass())) {
  152.18 +    oop call_site     = p;
  152.19 +    oop method_handle = x;
  152.20 +    assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "must be");
  152.21 +    assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
  152.22 +    {
  152.23 +      // Walk all nmethods depending on this call site.
  152.24 +      MutexLocker mu(Compile_lock, thread);
  152.25 +      Universe::flush_dependents_on(call_site, method_handle);
  152.26 +    }
  152.27 +  }
  152.28    void* addr = index_oop_from_field_offset_long(p, offset);
  152.29    OrderAccess::release();
  152.30    if (UseCompressedOops) {
   153.1 --- a/src/share/vm/runtime/arguments.cpp	Thu Sep 08 16:59:27 2011 -0700
   153.2 +++ b/src/share/vm/runtime/arguments.cpp	Fri Sep 09 16:17:16 2011 -0700
   153.3 @@ -1423,6 +1423,9 @@
   153.4      if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) {
   153.5        FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M);
   153.6      }
   153.7 +    // For those collectors or operating systems (eg, Windows) that do
   153.8 +    // not support full UseNUMA, we will map to UseNUMAInterleaving for now
   153.9 +    UseNUMAInterleaving = true;
  153.10    }
  153.11  }
  153.12  
   154.1 --- a/src/share/vm/runtime/globals.hpp	Thu Sep 08 16:59:27 2011 -0700
   154.2 +++ b/src/share/vm/runtime/globals.hpp	Fri Sep 09 16:17:16 2011 -0700
   154.3 @@ -475,6 +475,12 @@
   154.4    product(bool, UseNUMA, false,                                             \
   154.5            "Use NUMA if available")                                          \
   154.6                                                                              \
   154.7 +  product(bool, UseNUMAInterleaving, false,                                 \
   154.8 +          "Interleave memory across NUMA nodes if available")               \
   154.9 +                                                                            \
  154.10 +  product(uintx, NUMAInterleaveGranularity, 2*M,                            \
  154.11 +          "Granularity to use for NUMA interleaving on Windows OS")         \
  154.12 +                                                                            \
  154.13    product(bool, ForceNUMA, false,                                           \
  154.14            "Force NUMA optimizations on single-node/UMA systems")            \
  154.15                                                                              \
  154.16 @@ -1979,6 +1985,18 @@
  154.17    product(bool, TLABStats, true,                                            \
  154.18            "Print various TLAB related information")                         \
  154.19                                                                              \
  154.20 +  product(bool, UseBlockZeroing, false,                                     \
  154.21 +          "Use special cpu instructions for block zeroing")                 \
  154.22 +                                                                            \
  154.23 +  product(intx, BlockZeroingLowLimit, 2048,                                 \
  154.24 +          "Minimum size in bytes when block zeroing will be used")          \
  154.25 +                                                                            \
  154.26 +  product(bool, UseBlockCopy, false,                                        \
  154.27 +          "Use special cpu instructions for block copy")                    \
  154.28 +                                                                            \
  154.29 +  product(intx, BlockCopyLowLimit, 2048,                                    \
  154.30 +          "Minimum size in bytes when block copy will be used")             \
  154.31 +                                                                            \
  154.32    product(bool, PrintRevisitStats, false,                                   \
  154.33            "Print revisit (klass and MDO) stack related information")        \
  154.34                                                                              \
  154.35 @@ -2912,6 +2930,12 @@
  154.36    product(intx,  ReadPrefetchInstr, 0,                                      \
  154.37            "Prefetch instruction to prefetch ahead")                         \
  154.38                                                                              \
  154.39 +  product(uintx,  ArraycopySrcPrefetchDistance, 0,                          \
  154.40 +          "Distance to prefetch source array in arracopy")                  \
  154.41 +                                                                            \
  154.42 +  product(uintx,  ArraycopyDstPrefetchDistance, 0,                          \
  154.43 +          "Distance to prefetch destination array in arracopy")             \
  154.44 +                                                                            \
  154.45    /* deoptimization */                                                      \
  154.46    develop(bool, TraceDeoptimization, false,                                 \
  154.47            "Trace deoptimization")                                           \
   155.1 --- a/src/share/vm/runtime/java.cpp	Thu Sep 08 16:59:27 2011 -0700
   155.2 +++ b/src/share/vm/runtime/java.cpp	Fri Sep 09 16:17:16 2011 -0700
   155.3 @@ -672,7 +672,8 @@
   155.4      _current = JDK_Version(major, minor, micro, info.update_version,
   155.5                             info.special_update_version, build,
   155.6                             info.thread_park_blocker == 1,
   155.7 -                           info.post_vm_init_hook_enabled == 1);
   155.8 +                           info.post_vm_init_hook_enabled == 1,
   155.9 +                           info.pending_list_uses_discovered_field == 1);
  155.10    }
  155.11  }
  155.12  
   156.1 --- a/src/share/vm/runtime/java.hpp	Thu Sep 08 16:59:27 2011 -0700
   156.2 +++ b/src/share/vm/runtime/java.hpp	Fri Sep 09 16:17:16 2011 -0700
   156.3 @@ -92,6 +92,7 @@
   156.4    bool _partially_initialized;
   156.5  
   156.6    bool _thread_park_blocker;
   156.7 +  bool _pending_list_uses_discovered_field;
   156.8    bool _post_vm_init_hook_enabled;
   156.9  
  156.10    bool is_valid() const {
  156.11 @@ -114,15 +115,18 @@
  156.12  
  156.13    JDK_Version() : _major(0), _minor(0), _micro(0), _update(0),
  156.14                    _special(0), _build(0), _partially_initialized(false),
  156.15 -                  _thread_park_blocker(false), _post_vm_init_hook_enabled(false) {}
  156.16 +                  _thread_park_blocker(false), _post_vm_init_hook_enabled(false),
  156.17 +                  _pending_list_uses_discovered_field(false) {}
  156.18  
  156.19    JDK_Version(uint8_t major, uint8_t minor = 0, uint8_t micro = 0,
  156.20                uint8_t update = 0, uint8_t special = 0, uint8_t build = 0,
  156.21 -              bool thread_park_blocker = false, bool post_vm_init_hook_enabled = false) :
  156.22 +              bool thread_park_blocker = false, bool post_vm_init_hook_enabled = false,
  156.23 +              bool pending_list_uses_discovered_field = false) :
  156.24        _major(major), _minor(minor), _micro(micro), _update(update),
  156.25        _special(special), _build(build), _partially_initialized(false),
  156.26        _thread_park_blocker(thread_park_blocker),
  156.27 -      _post_vm_init_hook_enabled(post_vm_init_hook_enabled) {}
  156.28 +      _post_vm_init_hook_enabled(post_vm_init_hook_enabled),
  156.29 +      _pending_list_uses_discovered_field(pending_list_uses_discovered_field) {}
  156.30  
  156.31    // Returns the current running JDK version
  156.32    static JDK_Version current() { return _current; }
  156.33 @@ -149,6 +153,10 @@
  156.34    bool post_vm_init_hook_enabled() const {
  156.35      return _post_vm_init_hook_enabled;
  156.36    }
  156.37 +  // For compatibility wrt pre-4965777 JDK's
  156.38 +  bool pending_list_uses_discovered_field() const {
  156.39 +    return _pending_list_uses_discovered_field;
  156.40 +  }
  156.41  
  156.42    // Performs a full ordering comparison using all fields (update, build, etc.)
  156.43    int compare(const JDK_Version& other) const;
   157.1 --- a/src/share/vm/runtime/reflection.cpp	Thu Sep 08 16:59:27 2011 -0700
   157.2 +++ b/src/share/vm/runtime/reflection.cpp	Fri Sep 09 16:17:16 2011 -0700
   157.3 @@ -844,16 +844,6 @@
   157.4  }
   157.5  
   157.6  
   157.7 -//---------------------------------------------------------------------------
   157.8 -//
   157.9 -// Supporting routines for old native code-based reflection (pre-JDK 1.4).
  157.10 -//
  157.11 -// See reflection.hpp for details.
  157.12 -//
  157.13 -//---------------------------------------------------------------------------
  157.14 -
  157.15 -#ifdef SUPPORT_OLD_REFLECTION
  157.16 -
  157.17  methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
  157.18                                                  KlassHandle recv_klass, Handle receiver, TRAPS) {
  157.19    assert(!method.is_null() , "method should not be null");
  157.20 @@ -1081,519 +1071,6 @@
  157.21    return java_lang_Class::primitive_type(basic_type_mirror);
  157.22  }
  157.23  
  157.24 -
  157.25 -bool Reflection::match_parameter_types(methodHandle method, objArrayHandle types, int parameter_count, TRAPS) {
  157.26 -  int types_len = types.is_null() ? 0 : types->length();
  157.27 -  if (types_len != parameter_count) return false;
  157.28 -  if (parameter_count > 0) {
  157.29 -    objArrayHandle method_types = get_parameter_types(method, parameter_count, NULL, CHECK_false);
  157.30 -    for (int index = 0; index < parameter_count; index++) {
  157.31 -      if (types->obj_at(index) != method_types->obj_at(index)) {
  157.32 -        return false;
  157.33 -      }
  157.34 -    }
  157.35 -  }
  157.36 -  return true;
  157.37 -}
  157.38 -
  157.39 -
  157.40 -oop Reflection::new_field(FieldStream* st, TRAPS) {
  157.41 -  Symbol*  field_name = st->name();
  157.42 -  Handle name = java_lang_String::create_from_symbol(field_name, CHECK_NULL);
  157.43 -  Symbol*  signature = st->signature();
  157.44 -  Handle type = new_type(signature, st->klass(), CHECK_NULL);
  157.45 -  Handle rh  = java_lang_reflect_Field::create(CHECK_NULL);
  157.46 -  oop result = rh();
  157.47 -
  157.48 -  java_lang_reflect_Field::set_clazz(result, st->klass()->java_mirror());
  157.49 -  java_lang_reflect_Field::set_slot(result, st->index());
  157.50 -  java_lang_reflect_Field::set_name(result, name());
  157.51 -  java_lang_reflect_Field::set_type(result, type());
  157.52 -  // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
  157.53 -  java_lang_reflect_Field::set_modifiers(result, st->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
  157.54 -  java_lang_reflect_Field::set_override(result, false);
  157.55 -  return result;
  157.56 -}
  157.57 -
  157.58 -
  157.59 -bool Reflection::resolve_field(Handle field_mirror, Handle& receiver, fieldDescriptor* fd, bool check_final, TRAPS) {
  157.60 -  if (field_mirror.is_null()) {
  157.61 -    THROW_(vmSymbols::java_lang_NullPointerException(), false);
  157.62 -  }
  157.63 -
  157.64 -  instanceKlassHandle klass (THREAD, java_lang_Class::as_klassOop(java_lang_reflect_Field::clazz(field_mirror())));
  157.65 -  int                 slot  = java_lang_reflect_Field::slot(field_mirror());
  157.66 -
  157.67 -  // Ensure klass is initialized
  157.68 -  klass->initialize(CHECK_false);
  157.69 -  fd->initialize(klass(), slot);
  157.70 -
  157.71 -  bool is_static = fd->is_static();
  157.72 -  KlassHandle receiver_klass;
  157.73 -
  157.74 -  if (is_static) {
  157.75 -    receiver = KlassHandle(THREAD, klass());
  157.76 -    receiver_klass = klass;
  157.77 -  } else {
  157.78 -    // Check object is a non-null instance of declaring class
  157.79 -    if (receiver.is_null()) {
  157.80 -      THROW_(vmSymbols::java_lang_NullPointerException(), false);
  157.81 -    }
  157.82 -    if (!receiver->is_a(klass())) {
  157.83 -      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class", false);
  157.84 -    }
  157.85 -    receiver_klass = KlassHandle(THREAD, receiver->klass());
  157.86 -  }
  157.87 -
  157.88 -  // Access checking (unless overridden by Field)
  157.89 -  if (!java_lang_reflect_Field::override(field_mirror())) {
  157.90 -    if (!(klass->is_public() && fd->is_public())) {
  157.91 -      bool access_check = reflect_check_access(klass(), fd->access_flags(), receiver_klass(), false, CHECK_false);
  157.92 -      if (!access_check) {
  157.93 -        return false; // exception
  157.94 -      }
  157.95 -    }
  157.96 -  }
  157.97 -
  157.98 -  if (check_final && fd->is_final()) {
  157.99 -    // In 1.3 we always throw an error when attempting to set a final field.
 157.100 -    // In 1.2.x, this was allowed in the override bit was set by calling Field.setAccessible(true).
 157.101 -    // We currently maintain backwards compatibility. See bug 4250960.
 157.102 -    bool strict_final_check = !JDK_Version::is_jdk12x_version();
 157.103 -    if (strict_final_check || !java_lang_reflect_Field::override(field_mirror())) {
 157.104 -      THROW_MSG_(vmSymbols::java_lang_IllegalAccessException(), "field is final", false);
 157.105 -    }
 157.106 -  }
 157.107 -  return true;
 157.108 -}
 157.109 -
 157.110 -
 157.111 -BasicType Reflection::field_get(jvalue* value, fieldDescriptor* fd, Handle receiver)  {
 157.112 -  BasicType field_type = fd->field_type();
 157.113 -  int offset = fd->offset();
 157.114 -  switch (field_type) {
 157.115 -    case T_BOOLEAN:
 157.116 -      value->z = receiver->bool_field(offset);
 157.117 -      break;
 157.118 -    case T_CHAR:
 157.119 -      value->c = receiver->char_field(offset);
 157.120 -      break;
 157.121 -    case T_FLOAT:
 157.122 -      value->f = receiver->float_field(offset);
 157.123 -      break;
 157.124 -    case T_DOUBLE:
 157.125 -      value->d = receiver->double_field(offset);
 157.126 -      break;
 157.127 -    case T_BYTE:
 157.128 -      value->b = receiver->byte_field(offset);
 157.129 -      break;
 157.130 -    case T_SHORT:
 157.131 -      value->s = receiver->short_field(offset);
 157.132 -      break;
 157.133 -    case T_INT:
 157.134 -      value->i = receiver->int_field(offset);
 157.135 -      break;
 157.136 -    case T_LONG:
 157.137 -      value->j = receiver->long_field(offset);
 157.138 -      break;
 157.139 -    case T_OBJECT:
 157.140 -    case T_ARRAY:
 157.141 -      value->l = (jobject) receiver->obj_field(offset);
 157.142 -      break;
 157.143 -    default:
 157.144 -      return T_ILLEGAL;
 157.145 -  }
 157.146 -  return field_type;
 157.147 -}
 157.148 -
 157.149 -
 157.150 -void Reflection::field_set(jvalue* value, fieldDescriptor* fd, Handle receiver, BasicType value_type, TRAPS) {
 157.151 -  BasicType field_type = fd->field_type();
 157.152 -  if (field_type != value_type) {
 157.153 -    widen(value, value_type, field_type, CHECK);
 157.154 -  }
 157.155 -
 157.156 -  int offset = fd->offset();
 157.157 -  switch (field_type) {
 157.158 -    case T_BOOLEAN:
 157.159 -      receiver->bool_field_put(offset, value->z);
 157.160 -      break;
 157.161 -    case T_CHAR:
 157.162 -      receiver->char_field_put(offset, value->c);
 157.163 -      break;
 157.164 -    case T_FLOAT:
 157.165 -      receiver->float_field_put(offset, value->f);
 157.166 -      break;
 157.167 -    case T_DOUBLE:
 157.168 -      receiver->double_field_put(offset, value->d);
 157.169 -      break;
 157.170 -    case T_BYTE:
 157.171 -      receiver->byte_field_put(offset, value->b);
 157.172 -      break;
 157.173 -    case T_SHORT:
 157.174 -      receiver->short_field_put(offset, value->s);
 157.175 -      break;
 157.176 -    case T_INT:
 157.177 -      receiver->int_field_put(offset, value->i);
 157.178 -      break;
 157.179 -    case T_LONG:
 157.180 -      receiver->long_field_put(offset, value->j);
 157.181 -      break;
 157.182 -    case T_OBJECT:
 157.183 -    case T_ARRAY: {
 157.184 -      Handle obj(THREAD, (oop) value->l);
 157.185 -      if (obj.not_null()) {
 157.186 -        Symbol*  signature = fd->signature();
 157.187 -        Handle       loader   (THREAD, fd->loader());
 157.188 -        Handle       protect  (THREAD, Klass::cast(fd->field_holder())->protection_domain());
 157.189 -        klassOop k = SystemDictionary::resolve_or_fail(signature, loader, protect, true, CHECK); // may block
 157.190 -        if (!obj->is_a(k)) {
 157.191 -          THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "field type mismatch");
 157.192 -        }
 157.193 -      }
 157.194 -      receiver->obj_field_put(offset, obj());
 157.195 -      break;
 157.196 -    }
 157.197 -    default:
 157.198 -      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "field type mismatch");
 157.199 -  }
 157.200 -}
 157.201 -
 157.202 -
 157.203 -oop Reflection::reflect_field(oop mirror, Symbol* field_name, jint which, TRAPS) {
 157.204 -  // Exclude primitive types and array types
 157.205 -  if (java_lang_Class::is_primitive(mirror))                             return NULL;
 157.206 -  if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) return NULL;
 157.207 -
 157.208 -  instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(mirror));
 157.209 -  bool local_fields_only = (which == DECLARED);
 157.210 -
 157.211 -  // Ensure class is linked
 157.212 -  k->link_class(CHECK_NULL);
 157.213 -
 157.214 -  // Search class and interface fields
 157.215 -  for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
 157.216 -    if (st.name() == field_name) {
 157.217 -      if (local_fields_only || st.access_flags().is_public()) {
 157.218 -        return new_field(&st, THREAD);
 157.219 -      }
 157.220 -    }
 157.221 -  }
 157.222 -
 157.223 -  return NULL;
 157.224 -}
 157.225 -
 157.226 -
 157.227 -objArrayOop Reflection::reflect_fields(oop mirror, jint which, TRAPS) {
 157.228 -  // Exclude primitive types and array types
 157.229 -  if (java_lang_Class::is_primitive(mirror)
 157.230 -      || Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
 157.231 -    Symbol* name = vmSymbols::java_lang_reflect_Field();
 157.232 -    klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
 157.233 -    return oopFactory::new_objArray(klass, 0, CHECK_NULL);  // Return empty array
 157.234 -  }
 157.235 -
 157.236 -  instanceKlassHandle k(THREAD, java_lang_Class::as_klassOop(mirror));
 157.237 -
 157.238 -  // Ensure class is linked
 157.239 -  k->link_class(CHECK_NULL);
 157.240 -
 157.241 -  bool local_fields_only = (which == DECLARED);
 157.242 -  int count = 0;
 157.243 -  { // Compute fields count for class and interface fields
 157.244 -    for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
 157.245 -      if (local_fields_only || st.access_flags().is_public()) {
 157.246 -        count++;
 157.247 -      }
 157.248 -    }
 157.249 -  }
 157.250 -
 157.251 -  // Allocate result
 157.252 -  Symbol* name = vmSymbols::java_lang_reflect_Field();
 157.253 -  klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
 157.254 -  objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
 157.255 -  objArrayHandle result (THREAD, r);
 157.256 -
 157.257 -  // Fill in results backwards
 157.258 -  {
 157.259 -    for (FieldStream st(k, local_fields_only, false); !st.eos(); st.next()) {
 157.260 -      if (local_fields_only || st.access_flags().is_public()) {
 157.261 -        oop field = new_field(&st, CHECK_NULL);
 157.262 -        result->obj_at_put(--count, field);
 157.263 -      }
 157.264 -    }
 157.265 -    assert(count == 0, "just checking");
 157.266 -  }
 157.267 -  return result();
 157.268 -}
 157.269 -
 157.270 -
 157.271 -oop Reflection::reflect_method(oop mirror, Symbol* method_name, objArrayHandle types, jint which, TRAPS) {
 157.272 -  if (java_lang_Class::is_primitive(mirror))  return NULL;
 157.273 -  klassOop klass = java_lang_Class::as_klassOop(mirror);
 157.274 -  if (Klass::cast(klass)->oop_is_array() && which == MEMBER_DECLARED)  return NULL;
 157.275 -
 157.276 -  if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
 157.277 -    klass = SystemDictionary::Object_klass();
 157.278 -  }
 157.279 -  instanceKlassHandle h_k(THREAD, klass);
 157.280 -
 157.281 -  // Ensure klass is linked (need not be initialized)
 157.282 -  h_k->link_class(CHECK_NULL);
 157.283 -
 157.284 -  // For interfaces include static initializers under jdk1.2.x (since classic does that)
 157.285 -  bool include_clinit = JDK_Version::is_jdk12x_version() && h_k->is_interface();
 157.286 -
 157.287 -  switch (which) {
 157.288 -    case MEMBER_PUBLIC:
 157.289 -      // First the public non-static methods (works if method holder is an interface)
 157.290 -      // Note that we can ignore checks for overridden methods, since we go up the hierarchy.
 157.291 -      {
 157.292 -        for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
 157.293 -          methodHandle m(THREAD, st.method());
 157.294 -          // For interfaces include static initializers since classic does that!
 157.295 -          if (method_name == m->name() && (include_clinit || (m->is_public() && !m->is_static() && !m->is_initializer()))) {
 157.296 -            Symbol*  signature = m->signature();
 157.297 -            bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
 157.298 -            if (parameter_match) {
 157.299 -              return new_method(m, false, false, THREAD);
 157.300 -            }
 157.301 -          }
 157.302 -        }
 157.303 -      }
 157.304 -      // Then the public static methods (works if method holder is an interface)
 157.305 -      {
 157.306 -        for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
 157.307 -          methodHandle m(THREAD, st.method());
 157.308 -          if (method_name == m->name() && m->is_public() && m->is_static() && !m->is_initializer()) {
 157.309 -            Symbol*  signature = m->signature();
 157.310 -            bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
 157.311 -            if (parameter_match) {
 157.312 -              return new_method(m, false, false, THREAD);
 157.313 -            }
 157.314 -          }
 157.315 -        }
 157.316 -      }
 157.317 -      break;
 157.318 -    case MEMBER_DECLARED:
 157.319 -      // All local methods
 157.320 -      {
 157.321 -        for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
 157.322 -          methodHandle m(THREAD, st.method());
 157.323 -          if (method_name == m->name() && !m->is_initializer()) {
 157.324 -            Symbol*  signature = m->signature();
 157.325 -            bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
 157.326 -            if (parameter_match) {
 157.327 -              return new_method(m, false, false, THREAD);
 157.328 -            }
 157.329 -          }
 157.330 -        }
 157.331 -      }
 157.332 -      break;
 157.333 -    default:
 157.334 -      break;
 157.335 -  }
 157.336 -  return NULL;
 157.337 -}
 157.338 -
 157.339 -
 157.340 -objArrayOop Reflection::reflect_methods(oop mirror, jint which, TRAPS) {
 157.341 -  // Exclude primitive types
 157.342 -  if (java_lang_Class::is_primitive(mirror) ||
 157.343 -     (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array() && (which == MEMBER_DECLARED))) {
 157.344 -    klassOop klass = SystemDictionary::reflect_Method_klass();
 157.345 -    return oopFactory::new_objArray(klass, 0, CHECK_NULL);  // Return empty array
 157.346 -  }
 157.347 -
 157.348 -  klassOop klass = java_lang_Class::as_klassOop(mirror);
 157.349 -  if (Klass::cast(java_lang_Class::as_klassOop(mirror))->oop_is_array()) {
 157.350 -    klass = SystemDictionary::Object_klass();
 157.351 -  }
 157.352 -  instanceKlassHandle h_k(THREAD, klass);
 157.353 -
 157.354 -  // Ensure klass is linked (need not be initialized)
 157.355 -  h_k->link_class(CHECK_NULL);
 157.356 -
 157.357 -  // We search the (super)interfaces only if h_k is an interface itself
 157.358 -  bool is_interface = h_k->is_interface();
 157.359 -
 157.360 -  // For interfaces include static initializers under jdk1.2.x (since classic does that)
 157.361 -  bool include_clinit = JDK_Version::is_jdk12x_version() && is_interface;
 157.362 -
 157.363 -  switch (which) {
 157.364 -    case MEMBER_PUBLIC:
 157.365 -      {
 157.366 -
 157.367 -        // Count public methods (non-static and static)
 157.368 -        int count = 0;
 157.369 -        {
 157.370 -          for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
 157.371 -            methodOop m = st.method();
 157.372 -            // For interfaces include static initializers since classic does that!
 157.373 -            if (include_clinit || (!m->is_initializer() && m->is_public() && !m->is_overridden_in(h_k()))) {
 157.374 -              count++;
 157.375 -            }
 157.376 -          }
 157.377 -        }
 157.378 -
 157.379 -        // Allocate result
 157.380 -        klassOop klass = SystemDictionary::reflect_Method_klass();
 157.381 -        objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
 157.382 -        objArrayHandle h_result (THREAD, r);
 157.383 -
 157.384 -        // Fill in results backwards
 157.385 -        {
 157.386 -          // First the non-static public methods
 157.387 -          for (MethodStream st(h_k, false, false); !st.eos(); st.next()) {
 157.388 -            methodHandle m (THREAD, st.method());
 157.389 -            if (!m->is_static() && !m->is_initializer() && m->is_public() && !m->is_overridden_in(h_k())) {
 157.390 -              oop method = new_method(m, false, false, CHECK_NULL);
 157.391 -              if (method == NULL) {
 157.392 -                return NULL;
 157.393 -              } else {
 157.394 -                h_result->obj_at_put(--count, method);
 157.395 -              }
 157.396 -            }
 157.397 -          }
 157.398 -        }
 157.399 -        {
 157.400 -          // Then the static public methods
 157.401 -          for (MethodStream st(h_k, false, !is_interface); !st.eos(); st.next()) {
 157.402 -            methodHandle m (THREAD, st.method());
 157.403 -            if (m->is_static() && (include_clinit || (!m->is_initializer()) && m->is_public() && !m->is_overridden_in(h_k()))) {
 157.404 -              oop method = new_method(m, false, false, CHECK_NULL);
 157.405 -              if (method == NULL) {
 157.406 -                return NULL;
 157.407 -              } else {
 157.408 -                h_result->obj_at_put(--count, method);
 157.409 -              }
 157.410 -            }
 157.411 -          }
 157.412 -        }
 157.413 -
 157.414 -        assert(count == 0, "just checking");
 157.415 -        return h_result();
 157.416 -      }
 157.417 -
 157.418 -    case MEMBER_DECLARED:
 157.419 -      {
 157.420 -        // Count all methods
 157.421 -        int count = 0;
 157.422 -        {
 157.423 -          for (MethodStream st(h_k, true, !is_interface); !st.eos(); st.next()) {
 157.424 -            methodOop m = st.method();
 157.425 -            if (!m->is_initializer()) {
 157.426 -              count++;
 157.427 -            }
 157.428 -          }
 157.429 -        }
 157.430 -        // Allocate result
 157.431 -        klassOop klass = SystemDictionary::reflect_Method_klass();
 157.432 -        objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
 157.433 -        objArrayHandle h_result (THREAD, r);
 157.434 -
 157.435 -        // Fill in results backwards
 157.436 -        {
 157.437 -          for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
 157.438 -            methodHandle m (THREAD, st.method());
 157.439 -            if (!m->is_initializer()) {
 157.440 -              oop method = new_method(m, false, false, CHECK_NULL);
 157.441 -              if (method == NULL) {
 157.442 -                return NULL;
 157.443 -              } else {
 157.444 -                h_result->obj_at_put(--count, method);
 157.445 -              }
 157.446 -            }
 157.447 -          }
 157.448 -        }
 157.449 -        assert(count == 0, "just checking");
 157.450 -        return h_result();
 157.451 -      }
 157.452 -  }
 157.453 -  ShouldNotReachHere();
 157.454 -  return NULL;
 157.455 -}
 157.456 -
 157.457 -
 157.458 -oop Reflection::reflect_constructor(oop mirror, objArrayHandle types, jint which, TRAPS) {
 157.459 -
 157.460 -  // Exclude primitive, interface and array types
 157.461 -  bool prim = java_lang_Class::is_primitive(mirror);
 157.462 -  Klass* klass = prim ? NULL : Klass::cast(java_lang_Class::as_klassOop(mirror));
 157.463 -  if (prim || klass->is_interface() || klass->oop_is_array()) return NULL;
 157.464 -
 157.465 -  // Must be instance klass
 157.466 -  instanceKlassHandle h_k(THREAD, java_lang_Class::as_klassOop(mirror));
 157.467 -
 157.468 -  // Ensure klass is linked (need not be initialized)
 157.469 -  h_k->link_class(CHECK_NULL);
 157.470 -
 157.471 -  bool local_only = (which == MEMBER_DECLARED);
 157.472 -  for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
 157.473 -    methodHandle m(THREAD, st.method());
 157.474 -    if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
 157.475 -      Symbol*  signature = m->signature();
 157.476 -      bool parameter_match = match_parameter_types(m, types, ArgumentCount(signature).size(), CHECK_NULL);
 157.477 -      if (parameter_match) {
 157.478 -        return new_constructor(m, THREAD);
 157.479 -      }
 157.480 -    }
 157.481 -  }
 157.482 -
 157.483 -  return NULL;
 157.484 -}
 157.485 -
 157.486 -
 157.487 -objArrayOop Reflection::reflect_constructors(oop mirror, jint which, TRAPS) {
 157.488 -  // Exclude primitive, interface and array types
 157.489 -  bool prim  = java_lang_Class::is_primitive(mirror);
 157.490 -  Klass* k = prim ? NULL : Klass::cast(java_lang_Class::as_klassOop(mirror));
 157.491 -  if (prim || k->is_interface() || k->oop_is_array()) {
 157.492 -    return oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0, CHECK_NULL);  // Return empty array
 157.493 -  }
 157.494 -
 157.495 -  // Must be instanceKlass at this point
 157.496 -  instanceKlassHandle h_k(THREAD, java_lang_Class::as_klassOop(mirror));
 157.497 -
 157.498 -  // Ensure klass is linked (need not be initialized)
 157.499 -  h_k->link_class(CHECK_NULL);
 157.500 -
 157.501 -  bool local_only = (which == MEMBER_DECLARED);
 157.502 -  int count = 0;
 157.503 -  {
 157.504 -    for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
 157.505 -      methodOop m = st.method();
 157.506 -      if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
 157.507 -        count++;
 157.508 -      }
 157.509 -    }
 157.510 -  }
 157.511 -
 157.512 -  // Allocate result
 157.513 -  Symbol* name = vmSymbols::java_lang_reflect_Constructor();
 157.514 -  klassOop klass = SystemDictionary::resolve_or_fail(name, true, CHECK_NULL);
 157.515 -  objArrayOop r = oopFactory::new_objArray(klass, count, CHECK_NULL);
 157.516 -  objArrayHandle h_result (THREAD, r);
 157.517 -
 157.518 -  // Fill in results backwards
 157.519 -  {
 157.520 -    for (MethodStream st(h_k, true, true); !st.eos(); st.next()) {
 157.521 -      methodHandle m (THREAD, st.method());
 157.522 -      if (m->name() == vmSymbols::object_initializer_name() && (local_only || m->is_public())) {
 157.523 -        oop constr = new_constructor(m, CHECK_NULL);
 157.524 -        if (constr == NULL) {
 157.525 -          return NULL;
 157.526 -        } else {
 157.527 -          h_result->obj_at_put(--count, constr);
 157.528 -        }
 157.529 -      }
 157.530 -    }
 157.531 -    assert(count == 0, "just checking");
 157.532 -  }
 157.533 -  return h_result();
 157.534 -}
 157.535 -
 157.536 -
 157.537  // This would be nicer if, say, java.lang.reflect.Method was a subclass
 157.538  // of java.lang.reflect.Constructor
 157.539  
 157.540 @@ -1647,6 +1124,3 @@
 157.541    invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
 157.542    return receiver();
 157.543  }
 157.544 -
 157.545 -
 157.546 -#endif /* SUPPORT_OLD_REFLECTION */
   158.1 --- a/src/share/vm/runtime/reflection.hpp	Thu Sep 08 16:59:27 2011 -0700
   158.2 +++ b/src/share/vm/runtime/reflection.hpp	Fri Sep 09 16:17:16 2011 -0700
   158.3 @@ -27,7 +27,6 @@
   158.4  
   158.5  #include "oops/oop.hpp"
   158.6  #include "runtime/fieldDescriptor.hpp"
   158.7 -#include "runtime/reflectionCompat.hpp"
   158.8  #include "utilities/accessFlags.hpp"
   158.9  #include "utilities/growableArray.hpp"
  158.10  
  158.11 @@ -120,16 +119,6 @@
  158.12    // Create a java.lang.reflect.Field object based on a field descriptor
  158.13    static oop new_field(fieldDescriptor* fd, bool intern_name, TRAPS);
  158.14  
  158.15 -  //---------------------------------------------------------------------------
  158.16 -  //
  158.17 -  // Support for old native code-based reflection (pre-JDK 1.4)
  158.18 -  //
  158.19 -  // NOTE: the method and constructor invocation code is still used
  158.20 -  // for startup time reasons; see reflectionCompat.hpp.
  158.21 -  //
  158.22 -  //---------------------------------------------------------------------------
  158.23 -
  158.24 -#ifdef SUPPORT_OLD_REFLECTION
  158.25  private:
  158.26    // method resolution for invoke
  158.27    static methodHandle resolve_interface_call(instanceKlassHandle klass, methodHandle method, KlassHandle recv_klass, Handle receiver, TRAPS);
  158.28 @@ -144,35 +133,11 @@
  158.29    // Conversion
  158.30    static BasicType basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS);
  158.31  
  158.32 -  static bool match_parameter_types(methodHandle method, objArrayHandle types, int parameter_count, TRAPS);
  158.33 -  // Creating new java.lang.reflect.xxx wrappers
  158.34 -  static oop new_field(FieldStream* st, TRAPS);
  158.35 -
  158.36  public:
  158.37 -  // Field lookup and verification.
  158.38 -  static bool      resolve_field(Handle field_mirror, Handle& receiver, fieldDescriptor* fd, bool check_final, TRAPS);
  158.39 -
  158.40 -  // Reflective field access. Returns type code. Throws IllegalArgumentException.
  158.41 -  static BasicType field_get(jvalue* value, fieldDescriptor* fd, Handle receiver);
  158.42 -  static void      field_set(jvalue* value, fieldDescriptor* fd, Handle receiver, BasicType value_type, TRAPS);
  158.43 -
  158.44 -  // Reflective lookup of fields. Returns java.lang.reflect.Field instances.
  158.45 -  static oop         reflect_field(oop mirror, Symbol* field_name, jint which, TRAPS);
  158.46 -  static objArrayOop reflect_fields(oop mirror, jint which, TRAPS);
  158.47 -
  158.48 -  // Reflective lookup of methods. Returns java.lang.reflect.Method instances.
  158.49 -  static oop         reflect_method(oop mirror, Symbol* method_name, objArrayHandle types, jint which, TRAPS);
  158.50 -  static objArrayOop reflect_methods(oop mirror, jint which, TRAPS);
  158.51 -
  158.52 -  // Reflective lookup of constructors. Returns java.lang.reflect.Constructor instances.
  158.53 -  static oop         reflect_constructor(oop mirror, objArrayHandle types, jint which, TRAPS);
  158.54 -  static objArrayOop reflect_constructors(oop mirror, jint which, TRAPS);
  158.55 -
  158.56    // Method invokation through java.lang.reflect.Method
  158.57    static oop      invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS);
  158.58    // Method invokation through java.lang.reflect.Constructor
  158.59    static oop      invoke_constructor(oop method_mirror, objArrayHandle args, TRAPS);
  158.60 -#endif /* SUPPORT_OLD_REFLECTION */
  158.61  
  158.62  };
  158.63  
   159.1 --- a/src/share/vm/runtime/reflectionCompat.hpp	Thu Sep 08 16:59:27 2011 -0700
   159.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
   159.3 @@ -1,47 +0,0 @@
   159.4 -/*
   159.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
   159.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   159.7 - *
   159.8 - * This code is free software; you can redistribute it and/or modify it
   159.9 - * under the terms of the GNU General Public License version 2 only, as
  159.10 - * published by the Free Software Foundation.
  159.11 - *
  159.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
  159.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  159.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  159.15 - * version 2 for more details (a copy is included in the LICENSE file that
  159.16 - * accompanied this code).
  159.17 - *
  159.18 - * You should have received a copy of the GNU General Public License version
  159.19 - * 2 along with this work; if not, write to the Free Software Foundation,
  159.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  159.21 - *
  159.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  159.23 - * or visit www.oracle.com if you need additional information or have any
  159.24 - * questions.
  159.25 - *
  159.26 - */
  159.27 -
  159.28 -#ifndef SHARE_VM_RUNTIME_REFLECTIONCOMPAT_HPP
  159.29 -#define SHARE_VM_RUNTIME_REFLECTIONCOMPAT_HPP
  159.30 -
  159.31 -// During the development of the JDK 1.4 reflection implementation
  159.32 -// based on dynamic bytecode generation, it was hoped that the bulk of
  159.33 -// the native code for reflection could be removed. Unfortunately
  159.34 -// there is currently a significant cost associated with loading the
  159.35 -// stub classes which impacts startup time. Until this cost can be
  159.36 -// reduced, the JVM entry points JVM_InvokeMethod and
  159.37 -// JVM_NewInstanceFromConstructor are still needed; these and their
  159.38 -// dependents currently constitute the bulk of the native code for
  159.39 -// reflection. If this cost is reduced in the future, the
  159.40 -// NativeMethodAccessorImpl and NativeConstructorAccessorImpl classes
  159.41 -// can be removed from sun.reflect and all of the code guarded by this
  159.42 -// flag removed from the product build. (Non-product builds,
  159.43 -// specifically the "optimized" target, would retain the code so they
  159.44 -// could be dropped into earlier JDKs for comparative benchmarking.)
  159.45 -
  159.46 -//#ifndef PRODUCT
  159.47 -# define SUPPORT_OLD_REFLECTION
  159.48 -//#endif
  159.49 -
  159.50 -#endif // SHARE_VM_RUNTIME_REFLECTIONCOMPAT_HPP
   160.1 --- a/src/share/vm/runtime/sharedRuntime.hpp	Thu Sep 08 16:59:27 2011 -0700
   160.2 +++ b/src/share/vm/runtime/sharedRuntime.hpp	Fri Sep 09 16:17:16 2011 -0700
   160.3 @@ -45,6 +45,8 @@
   160.4  // information, etc.
   160.5  
   160.6  class SharedRuntime: AllStatic {
   160.7 +  friend class VMStructs;
   160.8 +
   160.9   private:
  160.10    static methodHandle resolve_sub_helper(JavaThread *thread,
  160.11                                       bool is_virtual,
   161.1 --- a/src/share/vm/runtime/stubRoutines.cpp	Thu Sep 08 16:59:27 2011 -0700
   161.2 +++ b/src/share/vm/runtime/stubRoutines.cpp	Fri Sep 09 16:17:16 2011 -0700
   161.3 @@ -108,6 +108,7 @@
   161.4  address StubRoutines::_arrayof_oop_disjoint_arraycopy    = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy);
   161.5  address StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit  = CAST_FROM_FN_PTR(address, StubRoutines::arrayof_oop_copy_uninit);
   161.6  
   161.7 +address StubRoutines::_zero_aligned_words = CAST_FROM_FN_PTR(address, Copy::zero_to_words);
   161.8  
   161.9  address StubRoutines::_checkcast_arraycopy               = NULL;
  161.10  address StubRoutines::_checkcast_arraycopy_uninit        = NULL;
   162.1 --- a/src/share/vm/runtime/stubRoutines.hpp	Thu Sep 08 16:59:27 2011 -0700
   162.2 +++ b/src/share/vm/runtime/stubRoutines.hpp	Fri Sep 09 16:17:16 2011 -0700
   162.3 @@ -199,6 +199,9 @@
   162.4    static address _arrayof_jshort_fill;
   162.5    static address _arrayof_jint_fill;
   162.6  
   162.7 +  // zero heap space aligned to jlong (8 bytes)
   162.8 +  static address _zero_aligned_words;
   162.9 +
  162.10    // These are versions of the java.lang.Math methods which perform
  162.11    // the same operations as the intrinsic version.  They are used for
  162.12    // constant folding in the compiler to ensure equivalence.  If the
  162.13 @@ -332,6 +335,7 @@
  162.14  
  162.15    static address select_fill_function(BasicType t, bool aligned, const char* &name);
  162.16  
  162.17 +  static address zero_aligned_words()   { return _zero_aligned_words; }
  162.18  
  162.19    static double  intrinsic_log(double d) {
  162.20      assert(_intrinsic_log != NULL, "must be defined");
   163.1 --- a/src/share/vm/runtime/thread.cpp	Thu Sep 08 16:59:27 2011 -0700
   163.2 +++ b/src/share/vm/runtime/thread.cpp	Fri Sep 09 16:17:16 2011 -0700
   163.3 @@ -1272,7 +1272,6 @@
   163.4    _exception_oop = NULL;
   163.5    _exception_pc  = 0;
   163.6    _exception_handler_pc = 0;
   163.7 -  _exception_stack_size = 0;
   163.8    _is_method_handle_return = 0;
   163.9    _jvmti_thread_state= NULL;
  163.10    _should_post_on_exceptions_flag = JNI_FALSE;
  163.11 @@ -2860,6 +2859,44 @@
  163.12    }
  163.13  }
  163.14  
  163.15 +class PrintAndVerifyOopClosure: public OopClosure {
  163.16 + protected:
  163.17 +  template <class T> inline void do_oop_work(T* p) {
  163.18 +    oop obj = oopDesc::load_decode_heap_oop(p);
  163.19 +    if (obj == NULL) return;
  163.20 +    tty->print(INTPTR_FORMAT ": ", p);
  163.21 +    if (obj->is_oop_or_null()) {
  163.22 +      if (obj->is_objArray()) {
  163.23 +        tty->print_cr("valid objArray: " INTPTR_FORMAT, (oopDesc*) obj);
  163.24 +      } else {
  163.25 +        obj->print();
  163.26 +      }
  163.27 +    } else {
  163.28 +      tty->print_cr("invalid oop: " INTPTR_FORMAT, (oopDesc*) obj);
  163.29 +    }
  163.30 +    tty->cr();
  163.31 +  }
  163.32 + public:
  163.33 +  virtual void do_oop(oop* p) { do_oop_work(p); }
  163.34 +  virtual void do_oop(narrowOop* p)  { do_oop_work(p); }
  163.35 +};
  163.36 +
  163.37 +
  163.38 +static void oops_print(frame* f, const RegisterMap *map) {
  163.39 +  PrintAndVerifyOopClosure print;
  163.40 +  f->print_value();
  163.41 +  f->oops_do(&print, NULL, (RegisterMap*)map);
  163.42 +}
  163.43 +
  163.44 +// Print our all the locations that contain oops and whether they are
  163.45 +// valid or not.  This useful when trying to find the oldest frame
  163.46 +// where an oop has gone bad since the frame walk is from youngest to
  163.47 +// oldest.
  163.48 +void JavaThread::trace_oops() {
  163.49 +  tty->print_cr("[Trace oops]");
  163.50 +  frames_do(oops_print);
  163.51 +}
  163.52 +
  163.53  
  163.54  #ifdef ASSERT
  163.55  // Print or validate the layout of stack frames
   164.1 --- a/src/share/vm/runtime/thread.hpp	Thu Sep 08 16:59:27 2011 -0700
   164.2 +++ b/src/share/vm/runtime/thread.hpp	Fri Sep 09 16:17:16 2011 -0700
   164.3 @@ -841,7 +841,6 @@
   164.4    volatile oop     _exception_oop;               // Exception thrown in compiled code
   164.5    volatile address _exception_pc;                // PC where exception happened
   164.6    volatile address _exception_handler_pc;        // PC for handler of exception
   164.7 -  volatile int     _exception_stack_size;        // Size of frame where exception happened
   164.8    volatile int     _is_method_handle_return;     // true (== 1) if the current exception PC is a MethodHandle call site.
   164.9  
  164.10    // support for compilation
  164.11 @@ -1182,7 +1181,6 @@
  164.12  
  164.13    // Exception handling for compiled methods
  164.14    oop      exception_oop() const                 { return _exception_oop; }
  164.15 -  int      exception_stack_size() const          { return _exception_stack_size; }
  164.16    address  exception_pc() const                  { return _exception_pc; }
  164.17    address  exception_handler_pc() const          { return _exception_handler_pc; }
  164.18    bool     is_method_handle_return() const       { return _is_method_handle_return == 1; }
  164.19 @@ -1190,7 +1188,6 @@
  164.20    void set_exception_oop(oop o)                  { _exception_oop = o; }
  164.21    void set_exception_pc(address a)               { _exception_pc = a; }
  164.22    void set_exception_handler_pc(address a)       { _exception_handler_pc = a; }
  164.23 -  void set_exception_stack_size(int size)        { _exception_stack_size = size; }
  164.24    void set_is_method_handle_return(bool value)   { _is_method_handle_return = value ? 1 : 0; }
  164.25  
  164.26    // Stack overflow support
  164.27 @@ -1264,7 +1261,6 @@
  164.28    static ByteSize exception_oop_offset()         { return byte_offset_of(JavaThread, _exception_oop       ); }
  164.29    static ByteSize exception_pc_offset()          { return byte_offset_of(JavaThread, _exception_pc        ); }
  164.30    static ByteSize exception_handler_pc_offset()  { return byte_offset_of(JavaThread, _exception_handler_pc); }
  164.31 -  static ByteSize exception_stack_size_offset()  { return byte_offset_of(JavaThread, _exception_stack_size); }
  164.32    static ByteSize is_method_handle_return_offset() { return byte_offset_of(JavaThread, _is_method_handle_return); }
  164.33    static ByteSize stack_guard_state_offset()     { return byte_offset_of(JavaThread, _stack_guard_state   ); }
  164.34    static ByteSize suspend_flags_offset()         { return byte_offset_of(JavaThread, _suspend_flags       ); }
  164.35 @@ -1379,6 +1375,7 @@
  164.36    void trace_stack()                             PRODUCT_RETURN;
  164.37    void trace_stack_from(vframe* start_vf)        PRODUCT_RETURN;
  164.38    void trace_frames()                            PRODUCT_RETURN;
  164.39 +  void trace_oops()                              PRODUCT_RETURN;
  164.40  
  164.41    // Print an annotated view of the stack frames
  164.42    void print_frame_layout(int depth = 0, bool validate_only = false) NOT_DEBUG_RETURN;
   165.1 --- a/src/share/vm/runtime/vmStructs.cpp	Thu Sep 08 16:59:27 2011 -0700
   165.2 +++ b/src/share/vm/runtime/vmStructs.cpp	Fri Sep 09 16:17:16 2011 -0700
   165.3 @@ -652,6 +652,7 @@
   165.4        static_field(SystemDictionary,            WK_KLASS(ThreadGroup_klass),                   klassOop)                             \
   165.5        static_field(SystemDictionary,            WK_KLASS(Properties_klass),                    klassOop)                             \
   165.6        static_field(SystemDictionary,            WK_KLASS(StringBuffer_klass),                  klassOop)                             \
   165.7 +      static_field(SystemDictionary,            WK_KLASS(MethodHandle_klass),                  klassOop)                             \
   165.8        static_field(SystemDictionary,            _box_klasses[0],                               klassOop)                             \
   165.9        static_field(SystemDictionary,            _java_system_loader,                           oop)                                  \
  165.10                                                                                                                                       \
  165.11 @@ -757,12 +758,19 @@
  165.12    nonstatic_field(PcDesc,                      _pc_offset,                                    int)                                   \
  165.13    nonstatic_field(PcDesc,                      _scope_decode_offset,                          int)                                   \
  165.14    nonstatic_field(PcDesc,                      _obj_decode_offset,                            int)                                   \
  165.15 -  nonstatic_field(PcDesc,                      _flags,                        PcDesc::PcDescFlags)                                   \
  165.16 +  nonstatic_field(PcDesc,                      _flags,                                        int)                                   \
  165.17                                                                                                                                       \
  165.18    /***************************************************/                                                                              \
  165.19    /* CodeBlobs (NOTE: incomplete, but only a little) */                                                                              \
  165.20    /***************************************************/                                                                              \
  165.21                                                                                                                                       \
  165.22 +  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_pc,                                     address))                   \
  165.23 +  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _exact_sender_sp,                              intptr_t*))                  \
  165.24 +  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_link,                                  intptr_t*))                  \
  165.25 +  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _saved_args_base,                              intptr_t*))                  \
  165.26 +                                                                                                                                     \
  165.27 +     static_field(SharedRuntime,               _ricochet_blob,                                RicochetBlob*)                         \
  165.28 +                                                                                                                                     \
  165.29    nonstatic_field(CodeBlob,                    _name,                                         const char*)                           \
  165.30    nonstatic_field(CodeBlob,                    _size,                                         int)                                   \
  165.31    nonstatic_field(CodeBlob,                    _header_size,                                  int)                                   \
  165.32 @@ -774,6 +782,8 @@
  165.33    nonstatic_field(CodeBlob,                    _frame_size,                                   int)                                   \
  165.34    nonstatic_field(CodeBlob,                    _oop_maps,                                     OopMapSet*)                            \
  165.35                                                                                                                                       \
  165.36 +  nonstatic_field(RuntimeStub,                 _caller_must_gc_arguments,                     bool)                                  \
  165.37 +                                                                                                                                     \
  165.38    /**************************************************/                                                                               \
  165.39    /* NMethods (NOTE: incomplete, but only a little) */                                                                               \
  165.40    /**************************************************/                                                                               \
  165.41 @@ -786,6 +796,7 @@
  165.42    nonstatic_field(nmethod,             _state,                                        unsigned char)                         \
  165.43    nonstatic_field(nmethod,             _exception_offset,                             int)                                   \
  165.44    nonstatic_field(nmethod,             _deoptimize_offset,                            int)                                   \
  165.45 +  nonstatic_field(nmethod,             _deoptimize_mh_offset,                         int)                                   \
  165.46    nonstatic_field(nmethod,             _orig_pc_offset,                               int)                                   \
  165.47    nonstatic_field(nmethod,             _stub_offset,                                  int)                                   \
  165.48    nonstatic_field(nmethod,             _consts_offset,                                int)                                   \
  165.49 @@ -804,6 +815,9 @@
  165.50    nonstatic_field(nmethod,             _compile_id,                                   int)                                   \
  165.51    nonstatic_field(nmethod,             _marked_for_deoptimization,                    bool)                                  \
  165.52                                                                                                                                       \
  165.53 +  nonstatic_field(RicochetBlob,        _bounce_offset,                                int)                                           \
  165.54 +  nonstatic_field(RicochetBlob,        _exception_offset,                             int)                                           \
  165.55 +                                                                                                                                     \
  165.56    /********************************/                                                                                                 \
  165.57    /* JavaCalls (NOTE: incomplete) */                                                                                                 \
  165.58    /********************************/                                                                                                 \
  165.59 @@ -1310,24 +1324,27 @@
  165.60    /* CodeBlob hierarchy (needed for run-time type information) */         \
  165.61    /*************************************************************/         \
  165.62                                                                            \
  165.63 +  declare_toplevel_type(SharedRuntime)                                    \
  165.64 +  X86_ONLY(declare_toplevel_type(MethodHandles::RicochetFrame))           \
  165.65 +                                                                          \
  165.66    declare_toplevel_type(CodeBlob)                                         \
  165.67 -  declare_type(BufferBlob,            CodeBlob)                           \
  165.68 -  declare_type(AdapterBlob,           BufferBlob)                         \
  165.69 -  declare_type(nmethod,               CodeBlob)                           \
  165.70 -  declare_type(RuntimeStub,           CodeBlob)                           \
  165.71 -  declare_type(SingletonBlob,         CodeBlob)                           \
  165.72 -  declare_type(SafepointBlob,         SingletonBlob)                      \
  165.73 -  declare_type(DeoptimizationBlob,    SingletonBlob)                      \
  165.74 -  declare_type(RicochetBlob,          SingletonBlob)                      \
  165.75 -  declare_c2_type(ExceptionBlob,      SingletonBlob)                      \
  165.76 -  declare_c2_type(UncommonTrapBlob,   CodeBlob)                           \
  165.77 +  declare_type(BufferBlob,               CodeBlob)                        \
  165.78 +  declare_type(AdapterBlob,              BufferBlob)                      \
  165.79 +  declare_type(MethodHandlesAdapterBlob, BufferBlob)                      \
  165.80 +  declare_type(nmethod,                  CodeBlob)                        \
  165.81 +  declare_type(RuntimeStub,              CodeBlob)                        \
  165.82 +  declare_type(SingletonBlob,            CodeBlob)                        \
  165.83 +  declare_type(SafepointBlob,            SingletonBlob)                   \
  165.84 +  declare_type(DeoptimizationBlob,       SingletonBlob)                   \
  165.85 +  declare_type(RicochetBlob,             SingletonBlob)                   \
  165.86 +  declare_c2_type(ExceptionBlob,         SingletonBlob)                   \
  165.87 +  declare_c2_type(UncommonTrapBlob,      CodeBlob)                        \
  165.88                                                                            \
  165.89    /***************************************/                               \
  165.90    /* PcDesc and other compiled code info */                               \
  165.91    /***************************************/                               \
  165.92                                                                            \
  165.93    declare_toplevel_type(PcDesc)                                           \
  165.94 -  declare_integer_type(PcDesc::PcDescFlags)                               \
  165.95                                                                            \
  165.96    /************************/                                              \
  165.97    /* OopMap and OopMapSet */                                              \
  165.98 @@ -1796,6 +1813,21 @@
  165.99                                                                            \
 165.100    declare_constant(ObjectSynchronizer::_BLOCKSIZE)                        \
 165.101                                                                            \
 165.102 +  /**********************/                                                \
 165.103 +  /* PcDesc             */                                                \
 165.104 +  /**********************/                                                \
 165.105 +                                                                          \
 165.106 +  declare_constant(PcDesc::PCDESC_reexecute)                              \
 165.107 +  declare_constant(PcDesc::PCDESC_is_method_handle_invoke)                \
 165.108 +  declare_constant(PcDesc::PCDESC_return_oop)                             \
 165.109 +                                                                          \
 165.110 +  /**********************/                                                \
 165.111 +  /* frame              */                                                \
 165.112 +  /**********************/                                                \
 165.113 +                                                                          \
 165.114 +  X86_ONLY(declare_constant(frame::entry_frame_call_wrapper_offset))      \
 165.115 +  declare_constant(frame::pc_return_offset)                               \
 165.116 +                                                                          \
 165.117    /********************************/                                      \
 165.118    /* Calling convention constants */                                      \
 165.119    /********************************/                                      \
   166.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   166.2 +++ b/test/compiler/7082949/Test7082949.java	Fri Sep 09 16:17:16 2011 -0700
   166.3 @@ -0,0 +1,54 @@
   166.4 +/*
   166.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
   166.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   166.7 + *
   166.8 + * This code is free software; you can redistribute it and/or modify it
   166.9 + * under the terms of the GNU General Public License version 2 only, as
  166.10 + * published by the Free Software Foundation.
  166.11 + *
  166.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  166.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  166.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  166.15 + * version 2 for more details (a copy is included in the LICENSE file that
  166.16 + * accompanied this code).
  166.17 + *
  166.18 + * You should have received a copy of the GNU General Public License version
  166.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  166.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  166.21 + *
  166.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  166.23 + * or visit www.oracle.com if you need additional information or have any
  166.24 + * questions.
  166.25 + *
  166.26 + */
  166.27 +
  166.28 +/**
  166.29 + * @test
  166.30 + * @bug 7082949
  166.31 + * @summary JSR 292: missing ResourceMark in methodOopDesc::make_invoke_method
  166.32 + *
  166.33 + * @run main Test7082949
  166.34 + */
  166.35 +
  166.36 +import java.lang.invoke.*;
  166.37 +import static java.lang.invoke.MethodHandles.*;
  166.38 +import static java.lang.invoke.MethodType.*;
  166.39 +
  166.40 +public class Test7082949 implements Runnable {
  166.41 +    public static void main(String... args) throws Throwable {
  166.42 +        new Thread(new Test7082949()).start();
  166.43 +    }
  166.44 +
  166.45 +    public static Test7082949 test() {
  166.46 +        return null;
  166.47 +    }
  166.48 +
  166.49 +    public void run() {
  166.50 +        try {
  166.51 +            MethodHandle m1 = MethodHandles.lookup().findStatic(Test7082949.class, "test",  methodType(Test7082949.class));
  166.52 +            Test7082949 v = (Test7082949)m1.invokeExact();
  166.53 +        } catch (Throwable t) {
  166.54 +            t.printStackTrace();
  166.55 +        }
  166.56 +    }
  166.57 +}

mercurial