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