Mercurial > hg > truffle
annotate src/share/vm/interpreter/bytecodeStream.hpp @ 4181:319860ae697a
Simplify FrameMap: make offsets of spill slots and outgoing parameters independent so that they can be allocated at the same time, eliminating the separate phases. This makes the separate StackBlock unnecesary. Change CiStackSlot to use byte offsets instead of spill slot index. This makes CiTarget.spillSlotSize unnecessary.
author | Christian Wimmer <Christian.Wimmer@Oracle.com> |
---|---|
date | Mon, 02 Jan 2012 14:16:08 -0800 |
parents | b92c45f2bc75 |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
2142 | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
844
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_INTERPRETER_BYTECODESTREAM_HPP |
26 #define SHARE_VM_INTERPRETER_BYTECODESTREAM_HPP | |
27 | |
28 #include "interpreter/bytecode.hpp" | |
29 #include "memory/allocation.hpp" | |
30 #include "oops/methodOop.hpp" | |
31 #ifdef TARGET_ARCH_x86 | |
32 # include "bytes_x86.hpp" | |
33 #endif | |
34 #ifdef TARGET_ARCH_sparc | |
35 # include "bytes_sparc.hpp" | |
36 #endif | |
37 #ifdef TARGET_ARCH_zero | |
38 # include "bytes_zero.hpp" | |
39 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
40 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
41 # include "bytes_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
42 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
43 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
44 # include "bytes_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
45 #endif |
1972 | 46 |
0 | 47 // A BytecodeStream is used for fast iteration over the bytecodes |
48 // of a methodOop. | |
49 // | |
50 // Usage: | |
51 // | |
52 // BytecodeStream s(method); | |
53 // Bytecodes::Code c; | |
54 // while ((c = s.next()) >= 0) { | |
55 // ... | |
56 // } | |
1565 | 57 |
0 | 58 // A RawBytecodeStream is a simple version of BytecodeStream. |
59 // It is used ONLY when we know the bytecodes haven't been rewritten | |
1565 | 60 // yet, such as in the rewriter or the verifier. |
0 | 61 |
1565 | 62 // Here is the common base class for both RawBytecodeStream and BytecodeStream: |
63 class BaseBytecodeStream: StackObj { | |
0 | 64 protected: |
65 // stream buffer | |
66 methodHandle _method; // read from method directly | |
67 | |
68 // reading position | |
69 int _bci; // bci if current bytecode | |
70 int _next_bci; // bci of next bytecode | |
71 int _end_bci; // bci after the current iteration interval | |
72 | |
73 // last bytecode read | |
1565 | 74 Bytecodes::Code _raw_code; |
0 | 75 bool _is_wide; |
1565 | 76 bool _is_raw; // false in 'cooked' BytecodeStream |
77 | |
78 // Construction | |
79 BaseBytecodeStream(methodHandle method) : _method(method) { | |
80 set_interval(0, _method->code_size()); | |
81 _is_raw = false; | |
82 } | |
0 | 83 |
84 public: | |
85 // Iteration control | |
86 void set_interval(int beg_bci, int end_bci) { | |
87 // iterate over the interval [beg_bci, end_bci) | |
88 assert(0 <= beg_bci && beg_bci <= method()->code_size(), "illegal beg_bci"); | |
89 assert(0 <= end_bci && end_bci <= method()->code_size(), "illegal end_bci"); | |
90 // setup of iteration pointers | |
91 _bci = beg_bci; | |
92 _next_bci = beg_bci; | |
93 _end_bci = end_bci; | |
94 } | |
95 void set_start (int beg_bci) { | |
96 set_interval(beg_bci, _method->code_size()); | |
97 } | |
98 | |
1565 | 99 bool is_raw() const { return _is_raw; } |
100 | |
101 // Stream attributes | |
102 methodHandle method() const { return _method; } | |
103 | |
104 int bci() const { return _bci; } | |
105 int next_bci() const { return _next_bci; } | |
106 int end_bci() const { return _end_bci; } | |
107 | |
108 Bytecodes::Code raw_code() const { return _raw_code; } | |
109 bool is_wide() const { return _is_wide; } | |
110 int instruction_size() const { return (_next_bci - _bci); } | |
111 bool is_last_bytecode() const { return _next_bci >= _end_bci; } | |
112 | |
113 address bcp() const { return method()->code_base() + _bci; } | |
2142 | 114 Bytecode bytecode() const { return Bytecode(_method(), bcp()); } |
1565 | 115 |
116 // State changes | |
117 void set_next_bci(int bci) { assert(0 <= bci && bci <= method()->code_size(), "illegal bci"); _next_bci = bci; } | |
118 | |
119 // Bytecode-specific attributes | |
2142 | 120 int dest() const { return bci() + bytecode().get_offset_s2(raw_code()); } |
121 int dest_w() const { return bci() + bytecode().get_offset_s4(raw_code()); } | |
1565 | 122 |
123 // One-byte indices. | |
124 int get_index_u1() const { assert_raw_index_size(1); return *(jubyte*)(bcp()+1); } | |
125 | |
126 protected: | |
127 void assert_raw_index_size(int size) const NOT_DEBUG_RETURN; | |
128 void assert_raw_stream(bool want_raw) const NOT_DEBUG_RETURN; | |
129 }; | |
130 | |
131 class RawBytecodeStream: public BaseBytecodeStream { | |
132 public: | |
133 // Construction | |
134 RawBytecodeStream(methodHandle method) : BaseBytecodeStream(method) { | |
135 _is_raw = true; | |
136 } | |
137 | |
138 public: | |
0 | 139 // Iteration |
140 // Use raw_next() rather than next() for faster method reference | |
141 Bytecodes::Code raw_next() { | |
142 Bytecodes::Code code; | |
143 // set reading position | |
144 _bci = _next_bci; | |
145 assert(!is_last_bytecode(), "caller should check is_last_bytecode()"); | |
146 | |
1565 | 147 address bcp = this->bcp(); |
0 | 148 code = Bytecodes::code_or_bp_at(bcp); |
149 | |
150 // set next bytecode position | |
151 int l = Bytecodes::length_for(code); | |
152 if (l > 0 && (_bci + l) <= _end_bci) { | |
153 assert(code != Bytecodes::_wide && code != Bytecodes::_tableswitch | |
154 && code != Bytecodes::_lookupswitch, "can't be special bytecode"); | |
155 _is_wide = false; | |
156 _next_bci += l; | |
1565 | 157 _raw_code = code; |
0 | 158 return code; |
159 } else { | |
160 return raw_next_special(code); | |
161 } | |
162 } | |
163 Bytecodes::Code raw_next_special(Bytecodes::Code code); | |
164 | |
1565 | 165 // Unsigned indices, widening, with no swapping of bytes |
166 int get_index() const { return (is_wide()) ? get_index_u2_raw(bcp() + 2) : get_index_u1(); } | |
167 // Get an unsigned 2-byte index, with no swapping of bytes. | |
168 int get_index_u2() const { assert(!is_wide(), ""); return get_index_u2_raw(bcp() + 1); } | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
169 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
170 private: |
1565 | 171 int get_index_u2_raw(address p) const { |
172 assert_raw_index_size(2); assert_raw_stream(true); | |
173 return Bytes::get_Java_u2(p); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
174 } |
0 | 175 }; |
176 | |
177 // In BytecodeStream, non-java bytecodes will be translated into the | |
178 // corresponding java bytecodes. | |
179 | |
1565 | 180 class BytecodeStream: public BaseBytecodeStream { |
181 Bytecodes::Code _code; | |
182 | |
0 | 183 public: |
184 // Construction | |
1565 | 185 BytecodeStream(methodHandle method) : BaseBytecodeStream(method) { } |
0 | 186 |
187 // Iteration | |
188 Bytecodes::Code next() { | |
1565 | 189 Bytecodes::Code raw_code, code; |
0 | 190 // set reading position |
191 _bci = _next_bci; | |
192 if (is_last_bytecode()) { | |
193 // indicate end of bytecode stream | |
1565 | 194 raw_code = code = Bytecodes::_illegal; |
0 | 195 } else { |
196 // get bytecode | |
1565 | 197 address bcp = this->bcp(); |
2142 | 198 raw_code = Bytecodes::code_at(_method(), bcp); |
1565 | 199 code = Bytecodes::java_code(raw_code); |
0 | 200 // set next bytecode position |
201 // | |
202 // note that we cannot advance before having the | |
203 // tty bytecode otherwise the stepping is wrong! | |
204 // (carefull: length_for(...) must be used first!) | |
205 int l = Bytecodes::length_for(code); | |
2142 | 206 if (l == 0) l = Bytecodes::length_at(_method(), bcp); |
0 | 207 _next_bci += l; |
208 assert(_bci < _next_bci, "length must be > 0"); | |
209 // set attributes | |
210 _is_wide = false; | |
211 // check for special (uncommon) cases | |
212 if (code == Bytecodes::_wide) { | |
1565 | 213 raw_code = (Bytecodes::Code)bcp[1]; |
214 code = raw_code; // wide BCs are always Java-normal | |
0 | 215 _is_wide = true; |
216 } | |
217 assert(Bytecodes::is_java_code(code), "sanity check"); | |
218 } | |
1565 | 219 _raw_code = raw_code; |
0 | 220 _code = code; |
221 return _code; | |
222 } | |
223 | |
224 bool is_active_breakpoint() const { return Bytecodes::is_active_breakpoint_at(bcp()); } | |
1565 | 225 Bytecodes::Code code() const { return _code; } |
226 | |
227 // Unsigned indices, widening | |
2142 | 228 int get_index() const { return is_wide() ? bytecode().get_index_u2(raw_code(), true) : get_index_u1(); } |
1565 | 229 // Get an unsigned 2-byte index, swapping the bytes if necessary. |
230 int get_index_u2() const { assert_raw_stream(false); | |
2142 | 231 return bytecode().get_index_u2(raw_code(), false); } |
1565 | 232 // Get an unsigned 2-byte index in native order. |
233 int get_index_u2_cpcache() const { assert_raw_stream(false); | |
2142 | 234 return bytecode().get_index_u2_cpcache(raw_code()); } |
1565 | 235 int get_index_u4() const { assert_raw_stream(false); |
2142 | 236 return bytecode().get_index_u4(raw_code()); } |
237 bool has_index_u4() const { return bytecode().has_index_u4(raw_code()); } | |
0 | 238 }; |
1972 | 239 |
240 #endif // SHARE_VM_INTERPRETER_BYTECODESTREAM_HPP |