|
1 /* |
|
2 * Copyright 1999-2005 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 // ciBytecodeStream |
|
26 // |
|
27 // The class is used to iterate over the bytecodes of a method. |
|
28 // It hides the details of constant pool structure/access by |
|
29 // providing accessors for constant pool items. It returns only pure |
|
30 // Java bytecodes; VM-internal _fast bytecodes are translated back to |
|
31 // their original form during iteration. |
|
32 class ciBytecodeStream : StackObj { |
|
33 private: |
|
34 // Handling for the weird bytecodes |
|
35 Bytecodes::Code wide(); // Handle wide bytecode |
|
36 Bytecodes::Code table(Bytecodes::Code); // Handle complicated inline table |
|
37 |
|
38 static Bytecodes::Code check_java(Bytecodes::Code c) { |
|
39 assert(Bytecodes::is_java_code(c), "should not return _fast bytecodes"); |
|
40 return c; |
|
41 } |
|
42 |
|
43 ciMethod* _method; // the method |
|
44 ciInstanceKlass* _holder; |
|
45 address _bc_start; // Start of current bytecode for table |
|
46 address _was_wide; // Address past last wide bytecode |
|
47 jint* _table_base; // Aligned start of last table or switch |
|
48 |
|
49 address _start; // Start of bytecodes |
|
50 address _end; // Past end of bytecodes |
|
51 address _pc; // Current PC |
|
52 Bytecodes::Code _bc; // Current bytecode |
|
53 |
|
54 void reset( address base, unsigned int size ) { |
|
55 _bc_start =_was_wide = 0; |
|
56 _start = _pc = base; _end = base + size; } |
|
57 |
|
58 public: |
|
59 // End-Of-Bytecodes |
|
60 static Bytecodes::Code EOBC() { |
|
61 return Bytecodes::_illegal; |
|
62 } |
|
63 |
|
64 ciBytecodeStream(ciMethod* m) { |
|
65 reset_to_method(m); |
|
66 } |
|
67 |
|
68 ciBytecodeStream() { |
|
69 reset_to_method(NULL); |
|
70 } |
|
71 |
|
72 ciMethod* method() const { return _method; } |
|
73 |
|
74 void reset_to_method(ciMethod* m) { |
|
75 _method = m; |
|
76 if (m == NULL) { |
|
77 _holder = NULL; |
|
78 reset(NULL, 0); |
|
79 } else { |
|
80 _holder = m->holder(); |
|
81 reset(m->code(), m->code_size()); |
|
82 } |
|
83 } |
|
84 |
|
85 void reset_to_bci( int bci ); |
|
86 |
|
87 // Force the iterator to report a certain bci. |
|
88 void force_bci(int bci); |
|
89 |
|
90 void set_max_bci( int max ) { |
|
91 _end = _start + max; |
|
92 } |
|
93 |
|
94 address cur_bcp() { return _bc_start; } // Returns bcp to current instruction |
|
95 int next_bci() const { return _pc -_start; } |
|
96 int cur_bci() const { return _bc_start - _start; } |
|
97 |
|
98 Bytecodes::Code cur_bc() const{ return check_java(_bc); } |
|
99 Bytecodes::Code next_bc() { return Bytecodes::java_code((Bytecodes::Code)* _pc); } |
|
100 |
|
101 // Return current ByteCode and increment PC to next bytecode, skipping all |
|
102 // intermediate constants. Returns EOBC at end. |
|
103 // Expected usage: |
|
104 // while( (bc = iter.next()) != EOBC() ) { ... } |
|
105 Bytecodes::Code next() { |
|
106 _bc_start = _pc; // Capture start of bc |
|
107 if( _pc >= _end ) return EOBC(); // End-Of-Bytecodes |
|
108 |
|
109 // Fetch Java bytecode |
|
110 // All rewritten bytecodes maintain the size of original bytecode. |
|
111 _bc = Bytecodes::java_code((Bytecodes::Code)*_pc); |
|
112 int csize = Bytecodes::length_for(_bc); // Expected size |
|
113 |
|
114 if( _bc == Bytecodes::_wide ) { |
|
115 _bc=wide(); // Handle wide bytecode |
|
116 } else if( csize == 0 ) { |
|
117 _bc=table(_bc); // Handle inline tables |
|
118 } else { |
|
119 _pc += csize; // Bump PC past bytecode |
|
120 } |
|
121 return check_java(_bc); |
|
122 } |
|
123 |
|
124 bool is_wide() { return ( _pc == _was_wide ); } |
|
125 |
|
126 // Get a byte index following this bytecode. |
|
127 // If prefixed with a wide bytecode, get a wide index. |
|
128 int get_index() const { |
|
129 return (_pc == _was_wide) // was widened? |
|
130 ? Bytes::get_Java_u2(_bc_start+2) // yes, return wide index |
|
131 : _bc_start[1]; // no, return narrow index |
|
132 } |
|
133 |
|
134 // Set a byte index following this bytecode. |
|
135 // If prefixed with a wide bytecode, get a wide index. |
|
136 void put_index(int idx) { |
|
137 if (_pc == _was_wide) // was widened? |
|
138 Bytes::put_Java_u2(_bc_start+2,idx); // yes, set wide index |
|
139 else |
|
140 _bc_start[1]=idx; // no, set narrow index |
|
141 } |
|
142 |
|
143 // Get 2-byte index (getfield/putstatic/etc) |
|
144 int get_index_big() const { return Bytes::get_Java_u2(_bc_start+1); } |
|
145 |
|
146 // Get dimensions byte (multinewarray) |
|
147 int get_dimensions() const { return *(unsigned char*)(_pc-1); } |
|
148 |
|
149 // Get unsigned index fast |
|
150 int get_index_fast() const { return Bytes::get_native_u2(_pc-2); } |
|
151 |
|
152 // Sign-extended index byte/short, no widening |
|
153 int get_byte() const { return (int8_t)(_pc[-1]); } |
|
154 int get_short() const { return (int16_t)Bytes::get_Java_u2(_pc-2); } |
|
155 int get_long() const { return (int32_t)Bytes::get_Java_u4(_pc-4); } |
|
156 |
|
157 // Get a byte signed constant for "iinc". Invalid for other bytecodes. |
|
158 // If prefixed with a wide bytecode, get a wide constant |
|
159 int get_iinc_con() const {return (_pc==_was_wide) ? get_short() :get_byte();} |
|
160 |
|
161 // 2-byte branch offset from current pc |
|
162 int get_dest( ) const { |
|
163 assert( Bytecodes::length_at(_bc_start) == sizeof(jshort)+1, "get_dest called with bad bytecode" ); |
|
164 return _bc_start-_start + (short)Bytes::get_Java_u2(_pc-2); |
|
165 } |
|
166 |
|
167 // 2-byte branch offset from next pc |
|
168 int next_get_dest( ) const { |
|
169 address next_bc_start = _pc; |
|
170 assert( _pc < _end, "" ); |
|
171 Bytecodes::Code next_bc = (Bytecodes::Code)*_pc; |
|
172 assert( next_bc != Bytecodes::_wide, ""); |
|
173 int next_csize = Bytecodes::length_for(next_bc); |
|
174 assert( next_csize != 0, "" ); |
|
175 assert( next_bc <= Bytecodes::_jsr_w, ""); |
|
176 address next_pc = _pc + next_csize; |
|
177 assert( Bytecodes::length_at(next_bc_start) == sizeof(jshort)+1, "next_get_dest called with bad bytecode" ); |
|
178 return next_bc_start-_start + (short)Bytes::get_Java_u2(next_pc-2); |
|
179 } |
|
180 |
|
181 // 4-byte branch offset from current pc |
|
182 int get_far_dest( ) const { |
|
183 assert( Bytecodes::length_at(_bc_start) == sizeof(jint)+1, "dest4 called with bad bytecode" ); |
|
184 return _bc_start-_start + (int)Bytes::get_Java_u4(_pc-4); |
|
185 } |
|
186 |
|
187 // For a lookup or switch table, return target destination |
|
188 int get_int_table( int index ) const { |
|
189 return Bytes::get_Java_u4((address)&_table_base[index]); } |
|
190 |
|
191 // For tableswitch - get length of offset part |
|
192 int get_tableswitch_length() { return get_int_table(2)-get_int_table(1)+1; } |
|
193 |
|
194 int get_dest_table( int index ) const { |
|
195 return cur_bci() + get_int_table(index); } |
|
196 |
|
197 // --- Constant pool access --- |
|
198 int get_constant_index() const; |
|
199 int get_field_index(); |
|
200 int get_method_index(); |
|
201 |
|
202 // If this bytecode is a new, newarray, multianewarray, instanceof, |
|
203 // or checkcast, get the referenced klass. |
|
204 ciKlass* get_klass(bool& will_link); |
|
205 int get_klass_index() const; |
|
206 |
|
207 // If this bytecode is one of the ldc variants, get the referenced |
|
208 // constant |
|
209 ciConstant get_constant(); |
|
210 // True if the ldc variant points to an unresolved string |
|
211 bool is_unresolved_string() const; |
|
212 // True if the ldc variant points to an unresolved klass |
|
213 bool is_unresolved_klass() const; |
|
214 |
|
215 // If this bytecode is one of get_field, get_static, put_field, |
|
216 // or put_static, get the referenced field. |
|
217 ciField* get_field(bool& will_link); |
|
218 |
|
219 ciInstanceKlass* get_declared_field_holder(); |
|
220 int get_field_holder_index(); |
|
221 int get_field_signature_index(); |
|
222 |
|
223 // If this is a method invocation bytecode, get the invoked method. |
|
224 ciMethod* get_method(bool& will_link); |
|
225 ciKlass* get_declared_method_holder(); |
|
226 int get_method_holder_index(); |
|
227 int get_method_signature_index(); |
|
228 }; |
|
229 |
|
230 |
|
231 // ciSignatureStream |
|
232 // |
|
233 // The class is used to iterate over the elements of a method signature. |
|
234 class ciSignatureStream : public StackObj { |
|
235 private: |
|
236 ciSignature* _sig; |
|
237 int _pos; |
|
238 public: |
|
239 ciSignatureStream(ciSignature* signature) { |
|
240 _sig = signature; |
|
241 _pos = 0; |
|
242 } |
|
243 |
|
244 bool at_return_type() { return _pos == _sig->count(); } |
|
245 |
|
246 bool is_done() { return _pos > _sig->count(); } |
|
247 |
|
248 void next() { |
|
249 if (_pos <= _sig->count()) { |
|
250 _pos++; |
|
251 } |
|
252 } |
|
253 |
|
254 ciType* type() { |
|
255 if (at_return_type()) { |
|
256 return _sig->return_type(); |
|
257 } else { |
|
258 return _sig->type_at(_pos); |
|
259 } |
|
260 } |
|
261 }; |
|
262 |
|
263 |
|
264 // ciExceptionHandlerStream |
|
265 // |
|
266 // The class is used to iterate over the exception handlers of |
|
267 // a method. |
|
268 class ciExceptionHandlerStream : public StackObj { |
|
269 private: |
|
270 // The method whose handlers we are traversing |
|
271 ciMethod* _method; |
|
272 |
|
273 // Our current position in the list of handlers |
|
274 int _pos; |
|
275 int _end; |
|
276 |
|
277 ciInstanceKlass* _exception_klass; |
|
278 int _bci; |
|
279 bool _is_exact; |
|
280 |
|
281 public: |
|
282 ciExceptionHandlerStream(ciMethod* method) { |
|
283 _method = method; |
|
284 |
|
285 // Force loading of method code and handlers. |
|
286 _method->code(); |
|
287 |
|
288 _pos = 0; |
|
289 _end = _method->_handler_count; |
|
290 _exception_klass = NULL; |
|
291 _bci = -1; |
|
292 _is_exact = false; |
|
293 } |
|
294 |
|
295 ciExceptionHandlerStream(ciMethod* method, int bci, |
|
296 ciInstanceKlass* exception_klass = NULL, |
|
297 bool is_exact = false) { |
|
298 _method = method; |
|
299 |
|
300 // Force loading of method code and handlers. |
|
301 _method->code(); |
|
302 |
|
303 _pos = -1; |
|
304 _end = _method->_handler_count + 1; // include the rethrow handler |
|
305 _exception_klass = (exception_klass != NULL && exception_klass->is_loaded() |
|
306 ? exception_klass |
|
307 : NULL); |
|
308 _bci = bci; |
|
309 assert(_bci >= 0, "bci out of range"); |
|
310 _is_exact = is_exact; |
|
311 next(); |
|
312 } |
|
313 |
|
314 // These methods are currently implemented in an odd way. |
|
315 // Count the number of handlers the iterator has ever produced |
|
316 // or will ever produce. Do not include the final rethrow handler. |
|
317 // That is, a trivial exception handler stream will have a count |
|
318 // of zero and produce just the rethrow handler. |
|
319 int count(); |
|
320 |
|
321 // Count the number of handlers this stream will produce from now on. |
|
322 // Include the current handler, and the final rethrow handler. |
|
323 // The remaining count will be zero iff is_done() is true, |
|
324 int count_remaining(); |
|
325 |
|
326 bool is_done() { |
|
327 return (_pos >= _end); |
|
328 } |
|
329 |
|
330 void next() { |
|
331 _pos++; |
|
332 if (_bci != -1) { |
|
333 // We are not iterating over all handlers... |
|
334 while (!is_done()) { |
|
335 ciExceptionHandler* handler = _method->_exception_handlers[_pos]; |
|
336 if (handler->is_in_range(_bci)) { |
|
337 if (handler->is_catch_all()) { |
|
338 // Found final active catch block. |
|
339 _end = _pos+1; |
|
340 return; |
|
341 } else if (_exception_klass == NULL || !handler->catch_klass()->is_loaded()) { |
|
342 // We cannot do any type analysis here. Must conservatively assume |
|
343 // catch block is reachable. |
|
344 return; |
|
345 } else if (_exception_klass->is_subtype_of(handler->catch_klass())) { |
|
346 // This catch clause will definitely catch the exception. |
|
347 // Final candidate. |
|
348 _end = _pos+1; |
|
349 return; |
|
350 } else if (!_is_exact && |
|
351 handler->catch_klass()->is_subtype_of(_exception_klass)) { |
|
352 // This catch block may be reachable. |
|
353 return; |
|
354 } |
|
355 } |
|
356 |
|
357 // The catch block was not pertinent. Go on. |
|
358 _pos++; |
|
359 } |
|
360 } else { |
|
361 // This is an iteration over all handlers. |
|
362 return; |
|
363 } |
|
364 } |
|
365 |
|
366 ciExceptionHandler* handler() { |
|
367 return _method->_exception_handlers[_pos]; |
|
368 } |
|
369 }; |