agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File JDK-8015774 Sdiff agent/src/share/classes/sun/jvm/hotspot/code

agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java

Print this page




  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.code;
  26 
  27 import java.util.*;
  28 import sun.jvm.hotspot.debugger.*;
  29 import sun.jvm.hotspot.memory.*;
  30 import sun.jvm.hotspot.runtime.*;
  31 import sun.jvm.hotspot.types.*;
  32 import sun.jvm.hotspot.utilities.*;
  33 
  34 public class CodeCache {
  35   private static AddressField       heapField;
  36   private static AddressField       scavengeRootNMethodsField;
  37   private static VirtualConstructor virtualConstructor;
  38 
  39   private CodeHeap heap;
  40 
  41   static {
  42     VM.registerVMInitializedObserver(new Observer() {
  43         public void update(Observable o, Object data) {
  44           initialize(VM.getVM().getTypeDataBase());
  45         }
  46       });
  47   }
  48 
  49   private static synchronized void initialize(TypeDataBase db) {
  50     Type type = db.lookupType("CodeCache");
  51 
  52     heapField = type.getAddressField("_heap");



  53     scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
  54 
  55     virtualConstructor = new VirtualConstructor(db);
  56     // Add mappings for all possible CodeBlob subclasses
  57     virtualConstructor.addMapping("BufferBlob", BufferBlob.class);
  58     virtualConstructor.addMapping("nmethod", NMethod.class);
  59     virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class);
  60     virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
  61     virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
  62     virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
  63     virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class);
  64     if (VM.getVM().isServerCompiler()) {
  65       virtualConstructor.addMapping("ExceptionBlob", ExceptionBlob.class);
  66       virtualConstructor.addMapping("UncommonTrapBlob", UncommonTrapBlob.class);
  67     }
  68   }
  69 
  70   public CodeCache() {
  71     heap = (CodeHeap) VMObjectFactory.newObject(CodeHeap.class, heapField.getValue());
  72   }
  73 
  74   public NMethod scavengeRootMethods() {
  75     return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootNMethodsField.getValue());
  76   }
  77 
  78   public boolean contains(Address p) {
  79     return getHeap().contains(p);





  80   }
  81 
  82   /** When VM.getVM().isDebugging() returns true, this behaves like
  83       findBlobUnsafe */
  84   public CodeBlob findBlob(Address start) {
  85     CodeBlob result = findBlobUnsafe(start);
  86     if (result == null) return null;
  87     if (VM.getVM().isDebugging()) {
  88       return result;
  89     }
  90     // We could potientially look up non_entrant methods
  91     // NOTE: this is effectively a "guarantee", and is slightly different from the one in the VM
  92     if (Assert.ASSERTS_ENABLED) {
  93       Assert.that(!(result.isZombie() || result.isLockedByVM()), "unsafe access to zombie method");
  94     }
  95     return result;
  96   }
  97 
  98   public CodeBlob findBlobUnsafe(Address start) {
  99     CodeBlob result = null;










 100 
 101     try {
 102       result = (CodeBlob) virtualConstructor.instantiateWrapperFor(getHeap().findStart(start));
 103     }
 104     catch (WrongTypeException wte) {
 105       Address cbAddr = null;
 106       try {
 107         cbAddr = getHeap().findStart(start);
 108       }
 109       catch (Exception findEx) {
 110         findEx.printStackTrace();
 111       }
 112 
 113       String message = "Couldn't deduce type of CodeBlob ";
 114       if (cbAddr != null) {
 115         message = message + "@" + cbAddr + " ";
 116       }
 117       message = message + "for PC=" + start;
 118 
 119       throw new RuntimeException(message, wte);
 120     }
 121     if (result == null) return null;
 122     if (Assert.ASSERTS_ENABLED) {
 123       // The HeapBlock that contains this blob is outside of the blob
 124       // but it shouldn't be an error to find a blob based on the
 125       // pointer to the HeapBlock.
 126       Assert.that(result.blobContains(start) || result.blobContains(start.addOffsetTo(8)),
 127                                                                     "found wrong CodeBlob");


 150   public CodeBlob createCodeBlobWrapper(Address codeBlobAddr) {
 151     try {
 152       return (CodeBlob) virtualConstructor.instantiateWrapperFor(codeBlobAddr);
 153     }
 154     catch (Exception e) {
 155       String message = "Unable to deduce type of CodeBlob from address " + codeBlobAddr +
 156                        " (expected type nmethod, RuntimeStub, ";
 157       if (VM.getVM().isClientCompiler()) {
 158         message = message + " or ";
 159       }
 160       message = message + "SafepointBlob";
 161       if (VM.getVM().isServerCompiler()) {
 162         message = message + ", DeoptimizationBlob, or ExceptionBlob";
 163       }
 164       message = message + ")";
 165       throw new RuntimeException(message);
 166     }
 167   }
 168 
 169   public void iterate(CodeCacheVisitor visitor) {
 170     CodeHeap heap = getHeap();
 171     Address ptr = heap.begin();
 172     Address end = heap.end();
 173 
 174     visitor.prologue(ptr, end);
 175     CodeBlob lastBlob = null;
 176     while (ptr != null && ptr.lessThan(end)) {




 177       try {
 178         // Use findStart to get a pointer inside blob other findBlob asserts
 179         CodeBlob blob = findBlobUnsafe(heap.findStart(ptr));
 180         if (blob != null) {
 181           visitor.visit(blob);
 182           if (blob == lastBlob) {
 183             throw new InternalError("saw same blob twice");
 184           }
 185           lastBlob = blob;
 186         }
 187       } catch (RuntimeException e) {
 188         e.printStackTrace();
 189       }
 190       Address next = heap.nextBlock(ptr);
 191       if (next != null && next.lessThan(ptr)) {
 192         throw new InternalError("pointer moved backwards");
 193       }
 194       ptr = next;
 195     }

 196     visitor.epilogue();
 197   }
 198 
 199   //--------------------------------------------------------------------------------
 200   // Internals only below this point
 201   //
 202 
 203   private CodeHeap getHeap() {
 204     return heap;
















 205   }
 206 }


  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.code;
  26 
  27 import java.util.*;
  28 import sun.jvm.hotspot.debugger.*;
  29 import sun.jvm.hotspot.memory.*;
  30 import sun.jvm.hotspot.runtime.*;
  31 import sun.jvm.hotspot.types.*;
  32 import sun.jvm.hotspot.utilities.*;
  33 
  34 public class CodeCache {
  35   private static GrowableArray<CodeHeap> heapArray;
  36   private static AddressField scavengeRootNMethodsField;
  37   private static VirtualConstructor virtualConstructor;
  38 


  39   static {
  40     VM.registerVMInitializedObserver(new Observer() {
  41         public void update(Observable o, Object data) {
  42           initialize(VM.getVM().getTypeDataBase());
  43         }
  44       });
  45   }
  46 
  47   private static synchronized void initialize(TypeDataBase db) {
  48     Type type = db.lookupType("CodeCache");
  49 
  50     // Get array of CodeHeaps
  51     AddressField heapsField = type.getAddressField("_heaps");
  52     heapArray = GrowableArray.create(heapsField.getValue(), new StaticBaseConstructor<CodeHeap>(CodeHeap.class));
  53 
  54     scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
  55 
  56     virtualConstructor = new VirtualConstructor(db);
  57     // Add mappings for all possible CodeBlob subclasses
  58     virtualConstructor.addMapping("BufferBlob", BufferBlob.class);
  59     virtualConstructor.addMapping("nmethod", NMethod.class);
  60     virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class);
  61     virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
  62     virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
  63     virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
  64     virtualConstructor.addMapping("DeoptimizationBlob", DeoptimizationBlob.class);
  65     if (VM.getVM().isServerCompiler()) {
  66       virtualConstructor.addMapping("ExceptionBlob", ExceptionBlob.class);
  67       virtualConstructor.addMapping("UncommonTrapBlob", UncommonTrapBlob.class);
  68     }
  69   }
  70 




  71   public NMethod scavengeRootMethods() {
  72     return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootNMethodsField.getValue());
  73   }
  74 
  75   public boolean contains(Address p) {
  76     for (int i = 0; i < heapArray.length(); ++i) {
  77       if (heapArray.at(i).contains(p)) {
  78         return true;
  79       }
  80     }
  81     return false;
  82   }
  83 
  84   /** When VM.getVM().isDebugging() returns true, this behaves like
  85       findBlobUnsafe */
  86   public CodeBlob findBlob(Address start) {
  87     CodeBlob result = findBlobUnsafe(start);
  88     if (result == null) return null;
  89     if (VM.getVM().isDebugging()) {
  90       return result;
  91     }
  92     // We could potientially look up non_entrant methods
  93     // NOTE: this is effectively a "guarantee", and is slightly different from the one in the VM
  94     if (Assert.ASSERTS_ENABLED) {
  95       Assert.that(!(result.isZombie() || result.isLockedByVM()), "unsafe access to zombie method");
  96     }
  97     return result;
  98   }
  99 
 100   public CodeBlob findBlobUnsafe(Address start) {
 101     CodeBlob result = null;
 102     CodeHeap containing_heap = null;
 103     for (int i = 0; i < heapArray.length(); ++i) {
 104       if (heapArray.at(i).contains(start)) {
 105         containing_heap = heapArray.at(i);
 106         break;
 107       }
 108     }
 109     if (containing_heap == null) {
 110       return null;
 111     }
 112     
 113     try {
 114       result = (CodeBlob) virtualConstructor.instantiateWrapperFor(containing_heap.findStart(start));
 115     }
 116     catch (WrongTypeException wte) {
 117       Address cbAddr = null;
 118       try {
 119         cbAddr = containing_heap.findStart(start);
 120       }
 121       catch (Exception findEx) {
 122         findEx.printStackTrace();
 123       }
 124 
 125       String message = "Couldn't deduce type of CodeBlob ";
 126       if (cbAddr != null) {
 127         message = message + "@" + cbAddr + " ";
 128       }
 129       message = message + "for PC=" + start;
 130 
 131       throw new RuntimeException(message, wte);
 132     }
 133     if (result == null) return null;
 134     if (Assert.ASSERTS_ENABLED) {
 135       // The HeapBlock that contains this blob is outside of the blob
 136       // but it shouldn't be an error to find a blob based on the
 137       // pointer to the HeapBlock.
 138       Assert.that(result.blobContains(start) || result.blobContains(start.addOffsetTo(8)),
 139                                                                     "found wrong CodeBlob");


 162   public CodeBlob createCodeBlobWrapper(Address codeBlobAddr) {
 163     try {
 164       return (CodeBlob) virtualConstructor.instantiateWrapperFor(codeBlobAddr);
 165     }
 166     catch (Exception e) {
 167       String message = "Unable to deduce type of CodeBlob from address " + codeBlobAddr +
 168                        " (expected type nmethod, RuntimeStub, ";
 169       if (VM.getVM().isClientCompiler()) {
 170         message = message + " or ";
 171       }
 172       message = message + "SafepointBlob";
 173       if (VM.getVM().isServerCompiler()) {
 174         message = message + ", DeoptimizationBlob, or ExceptionBlob";
 175       }
 176       message = message + ")";
 177       throw new RuntimeException(message);
 178     }
 179   }
 180 
 181   public void iterate(CodeCacheVisitor visitor) {
 182     visitor.prologue(lowBound(), highBound());




 183     CodeBlob lastBlob = null;
 184     
 185     for (int i = 0; i < heapArray.length(); ++i) {
 186       CodeHeap current_heap = heapArray.at(i);
 187       Address ptr = current_heap.begin();
 188       while (ptr != null && ptr.lessThan(current_heap.end())) {
 189         try {
 190           // Use findStart to get a pointer inside blob other findBlob asserts
 191           CodeBlob blob = findBlobUnsafe(current_heap.findStart(ptr));
 192           if (blob != null) {
 193             visitor.visit(blob);
 194             if (blob == lastBlob) {
 195               throw new InternalError("saw same blob twice");
 196             }
 197             lastBlob = blob;
 198           }
 199         } catch (RuntimeException e) {
 200           e.printStackTrace();
 201         }
 202         Address next = current_heap.nextBlock(ptr);
 203         if (next != null && next.lessThan(ptr)) {
 204           throw new InternalError("pointer moved backwards");
 205         }
 206         ptr = next;
 207       }
 208     }
 209     visitor.epilogue();
 210   }
 211 
 212   //--------------------------------------------------------------------------------
 213   // Internals only below this point
 214   //
 215   
 216   private Address lowBound() {
 217     Address low = heapArray.at(0).begin();
 218     for (int i = 1; i < heapArray.length(); ++i) {
 219       if (heapArray.at(i).begin().lessThan(low)) {
 220         low = heapArray.at(i).begin();
 221       }
 222     }
 223     return low;
 224   }
 225   
 226   private Address highBound() {
 227     Address high = heapArray.at(0).end();
 228     for (int i = 1; i < heapArray.length(); ++i) {
 229       if (heapArray.at(i).end().greaterThan(high)) {
 230         high = heapArray.at(i).end();
 231       }
 232     }
 233     return high;
 234   }
 235 }
agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File