Mercurial > hg > truffle
annotate src/share/vm/ci/ciStreams.hpp @ 1662:e0ba4e04c839
6969574: invokedynamic call sites deoptimize instead of executing
Reviewed-by: kvn
author | jrose |
---|---|
date | Fri, 16 Jul 2010 18:14:19 -0700 |
parents | 136b78722a08 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1579 | 2 * Copyright (c) 1999, 2010, 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:
1138
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1138
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:
1138
diff
changeset
|
21 * questions. |
0 | 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: | |
1565 | 34 // Handling for the weird bytecodes |
35 Bytecodes::Code next_wide_or_table(Bytecodes::Code); // Handle _wide & complicated inline table | |
0 | 36 |
37 static Bytecodes::Code check_java(Bytecodes::Code c) { | |
38 assert(Bytecodes::is_java_code(c), "should not return _fast bytecodes"); | |
39 return c; | |
40 } | |
41 | |
1565 | 42 static Bytecodes::Code check_defined(Bytecodes::Code c) { |
43 assert(Bytecodes::is_defined(c), ""); | |
44 return c; | |
45 } | |
46 | |
0 | 47 ciMethod* _method; // the method |
48 ciInstanceKlass* _holder; | |
1602 | 49 ciCPCache* _cpcache; |
0 | 50 address _bc_start; // Start of current bytecode for table |
51 address _was_wide; // Address past last wide bytecode | |
52 jint* _table_base; // Aligned start of last table or switch | |
53 | |
54 address _start; // Start of bytecodes | |
55 address _end; // Past end of bytecodes | |
56 address _pc; // Current PC | |
57 Bytecodes::Code _bc; // Current bytecode | |
1565 | 58 Bytecodes::Code _raw_bc; // Current bytecode, raw form |
0 | 59 |
60 void reset( address base, unsigned int size ) { | |
61 _bc_start =_was_wide = 0; | |
1602 | 62 _start = _pc = base; _end = base + size; |
63 _cpcache = NULL; | |
64 } | |
0 | 65 |
1565 | 66 void assert_wide(bool require_wide) const { |
67 if (require_wide) | |
68 { assert(is_wide(), "must be a wide instruction"); } | |
69 else { assert(!is_wide(), "must not be a wide instruction"); } | |
70 } | |
71 | |
72 Bytecode* bytecode() const { return Bytecode_at(_bc_start); } | |
73 Bytecode* next_bytecode() const { return Bytecode_at(_pc); } | |
74 | |
0 | 75 public: |
76 // End-Of-Bytecodes | |
77 static Bytecodes::Code EOBC() { | |
78 return Bytecodes::_illegal; | |
79 } | |
80 | |
81 ciBytecodeStream(ciMethod* m) { | |
82 reset_to_method(m); | |
83 } | |
84 | |
85 ciBytecodeStream() { | |
86 reset_to_method(NULL); | |
87 } | |
88 | |
89 ciMethod* method() const { return _method; } | |
90 | |
91 void reset_to_method(ciMethod* m) { | |
92 _method = m; | |
93 if (m == NULL) { | |
94 _holder = NULL; | |
95 reset(NULL, 0); | |
96 } else { | |
97 _holder = m->holder(); | |
98 reset(m->code(), m->code_size()); | |
99 } | |
100 } | |
101 | |
102 void reset_to_bci( int bci ); | |
103 | |
104 // Force the iterator to report a certain bci. | |
105 void force_bci(int bci); | |
106 | |
107 void set_max_bci( int max ) { | |
108 _end = _start + max; | |
109 } | |
110 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
111 address cur_bcp() const { return _bc_start; } // Returns bcp to current instruction |
1565 | 112 int next_bci() const { return _pc - _start; } |
0 | 113 int cur_bci() const { return _bc_start - _start; } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
114 int instruction_size() const { return _pc - _bc_start; } |
0 | 115 |
116 Bytecodes::Code cur_bc() const{ return check_java(_bc); } | |
1565 | 117 Bytecodes::Code cur_bc_raw() const { return check_defined(_raw_bc); } |
0 | 118 Bytecodes::Code next_bc() { return Bytecodes::java_code((Bytecodes::Code)* _pc); } |
119 | |
120 // Return current ByteCode and increment PC to next bytecode, skipping all | |
121 // intermediate constants. Returns EOBC at end. | |
122 // Expected usage: | |
123 // while( (bc = iter.next()) != EOBC() ) { ... } | |
124 Bytecodes::Code next() { | |
125 _bc_start = _pc; // Capture start of bc | |
126 if( _pc >= _end ) return EOBC(); // End-Of-Bytecodes | |
127 | |
128 // Fetch Java bytecode | |
129 // All rewritten bytecodes maintain the size of original bytecode. | |
1565 | 130 _bc = Bytecodes::java_code(_raw_bc = (Bytecodes::Code)*_pc); |
0 | 131 int csize = Bytecodes::length_for(_bc); // Expected size |
1565 | 132 _pc += csize; // Bump PC past bytecode |
133 if (csize == 0) { | |
134 _bc = next_wide_or_table(_bc); | |
0 | 135 } |
136 return check_java(_bc); | |
137 } | |
138 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
139 bool is_wide() const { return ( _pc == _was_wide ); } |
0 | 140 |
1565 | 141 // Does this instruction contain an index which refes into the CP cache? |
1602 | 142 bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); } |
1565 | 143 |
144 int get_index_u1() const { | |
145 return bytecode()->get_index_u1(cur_bc_raw()); | |
146 } | |
147 | |
1602 | 148 int get_index_u1_cpcache() const { |
149 return bytecode()->get_index_u1_cpcache(cur_bc_raw()); | |
150 } | |
151 | |
0 | 152 // Get a byte index following this bytecode. |
153 // If prefixed with a wide bytecode, get a wide index. | |
154 int get_index() const { | |
1602 | 155 assert(!has_cache_index(), "else use cpcache variant"); |
0 | 156 return (_pc == _was_wide) // was widened? |
1565 | 157 ? get_index_u2(true) // yes, return wide index |
158 : get_index_u1(); // no, return narrow index | |
0 | 159 } |
160 | |
1565 | 161 // Get 2-byte index (byte swapping depending on which bytecode) |
162 int get_index_u2(bool is_wide = false) const { | |
163 return bytecode()->get_index_u2(cur_bc_raw(), is_wide); | |
0 | 164 } |
165 | |
1565 | 166 // Get 2-byte index in native byte order. (Rewriter::rewrite makes these.) |
167 int get_index_u2_cpcache() const { | |
168 return bytecode()->get_index_u2_cpcache(cur_bc_raw()); | |
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 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
171 // Get 4-byte index, for invokedynamic. |
1565 | 172 int get_index_u4() const { |
173 return bytecode()->get_index_u4(cur_bc_raw()); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
174 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
175 |
1565 | 176 bool has_index_u4() const { |
177 return bytecode()->has_index_u4(cur_bc_raw()); | |
178 } | |
0 | 179 |
180 // Get dimensions byte (multinewarray) | |
181 int get_dimensions() const { return *(unsigned char*)(_pc-1); } | |
182 | |
183 // Sign-extended index byte/short, no widening | |
1565 | 184 int get_constant_u1() const { return bytecode()->get_constant_u1(instruction_size()-1, cur_bc_raw()); } |
185 int get_constant_u2(bool is_wide = false) const { return bytecode()->get_constant_u2(instruction_size()-2, cur_bc_raw(), is_wide); } | |
0 | 186 |
187 // Get a byte signed constant for "iinc". Invalid for other bytecodes. | |
188 // If prefixed with a wide bytecode, get a wide constant | |
1565 | 189 int get_iinc_con() const {return (_pc==_was_wide) ? (jshort) get_constant_u2(true) : (jbyte) get_constant_u1();} |
0 | 190 |
191 // 2-byte branch offset from current pc | |
1565 | 192 int get_dest() const { |
193 return cur_bci() + bytecode()->get_offset_s2(cur_bc_raw()); | |
0 | 194 } |
195 | |
196 // 2-byte branch offset from next pc | |
1565 | 197 int next_get_dest() const { |
198 assert(_pc < _end, ""); | |
199 return next_bci() + next_bytecode()->get_offset_s2(Bytecodes::_ifeq); | |
0 | 200 } |
201 | |
202 // 4-byte branch offset from current pc | |
1565 | 203 int get_far_dest() const { |
204 return cur_bci() + bytecode()->get_offset_s4(cur_bc_raw()); | |
0 | 205 } |
206 | |
207 // For a lookup or switch table, return target destination | |
208 int get_int_table( int index ) const { | |
209 return Bytes::get_Java_u4((address)&_table_base[index]); } | |
210 | |
211 // For tableswitch - get length of offset part | |
212 int get_tableswitch_length() { return get_int_table(2)-get_int_table(1)+1; } | |
213 | |
214 int get_dest_table( int index ) const { | |
215 return cur_bci() + get_int_table(index); } | |
216 | |
217 // --- Constant pool access --- | |
1602 | 218 int get_constant_raw_index() const; |
219 int get_constant_pool_index() const; | |
220 int get_constant_cache_index() const; | |
0 | 221 int get_field_index(); |
222 int get_method_index(); | |
223 | |
224 // If this bytecode is a new, newarray, multianewarray, instanceof, | |
225 // or checkcast, get the referenced klass. | |
226 ciKlass* get_klass(bool& will_link); | |
227 int get_klass_index() const; | |
228 | |
229 // If this bytecode is one of the ldc variants, get the referenced | |
1602 | 230 // constant. Do not attempt to resolve it, since that would require |
231 // execution of Java code. If it is not resolved, return an unloaded | |
232 // object (ciConstant.as_object()->is_loaded() == false). | |
0 | 233 ciConstant get_constant(); |
1602 | 234 constantTag get_constant_pool_tag(int index) const; |
235 | |
236 // True if the klass-using bytecode points to an unresolved klass | |
237 bool is_unresolved_klass() const { | |
238 constantTag tag = get_constant_pool_tag(get_klass_index()); | |
239 return tag.is_unresolved_klass(); | |
240 } | |
0 | 241 |
242 // If this bytecode is one of get_field, get_static, put_field, | |
243 // or put_static, get the referenced field. | |
244 ciField* get_field(bool& will_link); | |
245 | |
246 ciInstanceKlass* get_declared_field_holder(); | |
247 int get_field_holder_index(); | |
248 int get_field_signature_index(); | |
249 | |
250 // If this is a method invocation bytecode, get the invoked method. | |
251 ciMethod* get_method(bool& will_link); | |
252 ciKlass* get_declared_method_holder(); | |
253 int get_method_holder_index(); | |
254 int get_method_signature_index(); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
255 |
1602 | 256 ciCPCache* get_cpcache() const; |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1137
diff
changeset
|
257 ciCallSite* get_call_site(); |
0 | 258 }; |
259 | |
260 | |
261 // ciSignatureStream | |
262 // | |
263 // The class is used to iterate over the elements of a method signature. | |
264 class ciSignatureStream : public StackObj { | |
265 private: | |
266 ciSignature* _sig; | |
267 int _pos; | |
268 public: | |
269 ciSignatureStream(ciSignature* signature) { | |
270 _sig = signature; | |
271 _pos = 0; | |
272 } | |
273 | |
274 bool at_return_type() { return _pos == _sig->count(); } | |
275 | |
276 bool is_done() { return _pos > _sig->count(); } | |
277 | |
278 void next() { | |
279 if (_pos <= _sig->count()) { | |
280 _pos++; | |
281 } | |
282 } | |
283 | |
284 ciType* type() { | |
285 if (at_return_type()) { | |
286 return _sig->return_type(); | |
287 } else { | |
288 return _sig->type_at(_pos); | |
289 } | |
290 } | |
291 }; | |
292 | |
293 | |
294 // ciExceptionHandlerStream | |
295 // | |
296 // The class is used to iterate over the exception handlers of | |
297 // a method. | |
298 class ciExceptionHandlerStream : public StackObj { | |
299 private: | |
300 // The method whose handlers we are traversing | |
301 ciMethod* _method; | |
302 | |
303 // Our current position in the list of handlers | |
304 int _pos; | |
305 int _end; | |
306 | |
307 ciInstanceKlass* _exception_klass; | |
308 int _bci; | |
309 bool _is_exact; | |
310 | |
311 public: | |
312 ciExceptionHandlerStream(ciMethod* method) { | |
313 _method = method; | |
314 | |
315 // Force loading of method code and handlers. | |
316 _method->code(); | |
317 | |
318 _pos = 0; | |
319 _end = _method->_handler_count; | |
320 _exception_klass = NULL; | |
321 _bci = -1; | |
322 _is_exact = false; | |
323 } | |
324 | |
325 ciExceptionHandlerStream(ciMethod* method, int bci, | |
326 ciInstanceKlass* exception_klass = NULL, | |
327 bool is_exact = false) { | |
328 _method = method; | |
329 | |
330 // Force loading of method code and handlers. | |
331 _method->code(); | |
332 | |
333 _pos = -1; | |
334 _end = _method->_handler_count + 1; // include the rethrow handler | |
335 _exception_klass = (exception_klass != NULL && exception_klass->is_loaded() | |
336 ? exception_klass | |
337 : NULL); | |
338 _bci = bci; | |
339 assert(_bci >= 0, "bci out of range"); | |
340 _is_exact = is_exact; | |
341 next(); | |
342 } | |
343 | |
344 // These methods are currently implemented in an odd way. | |
345 // Count the number of handlers the iterator has ever produced | |
346 // or will ever produce. Do not include the final rethrow handler. | |
347 // That is, a trivial exception handler stream will have a count | |
348 // of zero and produce just the rethrow handler. | |
349 int count(); | |
350 | |
351 // Count the number of handlers this stream will produce from now on. | |
352 // Include the current handler, and the final rethrow handler. | |
353 // The remaining count will be zero iff is_done() is true, | |
354 int count_remaining(); | |
355 | |
356 bool is_done() { | |
357 return (_pos >= _end); | |
358 } | |
359 | |
360 void next() { | |
361 _pos++; | |
362 if (_bci != -1) { | |
363 // We are not iterating over all handlers... | |
364 while (!is_done()) { | |
365 ciExceptionHandler* handler = _method->_exception_handlers[_pos]; | |
366 if (handler->is_in_range(_bci)) { | |
367 if (handler->is_catch_all()) { | |
368 // Found final active catch block. | |
369 _end = _pos+1; | |
370 return; | |
371 } else if (_exception_klass == NULL || !handler->catch_klass()->is_loaded()) { | |
372 // We cannot do any type analysis here. Must conservatively assume | |
373 // catch block is reachable. | |
374 return; | |
375 } else if (_exception_klass->is_subtype_of(handler->catch_klass())) { | |
376 // This catch clause will definitely catch the exception. | |
377 // Final candidate. | |
378 _end = _pos+1; | |
379 return; | |
380 } else if (!_is_exact && | |
381 handler->catch_klass()->is_subtype_of(_exception_klass)) { | |
382 // This catch block may be reachable. | |
383 return; | |
384 } | |
385 } | |
386 | |
387 // The catch block was not pertinent. Go on. | |
388 _pos++; | |
389 } | |
390 } else { | |
391 // This is an iteration over all handlers. | |
392 return; | |
393 } | |
394 } | |
395 | |
396 ciExceptionHandler* handler() { | |
397 return _method->_exception_handlers[_pos]; | |
398 } | |
399 }; |