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