0
|
1 /*
|
|
2 * Copyright 2001-2002 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 package sun.jvm.hotspot.interpreter;
|
|
26
|
|
27 import sun.jvm.hotspot.oops.*;
|
|
28 import sun.jvm.hotspot.runtime.*;
|
|
29 import sun.jvm.hotspot.utilities.*;
|
|
30
|
|
31 public class BytecodeStream {
|
|
32 private Method _method;
|
|
33
|
|
34 // reading position
|
|
35 private int _bci; // bci if current bytecode
|
|
36 private int _next_bci; // bci of next bytecode
|
|
37 private int _end_bci; // bci after the current iteration interval
|
|
38
|
|
39 // last bytecode read
|
|
40 private int _code;
|
|
41 private boolean _is_wide;
|
|
42
|
|
43 // Construction
|
|
44 public BytecodeStream(Method method) {
|
|
45 _method = method;
|
|
46 setInterval(0, (int) method.getCodeSize());
|
|
47 }
|
|
48
|
|
49 // Iteration control
|
|
50 public void setInterval(int beg_bci, int end_bci) {
|
|
51 if (Assert.ASSERTS_ENABLED) {
|
|
52 Assert.that(0 <= beg_bci && beg_bci <= _method.getCodeSize(), "illegal beg_bci");
|
|
53 Assert.that(0 <= end_bci && end_bci <= _method.getCodeSize(), "illegal end_bci");
|
|
54 }
|
|
55 // setup of iteration pointers
|
|
56 _bci = beg_bci;
|
|
57 _next_bci = beg_bci;
|
|
58 _end_bci = end_bci;
|
|
59 }
|
|
60
|
|
61 public void setStart(int beg_bci) {
|
|
62 setInterval(beg_bci, (int) _method.getCodeSize());
|
|
63 }
|
|
64
|
|
65 // Iteration
|
|
66 public int next() {
|
|
67 int code;
|
|
68 // set reading position
|
|
69 _bci = _next_bci;
|
|
70 if (isLastBytecode()) {
|
|
71 // indicate end of bytecode stream
|
|
72 code = Bytecodes._illegal;
|
|
73 } else {
|
|
74 // get bytecode
|
|
75 int rawCode = Bytecodes.codeAt(_method, _bci);
|
|
76 code = 0; // Make javac happy
|
|
77 try {
|
|
78 code = Bytecodes.javaCode(rawCode);
|
|
79 } catch (AssertionFailure e) {
|
|
80 e.printStackTrace();
|
|
81 Assert.that(false, "Failure occurred at bci " + _bci + " in method " + _method.externalNameAndSignature());
|
|
82 }
|
|
83
|
|
84 // set next bytecode position
|
|
85 //
|
|
86 int l = Bytecodes.lengthFor(code);
|
|
87 if (l == 0) l = Bytecodes.lengthAt(_method, _bci);
|
|
88 _next_bci += l;
|
|
89 if (Assert.ASSERTS_ENABLED) {
|
|
90 Assert.that(_bci < _next_bci, "length must be > 0");
|
|
91 }
|
|
92 // set attributes
|
|
93 _is_wide = false;
|
|
94 // check for special (uncommon) cases
|
|
95 if (code == Bytecodes._wide) {
|
|
96 code = _method.getBytecodeOrBPAt(_bci + 1);
|
|
97 _is_wide = true;
|
|
98 }
|
|
99 if (Assert.ASSERTS_ENABLED) {
|
|
100 Assert.that(Bytecodes.isJavaCode(code), "sanity check");
|
|
101 }
|
|
102 }
|
|
103 _code = code;
|
|
104 return _code;
|
|
105 }
|
|
106
|
|
107 // Stream attributes
|
|
108 public Method method() { return _method; }
|
|
109 public int bci() { return _bci; }
|
|
110 public int nextBCI() { return _next_bci; }
|
|
111 public int endBCI() { return _end_bci; }
|
|
112 public int code() { return _code; }
|
|
113 public boolean isWide() { return _is_wide; }
|
|
114 public boolean isActiveBreakpoint() { return Bytecodes.isActiveBreakpointAt(_method, _bci); }
|
|
115 public boolean isLastBytecode() { return _next_bci >= _end_bci; }
|
|
116
|
|
117 // State changes
|
|
118 public void setNextBCI(int bci) {
|
|
119 if (Assert.ASSERTS_ENABLED) {
|
|
120 Assert.that(0 <= bci && bci <= _method.getCodeSize(), "illegal bci");
|
|
121 }
|
|
122 _next_bci = bci;
|
|
123 }
|
|
124
|
|
125 // Bytecode-specific attributes
|
|
126 public int dest() { return bci() + _method.getBytecodeShortArg(bci() + 1); }
|
|
127 public int dest_w() { return bci() + _method.getBytecodeIntArg(bci() + 1); }
|
|
128
|
|
129 // Unsigned indices, widening
|
|
130 public int getIndex() { return (isWide())
|
|
131 ? (_method.getBytecodeShortArg(bci() + 2) & 0xFFFF)
|
|
132 : (_method.getBytecodeOrBPAt(bci() + 1) & 0xFF); }
|
|
133 public int getIndexBig() { return _method.getBytecodeShortArg(bci() + 1); }
|
|
134
|
|
135 // Fetch at absolute BCI (for manual parsing of certain bytecodes)
|
|
136 public int codeAt(int bci) {
|
|
137 return _method.getBytecodeOrBPAt(bci);
|
|
138 }
|
|
139 }
|