Mercurial > hg > truffle
annotate src/share/vm/ci/ciStreams.hpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 55fb97c4c58d |
children | 4ca6dc0799b6 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
12875
diff
changeset
|
2 * Copyright (c) 1999, 2013, 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 | |
1972 | 25 #ifndef SHARE_VM_CI_CISTREAMS_HPP |
26 #define SHARE_VM_CI_CISTREAMS_HPP | |
27 | |
28 #include "ci/ciClassList.hpp" | |
29 #include "ci/ciExceptionHandler.hpp" | |
30 #include "ci/ciInstanceKlass.hpp" | |
31 #include "ci/ciMethod.hpp" | |
32 #include "interpreter/bytecode.hpp" | |
33 | |
0 | 34 // ciBytecodeStream |
35 // | |
36 // The class is used to iterate over the bytecodes of a method. | |
37 // It hides the details of constant pool structure/access by | |
38 // providing accessors for constant pool items. It returns only pure | |
39 // Java bytecodes; VM-internal _fast bytecodes are translated back to | |
40 // their original form during iteration. | |
41 class ciBytecodeStream : StackObj { | |
42 private: | |
1565 | 43 // Handling for the weird bytecodes |
44 Bytecodes::Code next_wide_or_table(Bytecodes::Code); // Handle _wide & complicated inline table | |
0 | 45 |
46 static Bytecodes::Code check_java(Bytecodes::Code c) { | |
47 assert(Bytecodes::is_java_code(c), "should not return _fast bytecodes"); | |
48 return c; | |
49 } | |
50 | |
1565 | 51 static Bytecodes::Code check_defined(Bytecodes::Code c) { |
52 assert(Bytecodes::is_defined(c), ""); | |
53 return c; | |
54 } | |
55 | |
0 | 56 ciMethod* _method; // the method |
57 ciInstanceKlass* _holder; | |
58 address _bc_start; // Start of current bytecode for table | |
59 address _was_wide; // Address past last wide bytecode | |
60 jint* _table_base; // Aligned start of last table or switch | |
61 | |
62 address _start; // Start of bytecodes | |
63 address _end; // Past end of bytecodes | |
64 address _pc; // Current PC | |
65 Bytecodes::Code _bc; // Current bytecode | |
1565 | 66 Bytecodes::Code _raw_bc; // Current bytecode, raw form |
0 | 67 |
68 void reset( address base, unsigned int size ) { | |
69 _bc_start =_was_wide = 0; | |
1602 | 70 _start = _pc = base; _end = base + size; |
71 } | |
0 | 72 |
1565 | 73 void assert_wide(bool require_wide) const { |
74 if (require_wide) | |
75 { assert(is_wide(), "must be a wide instruction"); } | |
76 else { assert(!is_wide(), "must not be a wide instruction"); } | |
77 } | |
78 | |
2142 | 79 Bytecode bytecode() const { return Bytecode(this, _bc_start); } |
80 Bytecode next_bytecode() const { return Bytecode(this, _pc); } | |
1565 | 81 |
0 | 82 public: |
83 // End-Of-Bytecodes | |
84 static Bytecodes::Code EOBC() { | |
85 return Bytecodes::_illegal; | |
86 } | |
87 | |
88 ciBytecodeStream(ciMethod* m) { | |
89 reset_to_method(m); | |
90 } | |
91 | |
92 ciBytecodeStream() { | |
93 reset_to_method(NULL); | |
94 } | |
95 | |
96 ciMethod* method() const { return _method; } | |
97 | |
98 void reset_to_method(ciMethod* m) { | |
99 _method = m; | |
100 if (m == NULL) { | |
101 _holder = NULL; | |
102 reset(NULL, 0); | |
103 } else { | |
104 _holder = m->holder(); | |
105 reset(m->code(), m->code_size()); | |
106 } | |
107 } | |
108 | |
109 void reset_to_bci( int bci ); | |
110 | |
111 // Force the iterator to report a certain bci. | |
112 void force_bci(int bci); | |
113 | |
114 void set_max_bci( int max ) { | |
115 _end = _start + max; | |
116 } | |
117 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
118 address cur_bcp() const { return _bc_start; } // Returns bcp to current instruction |
1565 | 119 int next_bci() const { return _pc - _start; } |
0 | 120 int cur_bci() const { return _bc_start - _start; } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
121 int instruction_size() const { return _pc - _bc_start; } |
0 | 122 |
123 Bytecodes::Code cur_bc() const{ return check_java(_bc); } | |
1565 | 124 Bytecodes::Code cur_bc_raw() const { return check_defined(_raw_bc); } |
0 | 125 Bytecodes::Code next_bc() { return Bytecodes::java_code((Bytecodes::Code)* _pc); } |
126 | |
127 // Return current ByteCode and increment PC to next bytecode, skipping all | |
128 // intermediate constants. Returns EOBC at end. | |
129 // Expected usage: | |
3897
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
2142
diff
changeset
|
130 // ciBytecodeStream iter(m); |
de847cac9235
7078382: JSR 292: don't count method handle adapters against inlining budgets
twisti
parents:
2142
diff
changeset
|
131 // while (iter.next() != ciBytecodeStream::EOBC()) { ... } |
0 | 132 Bytecodes::Code next() { |
133 _bc_start = _pc; // Capture start of bc | |
134 if( _pc >= _end ) return EOBC(); // End-Of-Bytecodes | |
135 | |
136 // Fetch Java bytecode | |
137 // All rewritten bytecodes maintain the size of original bytecode. | |
1565 | 138 _bc = Bytecodes::java_code(_raw_bc = (Bytecodes::Code)*_pc); |
0 | 139 int csize = Bytecodes::length_for(_bc); // Expected size |
1565 | 140 _pc += csize; // Bump PC past bytecode |
141 if (csize == 0) { | |
142 _bc = next_wide_or_table(_bc); | |
0 | 143 } |
144 return check_java(_bc); | |
145 } | |
146 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
147 bool is_wide() const { return ( _pc == _was_wide ); } |
0 | 148 |
1565 | 149 // Does this instruction contain an index which refes into the CP cache? |
1602 | 150 bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); } |
1565 | 151 |
6634
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
152 bool has_optional_appendix() { return Bytecodes::has_optional_appendix(cur_bc_raw()); } |
7f813940ac35
7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites
twisti
parents:
6266
diff
changeset
|
153 |
1565 | 154 int get_index_u1() const { |
2142 | 155 return bytecode().get_index_u1(cur_bc_raw()); |
1565 | 156 } |
157 | |
1602 | 158 int get_index_u1_cpcache() const { |
2142 | 159 return bytecode().get_index_u1_cpcache(cur_bc_raw()); |
1602 | 160 } |
161 | |
0 | 162 // Get a byte index following this bytecode. |
163 // If prefixed with a wide bytecode, get a wide index. | |
164 int get_index() const { | |
1602 | 165 assert(!has_cache_index(), "else use cpcache variant"); |
0 | 166 return (_pc == _was_wide) // was widened? |
1565 | 167 ? get_index_u2(true) // yes, return wide index |
168 : get_index_u1(); // no, return narrow index | |
0 | 169 } |
170 | |
1565 | 171 // Get 2-byte index (byte swapping depending on which bytecode) |
172 int get_index_u2(bool is_wide = false) const { | |
2142 | 173 return bytecode().get_index_u2(cur_bc_raw(), is_wide); |
0 | 174 } |
175 | |
1565 | 176 // Get 2-byte index in native byte order. (Rewriter::rewrite makes these.) |
177 int get_index_u2_cpcache() const { | |
2142 | 178 return bytecode().get_index_u2_cpcache(cur_bc_raw()); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
179 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
180 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
181 // Get 4-byte index, for invokedynamic. |
1565 | 182 int get_index_u4() const { |
2142 | 183 return bytecode().get_index_u4(cur_bc_raw()); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
184 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
185 |
1565 | 186 bool has_index_u4() const { |
2142 | 187 return bytecode().has_index_u4(cur_bc_raw()); |
1565 | 188 } |
0 | 189 |
190 // Get dimensions byte (multinewarray) | |
191 int get_dimensions() const { return *(unsigned char*)(_pc-1); } | |
192 | |
193 // Sign-extended index byte/short, no widening | |
2142 | 194 int get_constant_u1() const { return bytecode().get_constant_u1(instruction_size()-1, cur_bc_raw()); } |
195 int get_constant_u2(bool is_wide = false) const { return bytecode().get_constant_u2(instruction_size()-2, cur_bc_raw(), is_wide); } | |
0 | 196 |
197 // Get a byte signed constant for "iinc". Invalid for other bytecodes. | |
198 // If prefixed with a wide bytecode, get a wide constant | |
1565 | 199 int get_iinc_con() const {return (_pc==_was_wide) ? (jshort) get_constant_u2(true) : (jbyte) get_constant_u1();} |
0 | 200 |
201 // 2-byte branch offset from current pc | |
1565 | 202 int get_dest() const { |
2142 | 203 return cur_bci() + bytecode().get_offset_s2(cur_bc_raw()); |
0 | 204 } |
205 | |
206 // 2-byte branch offset from next pc | |
1565 | 207 int next_get_dest() const { |
208 assert(_pc < _end, ""); | |
2142 | 209 return next_bci() + next_bytecode().get_offset_s2(Bytecodes::_ifeq); |
0 | 210 } |
211 | |
212 // 4-byte branch offset from current pc | |
1565 | 213 int get_far_dest() const { |
2142 | 214 return cur_bci() + bytecode().get_offset_s4(cur_bc_raw()); |
0 | 215 } |
216 | |
217 // For a lookup or switch table, return target destination | |
218 int get_int_table( int index ) const { | |
219 return Bytes::get_Java_u4((address)&_table_base[index]); } | |
220 | |
221 // For tableswitch - get length of offset part | |
222 int get_tableswitch_length() { return get_int_table(2)-get_int_table(1)+1; } | |
223 | |
224 int get_dest_table( int index ) const { | |
225 return cur_bci() + get_int_table(index); } | |
226 | |
227 // --- Constant pool access --- | |
1602 | 228 int get_constant_raw_index() const; |
229 int get_constant_pool_index() const; | |
230 int get_constant_cache_index() const; | |
0 | 231 int get_field_index(); |
232 int get_method_index(); | |
233 | |
234 // If this bytecode is a new, newarray, multianewarray, instanceof, | |
235 // or checkcast, get the referenced klass. | |
236 ciKlass* get_klass(bool& will_link); | |
237 int get_klass_index() const; | |
238 | |
239 // If this bytecode is one of the ldc variants, get the referenced | |
1602 | 240 // constant. Do not attempt to resolve it, since that would require |
241 // execution of Java code. If it is not resolved, return an unloaded | |
242 // object (ciConstant.as_object()->is_loaded() == false). | |
0 | 243 ciConstant get_constant(); |
1602 | 244 constantTag get_constant_pool_tag(int index) const; |
245 | |
246 // True if the klass-using bytecode points to an unresolved klass | |
247 bool is_unresolved_klass() const { | |
248 constantTag tag = get_constant_pool_tag(get_klass_index()); | |
249 return tag.is_unresolved_klass(); | |
250 } | |
0 | 251 |
252 // If this bytecode is one of get_field, get_static, put_field, | |
253 // or put_static, get the referenced field. | |
254 ciField* get_field(bool& will_link); | |
255 | |
256 ciInstanceKlass* get_declared_field_holder(); | |
257 int get_field_holder_index(); | |
258 int get_field_signature_index(); | |
259 | |
6822
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
260 ciMethod* get_method(bool& will_link, ciSignature* *declared_signature_result); |
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
261 bool has_appendix(); |
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
262 ciObject* get_appendix(); |
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
263 bool has_method_type(); |
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
264 ciMethodType* get_method_type(); |
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
265 ciKlass* get_declared_method_holder(); |
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
266 int get_method_holder_index(); |
f6b0eb4e44cf
7200949: JSR 292: rubybench/bench/time/bench_base64.rb fails with jruby.jar not on boot class path
twisti
parents:
6725
diff
changeset
|
267 int get_method_signature_index(); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
268 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
269 // Get the resolved references arrays from the constant pool |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6634
diff
changeset
|
270 ciObjArray* get_resolved_references(); |
0 | 271 }; |
272 | |
273 | |
274 // ciSignatureStream | |
275 // | |
276 // The class is used to iterate over the elements of a method signature. | |
277 class ciSignatureStream : public StackObj { | |
278 private: | |
279 ciSignature* _sig; | |
12875
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
280 int _pos; |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
281 // holder is a method's holder |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
282 ciKlass* _holder; |
0 | 283 public: |
12875
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
284 ciSignatureStream(ciSignature* signature, ciKlass* holder = NULL) { |
0 | 285 _sig = signature; |
286 _pos = 0; | |
12875
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
287 _holder = holder; |
0 | 288 } |
289 | |
290 bool at_return_type() { return _pos == _sig->count(); } | |
291 | |
292 bool is_done() { return _pos > _sig->count(); } | |
293 | |
294 void next() { | |
295 if (_pos <= _sig->count()) { | |
296 _pos++; | |
297 } | |
298 } | |
299 | |
300 ciType* type() { | |
301 if (at_return_type()) { | |
302 return _sig->return_type(); | |
303 } else { | |
304 return _sig->type_at(_pos); | |
305 } | |
306 } | |
12875
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
307 |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
308 // next klass in the signature |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
309 ciKlass* next_klass() { |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
310 ciKlass* sig_k; |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
311 if (_holder != NULL) { |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
312 sig_k = _holder; |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
313 _holder = NULL; |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
314 } else { |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
315 while (!type()->is_klass()) { |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
316 next(); |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
317 } |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
318 assert(!at_return_type(), "passed end of signature"); |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
319 sig_k = type()->as_klass(); |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
320 next(); |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
321 } |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
322 return sig_k; |
d13d7aba8c12
8023657: New type profiling points: arguments to call
roland
parents:
6822
diff
changeset
|
323 } |
0 | 324 }; |
325 | |
326 | |
327 // ciExceptionHandlerStream | |
328 // | |
329 // The class is used to iterate over the exception handlers of | |
330 // a method. | |
331 class ciExceptionHandlerStream : public StackObj { | |
332 private: | |
333 // The method whose handlers we are traversing | |
334 ciMethod* _method; | |
335 | |
336 // Our current position in the list of handlers | |
337 int _pos; | |
338 int _end; | |
339 | |
340 ciInstanceKlass* _exception_klass; | |
341 int _bci; | |
342 bool _is_exact; | |
343 | |
344 public: | |
345 ciExceptionHandlerStream(ciMethod* method) { | |
346 _method = method; | |
347 | |
348 // Force loading of method code and handlers. | |
349 _method->code(); | |
350 | |
351 _pos = 0; | |
352 _end = _method->_handler_count; | |
353 _exception_klass = NULL; | |
354 _bci = -1; | |
355 _is_exact = false; | |
356 } | |
357 | |
358 ciExceptionHandlerStream(ciMethod* method, int bci, | |
359 ciInstanceKlass* exception_klass = NULL, | |
360 bool is_exact = false) { | |
361 _method = method; | |
362 | |
363 // Force loading of method code and handlers. | |
364 _method->code(); | |
365 | |
366 _pos = -1; | |
367 _end = _method->_handler_count + 1; // include the rethrow handler | |
368 _exception_klass = (exception_klass != NULL && exception_klass->is_loaded() | |
369 ? exception_klass | |
370 : NULL); | |
371 _bci = bci; | |
372 assert(_bci >= 0, "bci out of range"); | |
373 _is_exact = is_exact; | |
374 next(); | |
375 } | |
376 | |
377 // These methods are currently implemented in an odd way. | |
378 // Count the number of handlers the iterator has ever produced | |
379 // or will ever produce. Do not include the final rethrow handler. | |
380 // That is, a trivial exception handler stream will have a count | |
381 // of zero and produce just the rethrow handler. | |
382 int count(); | |
383 | |
384 // Count the number of handlers this stream will produce from now on. | |
385 // Include the current handler, and the final rethrow handler. | |
386 // The remaining count will be zero iff is_done() is true, | |
387 int count_remaining(); | |
388 | |
389 bool is_done() { | |
390 return (_pos >= _end); | |
391 } | |
392 | |
393 void next() { | |
394 _pos++; | |
395 if (_bci != -1) { | |
396 // We are not iterating over all handlers... | |
397 while (!is_done()) { | |
398 ciExceptionHandler* handler = _method->_exception_handlers[_pos]; | |
399 if (handler->is_in_range(_bci)) { | |
400 if (handler->is_catch_all()) { | |
401 // Found final active catch block. | |
402 _end = _pos+1; | |
403 return; | |
404 } else if (_exception_klass == NULL || !handler->catch_klass()->is_loaded()) { | |
405 // We cannot do any type analysis here. Must conservatively assume | |
406 // catch block is reachable. | |
407 return; | |
408 } else if (_exception_klass->is_subtype_of(handler->catch_klass())) { | |
409 // This catch clause will definitely catch the exception. | |
410 // Final candidate. | |
411 _end = _pos+1; | |
412 return; | |
413 } else if (!_is_exact && | |
414 handler->catch_klass()->is_subtype_of(_exception_klass)) { | |
415 // This catch block may be reachable. | |
416 return; | |
417 } | |
418 } | |
419 | |
420 // The catch block was not pertinent. Go on. | |
421 _pos++; | |
422 } | |
423 } else { | |
424 // This is an iteration over all handlers. | |
425 return; | |
426 } | |
427 } | |
428 | |
429 ciExceptionHandler* handler() { | |
430 return _method->_exception_handlers[_pos]; | |
431 } | |
432 }; | |
1972 | 433 |
2142 | 434 |
435 | |
436 // Implementation for declarations in bytecode.hpp | |
437 Bytecode::Bytecode(const ciBytecodeStream* stream, address bcp): _bcp(bcp != NULL ? bcp : stream->cur_bcp()), _code(Bytecodes::code_at(NULL, addr_at(0))) {} | |
438 Bytecode_lookupswitch::Bytecode_lookupswitch(const ciBytecodeStream* stream): Bytecode(stream) { verify(); } | |
439 Bytecode_tableswitch::Bytecode_tableswitch(const ciBytecodeStream* stream): Bytecode(stream) { verify(); } | |
440 | |
1972 | 441 #endif // SHARE_VM_CI_CISTREAMS_HPP |