1 /*
2  * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
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.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 
MultiBranchData(DataLayout layout)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 
numberOfCases()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 
defaultCount()61   int defaultCount() {
62     return arrayUintAt(defaultCountOffSet);
63   }
defaultDisplacement()64   int defaultDisplacement() {
65     return arrayIntAt(defaultDisaplacementOffSet);
66   }
67 
countAt(int index)68   int countAt(int index) {
69     return arrayUintAt(caseArrayStart +
70                          index * perCaseCellCount +
71                          relativeCountOffSet);
72   }
displacementAt(int index)73   int displacementAt(int index) {
74     return arrayIntAt(caseArrayStart +
75                         index * perCaseCellCount +
76                         relativeDisplacementOffSet);
77   }
78 
79   // Code generation support
defaultCountOffset()80   static int defaultCountOffset() {
81     return arrayElementOffset(defaultCountOffSet);
82   }
defaultDisplacementOffset()83   static int defaultDisplacementOffset() {
84     return arrayElementOffset(defaultDisaplacementOffSet);
85   }
caseCountOffset(int index)86   static int caseCountOffset(int index) {
87     return caseArrayOffset() +
88       (perCaseSize() * index) +
89       relativeCountOffset();
90   }
caseArrayOffset()91   static int caseArrayOffset() {
92     return arrayElementOffset(caseArrayStart);
93   }
perCaseSize()94   static int perCaseSize() {
95     return (perCaseCellCount) * MethodData.cellSize;
96   }
relativeCountOffset()97   static int relativeCountOffset() {
98     return (relativeCountOffSet) * MethodData.cellSize;
99   }
relativeDisplacementOffset()100   static int relativeDisplacementOffset() {
101     return (relativeDisplacementOffSet) * MethodData.cellSize;
102   }
103 
printDataOn(PrintStream st)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 }
114