content: package sun.jvm.hotspot.oops;
  
  import java.io.ByteArrayOutputStream;
  import java.io.PrintStream;
  
  import sun.jvm.hotspot.gc_implementation.parallelScavenge.PSOldGen;
  import sun.jvm.hotspot.gc_implementation.parallelScavenge.PSPermGen;
  import sun.jvm.hotspot.gc_implementation.parallelScavenge.PSYoungGen;
  import sun.jvm.hotspot.gc_implementation.parallelScavenge.ParallelScavengeHeap;
  import sun.jvm.hotspot.gc_interface.CollectedHeap;
  import sun.jvm.hotspot.memory.DefNewGeneration;
  import sun.jvm.hotspot.memory.GenCollectedHeap;
  import sun.jvm.hotspot.memory.Generation;
  import sun.jvm.hotspot.runtime.VM;
  
  public class TBObjectHistogramElement {
      private Klass klass;
      private long count; // Number of instances of klass
      private long size; // Total size of all these instances
      private long edenCount; // Number of instances of klass in eden
      private long edenSize; // Total size of all instances in eden
      private long survivorCount; // ditto in survivor
      private long survivorSize; // ditto in survivor
      private long oldCount; // ditto in old generation
      private long oldSize; // ditto in old generation
      private long permCount; // ditto in permanent generation
      private long permSize; // ditto in permanent generation
      private final static int Unknown = 0;
      private final static int InEden = 1;
      private final static int InSurvivor = 2;
      private final static int InOld = 3;
      private final static int InPerm = 4;
  
      public TBObjectHistogramElement(Klass k) {
          klass = k;
      }
  
      public void updateWith(Oop obj) {
          long objSize = obj.getObjectSize();
          count += 1;
          size += objSize;
          int result = getLocation(obj);
          switch (result) {
              case Unknown:
                  break;
              case InEden:
                  edenCount += 1;
                  edenSize += objSize;
                  break;
              case InSurvivor:
                  survivorCount += 1;
                  survivorSize += objSize;
                  break;
              case InOld:
                  oldCount += 1;
                  oldSize += objSize;
                  break;
              case InPerm:
                  permCount += 1;
                  permSize += objSize;
                  break;
              default:
                  break;
          }
      }
  
      public int compare(TBObjectHistogramElement other) {
          return (int) (other.size - size);
      }
  
      /**
       * Klass for this ObjectHistogramElement
       */
      public Klass getKlass() {
          return klass;
      }
  
      /**
       * Number of instances of klass
       */
      public long getCount() {
          return count;
      }
  
      /**
       * Total size of all these instances
       */
      public long getSize() {
          return size;
      }
  
      /**
       * Number of old instances of klass
       */
      public long getOldCount() {
          return oldCount;
      }
  
      /**
       * Total size of all old instances
       */
      public long getOldSize() {
          return oldSize;
      }
  
      /**
       * Number of perm instances of klass
       */
      public long getPermCount() {
          return permCount;
      }
  
      /**
       * Total size of all perm instances
       */
      public long getPermSize() {
          return permSize;
      }
  
      private String getInternalName(Klass k) {
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          getKlass().printValueOn(new PrintStream(bos));
          // '*' is used to denote VM internal klasses.
          return "* " + bos.toString();
      }
  
      /**
       * Human readable description *
       */
      public String getDescription() {
          Klass k = getKlass();
          if (k instanceof InstanceKlass) {
              return k.getName().asString().replace('/', '.');
          } else if (k instanceof ArrayKlass) {
              ArrayKlass ak = (ArrayKlass) k;
              if (k instanceof TypeArrayKlass) {
                  TypeArrayKlass tak = (TypeArrayKlass) ak;
                  return tak.getElementTypeName() + "[]";
              } else if (k instanceof ObjArrayKlass) {
                  ObjArrayKlass oak = (ObjArrayKlass) ak;
                  // See whether it's a "system objArray"
                  if (oak.equals(VM.getVM().getUniverse().systemObjArrayKlassObj())) {
                      return "* System ObjArray";
                  }
                  Klass bottom = oak.getBottomKlass();
                  int dim = (int) oak.getDimension();
                  StringBuffer buf = new StringBuffer();
                  if (bottom instanceof TypeArrayKlass) {
                      buf.append(((TypeArrayKlass) bottom).getElementTypeName());
                  } else if (bottom instanceof InstanceKlass) {
                      buf.append(bottom.getName().asString().replace('/', '.'));
                  } else {
                      throw new RuntimeException("should not reach here");
                  }
                  for (int i = 0; i < dim; i++) {
                      buf.append("[]");
                  }
                  return buf.toString();
              }
          }
          return getInternalName(k);
      }
  
      public static void titleOn(PrintStream tty) {
          tty.println("Object Histogram:");
          tty.println();
          tty.println("#num" + "\t" + "#all instances/bytes" + "\t"
                  + "#eden instances/bytes" + "\t" + "#survivor instances/bytes" + "\t" + "#old instances/bytes"
                  + "\t" + "#perm instances/bytes" + "\t" + "#Class description");
          tty.println("-----------------------------------------------------------------------------------");
      }
  
      public static void titleOnOld(PrintStream tty) {
          tty.println("Old Object Histogram:");
          tty.println();
          tty.println("#num" + "\t" + "#all instances/bytes" + "\t"
                  + "#old instances/bytes" + "\t" + "#Class description");
          tty.println("-----------------------------------------------------------------------------------");
      }
  
      public static void titleOnPerm(PrintStream tty) {
          tty.println("Perm Object Histogram:");
          tty.println();
          tty.println("#num" + "\t" + "#all instances/bytes" + "\t"
                  + "#Perm instances/bytes" + "\t" + "#Class description");
          tty.println("-----------------------------------------------------------------------------------");
      }
  
      public void printOn(PrintStream tty) {
          tty.print(count + "/" + size + "\t");
          tty.print(edenCount + "/" + edenSize + "\t" + survivorCount + "/" + survivorSize + "\t" + oldCount + "/"
                  + oldSize + "\t" + permCount + "/" + permSize + "\t");
          tty.print(getDescription());
          tty.println();
      }
  
      public void printOnOld(PrintStream tty) {
          tty.print(count + "/" + size + "\t");
          tty.print(oldCount + "/" + oldSize + "\t");
          tty.print(getDescription());
          tty.println();
      }
  
      public void printOnPerm(PrintStream tty) {
          tty.print(count + "/" + size + "\t");
          tty.print(permCount + "/" + permSize + "\t");
          tty.print(getDescription());
          tty.println();
      }
  
      private static int getLocation(Oop obj) {
          if (obj == null)
              return Unknown;
          CollectedHeap heap = VM.getVM().getUniverse().heap();
          if (heap instanceof GenCollectedHeap) {
              DefNewGeneration gen0 = (DefNewGeneration) ((GenCollectedHeap) heap).getGen(0);
              if (gen0.eden().contains(obj.getHandle())) {
                  return InEden;
              } else if (gen0.from().contains(obj.getHandle())) {
                  return InSurvivor;
              }
              Generation gen1 = ((GenCollectedHeap) heap).getGen(1);
              if (gen1.isIn(obj.getHandle())) {
                  return InOld;
              }
              Generation permGen = ((GenCollectedHeap) heap).permGen();
              if (permGen.isIn(obj.getHandle())) {
                  return InPerm;
              }
          } else if (heap instanceof ParallelScavengeHeap) {
              PSYoungGen youngGen = ((ParallelScavengeHeap) heap).youngGen();
              if (youngGen.edenSpace().contains(obj.getHandle())) {
                  return InEden;
              } else if (youngGen.fromSpace().contains(obj.getHandle())) {
                  return InSurvivor;
              }
              PSOldGen oldGen = ((ParallelScavengeHeap) heap).oldGen();
              if (oldGen.isIn(obj.getHandle())) {
                  return InOld;
              }
              PSPermGen permGen = ((ParallelScavengeHeap) heap).permGen();
              if (permGen.isIn(obj.getHandle())) {
                  return InPerm;
              }
          }
          return Unknown;
      }
  }
  