diff agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java @ 152:c70a245cad3a

6670684: 4/5 SA command universe did not print out CMS space information Summary: Forward port of Yumin's fix for 6670684 from HSX-11; Yumin verified the port was correct. Reviewed-by: dcubed
author dcubed
date Fri, 09 May 2008 08:55:13 -0700
parents a61af66fc99e
children c0ecab83e6f3
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java	Tue Apr 01 16:14:18 2008 -0700
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java	Fri May 09 08:55:13 2008 -0700
@@ -35,6 +35,20 @@
 public class CompactibleFreeListSpace extends CompactibleSpace {
    private static AddressField collectorField;
 
+   // for free size, three fields
+   //       FreeBlockDictionary* _dictionary;        // ptr to dictionary for large size blocks
+   //       FreeList _indexedFreeList[IndexSetSize]; // indexed array for small size blocks
+   //       LinearAllocBlock _smallLinearAllocBlock; // small linear alloc in TLAB
+   private static AddressField indexedFreeListField;
+   private static AddressField dictionaryField;
+   private static long         smallLinearAllocBlockFieldOffset;
+   private static long indexedFreeListSizeOf;
+
+   private int    heapWordSize;     // 4 for 32bit, 8 for 64 bits
+   private int    IndexSetStart;    // for small indexed list
+   private int    IndexSetSize;
+   private int    IndexSetStride;
+
    static {
       VM.registerVMInitializedObserver(new Observer() {
          public void update(Observable o, Object data) {
@@ -51,10 +65,26 @@
 
      Type type = db.lookupType("CompactibleFreeListSpace");
      collectorField = type.getAddressField("_collector");
+     collectorField       = type.getAddressField("_collector");
+     dictionaryField      = type.getAddressField("_dictionary");
+     indexedFreeListField = type.getAddressField("_indexedFreeList[0]");
+     smallLinearAllocBlockFieldOffset = type.getField("_smallLinearAllocBlock").getOffset();
    }
 
    public CompactibleFreeListSpace(Address addr) {
       super(addr);
+      if ( VM.getVM().isLP64() ) {
+         heapWordSize = 8;
+         IndexSetStart = 1;
+         IndexSetStride = 1;
+      }
+      else {
+         heapWordSize = 4;
+         IndexSetStart = 2;
+         IndexSetStride = 2;
+      }
+
+      IndexSetSize = 257;
    }
 
    // Accessing block offset table
@@ -62,9 +92,17 @@
     return (CMSCollector) VMObjectFactory.newObject(
                                  CMSCollector.class,
                                  collectorField.getValue(addr));
-  }
+   }
+
+   public long free0() {
+     return capacity() - used0();
+   }
 
    public long used() {
+     return capacity() - free();
+   }
+
+   public long used0() {
       List regions = getLiveRegions();
       long usedSize = 0L;
       for (Iterator itr = regions.iterator(); itr.hasNext();) {
@@ -75,11 +113,41 @@
    }
 
    public long free() {
-      return capacity() - used();
-   }
+      // small chunks
+      long size = 0;
+      Address cur = addr.addOffsetTo( indexedFreeListField.getOffset() );
+      cur = cur.addOffsetTo(IndexSetStart*FreeList.sizeOf());
+      for (int i=IndexSetStart; i<IndexSetSize; i += IndexSetStride) {
+         FreeList freeList = (FreeList) VMObjectFactory.newObject(FreeList.class, cur);
+         size += i*freeList.count();
+         cur= cur.addOffsetTo(IndexSetStride*FreeList.sizeOf());
+      }
+
+      // large block
+      BinaryTreeDictionary bfbd = (BinaryTreeDictionary) VMObjectFactory.newObject(BinaryTreeDictionary.class,
+                                                                                   dictionaryField.getValue(addr));
+      size += bfbd.size();
+
+
+      // linear block in TLAB
+      LinearAllocBlock lab = (LinearAllocBlock) VMObjectFactory.newObject(LinearAllocBlock.class,
+                                                                          addr.addOffsetTo(smallLinearAllocBlockFieldOffset));
+      size += lab.word_size();
+
+      return size*heapWordSize;
+  }
 
    public void printOn(PrintStream tty) {
       tty.print("free-list-space");
+      tty.print("[ " + bottom() + " , " + end() + " ) ");
+      long cap = capacity();
+      long used_size = used();
+      long free_size = free();
+      int  used_perc = (int)((double)used_size/cap*100);
+      tty.print("space capacity = " + cap + " used(" + used_perc + "%)= " + used_size + " ");
+      tty.print("free= " + free_size );
+      tty.print("\n");
+
    }
 
    public Address skipBlockSizeUsingPrintezisBits(Address pos) {