1 /*
   2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
   3  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
   4  *
   5  *
   6  *
   7  *
   8  *
   9  *
  10  *
  11  *
  12  *
  13  *
  14  *
  15  *
  16  *
  17  *
  18  *
  19  *
  20  *
  21  *
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.oops;
  26 
  27 import java.io.*;
  28 import java.util.*;
  29 import sun.jvm.hotspot.debugger.*;
  30 import sun.jvm.hotspot.runtime.*;
  31 import sun.jvm.hotspot.types.*;
  32 import sun.jvm.hotspot.utilities.*;
  33 
  34 // MultiBranchData
  35 //
  36 // A MultiBranchData is used to access profiling information for
  37 // a multi-way branch (*switch bytecodes).  It consists of a series
  38 // of (count, displacement) pairs, which count the number of times each
  39 // case was taken and specify the data displacment for each branch target.
  40 public class MultiBranchData extends ArrayData {
  41   static final int   defaultCountOffSet = 0;
  42   static final int     defaultDisaplacementOffSet = 1;
  43   static final int     caseArrayStart = 2;
  44   static final int   relativeCountOffSet = 0;
  45   static final int     relativeDisplacementOffSet = 1;
  46   static final int     perCaseCellCount = 2;
  47 
  48   public MultiBranchData(DataLayout layout) {
  49     super(layout);
  50     //assert(layout.tag() == DataLayout.multiBranchDataTag, "wrong type");
  51   }
  52 
  53   // static int computeCellCount(BytecodeStream stream);
  54 
  55   int numberOfCases() {
  56     int alen = arrayLen() - 2; // get rid of default case here.
  57     //assert(alen % perCaseCellCount == 0, "must be even");
  58     return (alen / perCaseCellCount);
  59   }
  60 
  61   int defaultCount() {
  62     return arrayUintAt(defaultCountOffSet);
  63   }
  64   int defaultDisplacement() {
  65     return arrayIntAt(defaultDisaplacementOffSet);
  66   }
  67 
  68   int countAt(int index) {
  69     return arrayUintAt(caseArrayStart +
  70                          index * perCaseCellCount +
  71                          relativeCountOffSet);
  72   }
  73   int displacementAt(int index) {
  74     return arrayIntAt(caseArrayStart +
  75                         index * perCaseCellCount +
  76                         relativeDisplacementOffSet);
  77   }
  78 
  79   // Code generation support
  80   static int defaultCountOffset() {
  81     return arrayElementOffset(defaultCountOffSet);
  82   }
  83   static int defaultDisplacementOffset() {
  84     return arrayElementOffset(defaultDisaplacementOffSet);
  85   }
  86   static int caseCountOffset(int index) {
  87     return caseArrayOffset() +
  88       (perCaseSize() * index) +
  89       relativeCountOffset();
  90   }
  91   static int caseArrayOffset() {
  92     return arrayElementOffset(caseArrayStart);
  93   }
  94   static int perCaseSize() {
  95     return (perCaseCellCount) * MethodData.cellSize;
  96   }
  97   static int relativeCountOffset() {
  98     return (relativeCountOffSet) * MethodData.cellSize;
  99   }
 100   static int relativeDisplacementOffset() {
 101     return (relativeDisplacementOffSet) * MethodData.cellSize;
 102   }
 103 
 104   public void printDataOn(PrintStream st) {
 105     printShared(st, "MultiBranchData");
 106     st.println("default_count(" + defaultCount() + ") displacement(" + defaultDisplacement() + ")");
 107     int cases = numberOfCases();
 108     for (int i = 0; i < cases; i++) {
 109       tab(st);
 110       st.println("count(" + countAt(i) + ") displacement(" + displacementAt(i) + ")");
 111     }
 112   }
 113 }