Mercurial > hg > truffle
annotate src/share/vm/c1/c1_GraphBuilder.cpp @ 2007:5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Thu, 02 Dec 2010 17:21:12 -0800 |
parents | ac637b7220d1 |
children | 8012aa3ccede 403dc4c1d7f5 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1540
diff
changeset
|
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:
1540
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1540
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:
1540
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_CFGPrinter.hpp" | |
27 #include "c1/c1_Canonicalizer.hpp" | |
28 #include "c1/c1_Compilation.hpp" | |
29 #include "c1/c1_GraphBuilder.hpp" | |
30 #include "c1/c1_InstructionPrinter.hpp" | |
31 #include "ci/ciField.hpp" | |
32 #include "ci/ciKlass.hpp" | |
33 #include "interpreter/bytecode.hpp" | |
34 #include "runtime/sharedRuntime.hpp" | |
35 #include "utilities/bitMap.inline.hpp" | |
0 | 36 |
37 class BlockListBuilder VALUE_OBJ_CLASS_SPEC { | |
38 private: | |
39 Compilation* _compilation; | |
40 IRScope* _scope; | |
41 | |
42 BlockList _blocks; // internal list of all blocks | |
43 BlockList* _bci2block; // mapping from bci to blocks for GraphBuilder | |
44 | |
45 // fields used by mark_loops | |
46 BitMap _active; // for iteration of control flow graph | |
47 BitMap _visited; // for iteration of control flow graph | |
48 intArray _loop_map; // caches the information if a block is contained in a loop | |
49 int _next_loop_index; // next free loop number | |
50 int _next_block_number; // for reverse postorder numbering of blocks | |
51 | |
52 // accessors | |
53 Compilation* compilation() const { return _compilation; } | |
54 IRScope* scope() const { return _scope; } | |
55 ciMethod* method() const { return scope()->method(); } | |
56 XHandlers* xhandlers() const { return scope()->xhandlers(); } | |
57 | |
58 // unified bailout support | |
59 void bailout(const char* msg) const { compilation()->bailout(msg); } | |
60 bool bailed_out() const { return compilation()->bailed_out(); } | |
61 | |
62 // helper functions | |
63 BlockBegin* make_block_at(int bci, BlockBegin* predecessor); | |
64 void handle_exceptions(BlockBegin* current, int cur_bci); | |
65 void handle_jsr(BlockBegin* current, int sr_bci, int next_bci); | |
66 void store_one(BlockBegin* current, int local); | |
67 void store_two(BlockBegin* current, int local); | |
68 void set_entries(int osr_bci); | |
69 void set_leaders(); | |
70 | |
71 void make_loop_header(BlockBegin* block); | |
72 void mark_loops(); | |
73 int mark_loops(BlockBegin* b, bool in_subroutine); | |
74 | |
75 // debugging | |
76 #ifndef PRODUCT | |
77 void print(); | |
78 #endif | |
79 | |
80 public: | |
81 // creation | |
82 BlockListBuilder(Compilation* compilation, IRScope* scope, int osr_bci); | |
83 | |
84 // accessors for GraphBuilder | |
85 BlockList* bci2block() const { return _bci2block; } | |
86 }; | |
87 | |
88 | |
89 // Implementation of BlockListBuilder | |
90 | |
91 BlockListBuilder::BlockListBuilder(Compilation* compilation, IRScope* scope, int osr_bci) | |
92 : _compilation(compilation) | |
93 , _scope(scope) | |
94 , _blocks(16) | |
95 , _bci2block(new BlockList(scope->method()->code_size(), NULL)) | |
96 , _next_block_number(0) | |
97 , _active() // size not known yet | |
98 , _visited() // size not known yet | |
99 , _next_loop_index(0) | |
100 , _loop_map() // size not known yet | |
101 { | |
102 set_entries(osr_bci); | |
103 set_leaders(); | |
104 CHECK_BAILOUT(); | |
105 | |
106 mark_loops(); | |
107 NOT_PRODUCT(if (PrintInitialBlockList) print()); | |
108 | |
109 #ifndef PRODUCT | |
110 if (PrintCFGToFile) { | |
111 stringStream title; | |
112 title.print("BlockListBuilder "); | |
113 scope->method()->print_name(&title); | |
114 CFGPrinter::print_cfg(_bci2block, title.as_string(), false, false); | |
115 } | |
116 #endif | |
117 } | |
118 | |
119 | |
120 void BlockListBuilder::set_entries(int osr_bci) { | |
121 // generate start blocks | |
122 BlockBegin* std_entry = make_block_at(0, NULL); | |
123 if (scope()->caller() == NULL) { | |
124 std_entry->set(BlockBegin::std_entry_flag); | |
125 } | |
126 if (osr_bci != -1) { | |
127 BlockBegin* osr_entry = make_block_at(osr_bci, NULL); | |
128 osr_entry->set(BlockBegin::osr_entry_flag); | |
129 } | |
130 | |
131 // generate exception entry blocks | |
132 XHandlers* list = xhandlers(); | |
133 const int n = list->length(); | |
134 for (int i = 0; i < n; i++) { | |
135 XHandler* h = list->handler_at(i); | |
136 BlockBegin* entry = make_block_at(h->handler_bci(), NULL); | |
137 entry->set(BlockBegin::exception_entry_flag); | |
138 h->set_entry_block(entry); | |
139 } | |
140 } | |
141 | |
142 | |
143 BlockBegin* BlockListBuilder::make_block_at(int cur_bci, BlockBegin* predecessor) { | |
144 assert(method()->bci_block_start().at(cur_bci), "wrong block starts of MethodLivenessAnalyzer"); | |
145 | |
146 BlockBegin* block = _bci2block->at(cur_bci); | |
147 if (block == NULL) { | |
148 block = new BlockBegin(cur_bci); | |
149 block->init_stores_to_locals(method()->max_locals()); | |
150 _bci2block->at_put(cur_bci, block); | |
151 _blocks.append(block); | |
152 | |
153 assert(predecessor == NULL || predecessor->bci() < cur_bci, "targets for backward branches must already exist"); | |
154 } | |
155 | |
156 if (predecessor != NULL) { | |
157 if (block->is_set(BlockBegin::exception_entry_flag)) { | |
158 BAILOUT_("Exception handler can be reached by both normal and exceptional control flow", block); | |
159 } | |
160 | |
161 predecessor->add_successor(block); | |
162 block->increment_total_preds(); | |
163 } | |
164 | |
165 return block; | |
166 } | |
167 | |
168 | |
169 inline void BlockListBuilder::store_one(BlockBegin* current, int local) { | |
170 current->stores_to_locals().set_bit(local); | |
171 } | |
172 inline void BlockListBuilder::store_two(BlockBegin* current, int local) { | |
173 store_one(current, local); | |
174 store_one(current, local + 1); | |
175 } | |
176 | |
177 | |
178 void BlockListBuilder::handle_exceptions(BlockBegin* current, int cur_bci) { | |
179 // Draws edges from a block to its exception handlers | |
180 XHandlers* list = xhandlers(); | |
181 const int n = list->length(); | |
182 | |
183 for (int i = 0; i < n; i++) { | |
184 XHandler* h = list->handler_at(i); | |
185 | |
186 if (h->covers(cur_bci)) { | |
187 BlockBegin* entry = h->entry_block(); | |
188 assert(entry != NULL && entry == _bci2block->at(h->handler_bci()), "entry must be set"); | |
189 assert(entry->is_set(BlockBegin::exception_entry_flag), "flag must be set"); | |
190 | |
191 // add each exception handler only once | |
192 if (!current->is_successor(entry)) { | |
193 current->add_successor(entry); | |
194 entry->increment_total_preds(); | |
195 } | |
196 | |
197 // stop when reaching catchall | |
198 if (h->catch_type() == 0) break; | |
199 } | |
200 } | |
201 } | |
202 | |
203 void BlockListBuilder::handle_jsr(BlockBegin* current, int sr_bci, int next_bci) { | |
204 // start a new block after jsr-bytecode and link this block into cfg | |
205 make_block_at(next_bci, current); | |
206 | |
207 // start a new block at the subroutine entry at mark it with special flag | |
208 BlockBegin* sr_block = make_block_at(sr_bci, current); | |
209 if (!sr_block->is_set(BlockBegin::subroutine_entry_flag)) { | |
210 sr_block->set(BlockBegin::subroutine_entry_flag); | |
211 } | |
212 } | |
213 | |
214 | |
215 void BlockListBuilder::set_leaders() { | |
216 bool has_xhandlers = xhandlers()->has_handlers(); | |
217 BlockBegin* current = NULL; | |
218 | |
219 // The information which bci starts a new block simplifies the analysis | |
220 // Without it, backward branches could jump to a bci where no block was created | |
221 // during bytecode iteration. This would require the creation of a new block at the | |
222 // branch target and a modification of the successor lists. | |
223 BitMap bci_block_start = method()->bci_block_start(); | |
224 | |
225 ciBytecodeStream s(method()); | |
226 while (s.next() != ciBytecodeStream::EOBC()) { | |
227 int cur_bci = s.cur_bci(); | |
228 | |
229 if (bci_block_start.at(cur_bci)) { | |
230 current = make_block_at(cur_bci, current); | |
231 } | |
232 assert(current != NULL, "must have current block"); | |
233 | |
234 if (has_xhandlers && GraphBuilder::can_trap(method(), s.cur_bc())) { | |
235 handle_exceptions(current, cur_bci); | |
236 } | |
237 | |
238 switch (s.cur_bc()) { | |
239 // track stores to local variables for selective creation of phi functions | |
240 case Bytecodes::_iinc: store_one(current, s.get_index()); break; | |
241 case Bytecodes::_istore: store_one(current, s.get_index()); break; | |
242 case Bytecodes::_lstore: store_two(current, s.get_index()); break; | |
243 case Bytecodes::_fstore: store_one(current, s.get_index()); break; | |
244 case Bytecodes::_dstore: store_two(current, s.get_index()); break; | |
245 case Bytecodes::_astore: store_one(current, s.get_index()); break; | |
246 case Bytecodes::_istore_0: store_one(current, 0); break; | |
247 case Bytecodes::_istore_1: store_one(current, 1); break; | |
248 case Bytecodes::_istore_2: store_one(current, 2); break; | |
249 case Bytecodes::_istore_3: store_one(current, 3); break; | |
250 case Bytecodes::_lstore_0: store_two(current, 0); break; | |
251 case Bytecodes::_lstore_1: store_two(current, 1); break; | |
252 case Bytecodes::_lstore_2: store_two(current, 2); break; | |
253 case Bytecodes::_lstore_3: store_two(current, 3); break; | |
254 case Bytecodes::_fstore_0: store_one(current, 0); break; | |
255 case Bytecodes::_fstore_1: store_one(current, 1); break; | |
256 case Bytecodes::_fstore_2: store_one(current, 2); break; | |
257 case Bytecodes::_fstore_3: store_one(current, 3); break; | |
258 case Bytecodes::_dstore_0: store_two(current, 0); break; | |
259 case Bytecodes::_dstore_1: store_two(current, 1); break; | |
260 case Bytecodes::_dstore_2: store_two(current, 2); break; | |
261 case Bytecodes::_dstore_3: store_two(current, 3); break; | |
262 case Bytecodes::_astore_0: store_one(current, 0); break; | |
263 case Bytecodes::_astore_1: store_one(current, 1); break; | |
264 case Bytecodes::_astore_2: store_one(current, 2); break; | |
265 case Bytecodes::_astore_3: store_one(current, 3); break; | |
266 | |
267 // track bytecodes that affect the control flow | |
268 case Bytecodes::_athrow: // fall through | |
269 case Bytecodes::_ret: // fall through | |
270 case Bytecodes::_ireturn: // fall through | |
271 case Bytecodes::_lreturn: // fall through | |
272 case Bytecodes::_freturn: // fall through | |
273 case Bytecodes::_dreturn: // fall through | |
274 case Bytecodes::_areturn: // fall through | |
275 case Bytecodes::_return: | |
276 current = NULL; | |
277 break; | |
278 | |
279 case Bytecodes::_ifeq: // fall through | |
280 case Bytecodes::_ifne: // fall through | |
281 case Bytecodes::_iflt: // fall through | |
282 case Bytecodes::_ifge: // fall through | |
283 case Bytecodes::_ifgt: // fall through | |
284 case Bytecodes::_ifle: // fall through | |
285 case Bytecodes::_if_icmpeq: // fall through | |
286 case Bytecodes::_if_icmpne: // fall through | |
287 case Bytecodes::_if_icmplt: // fall through | |
288 case Bytecodes::_if_icmpge: // fall through | |
289 case Bytecodes::_if_icmpgt: // fall through | |
290 case Bytecodes::_if_icmple: // fall through | |
291 case Bytecodes::_if_acmpeq: // fall through | |
292 case Bytecodes::_if_acmpne: // fall through | |
293 case Bytecodes::_ifnull: // fall through | |
294 case Bytecodes::_ifnonnull: | |
295 make_block_at(s.next_bci(), current); | |
296 make_block_at(s.get_dest(), current); | |
297 current = NULL; | |
298 break; | |
299 | |
300 case Bytecodes::_goto: | |
301 make_block_at(s.get_dest(), current); | |
302 current = NULL; | |
303 break; | |
304 | |
305 case Bytecodes::_goto_w: | |
306 make_block_at(s.get_far_dest(), current); | |
307 current = NULL; | |
308 break; | |
309 | |
310 case Bytecodes::_jsr: | |
311 handle_jsr(current, s.get_dest(), s.next_bci()); | |
312 current = NULL; | |
313 break; | |
314 | |
315 case Bytecodes::_jsr_w: | |
316 handle_jsr(current, s.get_far_dest(), s.next_bci()); | |
317 current = NULL; | |
318 break; | |
319 | |
320 case Bytecodes::_tableswitch: { | |
321 // set block for each case | |
322 Bytecode_tableswitch *switch_ = Bytecode_tableswitch_at(s.cur_bcp()); | |
323 int l = switch_->length(); | |
324 for (int i = 0; i < l; i++) { | |
325 make_block_at(cur_bci + switch_->dest_offset_at(i), current); | |
326 } | |
327 make_block_at(cur_bci + switch_->default_offset(), current); | |
328 current = NULL; | |
329 break; | |
330 } | |
331 | |
332 case Bytecodes::_lookupswitch: { | |
333 // set block for each case | |
334 Bytecode_lookupswitch *switch_ = Bytecode_lookupswitch_at(s.cur_bcp()); | |
335 int l = switch_->number_of_pairs(); | |
336 for (int i = 0; i < l; i++) { | |
337 make_block_at(cur_bci + switch_->pair_at(i)->offset(), current); | |
338 } | |
339 make_block_at(cur_bci + switch_->default_offset(), current); | |
340 current = NULL; | |
341 break; | |
342 } | |
343 } | |
344 } | |
345 } | |
346 | |
347 | |
348 void BlockListBuilder::mark_loops() { | |
349 ResourceMark rm; | |
350 | |
351 _active = BitMap(BlockBegin::number_of_blocks()); _active.clear(); | |
352 _visited = BitMap(BlockBegin::number_of_blocks()); _visited.clear(); | |
353 _loop_map = intArray(BlockBegin::number_of_blocks(), 0); | |
354 _next_loop_index = 0; | |
355 _next_block_number = _blocks.length(); | |
356 | |
357 // recursively iterate the control flow graph | |
358 mark_loops(_bci2block->at(0), false); | |
359 assert(_next_block_number >= 0, "invalid block numbers"); | |
360 } | |
361 | |
362 void BlockListBuilder::make_loop_header(BlockBegin* block) { | |
363 if (block->is_set(BlockBegin::exception_entry_flag)) { | |
364 // exception edges may look like loops but don't mark them as such | |
365 // since it screws up block ordering. | |
366 return; | |
367 } | |
368 if (!block->is_set(BlockBegin::parser_loop_header_flag)) { | |
369 block->set(BlockBegin::parser_loop_header_flag); | |
370 | |
371 assert(_loop_map.at(block->block_id()) == 0, "must not be set yet"); | |
372 assert(0 <= _next_loop_index && _next_loop_index < BitsPerInt, "_next_loop_index is used as a bit-index in integer"); | |
373 _loop_map.at_put(block->block_id(), 1 << _next_loop_index); | |
374 if (_next_loop_index < 31) _next_loop_index++; | |
375 } else { | |
376 // block already marked as loop header | |
1060 | 377 assert(is_power_of_2((unsigned int)_loop_map.at(block->block_id())), "exactly one bit must be set"); |
0 | 378 } |
379 } | |
380 | |
381 int BlockListBuilder::mark_loops(BlockBegin* block, bool in_subroutine) { | |
382 int block_id = block->block_id(); | |
383 | |
384 if (_visited.at(block_id)) { | |
385 if (_active.at(block_id)) { | |
386 // reached block via backward branch | |
387 make_loop_header(block); | |
388 } | |
389 // return cached loop information for this block | |
390 return _loop_map.at(block_id); | |
391 } | |
392 | |
393 if (block->is_set(BlockBegin::subroutine_entry_flag)) { | |
394 in_subroutine = true; | |
395 } | |
396 | |
397 // set active and visited bits before successors are processed | |
398 _visited.set_bit(block_id); | |
399 _active.set_bit(block_id); | |
400 | |
401 intptr_t loop_state = 0; | |
402 for (int i = block->number_of_sux() - 1; i >= 0; i--) { | |
403 // recursively process all successors | |
404 loop_state |= mark_loops(block->sux_at(i), in_subroutine); | |
405 } | |
406 | |
407 // clear active-bit after all successors are processed | |
408 _active.clear_bit(block_id); | |
409 | |
410 // reverse-post-order numbering of all blocks | |
411 block->set_depth_first_number(_next_block_number); | |
412 _next_block_number--; | |
413 | |
414 if (loop_state != 0 || in_subroutine ) { | |
415 // block is contained at least in one loop, so phi functions are necessary | |
416 // phi functions are also necessary for all locals stored in a subroutine | |
417 scope()->requires_phi_function().set_union(block->stores_to_locals()); | |
418 } | |
419 | |
420 if (block->is_set(BlockBegin::parser_loop_header_flag)) { | |
421 int header_loop_state = _loop_map.at(block_id); | |
422 assert(is_power_of_2((unsigned)header_loop_state), "exactly one bit must be set"); | |
423 | |
424 // If the highest bit is set (i.e. when integer value is negative), the method | |
425 // has 32 or more loops. This bit is never cleared because it is used for multiple loops | |
426 if (header_loop_state >= 0) { | |
427 clear_bits(loop_state, header_loop_state); | |
428 } | |
429 } | |
430 | |
431 // cache and return loop information for this block | |
432 _loop_map.at_put(block_id, loop_state); | |
433 return loop_state; | |
434 } | |
435 | |
436 | |
437 #ifndef PRODUCT | |
438 | |
439 int compare_depth_first(BlockBegin** a, BlockBegin** b) { | |
440 return (*a)->depth_first_number() - (*b)->depth_first_number(); | |
441 } | |
442 | |
443 void BlockListBuilder::print() { | |
444 tty->print("----- initial block list of BlockListBuilder for method "); | |
445 method()->print_short_name(); | |
446 tty->cr(); | |
447 | |
448 // better readability if blocks are sorted in processing order | |
449 _blocks.sort(compare_depth_first); | |
450 | |
451 for (int i = 0; i < _blocks.length(); i++) { | |
452 BlockBegin* cur = _blocks.at(i); | |
453 tty->print("%4d: B%-4d bci: %-4d preds: %-4d ", cur->depth_first_number(), cur->block_id(), cur->bci(), cur->total_preds()); | |
454 | |
455 tty->print(cur->is_set(BlockBegin::std_entry_flag) ? " std" : " "); | |
456 tty->print(cur->is_set(BlockBegin::osr_entry_flag) ? " osr" : " "); | |
457 tty->print(cur->is_set(BlockBegin::exception_entry_flag) ? " ex" : " "); | |
458 tty->print(cur->is_set(BlockBegin::subroutine_entry_flag) ? " sr" : " "); | |
459 tty->print(cur->is_set(BlockBegin::parser_loop_header_flag) ? " lh" : " "); | |
460 | |
461 if (cur->number_of_sux() > 0) { | |
462 tty->print(" sux: "); | |
463 for (int j = 0; j < cur->number_of_sux(); j++) { | |
464 BlockBegin* sux = cur->sux_at(j); | |
465 tty->print("B%d ", sux->block_id()); | |
466 } | |
467 } | |
468 tty->cr(); | |
469 } | |
470 } | |
471 | |
472 #endif | |
473 | |
474 | |
475 // A simple growable array of Values indexed by ciFields | |
476 class FieldBuffer: public CompilationResourceObj { | |
477 private: | |
478 GrowableArray<Value> _values; | |
479 | |
480 public: | |
481 FieldBuffer() {} | |
482 | |
483 void kill() { | |
484 _values.trunc_to(0); | |
485 } | |
486 | |
487 Value at(ciField* field) { | |
488 assert(field->holder()->is_loaded(), "must be a loaded field"); | |
489 int offset = field->offset(); | |
490 if (offset < _values.length()) { | |
491 return _values.at(offset); | |
492 } else { | |
493 return NULL; | |
494 } | |
495 } | |
496 | |
497 void at_put(ciField* field, Value value) { | |
498 assert(field->holder()->is_loaded(), "must be a loaded field"); | |
499 int offset = field->offset(); | |
500 _values.at_put_grow(offset, value, NULL); | |
501 } | |
502 | |
503 }; | |
504 | |
505 | |
506 // MemoryBuffer is fairly simple model of the current state of memory. | |
507 // It partitions memory into several pieces. The first piece is | |
508 // generic memory where little is known about the owner of the memory. | |
509 // This is conceptually represented by the tuple <O, F, V> which says | |
510 // that the field F of object O has value V. This is flattened so | |
511 // that F is represented by the offset of the field and the parallel | |
512 // arrays _objects and _values are used for O and V. Loads of O.F can | |
513 // simply use V. Newly allocated objects are kept in a separate list | |
514 // along with a parallel array for each object which represents the | |
515 // current value of its fields. Stores of the default value to fields | |
516 // which have never been stored to before are eliminated since they | |
517 // are redundant. Once newly allocated objects are stored into | |
518 // another object or they are passed out of the current compile they | |
519 // are treated like generic memory. | |
520 | |
521 class MemoryBuffer: public CompilationResourceObj { | |
522 private: | |
523 FieldBuffer _values; | |
524 GrowableArray<Value> _objects; | |
525 GrowableArray<Value> _newobjects; | |
526 GrowableArray<FieldBuffer*> _fields; | |
527 | |
528 public: | |
529 MemoryBuffer() {} | |
530 | |
531 StoreField* store(StoreField* st) { | |
532 if (!EliminateFieldAccess) { | |
533 return st; | |
534 } | |
535 | |
536 Value object = st->obj(); | |
537 Value value = st->value(); | |
538 ciField* field = st->field(); | |
539 if (field->holder()->is_loaded()) { | |
540 int offset = field->offset(); | |
541 int index = _newobjects.find(object); | |
542 if (index != -1) { | |
543 // newly allocated object with no other stores performed on this field | |
544 FieldBuffer* buf = _fields.at(index); | |
545 if (buf->at(field) == NULL && is_default_value(value)) { | |
546 #ifndef PRODUCT | |
547 if (PrintIRDuringConstruction && Verbose) { | |
548 tty->print_cr("Eliminated store for object %d:", index); | |
549 st->print_line(); | |
550 } | |
551 #endif | |
552 return NULL; | |
553 } else { | |
554 buf->at_put(field, value); | |
555 } | |
556 } else { | |
557 _objects.at_put_grow(offset, object, NULL); | |
558 _values.at_put(field, value); | |
559 } | |
560 | |
561 store_value(value); | |
562 } else { | |
563 // if we held onto field names we could alias based on names but | |
564 // we don't know what's being stored to so kill it all. | |
565 kill(); | |
566 } | |
567 return st; | |
568 } | |
569 | |
570 | |
571 // return true if this value correspond to the default value of a field. | |
572 bool is_default_value(Value value) { | |
573 Constant* con = value->as_Constant(); | |
574 if (con) { | |
575 switch (con->type()->tag()) { | |
576 case intTag: return con->type()->as_IntConstant()->value() == 0; | |
577 case longTag: return con->type()->as_LongConstant()->value() == 0; | |
578 case floatTag: return jint_cast(con->type()->as_FloatConstant()->value()) == 0; | |
579 case doubleTag: return jlong_cast(con->type()->as_DoubleConstant()->value()) == jlong_cast(0); | |
580 case objectTag: return con->type() == objectNull; | |
581 default: ShouldNotReachHere(); | |
582 } | |
583 } | |
584 return false; | |
585 } | |
586 | |
587 | |
588 // return either the actual value of a load or the load itself | |
589 Value load(LoadField* load) { | |
590 if (!EliminateFieldAccess) { | |
591 return load; | |
592 } | |
593 | |
594 if (RoundFPResults && UseSSE < 2 && load->type()->is_float_kind()) { | |
595 // can't skip load since value might get rounded as a side effect | |
596 return load; | |
597 } | |
598 | |
599 ciField* field = load->field(); | |
600 Value object = load->obj(); | |
601 if (field->holder()->is_loaded() && !field->is_volatile()) { | |
602 int offset = field->offset(); | |
603 Value result = NULL; | |
604 int index = _newobjects.find(object); | |
605 if (index != -1) { | |
606 result = _fields.at(index)->at(field); | |
607 } else if (_objects.at_grow(offset, NULL) == object) { | |
608 result = _values.at(field); | |
609 } | |
610 if (result != NULL) { | |
611 #ifndef PRODUCT | |
612 if (PrintIRDuringConstruction && Verbose) { | |
613 tty->print_cr("Eliminated load: "); | |
614 load->print_line(); | |
615 } | |
616 #endif | |
617 assert(result->type()->tag() == load->type()->tag(), "wrong types"); | |
618 return result; | |
619 } | |
620 } | |
621 return load; | |
622 } | |
623 | |
624 // Record this newly allocated object | |
625 void new_instance(NewInstance* object) { | |
626 int index = _newobjects.length(); | |
627 _newobjects.append(object); | |
628 if (_fields.at_grow(index, NULL) == NULL) { | |
629 _fields.at_put(index, new FieldBuffer()); | |
630 } else { | |
631 _fields.at(index)->kill(); | |
632 } | |
633 } | |
634 | |
635 void store_value(Value value) { | |
636 int index = _newobjects.find(value); | |
637 if (index != -1) { | |
638 // stored a newly allocated object into another object. | |
639 // Assume we've lost track of it as separate slice of memory. | |
640 // We could do better by keeping track of whether individual | |
641 // fields could alias each other. | |
642 _newobjects.remove_at(index); | |
643 // pull out the field info and store it at the end up the list | |
644 // of field info list to be reused later. | |
645 _fields.append(_fields.at(index)); | |
646 _fields.remove_at(index); | |
647 } | |
648 } | |
649 | |
650 void kill() { | |
651 _newobjects.trunc_to(0); | |
652 _objects.trunc_to(0); | |
653 _values.kill(); | |
654 } | |
655 }; | |
656 | |
657 | |
658 // Implementation of GraphBuilder's ScopeData | |
659 | |
660 GraphBuilder::ScopeData::ScopeData(ScopeData* parent) | |
661 : _parent(parent) | |
662 , _bci2block(NULL) | |
663 , _scope(NULL) | |
664 , _has_handler(false) | |
665 , _stream(NULL) | |
666 , _work_list(NULL) | |
667 , _parsing_jsr(false) | |
668 , _jsr_xhandlers(NULL) | |
669 , _caller_stack_size(-1) | |
670 , _continuation(NULL) | |
671 , _num_returns(0) | |
672 , _cleanup_block(NULL) | |
673 , _cleanup_return_prev(NULL) | |
674 , _cleanup_state(NULL) | |
675 { | |
676 if (parent != NULL) { | |
677 _max_inline_size = (intx) ((float) NestedInliningSizeRatio * (float) parent->max_inline_size() / 100.0f); | |
678 } else { | |
679 _max_inline_size = MaxInlineSize; | |
680 } | |
681 if (_max_inline_size < MaxTrivialSize) { | |
682 _max_inline_size = MaxTrivialSize; | |
683 } | |
684 } | |
685 | |
686 | |
687 void GraphBuilder::kill_all() { | |
688 if (UseLocalValueNumbering) { | |
689 vmap()->kill_all(); | |
690 } | |
691 _memory->kill(); | |
692 } | |
693 | |
694 | |
695 BlockBegin* GraphBuilder::ScopeData::block_at(int bci) { | |
696 if (parsing_jsr()) { | |
697 // It is necessary to clone all blocks associated with a | |
698 // subroutine, including those for exception handlers in the scope | |
699 // of the method containing the jsr (because those exception | |
700 // handlers may contain ret instructions in some cases). | |
701 BlockBegin* block = bci2block()->at(bci); | |
702 if (block != NULL && block == parent()->bci2block()->at(bci)) { | |
703 BlockBegin* new_block = new BlockBegin(block->bci()); | |
704 #ifndef PRODUCT | |
705 if (PrintInitialBlockList) { | |
706 tty->print_cr("CFG: cloned block %d (bci %d) as block %d for jsr", | |
707 block->block_id(), block->bci(), new_block->block_id()); | |
708 } | |
709 #endif | |
710 // copy data from cloned blocked | |
711 new_block->set_depth_first_number(block->depth_first_number()); | |
712 if (block->is_set(BlockBegin::parser_loop_header_flag)) new_block->set(BlockBegin::parser_loop_header_flag); | |
713 // Preserve certain flags for assertion checking | |
714 if (block->is_set(BlockBegin::subroutine_entry_flag)) new_block->set(BlockBegin::subroutine_entry_flag); | |
715 if (block->is_set(BlockBegin::exception_entry_flag)) new_block->set(BlockBegin::exception_entry_flag); | |
716 | |
717 // copy was_visited_flag to allow early detection of bailouts | |
718 // if a block that is used in a jsr has already been visited before, | |
719 // it is shared between the normal control flow and a subroutine | |
720 // BlockBegin::try_merge returns false when the flag is set, this leads | |
721 // to a compilation bailout | |
722 if (block->is_set(BlockBegin::was_visited_flag)) new_block->set(BlockBegin::was_visited_flag); | |
723 | |
724 bci2block()->at_put(bci, new_block); | |
725 block = new_block; | |
726 } | |
727 return block; | |
728 } else { | |
729 return bci2block()->at(bci); | |
730 } | |
731 } | |
732 | |
733 | |
734 XHandlers* GraphBuilder::ScopeData::xhandlers() const { | |
735 if (_jsr_xhandlers == NULL) { | |
736 assert(!parsing_jsr(), ""); | |
737 return scope()->xhandlers(); | |
738 } | |
739 assert(parsing_jsr(), ""); | |
740 return _jsr_xhandlers; | |
741 } | |
742 | |
743 | |
744 void GraphBuilder::ScopeData::set_scope(IRScope* scope) { | |
745 _scope = scope; | |
746 bool parent_has_handler = false; | |
747 if (parent() != NULL) { | |
748 parent_has_handler = parent()->has_handler(); | |
749 } | |
750 _has_handler = parent_has_handler || scope->xhandlers()->has_handlers(); | |
751 } | |
752 | |
753 | |
754 void GraphBuilder::ScopeData::set_inline_cleanup_info(BlockBegin* block, | |
755 Instruction* return_prev, | |
756 ValueStack* return_state) { | |
757 _cleanup_block = block; | |
758 _cleanup_return_prev = return_prev; | |
759 _cleanup_state = return_state; | |
760 } | |
761 | |
762 | |
763 void GraphBuilder::ScopeData::add_to_work_list(BlockBegin* block) { | |
764 if (_work_list == NULL) { | |
765 _work_list = new BlockList(); | |
766 } | |
767 | |
768 if (!block->is_set(BlockBegin::is_on_work_list_flag)) { | |
769 // Do not start parsing the continuation block while in a | |
770 // sub-scope | |
771 if (parsing_jsr()) { | |
772 if (block == jsr_continuation()) { | |
773 return; | |
774 } | |
775 } else { | |
776 if (block == continuation()) { | |
777 return; | |
778 } | |
779 } | |
780 block->set(BlockBegin::is_on_work_list_flag); | |
781 _work_list->push(block); | |
782 | |
783 sort_top_into_worklist(_work_list, block); | |
784 } | |
785 } | |
786 | |
787 | |
788 void GraphBuilder::sort_top_into_worklist(BlockList* worklist, BlockBegin* top) { | |
789 assert(worklist->top() == top, ""); | |
790 // sort block descending into work list | |
791 const int dfn = top->depth_first_number(); | |
792 assert(dfn != -1, "unknown depth first number"); | |
793 int i = worklist->length()-2; | |
794 while (i >= 0) { | |
795 BlockBegin* b = worklist->at(i); | |
796 if (b->depth_first_number() < dfn) { | |
797 worklist->at_put(i+1, b); | |
798 } else { | |
799 break; | |
800 } | |
801 i --; | |
802 } | |
803 if (i >= -1) worklist->at_put(i + 1, top); | |
804 } | |
805 | |
806 | |
807 BlockBegin* GraphBuilder::ScopeData::remove_from_work_list() { | |
808 if (is_work_list_empty()) { | |
809 return NULL; | |
810 } | |
811 return _work_list->pop(); | |
812 } | |
813 | |
814 | |
815 bool GraphBuilder::ScopeData::is_work_list_empty() const { | |
816 return (_work_list == NULL || _work_list->length() == 0); | |
817 } | |
818 | |
819 | |
820 void GraphBuilder::ScopeData::setup_jsr_xhandlers() { | |
821 assert(parsing_jsr(), ""); | |
822 // clone all the exception handlers from the scope | |
823 XHandlers* handlers = new XHandlers(scope()->xhandlers()); | |
824 const int n = handlers->length(); | |
825 for (int i = 0; i < n; i++) { | |
826 // The XHandlers need to be adjusted to dispatch to the cloned | |
827 // handler block instead of the default one but the synthetic | |
828 // unlocker needs to be handled specially. The synthetic unlocker | |
829 // should be left alone since there can be only one and all code | |
830 // should dispatch to the same one. | |
831 XHandler* h = handlers->handler_at(i); | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1295
diff
changeset
|
832 assert(h->handler_bci() != SynchronizationEntryBCI, "must be real"); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1295
diff
changeset
|
833 h->set_entry_block(block_at(h->handler_bci())); |
0 | 834 } |
835 _jsr_xhandlers = handlers; | |
836 } | |
837 | |
838 | |
839 int GraphBuilder::ScopeData::num_returns() { | |
840 if (parsing_jsr()) { | |
841 return parent()->num_returns(); | |
842 } | |
843 return _num_returns; | |
844 } | |
845 | |
846 | |
847 void GraphBuilder::ScopeData::incr_num_returns() { | |
848 if (parsing_jsr()) { | |
849 parent()->incr_num_returns(); | |
850 } else { | |
851 ++_num_returns; | |
852 } | |
853 } | |
854 | |
855 | |
856 // Implementation of GraphBuilder | |
857 | |
858 #define INLINE_BAILOUT(msg) { inline_bailout(msg); return false; } | |
859 | |
860 | |
861 void GraphBuilder::load_constant() { | |
862 ciConstant con = stream()->get_constant(); | |
863 if (con.basic_type() == T_ILLEGAL) { | |
864 BAILOUT("could not resolve a constant"); | |
865 } else { | |
866 ValueType* t = illegalType; | |
867 ValueStack* patch_state = NULL; | |
868 switch (con.basic_type()) { | |
869 case T_BOOLEAN: t = new IntConstant (con.as_boolean()); break; | |
870 case T_BYTE : t = new IntConstant (con.as_byte ()); break; | |
871 case T_CHAR : t = new IntConstant (con.as_char ()); break; | |
872 case T_SHORT : t = new IntConstant (con.as_short ()); break; | |
873 case T_INT : t = new IntConstant (con.as_int ()); break; | |
874 case T_LONG : t = new LongConstant (con.as_long ()); break; | |
875 case T_FLOAT : t = new FloatConstant (con.as_float ()); break; | |
876 case T_DOUBLE : t = new DoubleConstant (con.as_double ()); break; | |
877 case T_ARRAY : t = new ArrayConstant (con.as_object ()->as_array ()); break; | |
878 case T_OBJECT : | |
879 { | |
880 ciObject* obj = con.as_object(); | |
1602 | 881 if (!obj->is_loaded() |
882 || (PatchALot && obj->klass() != ciEnv::current()->String_klass())) { | |
1819 | 883 patch_state = copy_state_before(); |
1602 | 884 t = new ObjectConstant(obj); |
0 | 885 } else { |
1602 | 886 assert(!obj->is_klass(), "must be java_mirror of klass"); |
0 | 887 t = new InstanceConstant(obj->as_instance()); |
888 } | |
889 break; | |
890 } | |
891 default : ShouldNotReachHere(); | |
892 } | |
893 Value x; | |
894 if (patch_state != NULL) { | |
895 x = new Constant(t, patch_state); | |
896 } else { | |
897 x = new Constant(t); | |
898 } | |
899 push(t, append(x)); | |
900 } | |
901 } | |
902 | |
903 | |
904 void GraphBuilder::load_local(ValueType* type, int index) { | |
1819 | 905 Value x = state()->local_at(index); |
906 assert(x != NULL && !x->type()->is_illegal(), "access of illegal local variable"); | |
0 | 907 push(type, x); |
908 } | |
909 | |
910 | |
911 void GraphBuilder::store_local(ValueType* type, int index) { | |
912 Value x = pop(type); | |
913 store_local(state(), x, type, index); | |
914 } | |
915 | |
916 | |
917 void GraphBuilder::store_local(ValueStack* state, Value x, ValueType* type, int index) { | |
918 if (parsing_jsr()) { | |
919 // We need to do additional tracking of the location of the return | |
920 // address for jsrs since we don't handle arbitrary jsr/ret | |
921 // constructs. Here we are figuring out in which circumstances we | |
922 // need to bail out. | |
923 if (x->type()->is_address()) { | |
924 scope_data()->set_jsr_return_address_local(index); | |
925 | |
926 // Also check parent jsrs (if any) at this time to see whether | |
927 // they are using this local. We don't handle skipping over a | |
928 // ret. | |
929 for (ScopeData* cur_scope_data = scope_data()->parent(); | |
930 cur_scope_data != NULL && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope(); | |
931 cur_scope_data = cur_scope_data->parent()) { | |
932 if (cur_scope_data->jsr_return_address_local() == index) { | |
933 BAILOUT("subroutine overwrites return address from previous subroutine"); | |
934 } | |
935 } | |
936 } else if (index == scope_data()->jsr_return_address_local()) { | |
937 scope_data()->set_jsr_return_address_local(-1); | |
938 } | |
939 } | |
940 | |
941 state->store_local(index, round_fp(x)); | |
942 } | |
943 | |
944 | |
945 void GraphBuilder::load_indexed(BasicType type) { | |
1819 | 946 ValueStack* state_before = copy_state_for_exception(); |
0 | 947 Value index = ipop(); |
948 Value array = apop(); | |
949 Value length = NULL; | |
950 if (CSEArrayLength || | |
951 (array->as_AccessField() && array->as_AccessField()->field()->is_constant()) || | |
952 (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) { | |
1819 | 953 length = append(new ArrayLength(array, state_before)); |
0 | 954 } |
1819 | 955 push(as_ValueType(type), append(new LoadIndexed(array, index, length, type, state_before))); |
0 | 956 } |
957 | |
958 | |
959 void GraphBuilder::store_indexed(BasicType type) { | |
1819 | 960 ValueStack* state_before = copy_state_for_exception(); |
0 | 961 Value value = pop(as_ValueType(type)); |
962 Value index = ipop(); | |
963 Value array = apop(); | |
964 Value length = NULL; | |
965 if (CSEArrayLength || | |
966 (array->as_AccessField() && array->as_AccessField()->field()->is_constant()) || | |
967 (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) { | |
1819 | 968 length = append(new ArrayLength(array, state_before)); |
0 | 969 } |
1819 | 970 StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before); |
0 | 971 append(result); |
459 | 972 _memory->store_value(value); |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
973 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
974 if (type == T_OBJECT && is_profiling()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
975 // Note that we'd collect profile data in this method if we wanted it. |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
976 compilation()->set_would_profile(true); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
977 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
978 if (profile_checkcasts()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
979 result->set_profiled_method(method()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
980 result->set_profiled_bci(bci()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
981 result->set_should_profile(true); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
982 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
983 } |
0 | 984 } |
985 | |
986 | |
987 void GraphBuilder::stack_op(Bytecodes::Code code) { | |
988 switch (code) { | |
989 case Bytecodes::_pop: | |
990 { state()->raw_pop(); | |
991 } | |
992 break; | |
993 case Bytecodes::_pop2: | |
994 { state()->raw_pop(); | |
995 state()->raw_pop(); | |
996 } | |
997 break; | |
998 case Bytecodes::_dup: | |
999 { Value w = state()->raw_pop(); | |
1000 state()->raw_push(w); | |
1001 state()->raw_push(w); | |
1002 } | |
1003 break; | |
1004 case Bytecodes::_dup_x1: | |
1005 { Value w1 = state()->raw_pop(); | |
1006 Value w2 = state()->raw_pop(); | |
1007 state()->raw_push(w1); | |
1008 state()->raw_push(w2); | |
1009 state()->raw_push(w1); | |
1010 } | |
1011 break; | |
1012 case Bytecodes::_dup_x2: | |
1013 { Value w1 = state()->raw_pop(); | |
1014 Value w2 = state()->raw_pop(); | |
1015 Value w3 = state()->raw_pop(); | |
1016 state()->raw_push(w1); | |
1017 state()->raw_push(w3); | |
1018 state()->raw_push(w2); | |
1019 state()->raw_push(w1); | |
1020 } | |
1021 break; | |
1022 case Bytecodes::_dup2: | |
1023 { Value w1 = state()->raw_pop(); | |
1024 Value w2 = state()->raw_pop(); | |
1025 state()->raw_push(w2); | |
1026 state()->raw_push(w1); | |
1027 state()->raw_push(w2); | |
1028 state()->raw_push(w1); | |
1029 } | |
1030 break; | |
1031 case Bytecodes::_dup2_x1: | |
1032 { Value w1 = state()->raw_pop(); | |
1033 Value w2 = state()->raw_pop(); | |
1034 Value w3 = state()->raw_pop(); | |
1035 state()->raw_push(w2); | |
1036 state()->raw_push(w1); | |
1037 state()->raw_push(w3); | |
1038 state()->raw_push(w2); | |
1039 state()->raw_push(w1); | |
1040 } | |
1041 break; | |
1042 case Bytecodes::_dup2_x2: | |
1043 { Value w1 = state()->raw_pop(); | |
1044 Value w2 = state()->raw_pop(); | |
1045 Value w3 = state()->raw_pop(); | |
1046 Value w4 = state()->raw_pop(); | |
1047 state()->raw_push(w2); | |
1048 state()->raw_push(w1); | |
1049 state()->raw_push(w4); | |
1050 state()->raw_push(w3); | |
1051 state()->raw_push(w2); | |
1052 state()->raw_push(w1); | |
1053 } | |
1054 break; | |
1055 case Bytecodes::_swap: | |
1056 { Value w1 = state()->raw_pop(); | |
1057 Value w2 = state()->raw_pop(); | |
1058 state()->raw_push(w1); | |
1059 state()->raw_push(w2); | |
1060 } | |
1061 break; | |
1062 default: | |
1063 ShouldNotReachHere(); | |
1064 break; | |
1065 } | |
1066 } | |
1067 | |
1068 | |
1819 | 1069 void GraphBuilder::arithmetic_op(ValueType* type, Bytecodes::Code code, ValueStack* state_before) { |
0 | 1070 Value y = pop(type); |
1071 Value x = pop(type); | |
1072 // NOTE: strictfp can be queried from current method since we don't | |
1073 // inline methods with differing strictfp bits | |
1819 | 1074 Value res = new ArithmeticOp(code, x, y, method()->is_strict(), state_before); |
0 | 1075 // Note: currently single-precision floating-point rounding on Intel is handled at the LIRGenerator level |
1076 res = append(res); | |
1077 if (method()->is_strict()) { | |
1078 res = round_fp(res); | |
1079 } | |
1080 push(type, res); | |
1081 } | |
1082 | |
1083 | |
1084 void GraphBuilder::negate_op(ValueType* type) { | |
1085 push(type, append(new NegateOp(pop(type)))); | |
1086 } | |
1087 | |
1088 | |
1089 void GraphBuilder::shift_op(ValueType* type, Bytecodes::Code code) { | |
1090 Value s = ipop(); | |
1091 Value x = pop(type); | |
1092 // try to simplify | |
1093 // Note: This code should go into the canonicalizer as soon as it can | |
1094 // can handle canonicalized forms that contain more than one node. | |
1095 if (CanonicalizeNodes && code == Bytecodes::_iushr) { | |
1096 // pattern: x >>> s | |
1097 IntConstant* s1 = s->type()->as_IntConstant(); | |
1098 if (s1 != NULL) { | |
1099 // pattern: x >>> s1, with s1 constant | |
1100 ShiftOp* l = x->as_ShiftOp(); | |
1101 if (l != NULL && l->op() == Bytecodes::_ishl) { | |
1102 // pattern: (a << b) >>> s1 | |
1103 IntConstant* s0 = l->y()->type()->as_IntConstant(); | |
1104 if (s0 != NULL) { | |
1105 // pattern: (a << s0) >>> s1 | |
1106 const int s0c = s0->value() & 0x1F; // only the low 5 bits are significant for shifts | |
1107 const int s1c = s1->value() & 0x1F; // only the low 5 bits are significant for shifts | |
1108 if (s0c == s1c) { | |
1109 if (s0c == 0) { | |
1110 // pattern: (a << 0) >>> 0 => simplify to: a | |
1111 ipush(l->x()); | |
1112 } else { | |
1113 // pattern: (a << s0c) >>> s0c => simplify to: a & m, with m constant | |
1114 assert(0 < s0c && s0c < BitsPerInt, "adjust code below to handle corner cases"); | |
1115 const int m = (1 << (BitsPerInt - s0c)) - 1; | |
1116 Value s = append(new Constant(new IntConstant(m))); | |
1117 ipush(append(new LogicOp(Bytecodes::_iand, l->x(), s))); | |
1118 } | |
1119 return; | |
1120 } | |
1121 } | |
1122 } | |
1123 } | |
1124 } | |
1125 // could not simplify | |
1126 push(type, append(new ShiftOp(code, x, s))); | |
1127 } | |
1128 | |
1129 | |
1130 void GraphBuilder::logic_op(ValueType* type, Bytecodes::Code code) { | |
1131 Value y = pop(type); | |
1132 Value x = pop(type); | |
1133 push(type, append(new LogicOp(code, x, y))); | |
1134 } | |
1135 | |
1136 | |
1137 void GraphBuilder::compare_op(ValueType* type, Bytecodes::Code code) { | |
1819 | 1138 ValueStack* state_before = copy_state_before(); |
0 | 1139 Value y = pop(type); |
1140 Value x = pop(type); | |
1141 ipush(append(new CompareOp(code, x, y, state_before))); | |
1142 } | |
1143 | |
1144 | |
1145 void GraphBuilder::convert(Bytecodes::Code op, BasicType from, BasicType to) { | |
1146 push(as_ValueType(to), append(new Convert(op, pop(as_ValueType(from)), as_ValueType(to)))); | |
1147 } | |
1148 | |
1149 | |
1150 void GraphBuilder::increment() { | |
1151 int index = stream()->get_index(); | |
1152 int delta = stream()->is_wide() ? (signed short)Bytes::get_Java_u2(stream()->cur_bcp() + 4) : (signed char)(stream()->cur_bcp()[2]); | |
1153 load_local(intType, index); | |
1154 ipush(append(new Constant(new IntConstant(delta)))); | |
1155 arithmetic_op(intType, Bytecodes::_iadd); | |
1156 store_local(intType, index); | |
1157 } | |
1158 | |
1159 | |
1160 void GraphBuilder::_goto(int from_bci, int to_bci) { | |
1783 | 1161 Goto *x = new Goto(block_at(to_bci), to_bci <= from_bci); |
1162 if (is_profiling()) { | |
1163 compilation()->set_would_profile(true); | |
1164 } | |
1165 if (profile_branches()) { | |
1166 x->set_profiled_method(method()); | |
1167 x->set_profiled_bci(bci()); | |
1168 x->set_should_profile(true); | |
1169 } | |
1170 append(x); | |
0 | 1171 } |
1172 | |
1173 | |
1174 void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* state_before) { | |
1175 BlockBegin* tsux = block_at(stream()->get_dest()); | |
1176 BlockBegin* fsux = block_at(stream()->next_bci()); | |
1177 bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci(); | |
1783 | 1178 Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb)); |
1179 | |
1180 if (is_profiling()) { | |
1181 If* if_node = i->as_If(); | |
1182 if (if_node != NULL) { | |
1183 // Note that we'd collect profile data in this method if we wanted it. | |
1184 compilation()->set_would_profile(true); | |
1185 // At level 2 we need the proper bci to count backedges | |
1186 if_node->set_profiled_bci(bci()); | |
1187 if (profile_branches()) { | |
1188 // Successors can be rotated by the canonicalizer, check for this case. | |
1189 if_node->set_profiled_method(method()); | |
1190 if_node->set_should_profile(true); | |
1191 if (if_node->tsux() == fsux) { | |
1192 if_node->set_swapped(true); | |
1193 } | |
1194 } | |
1195 return; | |
1196 } | |
1197 | |
1198 // Check if this If was reduced to Goto. | |
1199 Goto *goto_node = i->as_Goto(); | |
1200 if (goto_node != NULL) { | |
1201 compilation()->set_would_profile(true); | |
1202 if (profile_branches()) { | |
1203 goto_node->set_profiled_method(method()); | |
1204 goto_node->set_profiled_bci(bci()); | |
1205 goto_node->set_should_profile(true); | |
1206 // Find out which successor is used. | |
1207 if (goto_node->default_sux() == tsux) { | |
1208 goto_node->set_direction(Goto::taken); | |
1209 } else if (goto_node->default_sux() == fsux) { | |
1210 goto_node->set_direction(Goto::not_taken); | |
1211 } else { | |
1212 ShouldNotReachHere(); | |
1213 } | |
1214 } | |
1215 return; | |
1216 } | |
0 | 1217 } |
1218 } | |
1219 | |
1220 | |
1221 void GraphBuilder::if_zero(ValueType* type, If::Condition cond) { | |
1222 Value y = append(new Constant(intZero)); | |
1819 | 1223 ValueStack* state_before = copy_state_before(); |
0 | 1224 Value x = ipop(); |
1225 if_node(x, cond, y, state_before); | |
1226 } | |
1227 | |
1228 | |
1229 void GraphBuilder::if_null(ValueType* type, If::Condition cond) { | |
1230 Value y = append(new Constant(objectNull)); | |
1819 | 1231 ValueStack* state_before = copy_state_before(); |
0 | 1232 Value x = apop(); |
1233 if_node(x, cond, y, state_before); | |
1234 } | |
1235 | |
1236 | |
1237 void GraphBuilder::if_same(ValueType* type, If::Condition cond) { | |
1819 | 1238 ValueStack* state_before = copy_state_before(); |
0 | 1239 Value y = pop(type); |
1240 Value x = pop(type); | |
1241 if_node(x, cond, y, state_before); | |
1242 } | |
1243 | |
1244 | |
1245 void GraphBuilder::jsr(int dest) { | |
1246 // We only handle well-formed jsrs (those which are "block-structured"). | |
1247 // If the bytecodes are strange (jumping out of a jsr block) then we | |
1248 // might end up trying to re-parse a block containing a jsr which | |
1249 // has already been activated. Watch for this case and bail out. | |
1250 for (ScopeData* cur_scope_data = scope_data(); | |
1251 cur_scope_data != NULL && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope(); | |
1252 cur_scope_data = cur_scope_data->parent()) { | |
1253 if (cur_scope_data->jsr_entry_bci() == dest) { | |
1254 BAILOUT("too-complicated jsr/ret structure"); | |
1255 } | |
1256 } | |
1257 | |
1258 push(addressType, append(new Constant(new AddressConstant(next_bci())))); | |
1259 if (!try_inline_jsr(dest)) { | |
1260 return; // bailed out while parsing and inlining subroutine | |
1261 } | |
1262 } | |
1263 | |
1264 | |
1265 void GraphBuilder::ret(int local_index) { | |
1266 if (!parsing_jsr()) BAILOUT("ret encountered while not parsing subroutine"); | |
1267 | |
1268 if (local_index != scope_data()->jsr_return_address_local()) { | |
1269 BAILOUT("can not handle complicated jsr/ret constructs"); | |
1270 } | |
1271 | |
1272 // Rets simply become (NON-SAFEPOINT) gotos to the jsr continuation | |
1273 append(new Goto(scope_data()->jsr_continuation(), false)); | |
1274 } | |
1275 | |
1276 | |
1277 void GraphBuilder::table_switch() { | |
1278 Bytecode_tableswitch* switch_ = Bytecode_tableswitch_at(method()->code() + bci()); | |
1279 const int l = switch_->length(); | |
1280 if (CanonicalizeNodes && l == 1) { | |
1281 // total of 2 successors => use If instead of switch | |
1282 // Note: This code should go into the canonicalizer as soon as it can | |
1283 // can handle canonicalized forms that contain more than one node. | |
1284 Value key = append(new Constant(new IntConstant(switch_->low_key()))); | |
1285 BlockBegin* tsux = block_at(bci() + switch_->dest_offset_at(0)); | |
1286 BlockBegin* fsux = block_at(bci() + switch_->default_offset()); | |
1287 bool is_bb = tsux->bci() < bci() || fsux->bci() < bci(); | |
1819 | 1288 ValueStack* state_before = is_bb ? copy_state_before() : NULL; |
0 | 1289 append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb)); |
1290 } else { | |
1291 // collect successors | |
1292 BlockList* sux = new BlockList(l + 1, NULL); | |
1293 int i; | |
1294 bool has_bb = false; | |
1295 for (i = 0; i < l; i++) { | |
1296 sux->at_put(i, block_at(bci() + switch_->dest_offset_at(i))); | |
1297 if (switch_->dest_offset_at(i) < 0) has_bb = true; | |
1298 } | |
1299 // add default successor | |
1300 sux->at_put(i, block_at(bci() + switch_->default_offset())); | |
1819 | 1301 ValueStack* state_before = has_bb ? copy_state_before() : NULL; |
0 | 1302 append(new TableSwitch(ipop(), sux, switch_->low_key(), state_before, has_bb)); |
1303 } | |
1304 } | |
1305 | |
1306 | |
1307 void GraphBuilder::lookup_switch() { | |
1308 Bytecode_lookupswitch* switch_ = Bytecode_lookupswitch_at(method()->code() + bci()); | |
1309 const int l = switch_->number_of_pairs(); | |
1310 if (CanonicalizeNodes && l == 1) { | |
1311 // total of 2 successors => use If instead of switch | |
1312 // Note: This code should go into the canonicalizer as soon as it can | |
1313 // can handle canonicalized forms that contain more than one node. | |
1314 // simplify to If | |
1315 LookupswitchPair* pair = switch_->pair_at(0); | |
1316 Value key = append(new Constant(new IntConstant(pair->match()))); | |
1317 BlockBegin* tsux = block_at(bci() + pair->offset()); | |
1318 BlockBegin* fsux = block_at(bci() + switch_->default_offset()); | |
1319 bool is_bb = tsux->bci() < bci() || fsux->bci() < bci(); | |
1819 | 1320 ValueStack* state_before = is_bb ? copy_state_before() : NULL; |
0 | 1321 append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb)); |
1322 } else { | |
1323 // collect successors & keys | |
1324 BlockList* sux = new BlockList(l + 1, NULL); | |
1325 intArray* keys = new intArray(l, 0); | |
1326 int i; | |
1327 bool has_bb = false; | |
1328 for (i = 0; i < l; i++) { | |
1329 LookupswitchPair* pair = switch_->pair_at(i); | |
1330 if (pair->offset() < 0) has_bb = true; | |
1331 sux->at_put(i, block_at(bci() + pair->offset())); | |
1332 keys->at_put(i, pair->match()); | |
1333 } | |
1334 // add default successor | |
1335 sux->at_put(i, block_at(bci() + switch_->default_offset())); | |
1819 | 1336 ValueStack* state_before = has_bb ? copy_state_before() : NULL; |
0 | 1337 append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb)); |
1338 } | |
1339 } | |
1340 | |
1341 void GraphBuilder::call_register_finalizer() { | |
1342 // If the receiver requires finalization then emit code to perform | |
1343 // the registration on return. | |
1344 | |
1345 // Gather some type information about the receiver | |
1819 | 1346 Value receiver = state()->local_at(0); |
0 | 1347 assert(receiver != NULL, "must have a receiver"); |
1348 ciType* declared_type = receiver->declared_type(); | |
1349 ciType* exact_type = receiver->exact_type(); | |
1350 if (exact_type == NULL && | |
1351 receiver->as_Local() && | |
1352 receiver->as_Local()->java_index() == 0) { | |
1353 ciInstanceKlass* ik = compilation()->method()->holder(); | |
1354 if (ik->is_final()) { | |
1355 exact_type = ik; | |
1356 } else if (UseCHA && !(ik->has_subklass() || ik->is_interface())) { | |
1357 // test class is leaf class | |
1358 compilation()->dependency_recorder()->assert_leaf_type(ik); | |
1359 exact_type = ik; | |
1360 } else { | |
1361 declared_type = ik; | |
1362 } | |
1363 } | |
1364 | |
1365 // see if we know statically that registration isn't required | |
1366 bool needs_check = true; | |
1367 if (exact_type != NULL) { | |
1368 needs_check = exact_type->as_instance_klass()->has_finalizer(); | |
1369 } else if (declared_type != NULL) { | |
1370 ciInstanceKlass* ik = declared_type->as_instance_klass(); | |
1371 if (!Dependencies::has_finalizable_subclass(ik)) { | |
1372 compilation()->dependency_recorder()->assert_has_no_finalizable_subclasses(ik); | |
1373 needs_check = false; | |
1374 } | |
1375 } | |
1376 | |
1377 if (needs_check) { | |
1378 // Perform the registration of finalizable objects. | |
1819 | 1379 ValueStack* state_before = copy_state_for_exception(); |
0 | 1380 load_local(objectType, 0); |
1381 append_split(new Intrinsic(voidType, vmIntrinsics::_Object_init, | |
1382 state()->pop_arguments(1), | |
1819 | 1383 true, state_before, true)); |
0 | 1384 } |
1385 } | |
1386 | |
1387 | |
1388 void GraphBuilder::method_return(Value x) { | |
1389 if (RegisterFinalizersAtInit && | |
1390 method()->intrinsic_id() == vmIntrinsics::_Object_init) { | |
1391 call_register_finalizer(); | |
1392 } | |
1393 | |
1394 // Check to see whether we are inlining. If so, Return | |
1395 // instructions become Gotos to the continuation point. | |
1396 if (continuation() != NULL) { | |
1397 assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet"); | |
1398 | |
1399 // If the inlined method is synchronized, the monitor must be | |
1400 // released before we jump to the continuation block. | |
1401 if (method()->is_synchronized()) { | |
1819 | 1402 assert(state()->locks_size() == 1, "receiver must be locked here"); |
1403 monitorexit(state()->lock_at(0), SynchronizationEntryBCI); | |
0 | 1404 } |
1405 | |
1819 | 1406 // State at end of inlined method is the state of the caller |
1407 // without the method parameters on stack, including the | |
1408 // return value, if any, of the inlined method on operand stack. | |
1409 set_state(state()->caller_state()->copy_for_parsing()); | |
0 | 1410 if (x != NULL) { |
1411 state()->push(x->type(), x); | |
1412 } | |
1413 Goto* goto_callee = new Goto(continuation(), false); | |
1414 | |
1415 // See whether this is the first return; if so, store off some | |
1416 // of the state for later examination | |
1417 if (num_returns() == 0) { | |
1418 set_inline_cleanup_info(_block, _last, state()); | |
1419 } | |
1420 | |
1421 // The current bci() is in the wrong scope, so use the bci() of | |
1422 // the continuation point. | |
1423 append_with_bci(goto_callee, scope_data()->continuation()->bci()); | |
1424 incr_num_returns(); | |
1425 | |
1426 return; | |
1427 } | |
1428 | |
1429 state()->truncate_stack(0); | |
1430 if (method()->is_synchronized()) { | |
1431 // perform the unlocking before exiting the method | |
1432 Value receiver; | |
1433 if (!method()->is_static()) { | |
1434 receiver = _initial_state->local_at(0); | |
1435 } else { | |
1436 receiver = append(new Constant(new ClassConstant(method()->holder()))); | |
1437 } | |
1438 append_split(new MonitorExit(receiver, state()->unlock())); | |
1439 } | |
1440 | |
1441 append(new Return(x)); | |
1442 } | |
1443 | |
1444 | |
1445 void GraphBuilder::access_field(Bytecodes::Code code) { | |
1446 bool will_link; | |
1447 ciField* field = stream()->get_field(will_link); | |
1448 ciInstanceKlass* holder = field->holder(); | |
1449 BasicType field_type = field->type()->basic_type(); | |
1450 ValueType* type = as_ValueType(field_type); | |
1451 // call will_link again to determine if the field is valid. | |
1452 const bool is_loaded = holder->is_loaded() && | |
1453 field->will_link(method()->holder(), code); | |
1454 const bool is_initialized = is_loaded && holder->is_initialized(); | |
1455 | |
1819 | 1456 ValueStack* state_before = NULL; |
0 | 1457 if (!is_initialized || PatchALot) { |
1458 // save state before instruction for debug info when | |
1459 // deoptimization happens during patching | |
1819 | 1460 state_before = copy_state_before(); |
0 | 1461 } |
1462 | |
1463 Value obj = NULL; | |
1464 if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) { | |
1465 // commoning of class constants should only occur if the class is | |
1466 // fully initialized and resolved in this constant pool. The will_link test | |
1467 // above essentially checks if this class is resolved in this constant pool | |
1468 // so, the is_initialized flag should be suffiect. | |
1819 | 1469 if (state_before != NULL) { |
0 | 1470 // build a patching constant |
1819 | 1471 obj = new Constant(new ClassConstant(holder), state_before); |
0 | 1472 } else { |
1473 obj = new Constant(new ClassConstant(holder)); | |
1474 } | |
1475 } | |
1476 | |
1477 | |
1478 const int offset = is_loaded ? field->offset() : -1; | |
1479 switch (code) { | |
1480 case Bytecodes::_getstatic: { | |
1481 // check for compile-time constants, i.e., initialized static final fields | |
1482 Instruction* constant = NULL; | |
1483 if (field->is_constant() && !PatchALot) { | |
1484 ciConstant field_val = field->constant_value(); | |
1485 BasicType field_type = field_val.basic_type(); | |
1486 switch (field_type) { | |
1487 case T_ARRAY: | |
1488 case T_OBJECT: | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
844
diff
changeset
|
1489 if (field_val.as_object()->should_be_constant()) { |
0 | 1490 constant = new Constant(as_ValueType(field_val)); |
1491 } | |
1492 break; | |
1493 | |
1494 default: | |
1495 constant = new Constant(as_ValueType(field_val)); | |
1496 } | |
1497 } | |
1498 if (constant != NULL) { | |
1499 push(type, append(constant)); | |
1500 } else { | |
1819 | 1501 if (state_before == NULL) { |
1502 state_before = copy_state_for_exception(); | |
1503 } | |
0 | 1504 push(type, append(new LoadField(append(obj), offset, field, true, |
1819 | 1505 state_before, is_loaded, is_initialized))); |
0 | 1506 } |
1507 break; | |
1508 } | |
1509 case Bytecodes::_putstatic: | |
1510 { Value val = pop(type); | |
1819 | 1511 if (state_before == NULL) { |
1512 state_before = copy_state_for_exception(); | |
1513 } | |
1514 append(new StoreField(append(obj), offset, field, val, true, state_before, is_loaded, is_initialized)); | |
0 | 1515 } |
1516 break; | |
1517 case Bytecodes::_getfield : | |
1518 { | |
1819 | 1519 if (state_before == NULL) { |
1520 state_before = copy_state_for_exception(); | |
1521 } | |
1522 LoadField* load = new LoadField(apop(), offset, field, false, state_before, is_loaded, true); | |
0 | 1523 Value replacement = is_loaded ? _memory->load(load) : load; |
1524 if (replacement != load) { | |
1819 | 1525 assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked"); |
0 | 1526 push(type, replacement); |
1527 } else { | |
1528 push(type, append(load)); | |
1529 } | |
1530 break; | |
1531 } | |
1532 | |
1533 case Bytecodes::_putfield : | |
1534 { Value val = pop(type); | |
1819 | 1535 if (state_before == NULL) { |
1536 state_before = copy_state_for_exception(); | |
1537 } | |
1538 StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, is_loaded, true); | |
0 | 1539 if (is_loaded) store = _memory->store(store); |
1540 if (store != NULL) { | |
1541 append(store); | |
1542 } | |
1543 } | |
1544 break; | |
1545 default : | |
1546 ShouldNotReachHere(); | |
1547 break; | |
1548 } | |
1549 } | |
1550 | |
1551 | |
1552 Dependencies* GraphBuilder::dependency_recorder() const { | |
1553 assert(DeoptC1, "need debug information"); | |
1554 return compilation()->dependency_recorder(); | |
1555 } | |
1556 | |
1557 | |
1558 void GraphBuilder::invoke(Bytecodes::Code code) { | |
1559 bool will_link; | |
1560 ciMethod* target = stream()->get_method(will_link); | |
1561 // we have to make sure the argument size (incl. the receiver) | |
1562 // is correct for compilation (the call would fail later during | |
1563 // linkage anyway) - was bug (gri 7/28/99) | |
1564 if (target->is_loaded() && target->is_static() != (code == Bytecodes::_invokestatic)) BAILOUT("will cause link error"); | |
1565 ciInstanceKlass* klass = target->holder(); | |
1566 | |
1567 // check if CHA possible: if so, change the code to invoke_special | |
1568 ciInstanceKlass* calling_klass = method()->holder(); | |
1569 ciKlass* holder = stream()->get_declared_method_holder(); | |
1570 ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder); | |
1571 ciInstanceKlass* actual_recv = callee_holder; | |
1572 | |
1573 // some methods are obviously bindable without any type checks so | |
1574 // convert them directly to an invokespecial. | |
1575 if (target->is_loaded() && !target->is_abstract() && | |
1576 target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) { | |
1577 code = Bytecodes::_invokespecial; | |
1578 } | |
1579 | |
1580 // NEEDS_CLEANUP | |
1581 // I've added the target-is_loaded() test below but I don't really understand | |
1582 // how klass->is_loaded() can be true and yet target->is_loaded() is false. | |
1583 // this happened while running the JCK invokevirtual tests under doit. TKR | |
1584 ciMethod* cha_monomorphic_target = NULL; | |
1585 ciMethod* exact_target = NULL; | |
1295 | 1586 if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() && |
1587 !target->is_method_handle_invoke()) { | |
0 | 1588 Value receiver = NULL; |
1589 ciInstanceKlass* receiver_klass = NULL; | |
1590 bool type_is_exact = false; | |
1591 // try to find a precise receiver type | |
1592 if (will_link && !target->is_static()) { | |
1593 int index = state()->stack_size() - (target->arg_size_no_receiver() + 1); | |
1594 receiver = state()->stack_at(index); | |
1595 ciType* type = receiver->exact_type(); | |
1596 if (type != NULL && type->is_loaded() && | |
1597 type->is_instance_klass() && !type->as_instance_klass()->is_interface()) { | |
1598 receiver_klass = (ciInstanceKlass*) type; | |
1599 type_is_exact = true; | |
1600 } | |
1601 if (type == NULL) { | |
1602 type = receiver->declared_type(); | |
1603 if (type != NULL && type->is_loaded() && | |
1604 type->is_instance_klass() && !type->as_instance_klass()->is_interface()) { | |
1605 receiver_klass = (ciInstanceKlass*) type; | |
1606 if (receiver_klass->is_leaf_type() && !receiver_klass->is_final()) { | |
1607 // Insert a dependency on this type since | |
1608 // find_monomorphic_target may assume it's already done. | |
1609 dependency_recorder()->assert_leaf_type(receiver_klass); | |
1610 type_is_exact = true; | |
1611 } | |
1612 } | |
1613 } | |
1614 } | |
1615 if (receiver_klass != NULL && type_is_exact && | |
1616 receiver_klass->is_loaded() && code != Bytecodes::_invokespecial) { | |
1617 // If we have the exact receiver type we can bind directly to | |
1618 // the method to call. | |
1619 exact_target = target->resolve_invoke(calling_klass, receiver_klass); | |
1620 if (exact_target != NULL) { | |
1621 target = exact_target; | |
1622 code = Bytecodes::_invokespecial; | |
1623 } | |
1624 } | |
1625 if (receiver_klass != NULL && | |
1626 receiver_klass->is_subtype_of(actual_recv) && | |
1627 actual_recv->is_initialized()) { | |
1628 actual_recv = receiver_klass; | |
1629 } | |
1630 | |
1631 if ((code == Bytecodes::_invokevirtual && callee_holder->is_initialized()) || | |
1632 (code == Bytecodes::_invokeinterface && callee_holder->is_initialized() && !actual_recv->is_interface())) { | |
1633 // Use CHA on the receiver to select a more precise method. | |
1634 cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv); | |
1635 } else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) { | |
1636 // if there is only one implementor of this interface then we | |
1637 // may be able bind this invoke directly to the implementing | |
1638 // klass but we need both a dependence on the single interface | |
1639 // and on the method we bind to. Additionally since all we know | |
1640 // about the receiver type is the it's supposed to implement the | |
1641 // interface we have to insert a check that it's the class we | |
1642 // expect. Interface types are not checked by the verifier so | |
1643 // they are roughly equivalent to Object. | |
1644 ciInstanceKlass* singleton = NULL; | |
1645 if (target->holder()->nof_implementors() == 1) { | |
1646 singleton = target->holder()->implementor(0); | |
1647 } | |
1648 if (singleton) { | |
1649 cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton); | |
1650 if (cha_monomorphic_target != NULL) { | |
1651 // If CHA is able to bind this invoke then update the class | |
1652 // to match that class, otherwise klass will refer to the | |
1653 // interface. | |
1654 klass = cha_monomorphic_target->holder(); | |
1655 actual_recv = target->holder(); | |
1656 | |
1657 // insert a check it's really the expected class. | |
1819 | 1658 CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception()); |
0 | 1659 c->set_incompatible_class_change_check(); |
1660 c->set_direct_compare(klass->is_final()); | |
1661 append_split(c); | |
1662 } | |
1663 } | |
1664 } | |
1665 } | |
1666 | |
1667 if (cha_monomorphic_target != NULL) { | |
1668 if (cha_monomorphic_target->is_abstract()) { | |
1669 // Do not optimize for abstract methods | |
1670 cha_monomorphic_target = NULL; | |
1671 } | |
1672 } | |
1673 | |
1674 if (cha_monomorphic_target != NULL) { | |
1675 if (!(target->is_final_method())) { | |
1676 // If we inlined because CHA revealed only a single target method, | |
1677 // then we are dependent on that target method not getting overridden | |
1678 // by dynamic class loading. Be sure to test the "static" receiver | |
1679 // dest_method here, as opposed to the actual receiver, which may | |
1680 // falsely lead us to believe that the receiver is final or private. | |
1681 dependency_recorder()->assert_unique_concrete_method(actual_recv, cha_monomorphic_target); | |
1682 } | |
1683 code = Bytecodes::_invokespecial; | |
1684 } | |
1685 // check if we could do inlining | |
1686 if (!PatchALot && Inline && klass->is_loaded() && | |
1687 (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized()) | |
1688 && target->will_link(klass, callee_holder, code)) { | |
1689 // callee is known => check if we have static binding | |
1690 assert(target->is_loaded(), "callee must be known"); | |
1691 if (code == Bytecodes::_invokestatic | |
1692 || code == Bytecodes::_invokespecial | |
1693 || code == Bytecodes::_invokevirtual && target->is_final_method() | |
1694 ) { | |
1695 // static binding => check if callee is ok | |
1696 ciMethod* inline_target = (cha_monomorphic_target != NULL) | |
1697 ? cha_monomorphic_target | |
1698 : target; | |
1699 bool res = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL)); | |
1700 CHECK_BAILOUT(); | |
1701 | |
1702 #ifndef PRODUCT | |
1703 // printing | |
1704 if (PrintInlining && !res) { | |
1705 // if it was successfully inlined, then it was already printed. | |
1706 print_inline_result(inline_target, res); | |
1707 } | |
1708 #endif | |
1709 clear_inline_bailout(); | |
1710 if (res) { | |
1711 // Register dependence if JVMTI has either breakpoint | |
1712 // setting or hotswapping of methods capabilities since they may | |
1713 // cause deoptimization. | |
780
c96bf21b756f
6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents:
726
diff
changeset
|
1714 if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) { |
0 | 1715 dependency_recorder()->assert_evol_method(inline_target); |
1716 } | |
1717 return; | |
1718 } | |
1719 } | |
1720 } | |
1721 // If we attempted an inline which did not succeed because of a | |
1722 // bailout during construction of the callee graph, the entire | |
1723 // compilation has to be aborted. This is fairly rare and currently | |
1724 // seems to only occur for jasm-generated classes which contain | |
1725 // jsr/ret pairs which are not associated with finally clauses and | |
1726 // do not have exception handlers in the containing method, and are | |
1727 // therefore not caught early enough to abort the inlining without | |
1728 // corrupting the graph. (We currently bail out with a non-empty | |
1729 // stack at a ret in these situations.) | |
1730 CHECK_BAILOUT(); | |
1731 | |
1732 // inlining not successful => standard invoke | |
1295 | 1733 bool is_loaded = target->is_loaded(); |
1734 bool has_receiver = | |
1735 code == Bytecodes::_invokespecial || | |
1736 code == Bytecodes::_invokevirtual || | |
1737 code == Bytecodes::_invokeinterface; | |
1738 bool is_invokedynamic = code == Bytecodes::_invokedynamic; | |
0 | 1739 ValueType* result_type = as_ValueType(target->return_type()); |
1295 | 1740 |
1741 // We require the debug info to be the "state before" because | |
1742 // invokedynamics may deoptimize. | |
1819 | 1743 ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling(); |
1295 | 1744 |
0 | 1745 Values* args = state()->pop_arguments(target->arg_size_no_receiver()); |
1295 | 1746 Value recv = has_receiver ? apop() : NULL; |
0 | 1747 int vtable_index = methodOopDesc::invalid_vtable_index; |
1748 | |
1749 #ifdef SPARC | |
1750 // Currently only supported on Sparc. | |
1751 // The UseInlineCaches only controls dispatch to invokevirtuals for | |
1752 // loaded classes which we weren't able to statically bind. | |
1753 if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual | |
1754 && !target->can_be_statically_bound()) { | |
1755 // Find a vtable index if one is available | |
1756 vtable_index = target->resolve_vtable_index(calling_klass, callee_holder); | |
1757 } | |
1758 #endif | |
1759 | |
1760 if (recv != NULL && | |
1761 (code == Bytecodes::_invokespecial || | |
1783 | 1762 !is_loaded || target->is_final())) { |
0 | 1763 // invokespecial always needs a NULL check. invokevirtual where |
1764 // the target is final or where it's not known that whether the | |
1765 // target is final requires a NULL check. Otherwise normal | |
1766 // invokevirtual will perform the null check during the lookup | |
1767 // logic or the unverified entry point. Profiling of calls | |
1768 // requires that the null check is performed in all cases. | |
1769 null_check(recv); | |
1770 } | |
1771 | |
1783 | 1772 if (is_profiling()) { |
1773 if (recv != NULL && profile_calls()) { | |
1774 null_check(recv); | |
0 | 1775 } |
1783 | 1776 // Note that we'd collect profile data in this method if we wanted it. |
1777 compilation()->set_would_profile(true); | |
1778 | |
1779 if (profile_calls()) { | |
1780 assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set"); | |
1781 ciKlass* target_klass = NULL; | |
1782 if (cha_monomorphic_target != NULL) { | |
1783 target_klass = cha_monomorphic_target->holder(); | |
1784 } else if (exact_target != NULL) { | |
1785 target_klass = exact_target->holder(); | |
1786 } | |
1787 profile_call(recv, target_klass); | |
1788 } | |
0 | 1789 } |
1790 | |
1295 | 1791 Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before); |
0 | 1792 // push result |
1793 append_split(result); | |
1794 | |
1795 if (result_type != voidType) { | |
1796 if (method()->is_strict()) { | |
1797 push(result_type, round_fp(result)); | |
1798 } else { | |
1799 push(result_type, result); | |
1800 } | |
1801 } | |
1802 } | |
1803 | |
1804 | |
1805 void GraphBuilder::new_instance(int klass_index) { | |
1819 | 1806 ValueStack* state_before = copy_state_exhandling(); |
0 | 1807 bool will_link; |
1808 ciKlass* klass = stream()->get_klass(will_link); | |
1809 assert(klass->is_instance_klass(), "must be an instance klass"); | |
1819 | 1810 NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before); |
0 | 1811 _memory->new_instance(new_instance); |
1812 apush(append_split(new_instance)); | |
1813 } | |
1814 | |
1815 | |
1816 void GraphBuilder::new_type_array() { | |
1819 | 1817 ValueStack* state_before = copy_state_exhandling(); |
1818 apush(append_split(new NewTypeArray(ipop(), (BasicType)stream()->get_index(), state_before))); | |
0 | 1819 } |
1820 | |
1821 | |
1822 void GraphBuilder::new_object_array() { | |
1823 bool will_link; | |
1824 ciKlass* klass = stream()->get_klass(will_link); | |
1819 | 1825 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling(); |
0 | 1826 NewArray* n = new NewObjectArray(klass, ipop(), state_before); |
1827 apush(append_split(n)); | |
1828 } | |
1829 | |
1830 | |
1831 bool GraphBuilder::direct_compare(ciKlass* k) { | |
1832 if (k->is_loaded() && k->is_instance_klass() && !UseSlowPath) { | |
1833 ciInstanceKlass* ik = k->as_instance_klass(); | |
1834 if (ik->is_final()) { | |
1835 return true; | |
1836 } else { | |
1837 if (DeoptC1 && UseCHA && !(ik->has_subklass() || ik->is_interface())) { | |
1838 // test class is leaf class | |
1839 dependency_recorder()->assert_leaf_type(ik); | |
1840 return true; | |
1841 } | |
1842 } | |
1843 } | |
1844 return false; | |
1845 } | |
1846 | |
1847 | |
1848 void GraphBuilder::check_cast(int klass_index) { | |
1849 bool will_link; | |
1850 ciKlass* klass = stream()->get_klass(will_link); | |
1819 | 1851 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_for_exception(); |
0 | 1852 CheckCast* c = new CheckCast(klass, apop(), state_before); |
1853 apush(append_split(c)); | |
1854 c->set_direct_compare(direct_compare(klass)); | |
1783 | 1855 |
1856 if (is_profiling()) { | |
1857 // Note that we'd collect profile data in this method if we wanted it. | |
1858 compilation()->set_would_profile(true); | |
1859 | |
1860 if (profile_checkcasts()) { | |
1861 c->set_profiled_method(method()); | |
1862 c->set_profiled_bci(bci()); | |
1863 c->set_should_profile(true); | |
1864 } | |
0 | 1865 } |
1866 } | |
1867 | |
1868 | |
1869 void GraphBuilder::instance_of(int klass_index) { | |
1870 bool will_link; | |
1871 ciKlass* klass = stream()->get_klass(will_link); | |
1819 | 1872 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling(); |
0 | 1873 InstanceOf* i = new InstanceOf(klass, apop(), state_before); |
1874 ipush(append_split(i)); | |
1875 i->set_direct_compare(direct_compare(klass)); | |
1791
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1876 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1877 if (is_profiling()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1878 // Note that we'd collect profile data in this method if we wanted it. |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1879 compilation()->set_would_profile(true); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1880 |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1881 if (profile_checkcasts()) { |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1882 i->set_profiled_method(method()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1883 i->set_profiled_bci(bci()); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1884 i->set_should_profile(true); |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1885 } |
3a294e483abc
6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents:
1783
diff
changeset
|
1886 } |
0 | 1887 } |
1888 | |
1889 | |
1890 void GraphBuilder::monitorenter(Value x, int bci) { | |
1891 // save state before locking in case of deoptimization after a NullPointerException | |
1819 | 1892 ValueStack* state_before = copy_state_for_exception_with_bci(bci); |
1893 append_with_bci(new MonitorEnter(x, state()->lock(x), state_before), bci); | |
0 | 1894 kill_all(); |
1895 } | |
1896 | |
1897 | |
1898 void GraphBuilder::monitorexit(Value x, int bci) { | |
1899 append_with_bci(new MonitorExit(x, state()->unlock()), bci); | |
1900 kill_all(); | |
1901 } | |
1902 | |
1903 | |
1904 void GraphBuilder::new_multi_array(int dimensions) { | |
1905 bool will_link; | |
1906 ciKlass* klass = stream()->get_klass(will_link); | |
1819 | 1907 ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling(); |
0 | 1908 |
1909 Values* dims = new Values(dimensions, NULL); | |
1910 // fill in all dimensions | |
1911 int i = dimensions; | |
1912 while (i-- > 0) dims->at_put(i, ipop()); | |
1913 // create array | |
1914 NewArray* n = new NewMultiArray(klass, dims, state_before); | |
1915 apush(append_split(n)); | |
1916 } | |
1917 | |
1918 | |
1919 void GraphBuilder::throw_op(int bci) { | |
1920 // We require that the debug info for a Throw be the "state before" | |
1921 // the Throw (i.e., exception oop is still on TOS) | |
1819 | 1922 ValueStack* state_before = copy_state_before_with_bci(bci); |
0 | 1923 Throw* t = new Throw(apop(), state_before); |
1819 | 1924 // operand stack not needed after a throw |
1925 state()->truncate_stack(0); | |
0 | 1926 append_with_bci(t, bci); |
1927 } | |
1928 | |
1929 | |
1930 Value GraphBuilder::round_fp(Value fp_value) { | |
1931 // no rounding needed if SSE2 is used | |
1932 if (RoundFPResults && UseSSE < 2) { | |
1933 // Must currently insert rounding node for doubleword values that | |
1934 // are results of expressions (i.e., not loads from memory or | |
1935 // constants) | |
1936 if (fp_value->type()->tag() == doubleTag && | |
1937 fp_value->as_Constant() == NULL && | |
1938 fp_value->as_Local() == NULL && // method parameters need no rounding | |
1939 fp_value->as_RoundFP() == NULL) { | |
1940 return append(new RoundFP(fp_value)); | |
1941 } | |
1942 } | |
1943 return fp_value; | |
1944 } | |
1945 | |
1946 | |
1947 Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) { | |
1783 | 1948 Canonicalizer canon(compilation(), instr, bci); |
0 | 1949 Instruction* i1 = canon.canonical(); |
1819 | 1950 if (i1->is_linked() || !i1->can_be_linked()) { |
0 | 1951 // Canonicalizer returned an instruction which was already |
1952 // appended so simply return it. | |
1953 return i1; | |
1819 | 1954 } |
1955 | |
1956 if (UseLocalValueNumbering) { | |
0 | 1957 // Lookup the instruction in the ValueMap and add it to the map if |
1958 // it's not found. | |
1959 Instruction* i2 = vmap()->find_insert(i1); | |
1960 if (i2 != i1) { | |
1961 // found an entry in the value map, so just return it. | |
1819 | 1962 assert(i2->is_linked(), "should already be linked"); |
0 | 1963 return i2; |
1964 } | |
459 | 1965 ValueNumberingEffects vne(vmap()); |
1966 i1->visit(&vne); | |
0 | 1967 } |
1968 | |
1819 | 1969 // i1 was not eliminated => append it |
1970 assert(i1->next() == NULL, "shouldn't already be linked"); | |
1971 _last = _last->set_next(i1, canon.bci()); | |
1972 | |
1973 if (++_instruction_count >= InstructionCountCutoff && !bailed_out()) { | |
1974 // set the bailout state but complete normal processing. We | |
1975 // might do a little more work before noticing the bailout so we | |
1976 // want processing to continue normally until it's noticed. | |
1977 bailout("Method and/or inlining is too large"); | |
1978 } | |
0 | 1979 |
1980 #ifndef PRODUCT | |
1819 | 1981 if (PrintIRDuringConstruction) { |
1982 InstructionPrinter ip; | |
1983 ip.print_line(i1); | |
1984 if (Verbose) { | |
1985 state()->print(); | |
1986 } | |
1987 } | |
1988 #endif | |
1989 | |
1990 // save state after modification of operand stack for StateSplit instructions | |
1991 StateSplit* s = i1->as_StateSplit(); | |
1992 if (s != NULL) { | |
1993 if (EliminateFieldAccess) { | |
1994 Intrinsic* intrinsic = s->as_Intrinsic(); | |
1995 if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) { | |
1996 _memory->kill(); | |
0 | 1997 } |
1998 } | |
1819 | 1999 s->set_state(state()->copy(ValueStack::StateAfter, canon.bci())); |
2000 } | |
2001 | |
2002 // set up exception handlers for this instruction if necessary | |
2003 if (i1->can_trap()) { | |
2004 i1->set_exception_handlers(handle_exception(i1)); | |
2005 assert(i1->exception_state() != NULL || !i1->needs_exception_state() || bailed_out(), "handle_exception must set exception state"); | |
0 | 2006 } |
2007 return i1; | |
2008 } | |
2009 | |
2010 | |
2011 Instruction* GraphBuilder::append(Instruction* instr) { | |
2012 assert(instr->as_StateSplit() == NULL || instr->as_BlockEnd() != NULL, "wrong append used"); | |
2013 return append_with_bci(instr, bci()); | |
2014 } | |
2015 | |
2016 | |
2017 Instruction* GraphBuilder::append_split(StateSplit* instr) { | |
2018 return append_with_bci(instr, bci()); | |
2019 } | |
2020 | |
2021 | |
2022 void GraphBuilder::null_check(Value value) { | |
2023 if (value->as_NewArray() != NULL || value->as_NewInstance() != NULL) { | |
2024 return; | |
2025 } else { | |
2026 Constant* con = value->as_Constant(); | |
2027 if (con) { | |
2028 ObjectType* c = con->type()->as_ObjectType(); | |
2029 if (c && c->is_loaded()) { | |
2030 ObjectConstant* oc = c->as_ObjectConstant(); | |
2031 if (!oc || !oc->value()->is_null_object()) { | |
2032 return; | |
2033 } | |
2034 } | |
2035 } | |
2036 } | |
1819 | 2037 append(new NullCheck(value, copy_state_for_exception())); |
0 | 2038 } |
2039 | |
2040 | |
2041 | |
1819 | 2042 XHandlers* GraphBuilder::handle_exception(Instruction* instruction) { |
2043 if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) { | |
2044 assert(instruction->exception_state() == NULL | |
2045 || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState | |
2046 || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()), | |
2047 "exception_state should be of exception kind"); | |
0 | 2048 return new XHandlers(); |
2049 } | |
2050 | |
2051 XHandlers* exception_handlers = new XHandlers(); | |
2052 ScopeData* cur_scope_data = scope_data(); | |
1819 | 2053 ValueStack* cur_state = instruction->state_before(); |
2054 ValueStack* prev_state = NULL; | |
0 | 2055 int scope_count = 0; |
2056 | |
1819 | 2057 assert(cur_state != NULL, "state_before must be set"); |
0 | 2058 do { |
1819 | 2059 int cur_bci = cur_state->bci(); |
2060 assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match"); | |
0 | 2061 assert(cur_bci == SynchronizationEntryBCI || cur_bci == cur_scope_data->stream()->cur_bci(), "invalid bci"); |
2062 | |
2063 // join with all potential exception handlers | |
2064 XHandlers* list = cur_scope_data->xhandlers(); | |
2065 const int n = list->length(); | |
2066 for (int i = 0; i < n; i++) { | |
2067 XHandler* h = list->handler_at(i); | |
2068 if (h->covers(cur_bci)) { | |
2069 // h is a potential exception handler => join it | |
2070 compilation()->set_has_exception_handlers(true); | |
2071 | |
2072 BlockBegin* entry = h->entry_block(); | |
2073 if (entry == block()) { | |
2074 // It's acceptable for an exception handler to cover itself | |
2075 // but we don't handle that in the parser currently. It's | |
2076 // very rare so we bailout instead of trying to handle it. | |
2077 BAILOUT_("exception handler covers itself", exception_handlers); | |
2078 } | |
2079 assert(entry->bci() == h->handler_bci(), "must match"); | |
2080 assert(entry->bci() == -1 || entry == cur_scope_data->block_at(entry->bci()), "blocks must correspond"); | |
2081 | |
2082 // previously this was a BAILOUT, but this is not necessary | |
2083 // now because asynchronous exceptions are not handled this way. | |
1819 | 2084 assert(entry->state() == NULL || cur_state->total_locks_size() == entry->state()->total_locks_size(), "locks do not match"); |
0 | 2085 |
2086 // xhandler start with an empty expression stack | |
1819 | 2087 if (cur_state->stack_size() != 0) { |
2088 cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci()); | |
2089 } | |
2090 if (instruction->exception_state() == NULL) { | |
2091 instruction->set_exception_state(cur_state); | |
2092 } | |
0 | 2093 |
2094 // Note: Usually this join must work. However, very | |
2095 // complicated jsr-ret structures where we don't ret from | |
2096 // the subroutine can cause the objects on the monitor | |
2097 // stacks to not match because blocks can be parsed twice. | |
2098 // The only test case we've seen so far which exhibits this | |
2099 // problem is caught by the infinite recursion test in | |
2100 // GraphBuilder::jsr() if the join doesn't work. | |
1819 | 2101 if (!entry->try_merge(cur_state)) { |
0 | 2102 BAILOUT_("error while joining with exception handler, prob. due to complicated jsr/rets", exception_handlers); |
2103 } | |
2104 | |
2105 // add current state for correct handling of phi functions at begin of xhandler | |
1819 | 2106 int phi_operand = entry->add_exception_state(cur_state); |
0 | 2107 |
2108 // add entry to the list of xhandlers of this block | |
2109 _block->add_exception_handler(entry); | |
2110 | |
2111 // add back-edge from xhandler entry to this block | |
2112 if (!entry->is_predecessor(_block)) { | |
2113 entry->add_predecessor(_block); | |
2114 } | |
2115 | |
2116 // clone XHandler because phi_operand and scope_count can not be shared | |
2117 XHandler* new_xhandler = new XHandler(h); | |
2118 new_xhandler->set_phi_operand(phi_operand); | |
2119 new_xhandler->set_scope_count(scope_count); | |
2120 exception_handlers->append(new_xhandler); | |
2121 | |
2122 // fill in exception handler subgraph lazily | |
2123 assert(!entry->is_set(BlockBegin::was_visited_flag), "entry must not be visited yet"); | |
2124 cur_scope_data->add_to_work_list(entry); | |
2125 | |
2126 // stop when reaching catchall | |
2127 if (h->catch_type() == 0) { | |
2128 return exception_handlers; | |
2129 } | |
2130 } | |
2131 } | |
2132 | |
1819 | 2133 if (exception_handlers->length() == 0) { |
2134 // This scope and all callees do not handle exceptions, so the local | |
2135 // variables of this scope are not needed. However, the scope itself is | |
2136 // required for a correct exception stack trace -> clear out the locals. | |
2137 if (_compilation->env()->jvmti_can_access_local_variables()) { | |
2138 cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci()); | |
2139 } else { | |
2140 cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci()); | |
2141 } | |
2142 if (prev_state != NULL) { | |
2143 prev_state->set_caller_state(cur_state); | |
2144 } | |
2145 if (instruction->exception_state() == NULL) { | |
2146 instruction->set_exception_state(cur_state); | |
2147 } | |
2148 } | |
2149 | |
0 | 2150 // Set up iteration for next time. |
2151 // If parsing a jsr, do not grab exception handlers from the | |
2152 // parent scopes for this method (already got them, and they | |
2153 // needed to be cloned) | |
1819 | 2154 |
2155 while (cur_scope_data->parsing_jsr()) { | |
2156 cur_scope_data = cur_scope_data->parent(); | |
0 | 2157 } |
1819 | 2158 |
2159 assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match"); | |
2160 assert(cur_state->locks_size() == 0 || cur_state->locks_size() == 1, "unlocking must be done in a catchall exception handler"); | |
2161 | |
2162 prev_state = cur_state; | |
2163 cur_state = cur_state->caller_state(); | |
2164 cur_scope_data = cur_scope_data->parent(); | |
2165 scope_count++; | |
0 | 2166 } while (cur_scope_data != NULL); |
2167 | |
2168 return exception_handlers; | |
2169 } | |
2170 | |
2171 | |
2172 // Helper class for simplifying Phis. | |
2173 class PhiSimplifier : public BlockClosure { | |
2174 private: | |
2175 bool _has_substitutions; | |
2176 Value simplify(Value v); | |
2177 | |
2178 public: | |
2179 PhiSimplifier(BlockBegin* start) : _has_substitutions(false) { | |
2180 start->iterate_preorder(this); | |
2181 if (_has_substitutions) { | |
2182 SubstitutionResolver sr(start); | |
2183 } | |
2184 } | |
2185 void block_do(BlockBegin* b); | |
2186 bool has_substitutions() const { return _has_substitutions; } | |
2187 }; | |
2188 | |
2189 | |
2190 Value PhiSimplifier::simplify(Value v) { | |
2191 Phi* phi = v->as_Phi(); | |
2192 | |
2193 if (phi == NULL) { | |
2194 // no phi function | |
2195 return v; | |
2196 } else if (v->has_subst()) { | |
2197 // already substituted; subst can be phi itself -> simplify | |
2198 return simplify(v->subst()); | |
2199 } else if (phi->is_set(Phi::cannot_simplify)) { | |
2200 // already tried to simplify phi before | |
2201 return phi; | |
2202 } else if (phi->is_set(Phi::visited)) { | |
2203 // break cycles in phi functions | |
2204 return phi; | |
2205 } else if (phi->type()->is_illegal()) { | |
2206 // illegal phi functions are ignored anyway | |
2207 return phi; | |
2208 | |
2209 } else { | |
2210 // mark phi function as processed to break cycles in phi functions | |
2211 phi->set(Phi::visited); | |
2212 | |
2213 // simplify x = [y, x] and x = [y, y] to y | |
2214 Value subst = NULL; | |
2215 int opd_count = phi->operand_count(); | |
2216 for (int i = 0; i < opd_count; i++) { | |
2217 Value opd = phi->operand_at(i); | |
2218 assert(opd != NULL, "Operand must exist!"); | |
2219 | |
2220 if (opd->type()->is_illegal()) { | |
2221 // if one operand is illegal, the entire phi function is illegal | |
2222 phi->make_illegal(); | |
2223 phi->clear(Phi::visited); | |
2224 return phi; | |
2225 } | |
2226 | |
2227 Value new_opd = simplify(opd); | |
2228 assert(new_opd != NULL, "Simplified operand must exist!"); | |
2229 | |
2230 if (new_opd != phi && new_opd != subst) { | |
2231 if (subst == NULL) { | |
2232 subst = new_opd; | |
2233 } else { | |
2234 // no simplification possible | |
2235 phi->set(Phi::cannot_simplify); | |
2236 phi->clear(Phi::visited); | |
2237 return phi; | |
2238 } | |
2239 } | |
2240 } | |
2241 | |
2242 // sucessfully simplified phi function | |
2243 assert(subst != NULL, "illegal phi function"); | |
2244 _has_substitutions = true; | |
2245 phi->clear(Phi::visited); | |
2246 phi->set_subst(subst); | |
2247 | |
2248 #ifndef PRODUCT | |
2249 if (PrintPhiFunctions) { | |
2250 tty->print_cr("simplified phi function %c%d to %c%d (Block B%d)", phi->type()->tchar(), phi->id(), subst->type()->tchar(), subst->id(), phi->block()->block_id()); | |
2251 } | |
2252 #endif | |
2253 | |
2254 return subst; | |
2255 } | |
2256 } | |
2257 | |
2258 | |
2259 void PhiSimplifier::block_do(BlockBegin* b) { | |
2260 for_each_phi_fun(b, phi, | |
2261 simplify(phi); | |
2262 ); | |
2263 | |
2264 #ifdef ASSERT | |
2265 for_each_phi_fun(b, phi, | |
2266 assert(phi->operand_count() != 1 || phi->subst() != phi, "missed trivial simplification"); | |
2267 ); | |
2268 | |
2269 ValueStack* state = b->state()->caller_state(); | |
1819 | 2270 for_each_state_value(state, value, |
2271 Phi* phi = value->as_Phi(); | |
2272 assert(phi == NULL || phi->block() != b, "must not have phi function to simplify in caller state"); | |
2273 ); | |
0 | 2274 #endif |
2275 } | |
2276 | |
2277 // This method is called after all blocks are filled with HIR instructions | |
2278 // It eliminates all Phi functions of the form x = [y, y] and x = [y, x] | |
2279 void GraphBuilder::eliminate_redundant_phis(BlockBegin* start) { | |
2280 PhiSimplifier simplifier(start); | |
2281 } | |
2282 | |
2283 | |
2284 void GraphBuilder::connect_to_end(BlockBegin* beg) { | |
2285 // setup iteration | |
2286 kill_all(); | |
2287 _block = beg; | |
1819 | 2288 _state = beg->state()->copy_for_parsing(); |
0 | 2289 _last = beg; |
2290 iterate_bytecodes_for_block(beg->bci()); | |
2291 } | |
2292 | |
2293 | |
2294 BlockEnd* GraphBuilder::iterate_bytecodes_for_block(int bci) { | |
2295 #ifndef PRODUCT | |
2296 if (PrintIRDuringConstruction) { | |
2297 tty->cr(); | |
2298 InstructionPrinter ip; | |
2299 ip.print_instr(_block); tty->cr(); | |
2300 ip.print_stack(_block->state()); tty->cr(); | |
2301 ip.print_inline_level(_block); | |
2302 ip.print_head(); | |
2303 tty->print_cr("locals size: %d stack size: %d", state()->locals_size(), state()->stack_size()); | |
2304 } | |
2305 #endif | |
2306 _skip_block = false; | |
2307 assert(state() != NULL, "ValueStack missing!"); | |
2308 ciBytecodeStream s(method()); | |
2309 s.reset_to_bci(bci); | |
2310 int prev_bci = bci; | |
2311 scope_data()->set_stream(&s); | |
2312 // iterate | |
2313 Bytecodes::Code code = Bytecodes::_illegal; | |
2314 bool push_exception = false; | |
2315 | |
2316 if (block()->is_set(BlockBegin::exception_entry_flag) && block()->next() == NULL) { | |
2317 // first thing in the exception entry block should be the exception object. | |
2318 push_exception = true; | |
2319 } | |
2320 | |
2321 while (!bailed_out() && last()->as_BlockEnd() == NULL && | |
2322 (code = stream()->next()) != ciBytecodeStream::EOBC() && | |
2323 (block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) { | |
1819 | 2324 assert(state()->kind() == ValueStack::Parsing, "invalid state kind"); |
0 | 2325 |
2326 // Check for active jsr during OSR compilation | |
2327 if (compilation()->is_osr_compile() | |
2328 && scope()->is_top_scope() | |
2329 && parsing_jsr() | |
2330 && s.cur_bci() == compilation()->osr_bci()) { | |
2331 bailout("OSR not supported while a jsr is active"); | |
2332 } | |
2333 | |
2334 if (push_exception) { | |
2335 apush(append(new ExceptionObject())); | |
2336 push_exception = false; | |
2337 } | |
2338 | |
2339 // handle bytecode | |
2340 switch (code) { | |
2341 case Bytecodes::_nop : /* nothing to do */ break; | |
2342 case Bytecodes::_aconst_null : apush(append(new Constant(objectNull ))); break; | |
2343 case Bytecodes::_iconst_m1 : ipush(append(new Constant(new IntConstant (-1)))); break; | |
2344 case Bytecodes::_iconst_0 : ipush(append(new Constant(intZero ))); break; | |
2345 case Bytecodes::_iconst_1 : ipush(append(new Constant(intOne ))); break; | |
2346 case Bytecodes::_iconst_2 : ipush(append(new Constant(new IntConstant ( 2)))); break; | |
2347 case Bytecodes::_iconst_3 : ipush(append(new Constant(new IntConstant ( 3)))); break; | |
2348 case Bytecodes::_iconst_4 : ipush(append(new Constant(new IntConstant ( 4)))); break; | |
2349 case Bytecodes::_iconst_5 : ipush(append(new Constant(new IntConstant ( 5)))); break; | |
2350 case Bytecodes::_lconst_0 : lpush(append(new Constant(new LongConstant ( 0)))); break; | |
2351 case Bytecodes::_lconst_1 : lpush(append(new Constant(new LongConstant ( 1)))); break; | |
2352 case Bytecodes::_fconst_0 : fpush(append(new Constant(new FloatConstant ( 0)))); break; | |
2353 case Bytecodes::_fconst_1 : fpush(append(new Constant(new FloatConstant ( 1)))); break; | |
2354 case Bytecodes::_fconst_2 : fpush(append(new Constant(new FloatConstant ( 2)))); break; | |
2355 case Bytecodes::_dconst_0 : dpush(append(new Constant(new DoubleConstant( 0)))); break; | |
2356 case Bytecodes::_dconst_1 : dpush(append(new Constant(new DoubleConstant( 1)))); break; | |
2357 case Bytecodes::_bipush : ipush(append(new Constant(new IntConstant(((signed char*)s.cur_bcp())[1])))); break; | |
2358 case Bytecodes::_sipush : ipush(append(new Constant(new IntConstant((short)Bytes::get_Java_u2(s.cur_bcp()+1))))); break; | |
2359 case Bytecodes::_ldc : // fall through | |
2360 case Bytecodes::_ldc_w : // fall through | |
2361 case Bytecodes::_ldc2_w : load_constant(); break; | |
2362 case Bytecodes::_iload : load_local(intType , s.get_index()); break; | |
2363 case Bytecodes::_lload : load_local(longType , s.get_index()); break; | |
2364 case Bytecodes::_fload : load_local(floatType , s.get_index()); break; | |
2365 case Bytecodes::_dload : load_local(doubleType , s.get_index()); break; | |
2366 case Bytecodes::_aload : load_local(instanceType, s.get_index()); break; | |
2367 case Bytecodes::_iload_0 : load_local(intType , 0); break; | |
2368 case Bytecodes::_iload_1 : load_local(intType , 1); break; | |
2369 case Bytecodes::_iload_2 : load_local(intType , 2); break; | |
2370 case Bytecodes::_iload_3 : load_local(intType , 3); break; | |
2371 case Bytecodes::_lload_0 : load_local(longType , 0); break; | |
2372 case Bytecodes::_lload_1 : load_local(longType , 1); break; | |
2373 case Bytecodes::_lload_2 : load_local(longType , 2); break; | |
2374 case Bytecodes::_lload_3 : load_local(longType , 3); break; | |
2375 case Bytecodes::_fload_0 : load_local(floatType , 0); break; | |
2376 case Bytecodes::_fload_1 : load_local(floatType , 1); break; | |
2377 case Bytecodes::_fload_2 : load_local(floatType , 2); break; | |
2378 case Bytecodes::_fload_3 : load_local(floatType , 3); break; | |
2379 case Bytecodes::_dload_0 : load_local(doubleType, 0); break; | |
2380 case Bytecodes::_dload_1 : load_local(doubleType, 1); break; | |
2381 case Bytecodes::_dload_2 : load_local(doubleType, 2); break; | |
2382 case Bytecodes::_dload_3 : load_local(doubleType, 3); break; | |
2383 case Bytecodes::_aload_0 : load_local(objectType, 0); break; | |
2384 case Bytecodes::_aload_1 : load_local(objectType, 1); break; | |
2385 case Bytecodes::_aload_2 : load_local(objectType, 2); break; | |
2386 case Bytecodes::_aload_3 : load_local(objectType, 3); break; | |
2387 case Bytecodes::_iaload : load_indexed(T_INT ); break; | |
2388 case Bytecodes::_laload : load_indexed(T_LONG ); break; | |
2389 case Bytecodes::_faload : load_indexed(T_FLOAT ); break; | |
2390 case Bytecodes::_daload : load_indexed(T_DOUBLE); break; | |
2391 case Bytecodes::_aaload : load_indexed(T_OBJECT); break; | |
2392 case Bytecodes::_baload : load_indexed(T_BYTE ); break; | |
2393 case Bytecodes::_caload : load_indexed(T_CHAR ); break; | |
2394 case Bytecodes::_saload : load_indexed(T_SHORT ); break; | |
2395 case Bytecodes::_istore : store_local(intType , s.get_index()); break; | |
2396 case Bytecodes::_lstore : store_local(longType , s.get_index()); break; | |
2397 case Bytecodes::_fstore : store_local(floatType , s.get_index()); break; | |
2398 case Bytecodes::_dstore : store_local(doubleType, s.get_index()); break; | |
2399 case Bytecodes::_astore : store_local(objectType, s.get_index()); break; | |
2400 case Bytecodes::_istore_0 : store_local(intType , 0); break; | |
2401 case Bytecodes::_istore_1 : store_local(intType , 1); break; | |
2402 case Bytecodes::_istore_2 : store_local(intType , 2); break; | |
2403 case Bytecodes::_istore_3 : store_local(intType , 3); break; | |
2404 case Bytecodes::_lstore_0 : store_local(longType , 0); break; | |
2405 case Bytecodes::_lstore_1 : store_local(longType , 1); break; | |
2406 case Bytecodes::_lstore_2 : store_local(longType , 2); break; | |
2407 case Bytecodes::_lstore_3 : store_local(longType , 3); break; | |
2408 case Bytecodes::_fstore_0 : store_local(floatType , 0); break; | |
2409 case Bytecodes::_fstore_1 : store_local(floatType , 1); break; | |
2410 case Bytecodes::_fstore_2 : store_local(floatType , 2); break; | |
2411 case Bytecodes::_fstore_3 : store_local(floatType , 3); break; | |
2412 case Bytecodes::_dstore_0 : store_local(doubleType, 0); break; | |
2413 case Bytecodes::_dstore_1 : store_local(doubleType, 1); break; | |
2414 case Bytecodes::_dstore_2 : store_local(doubleType, 2); break; | |
2415 case Bytecodes::_dstore_3 : store_local(doubleType, 3); break; | |
2416 case Bytecodes::_astore_0 : store_local(objectType, 0); break; | |
2417 case Bytecodes::_astore_1 : store_local(objectType, 1); break; | |
2418 case Bytecodes::_astore_2 : store_local(objectType, 2); break; | |
2419 case Bytecodes::_astore_3 : store_local(objectType, 3); break; | |
2420 case Bytecodes::_iastore : store_indexed(T_INT ); break; | |
2421 case Bytecodes::_lastore : store_indexed(T_LONG ); break; | |
2422 case Bytecodes::_fastore : store_indexed(T_FLOAT ); break; | |
2423 case Bytecodes::_dastore : store_indexed(T_DOUBLE); break; | |
2424 case Bytecodes::_aastore : store_indexed(T_OBJECT); break; | |
2425 case Bytecodes::_bastore : store_indexed(T_BYTE ); break; | |
2426 case Bytecodes::_castore : store_indexed(T_CHAR ); break; | |
2427 case Bytecodes::_sastore : store_indexed(T_SHORT ); break; | |
2428 case Bytecodes::_pop : // fall through | |
2429 case Bytecodes::_pop2 : // fall through | |
2430 case Bytecodes::_dup : // fall through | |
2431 case Bytecodes::_dup_x1 : // fall through | |
2432 case Bytecodes::_dup_x2 : // fall through | |
2433 case Bytecodes::_dup2 : // fall through | |
2434 case Bytecodes::_dup2_x1 : // fall through | |
2435 case Bytecodes::_dup2_x2 : // fall through | |
2436 case Bytecodes::_swap : stack_op(code); break; | |
2437 case Bytecodes::_iadd : arithmetic_op(intType , code); break; | |
2438 case Bytecodes::_ladd : arithmetic_op(longType , code); break; | |
2439 case Bytecodes::_fadd : arithmetic_op(floatType , code); break; | |
2440 case Bytecodes::_dadd : arithmetic_op(doubleType, code); break; | |
2441 case Bytecodes::_isub : arithmetic_op(intType , code); break; | |
2442 case Bytecodes::_lsub : arithmetic_op(longType , code); break; | |
2443 case Bytecodes::_fsub : arithmetic_op(floatType , code); break; | |
2444 case Bytecodes::_dsub : arithmetic_op(doubleType, code); break; | |
2445 case Bytecodes::_imul : arithmetic_op(intType , code); break; | |
2446 case Bytecodes::_lmul : arithmetic_op(longType , code); break; | |
2447 case Bytecodes::_fmul : arithmetic_op(floatType , code); break; | |
2448 case Bytecodes::_dmul : arithmetic_op(doubleType, code); break; | |
1819 | 2449 case Bytecodes::_idiv : arithmetic_op(intType , code, copy_state_for_exception()); break; |
2450 case Bytecodes::_ldiv : arithmetic_op(longType , code, copy_state_for_exception()); break; | |
0 | 2451 case Bytecodes::_fdiv : arithmetic_op(floatType , code); break; |
2452 case Bytecodes::_ddiv : arithmetic_op(doubleType, code); break; | |
1819 | 2453 case Bytecodes::_irem : arithmetic_op(intType , code, copy_state_for_exception()); break; |
2454 case Bytecodes::_lrem : arithmetic_op(longType , code, copy_state_for_exception()); break; | |
0 | 2455 case Bytecodes::_frem : arithmetic_op(floatType , code); break; |
2456 case Bytecodes::_drem : arithmetic_op(doubleType, code); break; | |
2457 case Bytecodes::_ineg : negate_op(intType ); break; | |
2458 case Bytecodes::_lneg : negate_op(longType ); break; | |
2459 case Bytecodes::_fneg : negate_op(floatType ); break; | |
2460 case Bytecodes::_dneg : negate_op(doubleType); break; | |
2461 case Bytecodes::_ishl : shift_op(intType , code); break; | |
2462 case Bytecodes::_lshl : shift_op(longType, code); break; | |
2463 case Bytecodes::_ishr : shift_op(intType , code); break; | |
2464 case Bytecodes::_lshr : shift_op(longType, code); break; | |
2465 case Bytecodes::_iushr : shift_op(intType , code); break; | |
2466 case Bytecodes::_lushr : shift_op(longType, code); break; | |
2467 case Bytecodes::_iand : logic_op(intType , code); break; | |
2468 case Bytecodes::_land : logic_op(longType, code); break; | |
2469 case Bytecodes::_ior : logic_op(intType , code); break; | |
2470 case Bytecodes::_lor : logic_op(longType, code); break; | |
2471 case Bytecodes::_ixor : logic_op(intType , code); break; | |
2472 case Bytecodes::_lxor : logic_op(longType, code); break; | |
2473 case Bytecodes::_iinc : increment(); break; | |
2474 case Bytecodes::_i2l : convert(code, T_INT , T_LONG ); break; | |
2475 case Bytecodes::_i2f : convert(code, T_INT , T_FLOAT ); break; | |
2476 case Bytecodes::_i2d : convert(code, T_INT , T_DOUBLE); break; | |
2477 case Bytecodes::_l2i : convert(code, T_LONG , T_INT ); break; | |
2478 case Bytecodes::_l2f : convert(code, T_LONG , T_FLOAT ); break; | |
2479 case Bytecodes::_l2d : convert(code, T_LONG , T_DOUBLE); break; | |
2480 case Bytecodes::_f2i : convert(code, T_FLOAT , T_INT ); break; | |
2481 case Bytecodes::_f2l : convert(code, T_FLOAT , T_LONG ); break; | |
2482 case Bytecodes::_f2d : convert(code, T_FLOAT , T_DOUBLE); break; | |
2483 case Bytecodes::_d2i : convert(code, T_DOUBLE, T_INT ); break; | |
2484 case Bytecodes::_d2l : convert(code, T_DOUBLE, T_LONG ); break; | |
2485 case Bytecodes::_d2f : convert(code, T_DOUBLE, T_FLOAT ); break; | |
2486 case Bytecodes::_i2b : convert(code, T_INT , T_BYTE ); break; | |
2487 case Bytecodes::_i2c : convert(code, T_INT , T_CHAR ); break; | |
2488 case Bytecodes::_i2s : convert(code, T_INT , T_SHORT ); break; | |
2489 case Bytecodes::_lcmp : compare_op(longType , code); break; | |
2490 case Bytecodes::_fcmpl : compare_op(floatType , code); break; | |
2491 case Bytecodes::_fcmpg : compare_op(floatType , code); break; | |
2492 case Bytecodes::_dcmpl : compare_op(doubleType, code); break; | |
2493 case Bytecodes::_dcmpg : compare_op(doubleType, code); break; | |
2494 case Bytecodes::_ifeq : if_zero(intType , If::eql); break; | |
2495 case Bytecodes::_ifne : if_zero(intType , If::neq); break; | |
2496 case Bytecodes::_iflt : if_zero(intType , If::lss); break; | |
2497 case Bytecodes::_ifge : if_zero(intType , If::geq); break; | |
2498 case Bytecodes::_ifgt : if_zero(intType , If::gtr); break; | |
2499 case Bytecodes::_ifle : if_zero(intType , If::leq); break; | |
2500 case Bytecodes::_if_icmpeq : if_same(intType , If::eql); break; | |
2501 case Bytecodes::_if_icmpne : if_same(intType , If::neq); break; | |
2502 case Bytecodes::_if_icmplt : if_same(intType , If::lss); break; | |
2503 case Bytecodes::_if_icmpge : if_same(intType , If::geq); break; | |
2504 case Bytecodes::_if_icmpgt : if_same(intType , If::gtr); break; | |
2505 case Bytecodes::_if_icmple : if_same(intType , If::leq); break; | |
2506 case Bytecodes::_if_acmpeq : if_same(objectType, If::eql); break; | |
2507 case Bytecodes::_if_acmpne : if_same(objectType, If::neq); break; | |
2508 case Bytecodes::_goto : _goto(s.cur_bci(), s.get_dest()); break; | |
2509 case Bytecodes::_jsr : jsr(s.get_dest()); break; | |
2510 case Bytecodes::_ret : ret(s.get_index()); break; | |
2511 case Bytecodes::_tableswitch : table_switch(); break; | |
2512 case Bytecodes::_lookupswitch : lookup_switch(); break; | |
2513 case Bytecodes::_ireturn : method_return(ipop()); break; | |
2514 case Bytecodes::_lreturn : method_return(lpop()); break; | |
2515 case Bytecodes::_freturn : method_return(fpop()); break; | |
2516 case Bytecodes::_dreturn : method_return(dpop()); break; | |
2517 case Bytecodes::_areturn : method_return(apop()); break; | |
2518 case Bytecodes::_return : method_return(NULL ); break; | |
2519 case Bytecodes::_getstatic : // fall through | |
2520 case Bytecodes::_putstatic : // fall through | |
2521 case Bytecodes::_getfield : // fall through | |
2522 case Bytecodes::_putfield : access_field(code); break; | |
2523 case Bytecodes::_invokevirtual : // fall through | |
2524 case Bytecodes::_invokespecial : // fall through | |
2525 case Bytecodes::_invokestatic : // fall through | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
470
diff
changeset
|
2526 case Bytecodes::_invokedynamic : // fall through |
0 | 2527 case Bytecodes::_invokeinterface: invoke(code); break; |
1565 | 2528 case Bytecodes::_new : new_instance(s.get_index_u2()); break; |
0 | 2529 case Bytecodes::_newarray : new_type_array(); break; |
2530 case Bytecodes::_anewarray : new_object_array(); break; | |
1819 | 2531 case Bytecodes::_arraylength : { ValueStack* state_before = copy_state_for_exception(); ipush(append(new ArrayLength(apop(), state_before))); break; } |
0 | 2532 case Bytecodes::_athrow : throw_op(s.cur_bci()); break; |
1565 | 2533 case Bytecodes::_checkcast : check_cast(s.get_index_u2()); break; |
2534 case Bytecodes::_instanceof : instance_of(s.get_index_u2()); break; | |
0 | 2535 case Bytecodes::_monitorenter : monitorenter(apop(), s.cur_bci()); break; |
2536 case Bytecodes::_monitorexit : monitorexit (apop(), s.cur_bci()); break; | |
2537 case Bytecodes::_wide : ShouldNotReachHere(); break; | |
2538 case Bytecodes::_multianewarray : new_multi_array(s.cur_bcp()[3]); break; | |
2539 case Bytecodes::_ifnull : if_null(objectType, If::eql); break; | |
2540 case Bytecodes::_ifnonnull : if_null(objectType, If::neq); break; | |
2541 case Bytecodes::_goto_w : _goto(s.cur_bci(), s.get_far_dest()); break; | |
2542 case Bytecodes::_jsr_w : jsr(s.get_far_dest()); break; | |
2543 case Bytecodes::_breakpoint : BAILOUT_("concurrent setting of breakpoint", NULL); | |
2544 default : ShouldNotReachHere(); break; | |
2545 } | |
2546 // save current bci to setup Goto at the end | |
2547 prev_bci = s.cur_bci(); | |
2548 } | |
2549 CHECK_BAILOUT_(NULL); | |
2550 // stop processing of this block (see try_inline_full) | |
2551 if (_skip_block) { | |
2552 _skip_block = false; | |
2553 assert(_last && _last->as_BlockEnd(), ""); | |
2554 return _last->as_BlockEnd(); | |
2555 } | |
2556 // if there are any, check if last instruction is a BlockEnd instruction | |
2557 BlockEnd* end = last()->as_BlockEnd(); | |
2558 if (end == NULL) { | |
2559 // all blocks must end with a BlockEnd instruction => add a Goto | |
2560 end = new Goto(block_at(s.cur_bci()), false); | |
1819 | 2561 append(end); |
0 | 2562 } |
2563 assert(end == last()->as_BlockEnd(), "inconsistency"); | |
2564 | |
1819 | 2565 assert(end->state() != NULL, "state must already be present"); |
2566 assert(end->as_Return() == NULL || end->as_Throw() == NULL || end->state()->stack_size() == 0, "stack not needed for return and throw"); | |
0 | 2567 |
2568 // connect to begin & set state | |
2569 // NOTE that inlining may have changed the block we are parsing | |
2570 block()->set_end(end); | |
2571 // propagate state | |
2572 for (int i = end->number_of_sux() - 1; i >= 0; i--) { | |
2573 BlockBegin* sux = end->sux_at(i); | |
2574 assert(sux->is_predecessor(block()), "predecessor missing"); | |
2575 // be careful, bailout if bytecodes are strange | |
1819 | 2576 if (!sux->try_merge(end->state())) BAILOUT_("block join failed", NULL); |
0 | 2577 scope_data()->add_to_work_list(end->sux_at(i)); |
2578 } | |
2579 | |
2580 scope_data()->set_stream(NULL); | |
2581 | |
2582 // done | |
2583 return end; | |
2584 } | |
2585 | |
2586 | |
2587 void GraphBuilder::iterate_all_blocks(bool start_in_current_block_for_inlining) { | |
2588 do { | |
2589 if (start_in_current_block_for_inlining && !bailed_out()) { | |
2590 iterate_bytecodes_for_block(0); | |
2591 start_in_current_block_for_inlining = false; | |
2592 } else { | |
2593 BlockBegin* b; | |
2594 while ((b = scope_data()->remove_from_work_list()) != NULL) { | |
2595 if (!b->is_set(BlockBegin::was_visited_flag)) { | |
2596 if (b->is_set(BlockBegin::osr_entry_flag)) { | |
2597 // we're about to parse the osr entry block, so make sure | |
2598 // we setup the OSR edge leading into this block so that | |
2599 // Phis get setup correctly. | |
2600 setup_osr_entry_block(); | |
2601 // this is no longer the osr entry block, so clear it. | |
2602 b->clear(BlockBegin::osr_entry_flag); | |
2603 } | |
2604 b->set(BlockBegin::was_visited_flag); | |
2605 connect_to_end(b); | |
2606 } | |
2607 } | |
2608 } | |
2609 } while (!bailed_out() && !scope_data()->is_work_list_empty()); | |
2610 } | |
2611 | |
2612 | |
2613 bool GraphBuilder::_can_trap [Bytecodes::number_of_java_codes]; | |
2614 | |
2615 void GraphBuilder::initialize() { | |
2616 // the following bytecodes are assumed to potentially | |
2617 // throw exceptions in compiled code - note that e.g. | |
2618 // monitorexit & the return bytecodes do not throw | |
2619 // exceptions since monitor pairing proved that they | |
2620 // succeed (if monitor pairing succeeded) | |
2621 Bytecodes::Code can_trap_list[] = | |
2622 { Bytecodes::_ldc | |
2623 , Bytecodes::_ldc_w | |
2624 , Bytecodes::_ldc2_w | |
2625 , Bytecodes::_iaload | |
2626 , Bytecodes::_laload | |
2627 , Bytecodes::_faload | |
2628 , Bytecodes::_daload | |
2629 , Bytecodes::_aaload | |
2630 , Bytecodes::_baload | |
2631 , Bytecodes::_caload | |
2632 , Bytecodes::_saload | |
2633 , Bytecodes::_iastore | |
2634 , Bytecodes::_lastore | |
2635 , Bytecodes::_fastore | |
2636 , Bytecodes::_dastore | |
2637 , Bytecodes::_aastore | |
2638 , Bytecodes::_bastore | |
2639 , Bytecodes::_castore | |
2640 , Bytecodes::_sastore | |
2641 , Bytecodes::_idiv | |
2642 , Bytecodes::_ldiv | |
2643 , Bytecodes::_irem | |
2644 , Bytecodes::_lrem | |
2645 , Bytecodes::_getstatic | |
2646 , Bytecodes::_putstatic | |
2647 , Bytecodes::_getfield | |
2648 , Bytecodes::_putfield | |
2649 , Bytecodes::_invokevirtual | |
2650 , Bytecodes::_invokespecial | |
2651 , Bytecodes::_invokestatic | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
470
diff
changeset
|
2652 , Bytecodes::_invokedynamic |
0 | 2653 , Bytecodes::_invokeinterface |
2654 , Bytecodes::_new | |
2655 , Bytecodes::_newarray | |
2656 , Bytecodes::_anewarray | |
2657 , Bytecodes::_arraylength | |
2658 , Bytecodes::_athrow | |
2659 , Bytecodes::_checkcast | |
2660 , Bytecodes::_instanceof | |
2661 , Bytecodes::_monitorenter | |
2662 , Bytecodes::_multianewarray | |
2663 }; | |
2664 | |
2665 // inititialize trap tables | |
2666 for (int i = 0; i < Bytecodes::number_of_java_codes; i++) { | |
2667 _can_trap[i] = false; | |
2668 } | |
2669 // set standard trap info | |
2670 for (uint j = 0; j < ARRAY_SIZE(can_trap_list); j++) { | |
2671 _can_trap[can_trap_list[j]] = true; | |
2672 } | |
2673 } | |
2674 | |
2675 | |
2676 BlockBegin* GraphBuilder::header_block(BlockBegin* entry, BlockBegin::Flag f, ValueStack* state) { | |
2677 assert(entry->is_set(f), "entry/flag mismatch"); | |
2678 // create header block | |
2679 BlockBegin* h = new BlockBegin(entry->bci()); | |
2680 h->set_depth_first_number(0); | |
2681 | |
2682 Value l = h; | |
2683 BlockEnd* g = new Goto(entry, false); | |
2684 l->set_next(g, entry->bci()); | |
2685 h->set_end(g); | |
2686 h->set(f); | |
2687 // setup header block end state | |
1819 | 2688 ValueStack* s = state->copy(ValueStack::StateAfter, entry->bci()); // can use copy since stack is empty (=> no phis) |
0 | 2689 assert(s->stack_is_empty(), "must have empty stack at entry point"); |
2690 g->set_state(s); | |
2691 return h; | |
2692 } | |
2693 | |
2694 | |
2695 | |
2696 BlockBegin* GraphBuilder::setup_start_block(int osr_bci, BlockBegin* std_entry, BlockBegin* osr_entry, ValueStack* state) { | |
2697 BlockBegin* start = new BlockBegin(0); | |
2698 | |
2699 // This code eliminates the empty start block at the beginning of | |
2700 // each method. Previously, each method started with the | |
2701 // start-block created below, and this block was followed by the | |
2702 // header block that was always empty. This header block is only | |
2703 // necesary if std_entry is also a backward branch target because | |
2704 // then phi functions may be necessary in the header block. It's | |
2705 // also necessary when profiling so that there's a single block that | |
2706 // can increment the interpreter_invocation_count. | |
2707 BlockBegin* new_header_block; | |
1783 | 2708 if (std_entry->number_of_preds() > 0 || count_invocations() || count_backedges()) { |
2709 new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state); | |
2710 } else { | |
0 | 2711 new_header_block = std_entry; |
2712 } | |
2713 | |
2714 // setup start block (root for the IR graph) | |
2715 Base* base = | |
2716 new Base( | |
2717 new_header_block, | |
2718 osr_entry | |
2719 ); | |
2720 start->set_next(base, 0); | |
2721 start->set_end(base); | |
2722 // create & setup state for start block | |
1819 | 2723 start->set_state(state->copy(ValueStack::StateAfter, std_entry->bci())); |
2724 base->set_state(state->copy(ValueStack::StateAfter, std_entry->bci())); | |
0 | 2725 |
2726 if (base->std_entry()->state() == NULL) { | |
2727 // setup states for header blocks | |
2728 base->std_entry()->merge(state); | |
2729 } | |
2730 | |
2731 assert(base->std_entry()->state() != NULL, ""); | |
2732 return start; | |
2733 } | |
2734 | |
2735 | |
2736 void GraphBuilder::setup_osr_entry_block() { | |
2737 assert(compilation()->is_osr_compile(), "only for osrs"); | |
2738 | |
2739 int osr_bci = compilation()->osr_bci(); | |
2740 ciBytecodeStream s(method()); | |
2741 s.reset_to_bci(osr_bci); | |
2742 s.next(); | |
2743 scope_data()->set_stream(&s); | |
2744 | |
2745 // create a new block to be the osr setup code | |
2746 _osr_entry = new BlockBegin(osr_bci); | |
2747 _osr_entry->set(BlockBegin::osr_entry_flag); | |
2748 _osr_entry->set_depth_first_number(0); | |
2749 BlockBegin* target = bci2block()->at(osr_bci); | |
2750 assert(target != NULL && target->is_set(BlockBegin::osr_entry_flag), "must be there"); | |
2751 // the osr entry has no values for locals | |
2752 ValueStack* state = target->state()->copy(); | |
2753 _osr_entry->set_state(state); | |
2754 | |
2755 kill_all(); | |
2756 _block = _osr_entry; | |
2757 _state = _osr_entry->state()->copy(); | |
1819 | 2758 assert(_state->bci() == osr_bci, "mismatch"); |
0 | 2759 _last = _osr_entry; |
2760 Value e = append(new OsrEntry()); | |
2761 e->set_needs_null_check(false); | |
2762 | |
2763 // OSR buffer is | |
2764 // | |
2765 // locals[nlocals-1..0] | |
2766 // monitors[number_of_locks-1..0] | |
2767 // | |
2768 // locals is a direct copy of the interpreter frame so in the osr buffer | |
2769 // so first slot in the local array is the last local from the interpreter | |
2770 // and last slot is local[0] (receiver) from the interpreter | |
2771 // | |
2772 // Similarly with locks. The first lock slot in the osr buffer is the nth lock | |
2773 // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock | |
2774 // in the interpreter frame (the method lock if a sync method) | |
2775 | |
2776 // Initialize monitors in the compiled activation. | |
2777 | |
2778 int index; | |
2779 Value local; | |
2780 | |
2781 // find all the locals that the interpreter thinks contain live oops | |
2782 const BitMap live_oops = method()->live_local_oops_at_bci(osr_bci); | |
2783 | |
2784 // compute the offset into the locals so that we can treat the buffer | |
2785 // as if the locals were still in the interpreter frame | |
2786 int locals_offset = BytesPerWord * (method()->max_locals() - 1); | |
2787 for_each_local_value(state, index, local) { | |
2788 int offset = locals_offset - (index + local->type()->size() - 1) * BytesPerWord; | |
2789 Value get; | |
2790 if (local->type()->is_object_kind() && !live_oops.at(index)) { | |
2791 // The interpreter thinks this local is dead but the compiler | |
2792 // doesn't so pretend that the interpreter passed in null. | |
2793 get = append(new Constant(objectNull)); | |
2794 } else { | |
2795 get = append(new UnsafeGetRaw(as_BasicType(local->type()), e, | |
2796 append(new Constant(new IntConstant(offset))), | |
2797 0, | |
2002 | 2798 true /*unaligned*/, true /*wide*/)); |
0 | 2799 } |
2800 _state->store_local(index, get); | |
2801 } | |
2802 | |
2803 // the storage for the OSR buffer is freed manually in the LIRGenerator. | |
2804 | |
2805 assert(state->caller_state() == NULL, "should be top scope"); | |
2806 state->clear_locals(); | |
2807 Goto* g = new Goto(target, false); | |
2808 append(g); | |
2809 _osr_entry->set_end(g); | |
2810 target->merge(_osr_entry->end()->state()); | |
2811 | |
2812 scope_data()->set_stream(NULL); | |
2813 } | |
2814 | |
2815 | |
2816 ValueStack* GraphBuilder::state_at_entry() { | |
1819 | 2817 ValueStack* state = new ValueStack(scope(), NULL); |
0 | 2818 |
2819 // Set up locals for receiver | |
2820 int idx = 0; | |
2821 if (!method()->is_static()) { | |
2822 // we should always see the receiver | |
2823 state->store_local(idx, new Local(objectType, idx)); | |
2824 idx = 1; | |
2825 } | |
2826 | |
2827 // Set up locals for incoming arguments | |
2828 ciSignature* sig = method()->signature(); | |
2829 for (int i = 0; i < sig->count(); i++) { | |
2830 ciType* type = sig->type_at(i); | |
2831 BasicType basic_type = type->basic_type(); | |
2832 // don't allow T_ARRAY to propagate into locals types | |
2833 if (basic_type == T_ARRAY) basic_type = T_OBJECT; | |
2834 ValueType* vt = as_ValueType(basic_type); | |
2835 state->store_local(idx, new Local(vt, idx)); | |
2836 idx += type->size(); | |
2837 } | |
2838 | |
2839 // lock synchronized method | |
2840 if (method()->is_synchronized()) { | |
1819 | 2841 state->lock(NULL); |
0 | 2842 } |
2843 | |
2844 return state; | |
2845 } | |
2846 | |
2847 | |
2848 GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope) | |
2849 : _scope_data(NULL) | |
2850 , _instruction_count(0) | |
2851 , _osr_entry(NULL) | |
2852 , _memory(new MemoryBuffer()) | |
2853 , _compilation(compilation) | |
2854 , _inline_bailout_msg(NULL) | |
2855 { | |
2856 int osr_bci = compilation->osr_bci(); | |
2857 | |
2858 // determine entry points and bci2block mapping | |
2859 BlockListBuilder blm(compilation, scope, osr_bci); | |
2860 CHECK_BAILOUT(); | |
2861 | |
2862 BlockList* bci2block = blm.bci2block(); | |
2863 BlockBegin* start_block = bci2block->at(0); | |
2864 | |
2865 push_root_scope(scope, bci2block, start_block); | |
2866 | |
2867 // setup state for std entry | |
2868 _initial_state = state_at_entry(); | |
2869 start_block->merge(_initial_state); | |
2870 | |
2871 // complete graph | |
2872 _vmap = new ValueMap(); | |
2873 switch (scope->method()->intrinsic_id()) { | |
2874 case vmIntrinsics::_dabs : // fall through | |
2875 case vmIntrinsics::_dsqrt : // fall through | |
2876 case vmIntrinsics::_dsin : // fall through | |
2877 case vmIntrinsics::_dcos : // fall through | |
2878 case vmIntrinsics::_dtan : // fall through | |
2879 case vmIntrinsics::_dlog : // fall through | |
2880 case vmIntrinsics::_dlog10 : // fall through | |
2881 { | |
2882 // Compiles where the root method is an intrinsic need a special | |
2883 // compilation environment because the bytecodes for the method | |
2884 // shouldn't be parsed during the compilation, only the special | |
2885 // Intrinsic node should be emitted. If this isn't done the the | |
2886 // code for the inlined version will be different than the root | |
2887 // compiled version which could lead to monotonicity problems on | |
2888 // intel. | |
2889 | |
2890 // Set up a stream so that appending instructions works properly. | |
2891 ciBytecodeStream s(scope->method()); | |
2892 s.reset_to_bci(0); | |
2893 scope_data()->set_stream(&s); | |
2894 s.next(); | |
2895 | |
2896 // setup the initial block state | |
2897 _block = start_block; | |
1819 | 2898 _state = start_block->state()->copy_for_parsing(); |
0 | 2899 _last = start_block; |
2900 load_local(doubleType, 0); | |
2901 | |
2902 // Emit the intrinsic node. | |
2903 bool result = try_inline_intrinsics(scope->method()); | |
2904 if (!result) BAILOUT("failed to inline intrinsic"); | |
2905 method_return(dpop()); | |
2906 | |
2907 // connect the begin and end blocks and we're all done. | |
2908 BlockEnd* end = last()->as_BlockEnd(); | |
2909 block()->set_end(end); | |
2910 break; | |
2911 } | |
2912 default: | |
2913 scope_data()->add_to_work_list(start_block); | |
2914 iterate_all_blocks(); | |
2915 break; | |
2916 } | |
2917 CHECK_BAILOUT(); | |
2918 | |
2919 _start = setup_start_block(osr_bci, start_block, _osr_entry, _initial_state); | |
2920 | |
2921 eliminate_redundant_phis(_start); | |
2922 | |
2923 NOT_PRODUCT(if (PrintValueNumbering && Verbose) print_stats()); | |
2924 // for osr compile, bailout if some requirements are not fulfilled | |
2925 if (osr_bci != -1) { | |
2926 BlockBegin* osr_block = blm.bci2block()->at(osr_bci); | |
2927 assert(osr_block->is_set(BlockBegin::was_visited_flag),"osr entry must have been visited for osr compile"); | |
2928 | |
2929 // check if osr entry point has empty stack - we cannot handle non-empty stacks at osr entry points | |
2930 if (!osr_block->state()->stack_is_empty()) { | |
2931 BAILOUT("stack not empty at OSR entry point"); | |
2932 } | |
2933 } | |
2934 #ifndef PRODUCT | |
2935 if (PrintCompilation && Verbose) tty->print_cr("Created %d Instructions", _instruction_count); | |
2936 #endif | |
2937 } | |
2938 | |
2939 | |
1819 | 2940 ValueStack* GraphBuilder::copy_state_before() { |
2941 return copy_state_before_with_bci(bci()); | |
2942 } | |
2943 | |
2944 ValueStack* GraphBuilder::copy_state_exhandling() { | |
2945 return copy_state_exhandling_with_bci(bci()); | |
2946 } | |
2947 | |
2948 ValueStack* GraphBuilder::copy_state_for_exception() { | |
2949 return copy_state_for_exception_with_bci(bci()); | |
2950 } | |
2951 | |
2952 ValueStack* GraphBuilder::copy_state_before_with_bci(int bci) { | |
2953 return state()->copy(ValueStack::StateBefore, bci); | |
0 | 2954 } |
2955 | |
1819 | 2956 ValueStack* GraphBuilder::copy_state_exhandling_with_bci(int bci) { |
2957 if (!has_handler()) return NULL; | |
2958 return state()->copy(ValueStack::StateBefore, bci); | |
2959 } | |
2960 | |
2961 ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) { | |
2962 ValueStack* s = copy_state_exhandling_with_bci(bci); | |
2963 if (s == NULL) { | |
2964 if (_compilation->env()->jvmti_can_access_local_variables()) { | |
2965 s = state()->copy(ValueStack::ExceptionState, bci); | |
2966 } else { | |
2967 s = state()->copy(ValueStack::EmptyExceptionState, bci); | |
2968 } | |
2969 } | |
2970 return s; | |
2971 } | |
0 | 2972 |
2973 int GraphBuilder::recursive_inline_level(ciMethod* cur_callee) const { | |
2974 int recur_level = 0; | |
2975 for (IRScope* s = scope(); s != NULL; s = s->caller()) { | |
2976 if (s->method() == cur_callee) { | |
2977 ++recur_level; | |
2978 } | |
2979 } | |
2980 return recur_level; | |
2981 } | |
2982 | |
2983 | |
2984 bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known) { | |
2985 // Clear out any existing inline bailout condition | |
2986 clear_inline_bailout(); | |
2987 | |
2988 if (callee->should_exclude()) { | |
2989 // callee is excluded | |
2990 INLINE_BAILOUT("excluded by CompilerOracle") | |
2991 } else if (!callee->can_be_compiled()) { | |
2992 // callee is not compilable (prob. has breakpoints) | |
2993 INLINE_BAILOUT("not compilable") | |
2994 } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) { | |
2995 // intrinsics can be native or not | |
2996 return true; | |
2997 } else if (callee->is_native()) { | |
2998 // non-intrinsic natives cannot be inlined | |
2999 INLINE_BAILOUT("non-intrinsic native") | |
3000 } else if (callee->is_abstract()) { | |
3001 INLINE_BAILOUT("abstract") | |
3002 } else { | |
3003 return try_inline_full(callee, holder_known); | |
3004 } | |
3005 } | |
3006 | |
3007 | |
3008 bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) { | |
3009 if (!InlineNatives ) INLINE_BAILOUT("intrinsic method inlining disabled"); | |
1540
99791ad65936
6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents:
1397
diff
changeset
|
3010 if (callee->is_synchronized()) { |
99791ad65936
6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents:
1397
diff
changeset
|
3011 // We don't currently support any synchronized intrinsics |
99791ad65936
6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents:
1397
diff
changeset
|
3012 return false; |
99791ad65936
6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents:
1397
diff
changeset
|
3013 } |
99791ad65936
6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents:
1397
diff
changeset
|
3014 |
0 | 3015 // callee seems like a good candidate |
3016 // determine id | |
3017 bool preserves_state = false; | |
3018 bool cantrap = true; | |
3019 vmIntrinsics::ID id = callee->intrinsic_id(); | |
3020 switch (id) { | |
3021 case vmIntrinsics::_arraycopy : | |
3022 if (!InlineArrayCopy) return false; | |
3023 break; | |
3024 | |
3025 case vmIntrinsics::_currentTimeMillis: | |
3026 case vmIntrinsics::_nanoTime: | |
3027 preserves_state = true; | |
3028 cantrap = false; | |
3029 break; | |
3030 | |
3031 case vmIntrinsics::_floatToRawIntBits : | |
3032 case vmIntrinsics::_intBitsToFloat : | |
3033 case vmIntrinsics::_doubleToRawLongBits : | |
3034 case vmIntrinsics::_longBitsToDouble : | |
3035 if (!InlineMathNatives) return false; | |
3036 preserves_state = true; | |
3037 cantrap = false; | |
3038 break; | |
3039 | |
3040 case vmIntrinsics::_getClass : | |
3041 if (!InlineClassNatives) return false; | |
3042 preserves_state = true; | |
3043 break; | |
3044 | |
3045 case vmIntrinsics::_currentThread : | |
3046 if (!InlineThreadNatives) return false; | |
3047 preserves_state = true; | |
3048 cantrap = false; | |
3049 break; | |
3050 | |
3051 case vmIntrinsics::_dabs : // fall through | |
3052 case vmIntrinsics::_dsqrt : // fall through | |
3053 case vmIntrinsics::_dsin : // fall through | |
3054 case vmIntrinsics::_dcos : // fall through | |
3055 case vmIntrinsics::_dtan : // fall through | |
3056 case vmIntrinsics::_dlog : // fall through | |
3057 case vmIntrinsics::_dlog10 : // fall through | |
3058 if (!InlineMathNatives) return false; | |
3059 cantrap = false; | |
3060 preserves_state = true; | |
3061 break; | |
3062 | |
3063 // sun/misc/AtomicLong.attemptUpdate | |
3064 case vmIntrinsics::_attemptUpdate : | |
3065 if (!VM_Version::supports_cx8()) return false; | |
3066 if (!InlineAtomicLong) return false; | |
3067 preserves_state = true; | |
3068 break; | |
3069 | |
3070 // Use special nodes for Unsafe instructions so we can more easily | |
3071 // perform an address-mode optimization on the raw variants | |
3072 case vmIntrinsics::_getObject : return append_unsafe_get_obj(callee, T_OBJECT, false); | |
3073 case vmIntrinsics::_getBoolean: return append_unsafe_get_obj(callee, T_BOOLEAN, false); | |
3074 case vmIntrinsics::_getByte : return append_unsafe_get_obj(callee, T_BYTE, false); | |
3075 case vmIntrinsics::_getShort : return append_unsafe_get_obj(callee, T_SHORT, false); | |
3076 case vmIntrinsics::_getChar : return append_unsafe_get_obj(callee, T_CHAR, false); | |
3077 case vmIntrinsics::_getInt : return append_unsafe_get_obj(callee, T_INT, false); | |
3078 case vmIntrinsics::_getLong : return append_unsafe_get_obj(callee, T_LONG, false); | |
3079 case vmIntrinsics::_getFloat : return append_unsafe_get_obj(callee, T_FLOAT, false); | |
3080 case vmIntrinsics::_getDouble : return append_unsafe_get_obj(callee, T_DOUBLE, false); | |
3081 | |
3082 case vmIntrinsics::_putObject : return append_unsafe_put_obj(callee, T_OBJECT, false); | |
3083 case vmIntrinsics::_putBoolean: return append_unsafe_put_obj(callee, T_BOOLEAN, false); | |
3084 case vmIntrinsics::_putByte : return append_unsafe_put_obj(callee, T_BYTE, false); | |
3085 case vmIntrinsics::_putShort : return append_unsafe_put_obj(callee, T_SHORT, false); | |
3086 case vmIntrinsics::_putChar : return append_unsafe_put_obj(callee, T_CHAR, false); | |
3087 case vmIntrinsics::_putInt : return append_unsafe_put_obj(callee, T_INT, false); | |
3088 case vmIntrinsics::_putLong : return append_unsafe_put_obj(callee, T_LONG, false); | |
3089 case vmIntrinsics::_putFloat : return append_unsafe_put_obj(callee, T_FLOAT, false); | |
3090 case vmIntrinsics::_putDouble : return append_unsafe_put_obj(callee, T_DOUBLE, false); | |
3091 | |
3092 case vmIntrinsics::_getObjectVolatile : return append_unsafe_get_obj(callee, T_OBJECT, true); | |
3093 case vmIntrinsics::_getBooleanVolatile: return append_unsafe_get_obj(callee, T_BOOLEAN, true); | |
3094 case vmIntrinsics::_getByteVolatile : return append_unsafe_get_obj(callee, T_BYTE, true); | |
3095 case vmIntrinsics::_getShortVolatile : return append_unsafe_get_obj(callee, T_SHORT, true); | |
3096 case vmIntrinsics::_getCharVolatile : return append_unsafe_get_obj(callee, T_CHAR, true); | |
3097 case vmIntrinsics::_getIntVolatile : return append_unsafe_get_obj(callee, T_INT, true); | |
3098 case vmIntrinsics::_getLongVolatile : return append_unsafe_get_obj(callee, T_LONG, true); | |
3099 case vmIntrinsics::_getFloatVolatile : return append_unsafe_get_obj(callee, T_FLOAT, true); | |
3100 case vmIntrinsics::_getDoubleVolatile : return append_unsafe_get_obj(callee, T_DOUBLE, true); | |
3101 | |
3102 case vmIntrinsics::_putObjectVolatile : return append_unsafe_put_obj(callee, T_OBJECT, true); | |
3103 case vmIntrinsics::_putBooleanVolatile: return append_unsafe_put_obj(callee, T_BOOLEAN, true); | |
3104 case vmIntrinsics::_putByteVolatile : return append_unsafe_put_obj(callee, T_BYTE, true); | |
3105 case vmIntrinsics::_putShortVolatile : return append_unsafe_put_obj(callee, T_SHORT, true); | |
3106 case vmIntrinsics::_putCharVolatile : return append_unsafe_put_obj(callee, T_CHAR, true); | |
3107 case vmIntrinsics::_putIntVolatile : return append_unsafe_put_obj(callee, T_INT, true); | |
3108 case vmIntrinsics::_putLongVolatile : return append_unsafe_put_obj(callee, T_LONG, true); | |
3109 case vmIntrinsics::_putFloatVolatile : return append_unsafe_put_obj(callee, T_FLOAT, true); | |
3110 case vmIntrinsics::_putDoubleVolatile : return append_unsafe_put_obj(callee, T_DOUBLE, true); | |
3111 | |
3112 case vmIntrinsics::_getByte_raw : return append_unsafe_get_raw(callee, T_BYTE); | |
3113 case vmIntrinsics::_getShort_raw : return append_unsafe_get_raw(callee, T_SHORT); | |
3114 case vmIntrinsics::_getChar_raw : return append_unsafe_get_raw(callee, T_CHAR); | |
3115 case vmIntrinsics::_getInt_raw : return append_unsafe_get_raw(callee, T_INT); | |
3116 case vmIntrinsics::_getLong_raw : return append_unsafe_get_raw(callee, T_LONG); | |
3117 case vmIntrinsics::_getFloat_raw : return append_unsafe_get_raw(callee, T_FLOAT); | |
3118 case vmIntrinsics::_getDouble_raw : return append_unsafe_get_raw(callee, T_DOUBLE); | |
3119 | |
3120 case vmIntrinsics::_putByte_raw : return append_unsafe_put_raw(callee, T_BYTE); | |
3121 case vmIntrinsics::_putShort_raw : return append_unsafe_put_raw(callee, T_SHORT); | |
3122 case vmIntrinsics::_putChar_raw : return append_unsafe_put_raw(callee, T_CHAR); | |
3123 case vmIntrinsics::_putInt_raw : return append_unsafe_put_raw(callee, T_INT); | |
3124 case vmIntrinsics::_putLong_raw : return append_unsafe_put_raw(callee, T_LONG); | |
3125 case vmIntrinsics::_putFloat_raw : return append_unsafe_put_raw(callee, T_FLOAT); | |
3126 case vmIntrinsics::_putDouble_raw : return append_unsafe_put_raw(callee, T_DOUBLE); | |
3127 | |
3128 case vmIntrinsics::_prefetchRead : return append_unsafe_prefetch(callee, false, false); | |
3129 case vmIntrinsics::_prefetchWrite : return append_unsafe_prefetch(callee, false, true); | |
3130 case vmIntrinsics::_prefetchReadStatic : return append_unsafe_prefetch(callee, true, false); | |
3131 case vmIntrinsics::_prefetchWriteStatic : return append_unsafe_prefetch(callee, true, true); | |
3132 | |
3133 case vmIntrinsics::_checkIndex : | |
3134 if (!InlineNIOCheckIndex) return false; | |
3135 preserves_state = true; | |
3136 break; | |
3137 case vmIntrinsics::_putOrderedObject : return append_unsafe_put_obj(callee, T_OBJECT, true); | |
3138 case vmIntrinsics::_putOrderedInt : return append_unsafe_put_obj(callee, T_INT, true); | |
3139 case vmIntrinsics::_putOrderedLong : return append_unsafe_put_obj(callee, T_LONG, true); | |
3140 | |
3141 case vmIntrinsics::_compareAndSwapLong: | |
3142 if (!VM_Version::supports_cx8()) return false; | |
3143 // fall through | |
3144 case vmIntrinsics::_compareAndSwapInt: | |
3145 case vmIntrinsics::_compareAndSwapObject: | |
3146 append_unsafe_CAS(callee); | |
3147 return true; | |
3148 | |
3149 default : return false; // do not inline | |
3150 } | |
3151 // create intrinsic node | |
3152 const bool has_receiver = !callee->is_static(); | |
3153 ValueType* result_type = as_ValueType(callee->return_type()); | |
1819 | 3154 ValueStack* state_before = copy_state_for_exception(); |
0 | 3155 |
3156 Values* args = state()->pop_arguments(callee->arg_size()); | |
1783 | 3157 |
3158 if (is_profiling()) { | |
0 | 3159 // Don't profile in the special case where the root method |
3160 // is the intrinsic | |
3161 if (callee != method()) { | |
1783 | 3162 // Note that we'd collect profile data in this method if we wanted it. |
3163 compilation()->set_would_profile(true); | |
3164 if (profile_calls()) { | |
3165 Value recv = NULL; | |
3166 if (has_receiver) { | |
3167 recv = args->at(0); | |
3168 null_check(recv); | |
3169 } | |
3170 profile_call(recv, NULL); | |
0 | 3171 } |
3172 } | |
3173 } | |
3174 | |
1819 | 3175 Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before, |
0 | 3176 preserves_state, cantrap); |
3177 // append instruction & push result | |
3178 Value value = append_split(result); | |
3179 if (result_type != voidType) push(result_type, value); | |
3180 | |
3181 #ifndef PRODUCT | |
3182 // printing | |
3183 if (PrintInlining) { | |
3184 print_inline_result(callee, true); | |
3185 } | |
3186 #endif | |
3187 | |
3188 // done | |
3189 return true; | |
3190 } | |
3191 | |
3192 | |
3193 bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) { | |
3194 // Introduce a new callee continuation point - all Ret instructions | |
3195 // will be replaced with Gotos to this point. | |
3196 BlockBegin* cont = block_at(next_bci()); | |
3197 assert(cont != NULL, "continuation must exist (BlockListBuilder starts a new block after a jsr"); | |
3198 | |
3199 // Note: can not assign state to continuation yet, as we have to | |
3200 // pick up the state from the Ret instructions. | |
3201 | |
3202 // Push callee scope | |
3203 push_scope_for_jsr(cont, jsr_dest_bci); | |
3204 | |
3205 // Temporarily set up bytecode stream so we can append instructions | |
3206 // (only using the bci of this stream) | |
3207 scope_data()->set_stream(scope_data()->parent()->stream()); | |
3208 | |
3209 BlockBegin* jsr_start_block = block_at(jsr_dest_bci); | |
3210 assert(jsr_start_block != NULL, "jsr start block must exist"); | |
3211 assert(!jsr_start_block->is_set(BlockBegin::was_visited_flag), "should not have visited jsr yet"); | |
3212 Goto* goto_sub = new Goto(jsr_start_block, false); | |
3213 // Must copy state to avoid wrong sharing when parsing bytecodes | |
3214 assert(jsr_start_block->state() == NULL, "should have fresh jsr starting block"); | |
1819 | 3215 jsr_start_block->set_state(copy_state_before_with_bci(jsr_dest_bci)); |
0 | 3216 append(goto_sub); |
3217 _block->set_end(goto_sub); | |
3218 _last = _block = jsr_start_block; | |
3219 | |
3220 // Clear out bytecode stream | |
3221 scope_data()->set_stream(NULL); | |
3222 | |
3223 scope_data()->add_to_work_list(jsr_start_block); | |
3224 | |
3225 // Ready to resume parsing in subroutine | |
3226 iterate_all_blocks(); | |
3227 | |
3228 // If we bailed out during parsing, return immediately (this is bad news) | |
3229 CHECK_BAILOUT_(false); | |
3230 | |
3231 // Detect whether the continuation can actually be reached. If not, | |
3232 // it has not had state set by the join() operations in | |
3233 // iterate_bytecodes_for_block()/ret() and we should not touch the | |
3234 // iteration state. The calling activation of | |
3235 // iterate_bytecodes_for_block will then complete normally. | |
3236 if (cont->state() != NULL) { | |
3237 if (!cont->is_set(BlockBegin::was_visited_flag)) { | |
3238 // add continuation to work list instead of parsing it immediately | |
3239 scope_data()->parent()->add_to_work_list(cont); | |
3240 } | |
3241 } | |
3242 | |
3243 assert(jsr_continuation() == cont, "continuation must not have changed"); | |
3244 assert(!jsr_continuation()->is_set(BlockBegin::was_visited_flag) || | |
3245 jsr_continuation()->is_set(BlockBegin::parser_loop_header_flag), | |
3246 "continuation can only be visited in case of backward branches"); | |
3247 assert(_last && _last->as_BlockEnd(), "block must have end"); | |
3248 | |
3249 // continuation is in work list, so end iteration of current block | |
3250 _skip_block = true; | |
3251 pop_scope_for_jsr(); | |
3252 | |
3253 return true; | |
3254 } | |
3255 | |
3256 | |
3257 // Inline the entry of a synchronized method as a monitor enter and | |
3258 // register the exception handler which releases the monitor if an | |
3259 // exception is thrown within the callee. Note that the monitor enter | |
3260 // cannot throw an exception itself, because the receiver is | |
3261 // guaranteed to be non-null by the explicit null check at the | |
3262 // beginning of inlining. | |
3263 void GraphBuilder::inline_sync_entry(Value lock, BlockBegin* sync_handler) { | |
3264 assert(lock != NULL && sync_handler != NULL, "lock or handler missing"); | |
3265 | |
3266 monitorenter(lock, SynchronizationEntryBCI); | |
3267 assert(_last->as_MonitorEnter() != NULL, "monitor enter expected"); | |
3268 _last->set_needs_null_check(false); | |
3269 | |
3270 sync_handler->set(BlockBegin::exception_entry_flag); | |
3271 sync_handler->set(BlockBegin::is_on_work_list_flag); | |
3272 | |
3273 ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0); | |
3274 XHandler* h = new XHandler(desc); | |
3275 h->set_entry_block(sync_handler); | |
3276 scope_data()->xhandlers()->append(h); | |
3277 scope_data()->set_has_handler(); | |
3278 } | |
3279 | |
3280 | |
3281 // If an exception is thrown and not handled within an inlined | |
3282 // synchronized method, the monitor must be released before the | |
3283 // exception is rethrown in the outer scope. Generate the appropriate | |
3284 // instructions here. | |
3285 void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler) { | |
3286 BlockBegin* orig_block = _block; | |
3287 ValueStack* orig_state = _state; | |
3288 Instruction* orig_last = _last; | |
3289 _last = _block = sync_handler; | |
3290 _state = sync_handler->state()->copy(); | |
3291 | |
3292 assert(sync_handler != NULL, "handler missing"); | |
3293 assert(!sync_handler->is_set(BlockBegin::was_visited_flag), "is visited here"); | |
3294 | |
3295 assert(lock != NULL || default_handler, "lock or handler missing"); | |
3296 | |
3297 XHandler* h = scope_data()->xhandlers()->remove_last(); | |
3298 assert(h->entry_block() == sync_handler, "corrupt list of handlers"); | |
3299 | |
3300 block()->set(BlockBegin::was_visited_flag); | |
3301 Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI); | |
3302 assert(exception->is_pinned(), "must be"); | |
3303 | |
3304 int bci = SynchronizationEntryBCI; | |
3305 if (lock) { | |
3306 assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing"); | |
1819 | 3307 if (!lock->is_linked()) { |
0 | 3308 lock = append_with_bci(lock, -1); |
3309 } | |
3310 | |
3311 // exit the monitor in the context of the synchronized method | |
3312 monitorexit(lock, SynchronizationEntryBCI); | |
3313 | |
3314 // exit the context of the synchronized method | |
3315 if (!default_handler) { | |
3316 pop_scope(); | |
1819 | 3317 bci = _state->caller_state()->bci(); |
3318 _state = _state->caller_state()->copy_for_parsing(); | |
0 | 3319 } |
3320 } | |
3321 | |
3322 // perform the throw as if at the the call site | |
3323 apush(exception); | |
3324 throw_op(bci); | |
3325 | |
3326 BlockEnd* end = last()->as_BlockEnd(); | |
3327 block()->set_end(end); | |
3328 | |
3329 _block = orig_block; | |
3330 _state = orig_state; | |
3331 _last = orig_last; | |
3332 } | |
3333 | |
3334 | |
3335 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) { | |
3336 assert(!callee->is_native(), "callee must not be native"); | |
1783 | 3337 if (count_backedges() && callee->has_loops()) { |
3338 INLINE_BAILOUT("too complex for tiered"); | |
3339 } | |
0 | 3340 // first perform tests of things it's not possible to inline |
3341 if (callee->has_exception_handlers() && | |
3342 !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers"); | |
3343 if (callee->is_synchronized() && | |
3344 !InlineSynchronizedMethods ) INLINE_BAILOUT("callee is synchronized"); | |
3345 if (!callee->holder()->is_initialized()) INLINE_BAILOUT("callee's klass not initialized yet"); | |
3346 if (!callee->has_balanced_monitors()) INLINE_BAILOUT("callee's monitors do not match"); | |
3347 | |
3348 // Proper inlining of methods with jsrs requires a little more work. | |
3349 if (callee->has_jsrs() ) INLINE_BAILOUT("jsrs not handled properly by inliner yet"); | |
3350 | |
3351 // now perform tests that are based on flag settings | |
3352 if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("too-deep inlining"); | |
3353 if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining"); | |
3354 if (callee->code_size() > max_inline_size() ) INLINE_BAILOUT("callee is too large"); | |
3355 | |
3356 // don't inline throwable methods unless the inlining tree is rooted in a throwable class | |
3357 if (callee->name() == ciSymbol::object_initializer_name() && | |
3358 callee->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) { | |
3359 // Throwable constructor call | |
3360 IRScope* top = scope(); | |
3361 while (top->caller() != NULL) { | |
3362 top = top->caller(); | |
3363 } | |
3364 if (!top->method()->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) { | |
3365 INLINE_BAILOUT("don't inline Throwable constructors"); | |
3366 } | |
3367 } | |
3368 | |
3369 // When SSE2 is used on intel, then no special handling is needed | |
3370 // for strictfp because the enum-constant is fixed at compile time, | |
3371 // the check for UseSSE2 is needed here | |
3372 if (strict_fp_requires_explicit_rounding && UseSSE < 2 && method()->is_strict() != callee->is_strict()) { | |
3373 INLINE_BAILOUT("caller and callee have different strict fp requirements"); | |
3374 } | |
3375 | |
3376 if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) { | |
3377 INLINE_BAILOUT("total inlining greater than DesiredMethodLimit"); | |
3378 } | |
3379 | |
2007
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
3380 if (is_profiling() && !callee->ensure_method_data()) { |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
3381 INLINE_BAILOUT("mdo allocation failed"); |
5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents:
2002
diff
changeset
|
3382 } |
0 | 3383 #ifndef PRODUCT |
3384 // printing | |
3385 if (PrintInlining) { | |
3386 print_inline_result(callee, true); | |
3387 } | |
3388 #endif | |
3389 | |
3390 // NOTE: Bailouts from this point on, which occur at the | |
3391 // GraphBuilder level, do not cause bailout just of the inlining but | |
3392 // in fact of the entire compilation. | |
3393 | |
3394 BlockBegin* orig_block = block(); | |
3395 | |
3396 const int args_base = state()->stack_size() - callee->arg_size(); | |
3397 assert(args_base >= 0, "stack underflow during inlining"); | |
3398 | |
3399 // Insert null check if necessary | |
3400 Value recv = NULL; | |
3401 if (code() != Bytecodes::_invokestatic) { | |
3402 // note: null check must happen even if first instruction of callee does | |
3403 // an implicit null check since the callee is in a different scope | |
3404 // and we must make sure exception handling does the right thing | |
3405 assert(!callee->is_static(), "callee must not be static"); | |
3406 assert(callee->arg_size() > 0, "must have at least a receiver"); | |
3407 recv = state()->stack_at(args_base); | |
3408 null_check(recv); | |
3409 } | |
3410 | |
1783 | 3411 if (is_profiling()) { |
3412 // Note that we'd collect profile data in this method if we wanted it. | |
3413 // this may be redundant here... | |
3414 compilation()->set_would_profile(true); | |
3415 | |
3416 if (profile_calls()) { | |
3417 profile_call(recv, holder_known ? callee->holder() : NULL); | |
3418 } | |
3419 if (profile_inlined_calls()) { | |
1825 | 3420 profile_invocation(callee, copy_state_before()); |
1783 | 3421 } |
0 | 3422 } |
3423 | |
3424 // Introduce a new callee continuation point - if the callee has | |
3425 // more than one return instruction or the return does not allow | |
3426 // fall-through of control flow, all return instructions of the | |
3427 // callee will need to be replaced by Goto's pointing to this | |
3428 // continuation point. | |
3429 BlockBegin* cont = block_at(next_bci()); | |
3430 bool continuation_existed = true; | |
3431 if (cont == NULL) { | |
3432 cont = new BlockBegin(next_bci()); | |
3433 // low number so that continuation gets parsed as early as possible | |
3434 cont->set_depth_first_number(0); | |
3435 #ifndef PRODUCT | |
3436 if (PrintInitialBlockList) { | |
3437 tty->print_cr("CFG: created block %d (bci %d) as continuation for inline at bci %d", | |
3438 cont->block_id(), cont->bci(), bci()); | |
3439 } | |
3440 #endif | |
3441 continuation_existed = false; | |
3442 } | |
3443 // Record number of predecessors of continuation block before | |
3444 // inlining, to detect if inlined method has edges to its | |
3445 // continuation after inlining. | |
3446 int continuation_preds = cont->number_of_preds(); | |
3447 | |
3448 // Push callee scope | |
3449 push_scope(callee, cont); | |
3450 | |
3451 // the BlockListBuilder for the callee could have bailed out | |
3452 CHECK_BAILOUT_(false); | |
3453 | |
3454 // Temporarily set up bytecode stream so we can append instructions | |
3455 // (only using the bci of this stream) | |
3456 scope_data()->set_stream(scope_data()->parent()->stream()); | |
3457 | |
3458 // Pass parameters into callee state: add assignments | |
3459 // note: this will also ensure that all arguments are computed before being passed | |
3460 ValueStack* callee_state = state(); | |
1819 | 3461 ValueStack* caller_state = state()->caller_state(); |
0 | 3462 { int i = args_base; |
3463 while (i < caller_state->stack_size()) { | |
3464 const int par_no = i - args_base; | |
3465 Value arg = caller_state->stack_at_inc(i); | |
3466 // NOTE: take base() of arg->type() to avoid problems storing | |
3467 // constants | |
3468 store_local(callee_state, arg, arg->type()->base(), par_no); | |
3469 } | |
3470 } | |
3471 | |
3472 // Remove args from stack. | |
3473 // Note that we preserve locals state in case we can use it later | |
3474 // (see use of pop_scope() below) | |
3475 caller_state->truncate_stack(args_base); | |
1819 | 3476 assert(callee_state->stack_size() == 0, "callee stack must be empty"); |
0 | 3477 |
3478 Value lock; | |
3479 BlockBegin* sync_handler; | |
3480 | |
3481 // Inline the locking of the receiver if the callee is synchronized | |
3482 if (callee->is_synchronized()) { | |
3483 lock = callee->is_static() ? append(new Constant(new InstanceConstant(callee->holder()->java_mirror()))) | |
3484 : state()->local_at(0); | |
1819 | 3485 sync_handler = new BlockBegin(SynchronizationEntryBCI); |
0 | 3486 inline_sync_entry(lock, sync_handler); |
3487 } | |
3488 | |
3489 | |
3490 BlockBegin* callee_start_block = block_at(0); | |
3491 if (callee_start_block != NULL) { | |
3492 assert(callee_start_block->is_set(BlockBegin::parser_loop_header_flag), "must be loop header"); | |
3493 Goto* goto_callee = new Goto(callee_start_block, false); | |
3494 // The state for this goto is in the scope of the callee, so use | |
3495 // the entry bci for the callee instead of the call site bci. | |
3496 append_with_bci(goto_callee, 0); | |
3497 _block->set_end(goto_callee); | |
3498 callee_start_block->merge(callee_state); | |
3499 | |
3500 _last = _block = callee_start_block; | |
3501 | |
3502 scope_data()->add_to_work_list(callee_start_block); | |
3503 } | |
3504 | |
3505 // Clear out bytecode stream | |
3506 scope_data()->set_stream(NULL); | |
3507 | |
3508 // Ready to resume parsing in callee (either in the same block we | |
3509 // were in before or in the callee's start block) | |
3510 iterate_all_blocks(callee_start_block == NULL); | |
3511 | |
3512 // If we bailed out during parsing, return immediately (this is bad news) | |
3513 if (bailed_out()) return false; | |
3514 | |
3515 // iterate_all_blocks theoretically traverses in random order; in | |
3516 // practice, we have only traversed the continuation if we are | |
3517 // inlining into a subroutine | |
3518 assert(continuation_existed || | |
3519 !continuation()->is_set(BlockBegin::was_visited_flag), | |
3520 "continuation should not have been parsed yet if we created it"); | |
3521 | |
3522 // If we bailed out during parsing, return immediately (this is bad news) | |
3523 CHECK_BAILOUT_(false); | |
3524 | |
3525 // At this point we are almost ready to return and resume parsing of | |
3526 // the caller back in the GraphBuilder. The only thing we want to do | |
3527 // first is an optimization: during parsing of the callee we | |
3528 // generated at least one Goto to the continuation block. If we | |
3529 // generated exactly one, and if the inlined method spanned exactly | |
3530 // one block (and we didn't have to Goto its entry), then we snip | |
3531 // off the Goto to the continuation, allowing control to fall | |
3532 // through back into the caller block and effectively performing | |
3533 // block merging. This allows load elimination and CSE to take place | |
3534 // across multiple callee scopes if they are relatively simple, and | |
3535 // is currently essential to making inlining profitable. | |
3536 if ( num_returns() == 1 | |
3537 && block() == orig_block | |
3538 && block() == inline_cleanup_block()) { | |
3539 _last = inline_cleanup_return_prev(); | |
1819 | 3540 _state = inline_cleanup_state(); |
0 | 3541 } else if (continuation_preds == cont->number_of_preds()) { |
3542 // Inlining caused that the instructions after the invoke in the | |
3543 // caller are not reachable any more. So skip filling this block | |
3544 // with instructions! | |
3545 assert (cont == continuation(), ""); | |
3546 assert(_last && _last->as_BlockEnd(), ""); | |
3547 _skip_block = true; | |
3548 } else { | |
3549 // Resume parsing in continuation block unless it was already parsed. | |
3550 // Note that if we don't change _last here, iteration in | |
3551 // iterate_bytecodes_for_block will stop when we return. | |
3552 if (!continuation()->is_set(BlockBegin::was_visited_flag)) { | |
3553 // add continuation to work list instead of parsing it immediately | |
3554 assert(_last && _last->as_BlockEnd(), ""); | |
3555 scope_data()->parent()->add_to_work_list(continuation()); | |
3556 _skip_block = true; | |
3557 } | |
3558 } | |
3559 | |
3560 // Fill the exception handler for synchronized methods with instructions | |
3561 if (callee->is_synchronized() && sync_handler->state() != NULL) { | |
3562 fill_sync_handler(lock, sync_handler); | |
3563 } else { | |
3564 pop_scope(); | |
3565 } | |
3566 | |
3567 compilation()->notice_inlined_method(callee); | |
3568 | |
3569 return true; | |
3570 } | |
3571 | |
3572 | |
3573 void GraphBuilder::inline_bailout(const char* msg) { | |
3574 assert(msg != NULL, "inline bailout msg must exist"); | |
3575 _inline_bailout_msg = msg; | |
3576 } | |
3577 | |
3578 | |
3579 void GraphBuilder::clear_inline_bailout() { | |
3580 _inline_bailout_msg = NULL; | |
3581 } | |
3582 | |
3583 | |
3584 void GraphBuilder::push_root_scope(IRScope* scope, BlockList* bci2block, BlockBegin* start) { | |
3585 ScopeData* data = new ScopeData(NULL); | |
3586 data->set_scope(scope); | |
3587 data->set_bci2block(bci2block); | |
3588 _scope_data = data; | |
3589 _block = start; | |
3590 } | |
3591 | |
3592 | |
3593 void GraphBuilder::push_scope(ciMethod* callee, BlockBegin* continuation) { | |
3594 IRScope* callee_scope = new IRScope(compilation(), scope(), bci(), callee, -1, false); | |
3595 scope()->add_callee(callee_scope); | |
3596 | |
3597 BlockListBuilder blb(compilation(), callee_scope, -1); | |
3598 CHECK_BAILOUT(); | |
3599 | |
3600 if (!blb.bci2block()->at(0)->is_set(BlockBegin::parser_loop_header_flag)) { | |
3601 // this scope can be inlined directly into the caller so remove | |
3602 // the block at bci 0. | |
3603 blb.bci2block()->at_put(0, NULL); | |
3604 } | |
3605 | |
1819 | 3606 set_state(new ValueStack(callee_scope, state()->copy(ValueStack::CallerState, bci()))); |
0 | 3607 |
3608 ScopeData* data = new ScopeData(scope_data()); | |
3609 data->set_scope(callee_scope); | |
3610 data->set_bci2block(blb.bci2block()); | |
3611 data->set_continuation(continuation); | |
3612 _scope_data = data; | |
3613 } | |
3614 | |
3615 | |
3616 void GraphBuilder::push_scope_for_jsr(BlockBegin* jsr_continuation, int jsr_dest_bci) { | |
3617 ScopeData* data = new ScopeData(scope_data()); | |
3618 data->set_parsing_jsr(); | |
3619 data->set_jsr_entry_bci(jsr_dest_bci); | |
3620 data->set_jsr_return_address_local(-1); | |
3621 // Must clone bci2block list as we will be mutating it in order to | |
3622 // properly clone all blocks in jsr region as well as exception | |
3623 // handlers containing rets | |
3624 BlockList* new_bci2block = new BlockList(bci2block()->length()); | |
3625 new_bci2block->push_all(bci2block()); | |
3626 data->set_bci2block(new_bci2block); | |
3627 data->set_scope(scope()); | |
3628 data->setup_jsr_xhandlers(); | |
3629 data->set_continuation(continuation()); | |
3630 data->set_jsr_continuation(jsr_continuation); | |
3631 _scope_data = data; | |
3632 } | |
3633 | |
3634 | |
3635 void GraphBuilder::pop_scope() { | |
3636 int number_of_locks = scope()->number_of_locks(); | |
3637 _scope_data = scope_data()->parent(); | |
3638 // accumulate minimum number of monitor slots to be reserved | |
3639 scope()->set_min_number_of_locks(number_of_locks); | |
3640 } | |
3641 | |
3642 | |
3643 void GraphBuilder::pop_scope_for_jsr() { | |
3644 _scope_data = scope_data()->parent(); | |
3645 } | |
3646 | |
3647 bool GraphBuilder::append_unsafe_get_obj(ciMethod* callee, BasicType t, bool is_volatile) { | |
3648 if (InlineUnsafeOps) { | |
3649 Values* args = state()->pop_arguments(callee->arg_size()); | |
3650 null_check(args->at(0)); | |
3651 Instruction* offset = args->at(2); | |
3652 #ifndef _LP64 | |
3653 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); | |
3654 #endif | |
3655 Instruction* op = append(new UnsafeGetObject(t, args->at(1), offset, is_volatile)); | |
3656 push(op->type(), op); | |
3657 compilation()->set_has_unsafe_access(true); | |
3658 } | |
3659 return InlineUnsafeOps; | |
3660 } | |
3661 | |
3662 | |
3663 bool GraphBuilder::append_unsafe_put_obj(ciMethod* callee, BasicType t, bool is_volatile) { | |
3664 if (InlineUnsafeOps) { | |
3665 Values* args = state()->pop_arguments(callee->arg_size()); | |
3666 null_check(args->at(0)); | |
3667 Instruction* offset = args->at(2); | |
3668 #ifndef _LP64 | |
3669 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); | |
3670 #endif | |
3671 Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile)); | |
3672 compilation()->set_has_unsafe_access(true); | |
3673 kill_all(); | |
3674 } | |
3675 return InlineUnsafeOps; | |
3676 } | |
3677 | |
3678 | |
3679 bool GraphBuilder::append_unsafe_get_raw(ciMethod* callee, BasicType t) { | |
3680 if (InlineUnsafeOps) { | |
3681 Values* args = state()->pop_arguments(callee->arg_size()); | |
3682 null_check(args->at(0)); | |
3683 Instruction* op = append(new UnsafeGetRaw(t, args->at(1), false)); | |
3684 push(op->type(), op); | |
3685 compilation()->set_has_unsafe_access(true); | |
3686 } | |
3687 return InlineUnsafeOps; | |
3688 } | |
3689 | |
3690 | |
3691 bool GraphBuilder::append_unsafe_put_raw(ciMethod* callee, BasicType t) { | |
3692 if (InlineUnsafeOps) { | |
3693 Values* args = state()->pop_arguments(callee->arg_size()); | |
3694 null_check(args->at(0)); | |
3695 Instruction* op = append(new UnsafePutRaw(t, args->at(1), args->at(2))); | |
3696 compilation()->set_has_unsafe_access(true); | |
3697 } | |
3698 return InlineUnsafeOps; | |
3699 } | |
3700 | |
3701 | |
3702 bool GraphBuilder::append_unsafe_prefetch(ciMethod* callee, bool is_static, bool is_store) { | |
3703 if (InlineUnsafeOps) { | |
3704 Values* args = state()->pop_arguments(callee->arg_size()); | |
3705 int obj_arg_index = 1; // Assume non-static case | |
3706 if (is_static) { | |
3707 obj_arg_index = 0; | |
3708 } else { | |
3709 null_check(args->at(0)); | |
3710 } | |
3711 Instruction* offset = args->at(obj_arg_index + 1); | |
3712 #ifndef _LP64 | |
3713 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); | |
3714 #endif | |
3715 Instruction* op = is_store ? append(new UnsafePrefetchWrite(args->at(obj_arg_index), offset)) | |
3716 : append(new UnsafePrefetchRead (args->at(obj_arg_index), offset)); | |
3717 compilation()->set_has_unsafe_access(true); | |
3718 } | |
3719 return InlineUnsafeOps; | |
3720 } | |
3721 | |
3722 | |
3723 void GraphBuilder::append_unsafe_CAS(ciMethod* callee) { | |
1819 | 3724 ValueStack* state_before = copy_state_for_exception(); |
0 | 3725 ValueType* result_type = as_ValueType(callee->return_type()); |
3726 assert(result_type->is_int(), "int result"); | |
3727 Values* args = state()->pop_arguments(callee->arg_size()); | |
3728 | |
3729 // Pop off some args to speically handle, then push back | |
3730 Value newval = args->pop(); | |
3731 Value cmpval = args->pop(); | |
3732 Value offset = args->pop(); | |
3733 Value src = args->pop(); | |
3734 Value unsafe_obj = args->pop(); | |
3735 | |
3736 // Separately handle the unsafe arg. It is not needed for code | |
3737 // generation, but must be null checked | |
3738 null_check(unsafe_obj); | |
3739 | |
3740 #ifndef _LP64 | |
3741 offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); | |
3742 #endif | |
3743 | |
3744 args->push(src); | |
3745 args->push(offset); | |
3746 args->push(cmpval); | |
3747 args->push(newval); | |
3748 | |
3749 // An unsafe CAS can alias with other field accesses, but we don't | |
3750 // know which ones so mark the state as no preserved. This will | |
3751 // cause CSE to invalidate memory across it. | |
3752 bool preserves_state = false; | |
1819 | 3753 Intrinsic* result = new Intrinsic(result_type, callee->intrinsic_id(), args, false, state_before, preserves_state); |
0 | 3754 append_split(result); |
3755 push(result_type, result); | |
3756 compilation()->set_has_unsafe_access(true); | |
3757 } | |
3758 | |
3759 | |
3760 #ifndef PRODUCT | |
3761 void GraphBuilder::print_inline_result(ciMethod* callee, bool res) { | |
3762 const char sync_char = callee->is_synchronized() ? 's' : ' '; | |
3763 const char exception_char = callee->has_exception_handlers() ? '!' : ' '; | |
3764 const char monitors_char = callee->has_monitor_bytecodes() ? 'm' : ' '; | |
3765 tty->print(" %c%c%c ", sync_char, exception_char, monitors_char); | |
3766 for (int i = 0; i < scope()->level(); i++) tty->print(" "); | |
3767 if (res) { | |
3768 tty->print(" "); | |
3769 } else { | |
3770 tty->print("- "); | |
3771 } | |
3772 tty->print("@ %d ", bci()); | |
3773 callee->print_short_name(); | |
3774 tty->print(" (%d bytes)", callee->code_size()); | |
3775 if (_inline_bailout_msg) { | |
3776 tty->print(" %s", _inline_bailout_msg); | |
3777 } | |
3778 tty->cr(); | |
3779 | |
3780 if (res && CIPrintMethodCodes) { | |
3781 callee->print_codes(); | |
3782 } | |
3783 } | |
3784 | |
3785 | |
3786 void GraphBuilder::print_stats() { | |
3787 vmap()->print(); | |
3788 } | |
3789 #endif // PRODUCT | |
3790 | |
3791 void GraphBuilder::profile_call(Value recv, ciKlass* known_holder) { | |
3792 append(new ProfileCall(method(), bci(), recv, known_holder)); | |
3793 } | |
3794 | |
1825 | 3795 void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) { |
3796 append(new ProfileInvoke(callee, state)); | |
0 | 3797 } |