Mercurial > hg > graal-compiler
annotate src/share/vm/shark/sharkTopLevelBlock.cpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | 606eada1bf86 |
children | de6a9e811145 |
rev | line source |
---|---|
1692 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4762
diff
changeset
|
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
1692 | 3 * Copyright 2008, 2009, 2010 Red Hat, Inc. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
21 * or visit www.oracle.com if you need additional information or have any | |
22 * questions. | |
23 * | |
24 */ | |
25 | |
1972 | 26 #include "precompiled.hpp" |
27 #include "ci/ciField.hpp" | |
28 #include "ci/ciInstance.hpp" | |
29 #include "ci/ciObjArrayKlass.hpp" | |
30 #include "ci/ciStreams.hpp" | |
31 #include "ci/ciType.hpp" | |
32 #include "ci/ciTypeFlow.hpp" | |
33 #include "interpreter/bytecodes.hpp" | |
34 #include "memory/allocation.hpp" | |
35 #include "runtime/deoptimization.hpp" | |
36 #include "shark/llvmHeaders.hpp" | |
37 #include "shark/llvmValue.hpp" | |
38 #include "shark/sharkBuilder.hpp" | |
39 #include "shark/sharkCacheDecache.hpp" | |
40 #include "shark/sharkConstant.hpp" | |
41 #include "shark/sharkInliner.hpp" | |
42 #include "shark/sharkState.hpp" | |
43 #include "shark/sharkTopLevelBlock.hpp" | |
44 #include "shark/sharkValue.hpp" | |
45 #include "shark/shark_globals.hpp" | |
46 #include "utilities/debug.hpp" | |
1692 | 47 |
48 using namespace llvm; | |
49 | |
50 void SharkTopLevelBlock::scan_for_traps() { | |
51 // If typeflow found a trap then don't scan past it | |
52 int limit_bci = ciblock()->has_trap() ? ciblock()->trap_bci() : limit(); | |
53 | |
54 // Scan the bytecode for traps that are always hit | |
55 iter()->reset_to_bci(start()); | |
56 while (iter()->next_bci() < limit_bci) { | |
57 iter()->next(); | |
58 | |
59 ciField *field; | |
60 ciMethod *method; | |
61 ciInstanceKlass *klass; | |
62 bool will_link; | |
63 bool is_field; | |
64 | |
65 switch (bc()) { | |
66 case Bytecodes::_ldc: | |
67 case Bytecodes::_ldc_w: | |
7195 | 68 case Bytecodes::_ldc2_w: |
1692 | 69 if (!SharkConstant::for_ldc(iter())->is_loaded()) { |
70 set_trap( | |
71 Deoptimization::make_trap_request( | |
72 Deoptimization::Reason_uninitialized, | |
73 Deoptimization::Action_reinterpret), bci()); | |
74 return; | |
75 } | |
76 break; | |
77 | |
78 case Bytecodes::_getfield: | |
79 case Bytecodes::_getstatic: | |
80 case Bytecodes::_putfield: | |
81 case Bytecodes::_putstatic: | |
82 field = iter()->get_field(will_link); | |
83 assert(will_link, "typeflow responsibility"); | |
84 is_field = (bc() == Bytecodes::_getfield || bc() == Bytecodes::_putfield); | |
85 | |
86 // If the bytecode does not match the field then bail out to | |
87 // the interpreter to throw an IncompatibleClassChangeError | |
88 if (is_field == field->is_static()) { | |
89 set_trap( | |
90 Deoptimization::make_trap_request( | |
91 Deoptimization::Reason_unhandled, | |
92 Deoptimization::Action_none), bci()); | |
93 return; | |
94 } | |
95 | |
96 // Bail out if we are trying to access a static variable | |
97 // before the class initializer has completed. | |
98 if (!is_field && !field->holder()->is_initialized()) { | |
99 if (!static_field_ok_in_clinit(field)) { | |
100 set_trap( | |
101 Deoptimization::make_trap_request( | |
102 Deoptimization::Reason_uninitialized, | |
103 Deoptimization::Action_reinterpret), bci()); | |
104 return; | |
105 } | |
106 } | |
107 break; | |
108 | |
109 case Bytecodes::_invokestatic: | |
110 case Bytecodes::_invokespecial: | |
111 case Bytecodes::_invokevirtual: | |
112 case Bytecodes::_invokeinterface: | |
7195 | 113 ciSignature* sig; |
114 method = iter()->get_method(will_link, &sig); | |
1692 | 115 assert(will_link, "typeflow responsibility"); |
7601 | 116 // We can't compile calls to method handle intrinsics, because we use |
117 // the interpreter entry points and they expect the top frame to be an | |
118 // interpreter frame. We need to implement the intrinsics for Shark. | |
119 if (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()) { | |
120 if (SharkPerformanceWarnings) { | |
121 warning("JSR292 optimization not yet implemented in Shark"); | |
122 } | |
123 set_trap( | |
124 Deoptimization::make_trap_request( | |
125 Deoptimization::Reason_unhandled, | |
126 Deoptimization::Action_make_not_compilable), bci()); | |
127 return; | |
128 } | |
1692 | 129 if (!method->holder()->is_linked()) { |
130 set_trap( | |
131 Deoptimization::make_trap_request( | |
132 Deoptimization::Reason_uninitialized, | |
133 Deoptimization::Action_reinterpret), bci()); | |
134 return; | |
135 } | |
136 | |
137 if (bc() == Bytecodes::_invokevirtual) { | |
138 klass = ciEnv::get_instance_klass_for_declared_method_holder( | |
139 iter()->get_declared_method_holder()); | |
140 if (!klass->is_linked()) { | |
141 set_trap( | |
142 Deoptimization::make_trap_request( | |
143 Deoptimization::Reason_uninitialized, | |
144 Deoptimization::Action_reinterpret), bci()); | |
145 return; | |
146 } | |
147 } | |
148 break; | |
149 | |
150 case Bytecodes::_new: | |
151 klass = iter()->get_klass(will_link)->as_instance_klass(); | |
152 assert(will_link, "typeflow responsibility"); | |
153 | |
154 // Bail out if the class is unloaded | |
155 if (iter()->is_unresolved_klass() || !klass->is_initialized()) { | |
156 set_trap( | |
157 Deoptimization::make_trap_request( | |
158 Deoptimization::Reason_uninitialized, | |
159 Deoptimization::Action_reinterpret), bci()); | |
160 return; | |
161 } | |
162 | |
163 // Bail out if the class cannot be instantiated | |
164 if (klass->is_abstract() || klass->is_interface() || | |
165 klass->name() == ciSymbol::java_lang_Class()) { | |
166 set_trap( | |
167 Deoptimization::make_trap_request( | |
168 Deoptimization::Reason_unhandled, | |
169 Deoptimization::Action_reinterpret), bci()); | |
170 return; | |
171 } | |
172 break; | |
7601 | 173 case Bytecodes::_invokedynamic: |
174 case Bytecodes::_invokehandle: | |
175 if (SharkPerformanceWarnings) { | |
176 warning("JSR292 optimization not yet implemented in Shark"); | |
177 } | |
178 set_trap( | |
179 Deoptimization::make_trap_request( | |
180 Deoptimization::Reason_unhandled, | |
181 Deoptimization::Action_make_not_compilable), bci()); | |
182 return; | |
1692 | 183 } |
184 } | |
185 | |
186 // Trap if typeflow trapped (and we didn't before) | |
187 if (ciblock()->has_trap()) { | |
188 set_trap( | |
189 Deoptimization::make_trap_request( | |
190 Deoptimization::Reason_unloaded, | |
191 Deoptimization::Action_reinterpret, | |
192 ciblock()->trap_index()), ciblock()->trap_bci()); | |
193 return; | |
194 } | |
195 } | |
196 | |
197 bool SharkTopLevelBlock::static_field_ok_in_clinit(ciField* field) { | |
198 assert(field->is_static(), "should be"); | |
199 | |
200 // This code is lifted pretty much verbatim from C2's | |
201 // Parse::static_field_ok_in_clinit() in parse3.cpp. | |
202 bool access_OK = false; | |
203 if (target()->holder()->is_subclass_of(field->holder())) { | |
204 if (target()->is_static()) { | |
205 if (target()->name() == ciSymbol::class_initializer_name()) { | |
206 // It's OK to access static fields from the class initializer | |
207 access_OK = true; | |
208 } | |
209 } | |
210 else { | |
211 if (target()->name() == ciSymbol::object_initializer_name()) { | |
212 // It's also OK to access static fields inside a constructor, | |
213 // because any thread calling the constructor must first have | |
214 // synchronized on the class by executing a "new" bytecode. | |
215 access_OK = true; | |
216 } | |
217 } | |
218 } | |
219 return access_OK; | |
220 } | |
221 | |
222 SharkState* SharkTopLevelBlock::entry_state() { | |
223 if (_entry_state == NULL) { | |
224 assert(needs_phis(), "should do"); | |
225 _entry_state = new SharkPHIState(this); | |
226 } | |
227 return _entry_state; | |
228 } | |
229 | |
230 void SharkTopLevelBlock::add_incoming(SharkState* incoming_state) { | |
231 if (needs_phis()) { | |
232 ((SharkPHIState *) entry_state())->add_incoming(incoming_state); | |
233 } | |
234 else if (_entry_state == NULL) { | |
235 _entry_state = incoming_state; | |
236 } | |
237 else { | |
238 assert(entry_state()->equal_to(incoming_state), "should be"); | |
239 } | |
240 } | |
241 | |
242 void SharkTopLevelBlock::enter(SharkTopLevelBlock* predecessor, | |
243 bool is_exception) { | |
244 // This block requires phis: | |
245 // - if it is entered more than once | |
246 // - if it is an exception handler, because in which | |
247 // case we assume it's entered more than once. | |
248 // - if the predecessor will be compiled after this | |
249 // block, in which case we can't simple propagate | |
250 // the state forward. | |
251 if (!needs_phis() && | |
252 (entered() || | |
253 is_exception || | |
254 (predecessor && predecessor->index() >= index()))) | |
255 _needs_phis = true; | |
256 | |
257 // Recurse into the tree | |
258 if (!entered()) { | |
259 _entered = true; | |
260 | |
261 scan_for_traps(); | |
262 if (!has_trap()) { | |
263 for (int i = 0; i < num_successors(); i++) { | |
264 successor(i)->enter(this, false); | |
265 } | |
266 } | |
267 compute_exceptions(); | |
268 for (int i = 0; i < num_exceptions(); i++) { | |
269 SharkTopLevelBlock *handler = exception(i); | |
270 if (handler) | |
271 handler->enter(this, true); | |
272 } | |
273 } | |
274 } | |
275 | |
276 void SharkTopLevelBlock::initialize() { | |
277 char name[28]; | |
278 snprintf(name, sizeof(name), | |
279 "bci_%d%s", | |
280 start(), is_backedge_copy() ? "_backedge_copy" : ""); | |
281 _entry_block = function()->CreateBlock(name); | |
282 } | |
283 | |
284 void SharkTopLevelBlock::decache_for_Java_call(ciMethod *callee) { | |
285 SharkJavaCallDecacher(function(), bci(), callee).scan(current_state()); | |
286 for (int i = 0; i < callee->arg_size(); i++) | |
287 xpop(); | |
288 } | |
289 | |
290 void SharkTopLevelBlock::cache_after_Java_call(ciMethod *callee) { | |
291 if (callee->return_type()->size()) { | |
292 ciType *type; | |
293 switch (callee->return_type()->basic_type()) { | |
294 case T_BOOLEAN: | |
295 case T_BYTE: | |
296 case T_CHAR: | |
297 case T_SHORT: | |
298 type = ciType::make(T_INT); | |
299 break; | |
300 | |
301 default: | |
302 type = callee->return_type(); | |
303 } | |
304 | |
305 push(SharkValue::create_generic(type, NULL, false)); | |
306 } | |
307 SharkJavaCallCacher(function(), callee).scan(current_state()); | |
308 } | |
309 | |
310 void SharkTopLevelBlock::decache_for_VM_call() { | |
311 SharkVMCallDecacher(function(), bci()).scan(current_state()); | |
312 } | |
313 | |
314 void SharkTopLevelBlock::cache_after_VM_call() { | |
315 SharkVMCallCacher(function()).scan(current_state()); | |
316 } | |
317 | |
318 void SharkTopLevelBlock::decache_for_trap() { | |
319 SharkTrapDecacher(function(), bci()).scan(current_state()); | |
320 } | |
321 | |
322 void SharkTopLevelBlock::emit_IR() { | |
323 builder()->SetInsertPoint(entry_block()); | |
324 | |
325 // Parse the bytecode | |
326 parse_bytecode(start(), limit()); | |
327 | |
328 // If this block falls through to the next then it won't have been | |
329 // terminated by a bytecode and we have to add the branch ourselves | |
330 if (falls_through() && !has_trap()) | |
331 do_branch(ciTypeFlow::FALL_THROUGH); | |
332 } | |
333 | |
334 SharkTopLevelBlock* SharkTopLevelBlock::bci_successor(int bci) const { | |
335 // XXX now with Linear Search Technology (tm) | |
336 for (int i = 0; i < num_successors(); i++) { | |
337 ciTypeFlow::Block *successor = ciblock()->successors()->at(i); | |
338 if (successor->start() == bci) | |
339 return function()->block(successor->pre_order()); | |
340 } | |
341 ShouldNotReachHere(); | |
342 } | |
343 | |
344 void SharkTopLevelBlock::do_zero_check(SharkValue *value) { | |
345 if (value->is_phi() && value->as_phi()->all_incomers_zero_checked()) { | |
346 function()->add_deferred_zero_check(this, value); | |
347 } | |
348 else { | |
349 BasicBlock *continue_block = function()->CreateBlock("not_zero"); | |
350 SharkState *saved_state = current_state(); | |
351 set_current_state(saved_state->copy()); | |
352 zero_check_value(value, continue_block); | |
353 builder()->SetInsertPoint(continue_block); | |
354 set_current_state(saved_state); | |
355 } | |
356 | |
357 value->set_zero_checked(true); | |
358 } | |
359 | |
360 void SharkTopLevelBlock::do_deferred_zero_check(SharkValue* value, | |
361 int bci, | |
362 SharkState* saved_state, | |
363 BasicBlock* continue_block) { | |
364 if (value->as_phi()->all_incomers_zero_checked()) { | |
365 builder()->CreateBr(continue_block); | |
366 } | |
367 else { | |
368 iter()->force_bci(start()); | |
369 set_current_state(saved_state); | |
370 zero_check_value(value, continue_block); | |
371 } | |
372 } | |
373 | |
374 void SharkTopLevelBlock::zero_check_value(SharkValue* value, | |
375 BasicBlock* continue_block) { | |
376 BasicBlock *zero_block = builder()->CreateBlock(continue_block, "zero"); | |
377 | |
378 Value *a, *b; | |
379 switch (value->basic_type()) { | |
380 case T_BYTE: | |
381 case T_CHAR: | |
382 case T_SHORT: | |
383 case T_INT: | |
384 a = value->jint_value(); | |
385 b = LLVMValue::jint_constant(0); | |
386 break; | |
387 case T_LONG: | |
388 a = value->jlong_value(); | |
389 b = LLVMValue::jlong_constant(0); | |
390 break; | |
391 case T_OBJECT: | |
392 case T_ARRAY: | |
393 a = value->jobject_value(); | |
394 b = LLVMValue::LLVMValue::null(); | |
395 break; | |
396 default: | |
397 tty->print_cr("Unhandled type %s", type2name(value->basic_type())); | |
398 ShouldNotReachHere(); | |
399 } | |
400 | |
401 builder()->CreateCondBr( | |
402 builder()->CreateICmpNE(a, b), continue_block, zero_block); | |
403 | |
404 builder()->SetInsertPoint(zero_block); | |
405 if (value->is_jobject()) { | |
406 call_vm( | |
407 builder()->throw_NullPointerException(), | |
408 builder()->CreateIntToPtr( | |
409 LLVMValue::intptr_constant((intptr_t) __FILE__), | |
410 PointerType::getUnqual(SharkType::jbyte_type())), | |
411 LLVMValue::jint_constant(__LINE__), | |
412 EX_CHECK_NONE); | |
413 } | |
414 else { | |
415 call_vm( | |
416 builder()->throw_ArithmeticException(), | |
417 builder()->CreateIntToPtr( | |
418 LLVMValue::intptr_constant((intptr_t) __FILE__), | |
419 PointerType::getUnqual(SharkType::jbyte_type())), | |
420 LLVMValue::jint_constant(__LINE__), | |
421 EX_CHECK_NONE); | |
422 } | |
423 | |
424 Value *pending_exception = get_pending_exception(); | |
425 clear_pending_exception(); | |
426 handle_exception(pending_exception, EX_CHECK_FULL); | |
427 } | |
428 | |
429 void SharkTopLevelBlock::check_bounds(SharkValue* array, SharkValue* index) { | |
430 BasicBlock *out_of_bounds = function()->CreateBlock("out_of_bounds"); | |
431 BasicBlock *in_bounds = function()->CreateBlock("in_bounds"); | |
432 | |
433 Value *length = builder()->CreateArrayLength(array->jarray_value()); | |
434 // we use an unsigned comparison to catch negative values | |
435 builder()->CreateCondBr( | |
436 builder()->CreateICmpULT(index->jint_value(), length), | |
437 in_bounds, out_of_bounds); | |
438 | |
439 builder()->SetInsertPoint(out_of_bounds); | |
440 SharkState *saved_state = current_state()->copy(); | |
441 | |
442 call_vm( | |
443 builder()->throw_ArrayIndexOutOfBoundsException(), | |
444 builder()->CreateIntToPtr( | |
445 LLVMValue::intptr_constant((intptr_t) __FILE__), | |
446 PointerType::getUnqual(SharkType::jbyte_type())), | |
447 LLVMValue::jint_constant(__LINE__), | |
448 index->jint_value(), | |
449 EX_CHECK_NONE); | |
450 | |
451 Value *pending_exception = get_pending_exception(); | |
452 clear_pending_exception(); | |
453 handle_exception(pending_exception, EX_CHECK_FULL); | |
454 | |
455 set_current_state(saved_state); | |
456 | |
457 builder()->SetInsertPoint(in_bounds); | |
458 } | |
459 | |
460 void SharkTopLevelBlock::check_pending_exception(int action) { | |
461 assert(action & EAM_CHECK, "should be"); | |
462 | |
463 BasicBlock *exception = function()->CreateBlock("exception"); | |
464 BasicBlock *no_exception = function()->CreateBlock("no_exception"); | |
465 | |
466 Value *pending_exception = get_pending_exception(); | |
467 builder()->CreateCondBr( | |
468 builder()->CreateICmpEQ(pending_exception, LLVMValue::null()), | |
469 no_exception, exception); | |
470 | |
471 builder()->SetInsertPoint(exception); | |
472 SharkState *saved_state = current_state()->copy(); | |
473 if (action & EAM_MONITOR_FUDGE) { | |
474 // The top monitor is marked live, but the exception was thrown | |
475 // while setting it up so we need to mark it dead before we enter | |
476 // any exception handlers as they will not expect it to be there. | |
477 set_num_monitors(num_monitors() - 1); | |
478 action ^= EAM_MONITOR_FUDGE; | |
479 } | |
480 clear_pending_exception(); | |
481 handle_exception(pending_exception, action); | |
482 set_current_state(saved_state); | |
483 | |
484 builder()->SetInsertPoint(no_exception); | |
485 } | |
486 | |
487 void SharkTopLevelBlock::compute_exceptions() { | |
488 ciExceptionHandlerStream str(target(), start()); | |
489 | |
490 int exc_count = str.count(); | |
491 _exc_handlers = new GrowableArray<ciExceptionHandler*>(exc_count); | |
492 _exceptions = new GrowableArray<SharkTopLevelBlock*>(exc_count); | |
493 | |
494 int index = 0; | |
495 for (; !str.is_done(); str.next()) { | |
496 ciExceptionHandler *handler = str.handler(); | |
497 if (handler->handler_bci() == -1) | |
498 break; | |
499 _exc_handlers->append(handler); | |
500 | |
501 // Try and get this exception's handler from typeflow. We should | |
502 // do it this way always, really, except that typeflow sometimes | |
503 // doesn't record exceptions, even loaded ones, and sometimes it | |
504 // returns them with a different handler bci. Why??? | |
505 SharkTopLevelBlock *block = NULL; | |
506 ciInstanceKlass* klass; | |
507 if (handler->is_catch_all()) { | |
508 klass = java_lang_Throwable_klass(); | |
509 } | |
510 else { | |
511 klass = handler->catch_klass(); | |
512 } | |
513 for (int i = 0; i < ciblock()->exceptions()->length(); i++) { | |
514 if (klass == ciblock()->exc_klasses()->at(i)) { | |
515 block = function()->block(ciblock()->exceptions()->at(i)->pre_order()); | |
516 if (block->start() == handler->handler_bci()) | |
517 break; | |
518 else | |
519 block = NULL; | |
520 } | |
521 } | |
522 | |
523 // If typeflow let us down then try and figure it out ourselves | |
524 if (block == NULL) { | |
525 for (int i = 0; i < function()->block_count(); i++) { | |
526 SharkTopLevelBlock *candidate = function()->block(i); | |
527 if (candidate->start() == handler->handler_bci()) { | |
528 if (block != NULL) { | |
529 NOT_PRODUCT(warning("there may be trouble ahead")); | |
530 block = NULL; | |
531 break; | |
532 } | |
533 block = candidate; | |
534 } | |
535 } | |
536 } | |
537 _exceptions->append(block); | |
538 } | |
539 } | |
540 | |
541 void SharkTopLevelBlock::handle_exception(Value* exception, int action) { | |
542 if (action & EAM_HANDLE && num_exceptions() != 0) { | |
543 // Clear the stack and push the exception onto it | |
544 while (xstack_depth()) | |
545 pop(); | |
546 push(SharkValue::create_jobject(exception, true)); | |
547 | |
548 // Work out how many options we have to check | |
549 bool has_catch_all = exc_handler(num_exceptions() - 1)->is_catch_all(); | |
550 int num_options = num_exceptions(); | |
551 if (has_catch_all) | |
552 num_options--; | |
553 | |
554 // Marshal any non-catch-all handlers | |
555 if (num_options > 0) { | |
556 bool all_loaded = true; | |
557 for (int i = 0; i < num_options; i++) { | |
558 if (!exc_handler(i)->catch_klass()->is_loaded()) { | |
559 all_loaded = false; | |
560 break; | |
561 } | |
562 } | |
563 | |
564 if (all_loaded) | |
565 marshal_exception_fast(num_options); | |
566 else | |
567 marshal_exception_slow(num_options); | |
568 } | |
569 | |
570 // Install the catch-all handler, if present | |
571 if (has_catch_all) { | |
572 SharkTopLevelBlock* handler = this->exception(num_options); | |
573 assert(handler != NULL, "catch-all handler cannot be unloaded"); | |
574 | |
575 builder()->CreateBr(handler->entry_block()); | |
576 handler->add_incoming(current_state()); | |
577 return; | |
578 } | |
579 } | |
580 | |
581 // No exception handler was found; unwind and return | |
582 handle_return(T_VOID, exception); | |
583 } | |
584 | |
585 void SharkTopLevelBlock::marshal_exception_fast(int num_options) { | |
586 Value *exception_klass = builder()->CreateValueOfStructEntry( | |
587 xstack(0)->jobject_value(), | |
588 in_ByteSize(oopDesc::klass_offset_in_bytes()), | |
7195 | 589 SharkType::klass_type(), |
1692 | 590 "exception_klass"); |
591 | |
592 for (int i = 0; i < num_options; i++) { | |
593 Value *check_klass = | |
7195 | 594 builder()->CreateInlineMetadata(exc_handler(i)->catch_klass(), SharkType::klass_type()); |
1692 | 595 |
596 BasicBlock *not_exact = function()->CreateBlock("not_exact"); | |
597 BasicBlock *not_subtype = function()->CreateBlock("not_subtype"); | |
598 | |
599 builder()->CreateCondBr( | |
600 builder()->CreateICmpEQ(check_klass, exception_klass), | |
601 handler_for_exception(i), not_exact); | |
602 | |
603 builder()->SetInsertPoint(not_exact); | |
604 builder()->CreateCondBr( | |
605 builder()->CreateICmpNE( | |
606 builder()->CreateCall2( | |
607 builder()->is_subtype_of(), check_klass, exception_klass), | |
608 LLVMValue::jbyte_constant(0)), | |
609 handler_for_exception(i), not_subtype); | |
610 | |
611 builder()->SetInsertPoint(not_subtype); | |
612 } | |
613 } | |
614 | |
615 void SharkTopLevelBlock::marshal_exception_slow(int num_options) { | |
616 int *indexes = NEW_RESOURCE_ARRAY(int, num_options); | |
617 for (int i = 0; i < num_options; i++) | |
618 indexes[i] = exc_handler(i)->catch_klass_index(); | |
619 | |
620 Value *index = call_vm( | |
621 builder()->find_exception_handler(), | |
622 builder()->CreateInlineData( | |
623 indexes, | |
624 num_options * sizeof(int), | |
625 PointerType::getUnqual(SharkType::jint_type())), | |
626 LLVMValue::jint_constant(num_options), | |
627 EX_CHECK_NO_CATCH); | |
628 | |
629 BasicBlock *no_handler = function()->CreateBlock("no_handler"); | |
630 SwitchInst *switchinst = builder()->CreateSwitch( | |
631 index, no_handler, num_options); | |
632 | |
633 for (int i = 0; i < num_options; i++) { | |
634 switchinst->addCase( | |
635 LLVMValue::jint_constant(i), | |
636 handler_for_exception(i)); | |
637 } | |
638 | |
639 builder()->SetInsertPoint(no_handler); | |
640 } | |
641 | |
642 BasicBlock* SharkTopLevelBlock::handler_for_exception(int index) { | |
643 SharkTopLevelBlock *successor = this->exception(index); | |
644 if (successor) { | |
645 successor->add_incoming(current_state()); | |
646 return successor->entry_block(); | |
647 } | |
648 else { | |
649 return make_trap( | |
650 exc_handler(index)->handler_bci(), | |
651 Deoptimization::make_trap_request( | |
652 Deoptimization::Reason_unhandled, | |
653 Deoptimization::Action_reinterpret)); | |
654 } | |
655 } | |
656 | |
657 void SharkTopLevelBlock::maybe_add_safepoint() { | |
658 if (current_state()->has_safepointed()) | |
659 return; | |
660 | |
661 BasicBlock *orig_block = builder()->GetInsertBlock(); | |
662 SharkState *orig_state = current_state()->copy(); | |
663 | |
664 BasicBlock *do_safepoint = function()->CreateBlock("do_safepoint"); | |
665 BasicBlock *safepointed = function()->CreateBlock("safepointed"); | |
666 | |
667 Value *state = builder()->CreateLoad( | |
668 builder()->CreateIntToPtr( | |
669 LLVMValue::intptr_constant( | |
670 (intptr_t) SafepointSynchronize::address_of_state()), | |
671 PointerType::getUnqual(SharkType::jint_type())), | |
672 "state"); | |
673 | |
674 builder()->CreateCondBr( | |
675 builder()->CreateICmpEQ( | |
676 state, | |
677 LLVMValue::jint_constant(SafepointSynchronize::_synchronizing)), | |
678 do_safepoint, safepointed); | |
679 | |
680 builder()->SetInsertPoint(do_safepoint); | |
681 call_vm(builder()->safepoint(), EX_CHECK_FULL); | |
682 BasicBlock *safepointed_block = builder()->GetInsertBlock(); | |
683 builder()->CreateBr(safepointed); | |
684 | |
685 builder()->SetInsertPoint(safepointed); | |
686 current_state()->merge(orig_state, orig_block, safepointed_block); | |
687 | |
688 current_state()->set_has_safepointed(true); | |
689 } | |
690 | |
691 void SharkTopLevelBlock::maybe_add_backedge_safepoint() { | |
692 if (current_state()->has_safepointed()) | |
693 return; | |
694 | |
695 for (int i = 0; i < num_successors(); i++) { | |
696 if (successor(i)->can_reach(this)) { | |
697 maybe_add_safepoint(); | |
698 break; | |
699 } | |
700 } | |
701 } | |
702 | |
703 bool SharkTopLevelBlock::can_reach(SharkTopLevelBlock* other) { | |
704 for (int i = 0; i < function()->block_count(); i++) | |
705 function()->block(i)->_can_reach_visited = false; | |
706 | |
707 return can_reach_helper(other); | |
708 } | |
709 | |
710 bool SharkTopLevelBlock::can_reach_helper(SharkTopLevelBlock* other) { | |
711 if (this == other) | |
712 return true; | |
713 | |
714 if (_can_reach_visited) | |
715 return false; | |
716 _can_reach_visited = true; | |
717 | |
718 if (!has_trap()) { | |
719 for (int i = 0; i < num_successors(); i++) { | |
720 if (successor(i)->can_reach_helper(other)) | |
721 return true; | |
722 } | |
723 } | |
724 | |
725 for (int i = 0; i < num_exceptions(); i++) { | |
726 SharkTopLevelBlock *handler = exception(i); | |
727 if (handler && handler->can_reach_helper(other)) | |
728 return true; | |
729 } | |
730 | |
731 return false; | |
732 } | |
733 | |
734 BasicBlock* SharkTopLevelBlock::make_trap(int trap_bci, int trap_request) { | |
735 BasicBlock *trap_block = function()->CreateBlock("trap"); | |
736 BasicBlock *orig_block = builder()->GetInsertBlock(); | |
737 builder()->SetInsertPoint(trap_block); | |
738 | |
739 int orig_bci = bci(); | |
740 iter()->force_bci(trap_bci); | |
741 | |
742 do_trap(trap_request); | |
743 | |
744 builder()->SetInsertPoint(orig_block); | |
745 iter()->force_bci(orig_bci); | |
746 | |
747 return trap_block; | |
748 } | |
749 | |
750 void SharkTopLevelBlock::do_trap(int trap_request) { | |
751 decache_for_trap(); | |
752 builder()->CreateRet( | |
753 builder()->CreateCall2( | |
754 builder()->uncommon_trap(), | |
755 thread(), | |
756 LLVMValue::jint_constant(trap_request))); | |
757 } | |
758 | |
759 void SharkTopLevelBlock::call_register_finalizer(Value *receiver) { | |
760 BasicBlock *orig_block = builder()->GetInsertBlock(); | |
761 SharkState *orig_state = current_state()->copy(); | |
762 | |
763 BasicBlock *do_call = function()->CreateBlock("has_finalizer"); | |
764 BasicBlock *done = function()->CreateBlock("done"); | |
765 | |
766 Value *klass = builder()->CreateValueOfStructEntry( | |
767 receiver, | |
768 in_ByteSize(oopDesc::klass_offset_in_bytes()), | |
769 SharkType::oop_type(), | |
770 "klass"); | |
771 | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
1972
diff
changeset
|
772 Value *access_flags = builder()->CreateValueOfStructEntry( |
1692 | 773 klass, |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
1972
diff
changeset
|
774 Klass::access_flags_offset(), |
1692 | 775 SharkType::jint_type(), |
776 "access_flags"); | |
777 | |
778 builder()->CreateCondBr( | |
779 builder()->CreateICmpNE( | |
780 builder()->CreateAnd( | |
781 access_flags, | |
782 LLVMValue::jint_constant(JVM_ACC_HAS_FINALIZER)), | |
783 LLVMValue::jint_constant(0)), | |
784 do_call, done); | |
785 | |
786 builder()->SetInsertPoint(do_call); | |
787 call_vm(builder()->register_finalizer(), receiver, EX_CHECK_FULL); | |
788 BasicBlock *branch_block = builder()->GetInsertBlock(); | |
789 builder()->CreateBr(done); | |
790 | |
791 builder()->SetInsertPoint(done); | |
792 current_state()->merge(orig_state, orig_block, branch_block); | |
793 } | |
794 | |
795 void SharkTopLevelBlock::handle_return(BasicType type, Value* exception) { | |
796 assert (exception == NULL || type == T_VOID, "exception OR result, please"); | |
797 | |
798 if (num_monitors()) { | |
799 // Protect our exception across possible monitor release decaches | |
800 if (exception) | |
801 set_oop_tmp(exception); | |
802 | |
803 // We don't need to check for exceptions thrown here. If | |
804 // we're returning a value then we just carry on as normal: | |
805 // the caller will see the pending exception and handle it. | |
806 // If we're returning with an exception then that exception | |
807 // takes priority and the release_lock one will be ignored. | |
808 while (num_monitors()) | |
809 release_lock(EX_CHECK_NONE); | |
810 | |
811 // Reload the exception we're throwing | |
812 if (exception) | |
813 exception = get_oop_tmp(); | |
814 } | |
815 | |
816 if (exception) { | |
817 builder()->CreateStore(exception, pending_exception_address()); | |
818 } | |
819 | |
820 Value *result_addr = stack()->CreatePopFrame(type2size[type]); | |
821 if (type != T_VOID) { | |
822 builder()->CreateStore( | |
823 pop_result(type)->generic_value(), | |
824 builder()->CreateIntToPtr( | |
825 result_addr, | |
826 PointerType::getUnqual(SharkType::to_stackType(type)))); | |
827 } | |
828 | |
829 builder()->CreateRet(LLVMValue::jint_constant(0)); | |
830 } | |
831 | |
832 void SharkTopLevelBlock::do_arraylength() { | |
833 SharkValue *array = pop(); | |
834 check_null(array); | |
835 Value *length = builder()->CreateArrayLength(array->jarray_value()); | |
836 push(SharkValue::create_jint(length, false)); | |
837 } | |
838 | |
839 void SharkTopLevelBlock::do_aload(BasicType basic_type) { | |
840 SharkValue *index = pop(); | |
841 SharkValue *array = pop(); | |
842 | |
843 check_null(array); | |
844 check_bounds(array, index); | |
845 | |
846 Value *value = builder()->CreateLoad( | |
847 builder()->CreateArrayAddress( | |
848 array->jarray_value(), basic_type, index->jint_value())); | |
849 | |
7195 | 850 Type *stack_type = SharkType::to_stackType(basic_type); |
1692 | 851 if (value->getType() != stack_type) |
852 value = builder()->CreateIntCast(value, stack_type, basic_type != T_CHAR); | |
853 | |
854 switch (basic_type) { | |
855 case T_BYTE: | |
856 case T_CHAR: | |
857 case T_SHORT: | |
858 case T_INT: | |
859 push(SharkValue::create_jint(value, false)); | |
860 break; | |
861 | |
862 case T_LONG: | |
863 push(SharkValue::create_jlong(value, false)); | |
864 break; | |
865 | |
866 case T_FLOAT: | |
867 push(SharkValue::create_jfloat(value)); | |
868 break; | |
869 | |
870 case T_DOUBLE: | |
871 push(SharkValue::create_jdouble(value)); | |
872 break; | |
873 | |
874 case T_OBJECT: | |
875 // You might expect that array->type()->is_array_klass() would | |
876 // always be true, but it isn't. If ciTypeFlow detects that a | |
877 // value is always null then that value becomes an untyped null | |
878 // object. Shark doesn't presently support this, so a generic | |
879 // T_OBJECT is created. In this case we guess the type using | |
880 // the BasicType we were supplied. In reality the generated | |
881 // code will never be used, as the null value will be caught | |
882 // by the above null pointer check. | |
883 // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=324 | |
884 push( | |
885 SharkValue::create_generic( | |
886 array->type()->is_array_klass() ? | |
887 ((ciArrayKlass *) array->type())->element_type() : | |
888 ciType::make(basic_type), | |
889 value, false)); | |
890 break; | |
891 | |
892 default: | |
893 tty->print_cr("Unhandled type %s", type2name(basic_type)); | |
894 ShouldNotReachHere(); | |
895 } | |
896 } | |
897 | |
898 void SharkTopLevelBlock::do_astore(BasicType basic_type) { | |
899 SharkValue *svalue = pop(); | |
900 SharkValue *index = pop(); | |
901 SharkValue *array = pop(); | |
902 | |
903 check_null(array); | |
904 check_bounds(array, index); | |
905 | |
906 Value *value; | |
907 switch (basic_type) { | |
908 case T_BYTE: | |
909 case T_CHAR: | |
910 case T_SHORT: | |
911 case T_INT: | |
912 value = svalue->jint_value(); | |
913 break; | |
914 | |
915 case T_LONG: | |
916 value = svalue->jlong_value(); | |
917 break; | |
918 | |
919 case T_FLOAT: | |
920 value = svalue->jfloat_value(); | |
921 break; | |
922 | |
923 case T_DOUBLE: | |
924 value = svalue->jdouble_value(); | |
925 break; | |
926 | |
927 case T_OBJECT: | |
928 value = svalue->jobject_value(); | |
929 // XXX assignability check | |
930 break; | |
931 | |
932 default: | |
933 tty->print_cr("Unhandled type %s", type2name(basic_type)); | |
934 ShouldNotReachHere(); | |
935 } | |
936 | |
7195 | 937 Type *array_type = SharkType::to_arrayType(basic_type); |
1692 | 938 if (value->getType() != array_type) |
939 value = builder()->CreateIntCast(value, array_type, basic_type != T_CHAR); | |
940 | |
941 Value *addr = builder()->CreateArrayAddress( | |
942 array->jarray_value(), basic_type, index->jint_value(), "addr"); | |
943 | |
944 builder()->CreateStore(value, addr); | |
945 | |
946 if (basic_type == T_OBJECT) // XXX or T_ARRAY? | |
947 builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr); | |
948 } | |
949 | |
950 void SharkTopLevelBlock::do_return(BasicType type) { | |
951 if (target()->intrinsic_id() == vmIntrinsics::_Object_init) | |
952 call_register_finalizer(local(0)->jobject_value()); | |
953 maybe_add_safepoint(); | |
954 handle_return(type, NULL); | |
955 } | |
956 | |
957 void SharkTopLevelBlock::do_athrow() { | |
958 SharkValue *exception = pop(); | |
959 check_null(exception); | |
960 handle_exception(exception->jobject_value(), EX_CHECK_FULL); | |
961 } | |
962 | |
963 void SharkTopLevelBlock::do_goto() { | |
964 do_branch(ciTypeFlow::GOTO_TARGET); | |
965 } | |
966 | |
967 void SharkTopLevelBlock::do_jsr() { | |
968 push(SharkValue::address_constant(iter()->next_bci())); | |
969 do_branch(ciTypeFlow::GOTO_TARGET); | |
970 } | |
971 | |
972 void SharkTopLevelBlock::do_ret() { | |
973 assert(local(iter()->get_index())->address_value() == | |
974 successor(ciTypeFlow::GOTO_TARGET)->start(), "should be"); | |
975 do_branch(ciTypeFlow::GOTO_TARGET); | |
976 } | |
977 | |
978 // All propagation of state from one block to the next (via | |
979 // dest->add_incoming) is handled by these methods: | |
980 // do_branch | |
981 // do_if_helper | |
982 // do_switch | |
983 // handle_exception | |
984 | |
985 void SharkTopLevelBlock::do_branch(int successor_index) { | |
986 SharkTopLevelBlock *dest = successor(successor_index); | |
987 builder()->CreateBr(dest->entry_block()); | |
988 dest->add_incoming(current_state()); | |
989 } | |
990 | |
991 void SharkTopLevelBlock::do_if(ICmpInst::Predicate p, | |
992 SharkValue* b, | |
993 SharkValue* a) { | |
994 Value *llvm_a, *llvm_b; | |
995 if (a->is_jobject()) { | |
996 llvm_a = a->intptr_value(builder()); | |
997 llvm_b = b->intptr_value(builder()); | |
998 } | |
999 else { | |
1000 llvm_a = a->jint_value(); | |
1001 llvm_b = b->jint_value(); | |
1002 } | |
1003 do_if_helper(p, llvm_b, llvm_a, current_state(), current_state()); | |
1004 } | |
1005 | |
1006 void SharkTopLevelBlock::do_if_helper(ICmpInst::Predicate p, | |
1007 Value* b, | |
1008 Value* a, | |
1009 SharkState* if_taken_state, | |
1010 SharkState* not_taken_state) { | |
1011 SharkTopLevelBlock *if_taken = successor(ciTypeFlow::IF_TAKEN); | |
1012 SharkTopLevelBlock *not_taken = successor(ciTypeFlow::IF_NOT_TAKEN); | |
1013 | |
1014 builder()->CreateCondBr( | |
1015 builder()->CreateICmp(p, a, b), | |
1016 if_taken->entry_block(), not_taken->entry_block()); | |
1017 | |
1018 if_taken->add_incoming(if_taken_state); | |
1019 not_taken->add_incoming(not_taken_state); | |
1020 } | |
1021 | |
1022 void SharkTopLevelBlock::do_switch() { | |
1023 int len = switch_table_length(); | |
1024 | |
1025 SharkTopLevelBlock *dest_block = successor(ciTypeFlow::SWITCH_DEFAULT); | |
1026 SwitchInst *switchinst = builder()->CreateSwitch( | |
1027 pop()->jint_value(), dest_block->entry_block(), len); | |
1028 dest_block->add_incoming(current_state()); | |
1029 | |
1030 for (int i = 0; i < len; i++) { | |
1031 int dest_bci = switch_dest(i); | |
1032 if (dest_bci != switch_default_dest()) { | |
1033 dest_block = bci_successor(dest_bci); | |
1034 switchinst->addCase( | |
1035 LLVMValue::jint_constant(switch_key(i)), | |
1036 dest_block->entry_block()); | |
1037 dest_block->add_incoming(current_state()); | |
1038 } | |
1039 } | |
1040 } | |
1041 | |
1042 ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller, | |
1043 ciInstanceKlass* klass, | |
1044 ciMethod* dest_method, | |
1045 ciType* receiver_type) { | |
1046 // If the method is obviously final then we are already done | |
1047 if (dest_method->can_be_statically_bound()) | |
1048 return dest_method; | |
1049 | |
1050 // Array methods are all inherited from Object and are monomorphic | |
1051 if (receiver_type->is_array_klass() && | |
1052 dest_method->holder() == java_lang_Object_klass()) | |
1053 return dest_method; | |
1054 | |
1055 // This code can replace a virtual call with a direct call if this | |
1056 // class is the only one in the entire set of loaded classes that | |
1057 // implements this method. This makes the compiled code dependent | |
1058 // on other classes that implement the method not being loaded, a | |
1059 // condition which is enforced by the dependency tracker. If the | |
1060 // dependency tracker determines a method has become invalid it | |
1061 // will mark it for recompilation, causing running copies to be | |
1062 // deoptimized. Shark currently can't deoptimize arbitrarily like | |
1063 // that, so this optimization cannot be used. | |
1064 // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=481 | |
1065 | |
1066 // All other interesting cases are instance classes | |
1067 if (!receiver_type->is_instance_klass()) | |
1068 return NULL; | |
1069 | |
1070 // Attempt to improve the receiver | |
1071 ciInstanceKlass* actual_receiver = klass; | |
1072 ciInstanceKlass *improved_receiver = receiver_type->as_instance_klass(); | |
1073 if (improved_receiver->is_loaded() && | |
1074 improved_receiver->is_initialized() && | |
1075 !improved_receiver->is_interface() && | |
1076 improved_receiver->is_subtype_of(actual_receiver)) { | |
1077 actual_receiver = improved_receiver; | |
1078 } | |
1079 | |
1080 // Attempt to find a monomorphic target for this call using | |
1081 // class heirachy analysis. | |
1082 ciInstanceKlass *calling_klass = caller->holder(); | |
1083 ciMethod* monomorphic_target = | |
1084 dest_method->find_monomorphic_target(calling_klass, klass, actual_receiver); | |
1085 if (monomorphic_target != NULL) { | |
1086 assert(!monomorphic_target->is_abstract(), "shouldn't be"); | |
1087 | |
7599 | 1088 function()->dependencies()->assert_unique_concrete_method(actual_receiver, monomorphic_target); |
1089 | |
1692 | 1090 // Opto has a bunch of type checking here that I don't |
1091 // understand. It's to inhibit casting in one direction, | |
1092 // possibly because objects in Opto can have inexact | |
1093 // types, but I can't even tell which direction it | |
1094 // doesn't like. For now I'm going to block *any* cast. | |
1095 if (monomorphic_target != dest_method) { | |
1096 if (SharkPerformanceWarnings) { | |
1097 warning("found monomorphic target, but inhibited cast:"); | |
1098 tty->print(" dest_method = "); | |
1099 dest_method->print_short_name(tty); | |
1100 tty->cr(); | |
1101 tty->print(" monomorphic_target = "); | |
1102 monomorphic_target->print_short_name(tty); | |
1103 tty->cr(); | |
1104 } | |
1105 monomorphic_target = NULL; | |
1106 } | |
1107 } | |
1108 | |
1109 // Replace the virtual call with a direct one. This makes | |
1110 // us dependent on that target method not getting overridden | |
1111 // by dynamic class loading. | |
1112 if (monomorphic_target != NULL) { | |
1113 dependencies()->assert_unique_concrete_method( | |
1114 actual_receiver, monomorphic_target); | |
1115 return monomorphic_target; | |
1116 } | |
1117 | |
1118 // Because Opto distinguishes exact types from inexact ones | |
1119 // it can perform a further optimization to replace calls | |
1120 // with non-monomorphic targets if the receiver has an exact | |
1121 // type. We don't mark types this way, so we can't do this. | |
1122 | |
1123 | |
1124 return NULL; | |
1125 } | |
1126 | |
1127 Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) { | |
1128 return builder()->CreateBitCast( | |
7195 | 1129 builder()->CreateInlineMetadata(method, SharkType::Method_type()), |
1130 SharkType::Method_type(), | |
1131 "callee"); | |
1692 | 1132 } |
1133 | |
1134 Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver, | |
1135 int vtable_index) { | |
1136 Value *klass = builder()->CreateValueOfStructEntry( | |
1137 receiver->jobject_value(), | |
1138 in_ByteSize(oopDesc::klass_offset_in_bytes()), | |
1139 SharkType::oop_type(), | |
1140 "klass"); | |
1141 | |
1142 return builder()->CreateLoad( | |
1143 builder()->CreateArrayAddress( | |
1144 klass, | |
7195 | 1145 SharkType::Method_type(), |
1692 | 1146 vtableEntry::size() * wordSize, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4762
diff
changeset
|
1147 in_ByteSize(InstanceKlass::vtable_start_offset() * wordSize), |
1692 | 1148 LLVMValue::intptr_constant(vtable_index)), |
1149 "callee"); | |
1150 } | |
1151 | |
1152 Value* SharkTopLevelBlock::get_interface_callee(SharkValue *receiver, | |
1153 ciMethod* method) { | |
1154 BasicBlock *loop = function()->CreateBlock("loop"); | |
1155 BasicBlock *got_null = function()->CreateBlock("got_null"); | |
1156 BasicBlock *not_null = function()->CreateBlock("not_null"); | |
1157 BasicBlock *next = function()->CreateBlock("next"); | |
1158 BasicBlock *got_entry = function()->CreateBlock("got_entry"); | |
1159 | |
1160 // Locate the receiver's itable | |
1161 Value *object_klass = builder()->CreateValueOfStructEntry( | |
1162 receiver->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()), | |
7195 | 1163 SharkType::klass_type(), |
1692 | 1164 "object_klass"); |
1165 | |
1166 Value *vtable_start = builder()->CreateAdd( | |
1167 builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()), | |
1168 LLVMValue::intptr_constant( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4762
diff
changeset
|
1169 InstanceKlass::vtable_start_offset() * HeapWordSize), |
1692 | 1170 "vtable_start"); |
1171 | |
1172 Value *vtable_length = builder()->CreateValueOfStructEntry( | |
1173 object_klass, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4762
diff
changeset
|
1174 in_ByteSize(InstanceKlass::vtable_length_offset() * HeapWordSize), |
1692 | 1175 SharkType::jint_type(), |
1176 "vtable_length"); | |
1177 vtable_length = | |
1178 builder()->CreateIntCast(vtable_length, SharkType::intptr_type(), false); | |
1179 | |
1180 bool needs_aligning = HeapWordsPerLong > 1; | |
1181 Value *itable_start = builder()->CreateAdd( | |
1182 vtable_start, | |
1183 builder()->CreateShl( | |
1184 vtable_length, | |
1185 LLVMValue::intptr_constant(exact_log2(vtableEntry::size() * wordSize))), | |
1186 needs_aligning ? "" : "itable_start"); | |
1187 if (needs_aligning) { | |
1188 itable_start = builder()->CreateAnd( | |
1189 builder()->CreateAdd( | |
1190 itable_start, LLVMValue::intptr_constant(BytesPerLong - 1)), | |
1191 LLVMValue::intptr_constant(~(BytesPerLong - 1)), | |
1192 "itable_start"); | |
1193 } | |
1194 | |
1195 // Locate this interface's entry in the table | |
7195 | 1196 Value *iklass = builder()->CreateInlineMetadata(method->holder(), SharkType::klass_type()); |
1692 | 1197 BasicBlock *loop_entry = builder()->GetInsertBlock(); |
1198 builder()->CreateBr(loop); | |
1199 builder()->SetInsertPoint(loop); | |
1200 PHINode *itable_entry_addr = builder()->CreatePHI( | |
7195 | 1201 SharkType::intptr_type(), 0, "itable_entry_addr"); |
1692 | 1202 itable_entry_addr->addIncoming(itable_start, loop_entry); |
1203 | |
1204 Value *itable_entry = builder()->CreateIntToPtr( | |
1205 itable_entry_addr, SharkType::itableOffsetEntry_type(), "itable_entry"); | |
1206 | |
1207 Value *itable_iklass = builder()->CreateValueOfStructEntry( | |
1208 itable_entry, | |
1209 in_ByteSize(itableOffsetEntry::interface_offset_in_bytes()), | |
7195 | 1210 SharkType::klass_type(), |
1692 | 1211 "itable_iklass"); |
1212 | |
1213 builder()->CreateCondBr( | |
7195 | 1214 builder()->CreateICmpEQ(itable_iklass, LLVMValue::nullKlass()), |
1692 | 1215 got_null, not_null); |
1216 | |
1217 // A null entry means that the class doesn't implement the | |
1218 // interface, and wasn't the same as the class checked when | |
1219 // the interface was resolved. | |
1220 builder()->SetInsertPoint(got_null); | |
1221 builder()->CreateUnimplemented(__FILE__, __LINE__); | |
1222 builder()->CreateUnreachable(); | |
1223 | |
1224 builder()->SetInsertPoint(not_null); | |
1225 builder()->CreateCondBr( | |
1226 builder()->CreateICmpEQ(itable_iklass, iklass), | |
1227 got_entry, next); | |
1228 | |
1229 builder()->SetInsertPoint(next); | |
1230 Value *next_entry = builder()->CreateAdd( | |
1231 itable_entry_addr, | |
1232 LLVMValue::intptr_constant(itableOffsetEntry::size() * wordSize)); | |
1233 builder()->CreateBr(loop); | |
1234 itable_entry_addr->addIncoming(next_entry, next); | |
1235 | |
1236 // Locate the method pointer | |
1237 builder()->SetInsertPoint(got_entry); | |
1238 Value *offset = builder()->CreateValueOfStructEntry( | |
1239 itable_entry, | |
1240 in_ByteSize(itableOffsetEntry::offset_offset_in_bytes()), | |
1241 SharkType::jint_type(), | |
1242 "offset"); | |
1243 offset = | |
1244 builder()->CreateIntCast(offset, SharkType::intptr_type(), false); | |
1245 | |
1246 return builder()->CreateLoad( | |
1247 builder()->CreateIntToPtr( | |
1248 builder()->CreateAdd( | |
1249 builder()->CreateAdd( | |
1250 builder()->CreateAdd( | |
1251 builder()->CreatePtrToInt( | |
1252 object_klass, SharkType::intptr_type()), | |
1253 offset), | |
1254 LLVMValue::intptr_constant( | |
1255 method->itable_index() * itableMethodEntry::size() * wordSize)), | |
1256 LLVMValue::intptr_constant( | |
1257 itableMethodEntry::method_offset_in_bytes())), | |
7195 | 1258 PointerType::getUnqual(SharkType::Method_type())), |
1692 | 1259 "callee"); |
1260 } | |
1261 | |
1262 void SharkTopLevelBlock::do_call() { | |
1263 // Set frequently used booleans | |
1264 bool is_static = bc() == Bytecodes::_invokestatic; | |
1265 bool is_virtual = bc() == Bytecodes::_invokevirtual; | |
1266 bool is_interface = bc() == Bytecodes::_invokeinterface; | |
1267 | |
1268 // Find the method being called | |
1269 bool will_link; | |
7195 | 1270 ciSignature* sig; |
1271 ciMethod *dest_method = iter()->get_method(will_link, &sig); | |
1272 | |
1692 | 1273 assert(will_link, "typeflow responsibility"); |
1274 assert(dest_method->is_static() == is_static, "must match bc"); | |
1275 | |
1276 // Find the class of the method being called. Note | |
1277 // that the superclass check in the second assertion | |
1278 // is to cope with a hole in the spec that allows for | |
1279 // invokeinterface instructions where the resolved | |
1280 // method is a virtual method in java.lang.Object. | |
1281 // javac doesn't generate code like that, but there's | |
1282 // no reason a compliant Java compiler might not. | |
1283 ciInstanceKlass *holder_klass = dest_method->holder(); | |
1284 assert(holder_klass->is_loaded(), "scan_for_traps responsibility"); | |
1285 assert(holder_klass->is_interface() || | |
1286 holder_klass->super() == NULL || | |
1287 !is_interface, "must match bc"); | |
7195 | 1288 |
1289 bool is_forced_virtual = is_interface && holder_klass == java_lang_Object_klass(); | |
1290 | |
1692 | 1291 ciKlass *holder = iter()->get_declared_method_holder(); |
1292 ciInstanceKlass *klass = | |
1293 ciEnv::get_instance_klass_for_declared_method_holder(holder); | |
1294 | |
7195 | 1295 if (is_forced_virtual) { |
1296 klass = java_lang_Object_klass(); | |
1297 } | |
1298 | |
1692 | 1299 // Find the receiver in the stack. We do this before |
1300 // trying to inline because the inliner can only use | |
1301 // zero-checked values, not being able to perform the | |
1302 // check itself. | |
1303 SharkValue *receiver = NULL; | |
1304 if (!is_static) { | |
1305 receiver = xstack(dest_method->arg_size() - 1); | |
1306 check_null(receiver); | |
1307 } | |
1308 | |
1309 // Try to improve non-direct calls | |
1310 bool call_is_virtual = is_virtual || is_interface; | |
1311 ciMethod *call_method = dest_method; | |
1312 if (call_is_virtual) { | |
1313 ciMethod *optimized_method = improve_virtual_call( | |
1314 target(), klass, dest_method, receiver->type()); | |
1315 if (optimized_method) { | |
1316 call_method = optimized_method; | |
1317 call_is_virtual = false; | |
1318 } | |
1319 } | |
1320 | |
1321 // Try to inline the call | |
1322 if (!call_is_virtual) { | |
7599 | 1323 if (SharkInliner::attempt_inline(call_method, current_state())) { |
1692 | 1324 return; |
7599 | 1325 } |
1692 | 1326 } |
1327 | |
1328 // Find the method we are calling | |
1329 Value *callee; | |
1330 if (call_is_virtual) { | |
7195 | 1331 if (is_virtual || is_forced_virtual) { |
1692 | 1332 assert(klass->is_linked(), "scan_for_traps responsibility"); |
1333 int vtable_index = call_method->resolve_vtable_index( | |
1334 target()->holder(), klass); | |
1335 assert(vtable_index >= 0, "should be"); | |
1336 callee = get_virtual_callee(receiver, vtable_index); | |
1337 } | |
1338 else { | |
1339 assert(is_interface, "should be"); | |
1340 callee = get_interface_callee(receiver, call_method); | |
1341 } | |
1342 } | |
1343 else { | |
1344 callee = get_direct_callee(call_method); | |
1345 } | |
1346 | |
1347 // Load the SharkEntry from the callee | |
1348 Value *base_pc = builder()->CreateValueOfStructEntry( | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
4762
diff
changeset
|
1349 callee, Method::from_interpreted_offset(), |
1692 | 1350 SharkType::intptr_type(), |
1351 "base_pc"); | |
1352 | |
1353 // Load the entry point from the SharkEntry | |
1354 Value *entry_point = builder()->CreateLoad( | |
1355 builder()->CreateIntToPtr( | |
1356 builder()->CreateAdd( | |
1357 base_pc, | |
1358 LLVMValue::intptr_constant(in_bytes(ZeroEntry::entry_point_offset()))), | |
1359 PointerType::getUnqual( | |
1360 PointerType::getUnqual(SharkType::entry_point_type()))), | |
1361 "entry_point"); | |
1362 | |
1363 // Make the call | |
1364 decache_for_Java_call(call_method); | |
1365 Value *deoptimized_frames = builder()->CreateCall3( | |
1366 entry_point, callee, base_pc, thread()); | |
1367 | |
1368 // If the callee got deoptimized then reexecute in the interpreter | |
1369 BasicBlock *reexecute = function()->CreateBlock("reexecute"); | |
1370 BasicBlock *call_completed = function()->CreateBlock("call_completed"); | |
1371 builder()->CreateCondBr( | |
1372 builder()->CreateICmpNE(deoptimized_frames, LLVMValue::jint_constant(0)), | |
1373 reexecute, call_completed); | |
1374 | |
1375 builder()->SetInsertPoint(reexecute); | |
1376 builder()->CreateCall2( | |
1377 builder()->deoptimized_entry_point(), | |
1378 builder()->CreateSub(deoptimized_frames, LLVMValue::jint_constant(1)), | |
1379 thread()); | |
1380 builder()->CreateBr(call_completed); | |
1381 | |
1382 // Cache after the call | |
1383 builder()->SetInsertPoint(call_completed); | |
1384 cache_after_Java_call(call_method); | |
1385 | |
1386 // Check for pending exceptions | |
1387 check_pending_exception(EX_CHECK_FULL); | |
1388 | |
1389 // Mark that a safepoint check has occurred | |
1390 current_state()->set_has_safepointed(true); | |
1391 } | |
1392 | |
1393 bool SharkTopLevelBlock::static_subtype_check(ciKlass* check_klass, | |
1394 ciKlass* object_klass) { | |
1395 // If the class we're checking against is java.lang.Object | |
1396 // then this is a no brainer. Apparently this can happen | |
1397 // in reflective code... | |
1398 if (check_klass == java_lang_Object_klass()) | |
1399 return true; | |
1400 | |
1401 // Perform a subtype check. NB in opto's code for this | |
1402 // (GraphKit::static_subtype_check) it says that static | |
1403 // interface types cannot be trusted, and if opto can't | |
1404 // trust them then I assume we can't either. | |
1405 if (object_klass->is_loaded() && !object_klass->is_interface()) { | |
1406 if (object_klass == check_klass) | |
1407 return true; | |
1408 | |
1409 if (check_klass->is_loaded() && object_klass->is_subtype_of(check_klass)) | |
1410 return true; | |
1411 } | |
1412 | |
1413 return false; | |
1414 } | |
1415 | |
1416 void SharkTopLevelBlock::do_instance_check() { | |
1417 // Get the class we're checking against | |
1418 bool will_link; | |
1419 ciKlass *check_klass = iter()->get_klass(will_link); | |
1420 | |
1421 // Get the class of the object we're checking | |
1422 ciKlass *object_klass = xstack(0)->type()->as_klass(); | |
1423 | |
1424 // Can we optimize this check away? | |
1425 if (static_subtype_check(check_klass, object_klass)) { | |
1426 if (bc() == Bytecodes::_instanceof) { | |
1427 pop(); | |
1428 push(SharkValue::jint_constant(1)); | |
1429 } | |
1430 return; | |
1431 } | |
1432 | |
1433 // Need to check this one at runtime | |
1434 if (will_link) | |
1435 do_full_instance_check(check_klass); | |
1436 else | |
1437 do_trapping_instance_check(check_klass); | |
1438 } | |
1439 | |
1440 bool SharkTopLevelBlock::maybe_do_instanceof_if() { | |
1441 // Get the class we're checking against | |
1442 bool will_link; | |
1443 ciKlass *check_klass = iter()->get_klass(will_link); | |
1444 | |
1445 // If the class is unloaded then the instanceof | |
1446 // cannot possibly succeed. | |
1447 if (!will_link) | |
1448 return false; | |
1449 | |
1450 // Keep a copy of the object we're checking | |
1451 SharkValue *old_object = xstack(0); | |
1452 | |
1453 // Get the class of the object we're checking | |
1454 ciKlass *object_klass = old_object->type()->as_klass(); | |
1455 | |
1456 // If the instanceof can be optimized away at compile time | |
1457 // then any subsequent checkcasts will be too so we handle | |
1458 // it normally. | |
1459 if (static_subtype_check(check_klass, object_klass)) | |
1460 return false; | |
1461 | |
1462 // Perform the instance check | |
1463 do_full_instance_check(check_klass); | |
1464 Value *result = pop()->jint_value(); | |
1465 | |
1466 // Create the casted object | |
1467 SharkValue *new_object = SharkValue::create_generic( | |
1468 check_klass, old_object->jobject_value(), old_object->zero_checked()); | |
1469 | |
1470 // Create two copies of the current state, one with the | |
1471 // original object and one with all instances of the | |
1472 // original object replaced with the new, casted object. | |
1473 SharkState *new_state = current_state(); | |
1474 SharkState *old_state = new_state->copy(); | |
1475 new_state->replace_all(old_object, new_object); | |
1476 | |
1477 // Perform the check-and-branch | |
1478 switch (iter()->next_bc()) { | |
1479 case Bytecodes::_ifeq: | |
1480 // branch if not an instance | |
1481 do_if_helper( | |
1482 ICmpInst::ICMP_EQ, | |
1483 LLVMValue::jint_constant(0), result, | |
1484 old_state, new_state); | |
1485 break; | |
1486 | |
1487 case Bytecodes::_ifne: | |
1488 // branch if an instance | |
1489 do_if_helper( | |
1490 ICmpInst::ICMP_NE, | |
1491 LLVMValue::jint_constant(0), result, | |
1492 new_state, old_state); | |
1493 break; | |
1494 | |
1495 default: | |
1496 ShouldNotReachHere(); | |
1497 } | |
1498 | |
1499 return true; | |
1500 } | |
1501 | |
1502 void SharkTopLevelBlock::do_full_instance_check(ciKlass* klass) { | |
1503 BasicBlock *not_null = function()->CreateBlock("not_null"); | |
1504 BasicBlock *subtype_check = function()->CreateBlock("subtype_check"); | |
1505 BasicBlock *is_instance = function()->CreateBlock("is_instance"); | |
1506 BasicBlock *not_instance = function()->CreateBlock("not_instance"); | |
1507 BasicBlock *merge1 = function()->CreateBlock("merge1"); | |
1508 BasicBlock *merge2 = function()->CreateBlock("merge2"); | |
1509 | |
1510 enum InstanceCheckStates { | |
1511 IC_IS_NULL, | |
1512 IC_IS_INSTANCE, | |
1513 IC_NOT_INSTANCE, | |
1514 }; | |
1515 | |
1516 // Pop the object off the stack | |
1517 Value *object = pop()->jobject_value(); | |
1518 | |
1519 // Null objects aren't instances of anything | |
1520 builder()->CreateCondBr( | |
1521 builder()->CreateICmpEQ(object, LLVMValue::null()), | |
1522 merge2, not_null); | |
1523 BasicBlock *null_block = builder()->GetInsertBlock(); | |
1524 | |
1525 // Get the class we're checking against | |
1526 builder()->SetInsertPoint(not_null); | |
7195 | 1527 Value *check_klass = builder()->CreateInlineMetadata(klass, SharkType::klass_type()); |
1692 | 1528 |
1529 // Get the class of the object being tested | |
1530 Value *object_klass = builder()->CreateValueOfStructEntry( | |
1531 object, in_ByteSize(oopDesc::klass_offset_in_bytes()), | |
7195 | 1532 SharkType::klass_type(), |
1692 | 1533 "object_klass"); |
1534 | |
1535 // Perform the check | |
1536 builder()->CreateCondBr( | |
1537 builder()->CreateICmpEQ(check_klass, object_klass), | |
1538 is_instance, subtype_check); | |
1539 | |
1540 builder()->SetInsertPoint(subtype_check); | |
1541 builder()->CreateCondBr( | |
1542 builder()->CreateICmpNE( | |
1543 builder()->CreateCall2( | |
1544 builder()->is_subtype_of(), check_klass, object_klass), | |
1545 LLVMValue::jbyte_constant(0)), | |
1546 is_instance, not_instance); | |
1547 | |
1548 builder()->SetInsertPoint(is_instance); | |
1549 builder()->CreateBr(merge1); | |
1550 | |
1551 builder()->SetInsertPoint(not_instance); | |
1552 builder()->CreateBr(merge1); | |
1553 | |
1554 // First merge | |
1555 builder()->SetInsertPoint(merge1); | |
1556 PHINode *nonnull_result = builder()->CreatePHI( | |
7195 | 1557 SharkType::jint_type(), 0, "nonnull_result"); |
1692 | 1558 nonnull_result->addIncoming( |
1559 LLVMValue::jint_constant(IC_IS_INSTANCE), is_instance); | |
1560 nonnull_result->addIncoming( | |
1561 LLVMValue::jint_constant(IC_NOT_INSTANCE), not_instance); | |
1562 BasicBlock *nonnull_block = builder()->GetInsertBlock(); | |
1563 builder()->CreateBr(merge2); | |
1564 | |
1565 // Second merge | |
1566 builder()->SetInsertPoint(merge2); | |
1567 PHINode *result = builder()->CreatePHI( | |
7195 | 1568 SharkType::jint_type(), 0, "result"); |
1692 | 1569 result->addIncoming(LLVMValue::jint_constant(IC_IS_NULL), null_block); |
1570 result->addIncoming(nonnull_result, nonnull_block); | |
1571 | |
1572 // Handle the result | |
1573 if (bc() == Bytecodes::_checkcast) { | |
1574 BasicBlock *failure = function()->CreateBlock("failure"); | |
1575 BasicBlock *success = function()->CreateBlock("success"); | |
1576 | |
1577 builder()->CreateCondBr( | |
1578 builder()->CreateICmpNE( | |
1579 result, LLVMValue::jint_constant(IC_NOT_INSTANCE)), | |
1580 success, failure); | |
1581 | |
1582 builder()->SetInsertPoint(failure); | |
1583 SharkState *saved_state = current_state()->copy(); | |
1584 | |
1585 call_vm( | |
1586 builder()->throw_ClassCastException(), | |
1587 builder()->CreateIntToPtr( | |
1588 LLVMValue::intptr_constant((intptr_t) __FILE__), | |
1589 PointerType::getUnqual(SharkType::jbyte_type())), | |
1590 LLVMValue::jint_constant(__LINE__), | |
1591 EX_CHECK_NONE); | |
1592 | |
1593 Value *pending_exception = get_pending_exception(); | |
1594 clear_pending_exception(); | |
1595 handle_exception(pending_exception, EX_CHECK_FULL); | |
1596 | |
1597 set_current_state(saved_state); | |
1598 builder()->SetInsertPoint(success); | |
1599 push(SharkValue::create_generic(klass, object, false)); | |
1600 } | |
1601 else { | |
1602 push( | |
1603 SharkValue::create_jint( | |
1604 builder()->CreateIntCast( | |
1605 builder()->CreateICmpEQ( | |
1606 result, LLVMValue::jint_constant(IC_IS_INSTANCE)), | |
1607 SharkType::jint_type(), false), false)); | |
1608 } | |
1609 } | |
1610 | |
1611 void SharkTopLevelBlock::do_trapping_instance_check(ciKlass* klass) { | |
1612 BasicBlock *not_null = function()->CreateBlock("not_null"); | |
1613 BasicBlock *is_null = function()->CreateBlock("null"); | |
1614 | |
1615 // Leave the object on the stack so it's there if we trap | |
1616 builder()->CreateCondBr( | |
1617 builder()->CreateICmpEQ(xstack(0)->jobject_value(), LLVMValue::null()), | |
1618 is_null, not_null); | |
1619 SharkState *saved_state = current_state()->copy(); | |
1620 | |
1621 // If it's not null then we need to trap | |
1622 builder()->SetInsertPoint(not_null); | |
1623 set_current_state(saved_state->copy()); | |
1624 do_trap( | |
1625 Deoptimization::make_trap_request( | |
1626 Deoptimization::Reason_uninitialized, | |
1627 Deoptimization::Action_reinterpret)); | |
1628 | |
1629 // If it's null then we're ok | |
1630 builder()->SetInsertPoint(is_null); | |
1631 set_current_state(saved_state); | |
1632 if (bc() == Bytecodes::_checkcast) { | |
1633 push(SharkValue::create_generic(klass, pop()->jobject_value(), false)); | |
1634 } | |
1635 else { | |
1636 pop(); | |
1637 push(SharkValue::jint_constant(0)); | |
1638 } | |
1639 } | |
1640 | |
1641 void SharkTopLevelBlock::do_new() { | |
1642 bool will_link; | |
1643 ciInstanceKlass* klass = iter()->get_klass(will_link)->as_instance_klass(); | |
1644 assert(will_link, "typeflow responsibility"); | |
1645 | |
1646 BasicBlock *got_tlab = NULL; | |
1647 BasicBlock *heap_alloc = NULL; | |
1648 BasicBlock *retry = NULL; | |
1649 BasicBlock *got_heap = NULL; | |
1650 BasicBlock *initialize = NULL; | |
1651 BasicBlock *got_fast = NULL; | |
1652 BasicBlock *slow_alloc_and_init = NULL; | |
1653 BasicBlock *got_slow = NULL; | |
1654 BasicBlock *push_object = NULL; | |
1655 | |
1656 SharkState *fast_state = NULL; | |
1657 | |
1658 Value *tlab_object = NULL; | |
1659 Value *heap_object = NULL; | |
1660 Value *fast_object = NULL; | |
1661 Value *slow_object = NULL; | |
1662 Value *object = NULL; | |
1663 | |
1664 // The fast path | |
1665 if (!Klass::layout_helper_needs_slow_path(klass->layout_helper())) { | |
1666 if (UseTLAB) { | |
1667 got_tlab = function()->CreateBlock("got_tlab"); | |
1668 heap_alloc = function()->CreateBlock("heap_alloc"); | |
1669 } | |
1670 retry = function()->CreateBlock("retry"); | |
1671 got_heap = function()->CreateBlock("got_heap"); | |
1672 initialize = function()->CreateBlock("initialize"); | |
1673 slow_alloc_and_init = function()->CreateBlock("slow_alloc_and_init"); | |
1674 push_object = function()->CreateBlock("push_object"); | |
1675 | |
1676 size_t size_in_bytes = klass->size_helper() << LogHeapWordSize; | |
1677 | |
1678 // Thread local allocation | |
1679 if (UseTLAB) { | |
1680 Value *top_addr = builder()->CreateAddressOfStructEntry( | |
1681 thread(), Thread::tlab_top_offset(), | |
1682 PointerType::getUnqual(SharkType::intptr_type()), | |
1683 "top_addr"); | |
1684 | |
1685 Value *end = builder()->CreateValueOfStructEntry( | |
1686 thread(), Thread::tlab_end_offset(), | |
1687 SharkType::intptr_type(), | |
1688 "end"); | |
1689 | |
1690 Value *old_top = builder()->CreateLoad(top_addr, "old_top"); | |
1691 Value *new_top = builder()->CreateAdd( | |
1692 old_top, LLVMValue::intptr_constant(size_in_bytes)); | |
1693 | |
1694 builder()->CreateCondBr( | |
1695 builder()->CreateICmpULE(new_top, end), | |
1696 got_tlab, heap_alloc); | |
1697 | |
1698 builder()->SetInsertPoint(got_tlab); | |
1699 tlab_object = builder()->CreateIntToPtr( | |
1700 old_top, SharkType::oop_type(), "tlab_object"); | |
1701 | |
1702 builder()->CreateStore(new_top, top_addr); | |
1703 builder()->CreateBr(initialize); | |
1704 | |
1705 builder()->SetInsertPoint(heap_alloc); | |
1706 } | |
1707 | |
1708 // Heap allocation | |
1709 Value *top_addr = builder()->CreateIntToPtr( | |
1710 LLVMValue::intptr_constant((intptr_t) Universe::heap()->top_addr()), | |
1711 PointerType::getUnqual(SharkType::intptr_type()), | |
1712 "top_addr"); | |
1713 | |
1714 Value *end = builder()->CreateLoad( | |
1715 builder()->CreateIntToPtr( | |
1716 LLVMValue::intptr_constant((intptr_t) Universe::heap()->end_addr()), | |
1717 PointerType::getUnqual(SharkType::intptr_type())), | |
1718 "end"); | |
1719 | |
1720 builder()->CreateBr(retry); | |
1721 builder()->SetInsertPoint(retry); | |
1722 | |
1723 Value *old_top = builder()->CreateLoad(top_addr, "top"); | |
1724 Value *new_top = builder()->CreateAdd( | |
1725 old_top, LLVMValue::intptr_constant(size_in_bytes)); | |
1726 | |
1727 builder()->CreateCondBr( | |
1728 builder()->CreateICmpULE(new_top, end), | |
1729 got_heap, slow_alloc_and_init); | |
1730 | |
1731 builder()->SetInsertPoint(got_heap); | |
1732 heap_object = builder()->CreateIntToPtr( | |
1733 old_top, SharkType::oop_type(), "heap_object"); | |
1734 | |
7195 | 1735 Value *check = builder()->CreateAtomicCmpXchg(top_addr, old_top, new_top, llvm::SequentiallyConsistent); |
1692 | 1736 builder()->CreateCondBr( |
1737 builder()->CreateICmpEQ(old_top, check), | |
1738 initialize, retry); | |
1739 | |
1740 // Initialize the object | |
1741 builder()->SetInsertPoint(initialize); | |
1742 if (tlab_object) { | |
1743 PHINode *phi = builder()->CreatePHI( | |
7195 | 1744 SharkType::oop_type(), 0, "fast_object"); |
1692 | 1745 phi->addIncoming(tlab_object, got_tlab); |
1746 phi->addIncoming(heap_object, got_heap); | |
1747 fast_object = phi; | |
1748 } | |
1749 else { | |
1750 fast_object = heap_object; | |
1751 } | |
1752 | |
1753 builder()->CreateMemset( | |
1754 builder()->CreateBitCast( | |
1755 fast_object, PointerType::getUnqual(SharkType::jbyte_type())), | |
1756 LLVMValue::jbyte_constant(0), | |
1757 LLVMValue::jint_constant(size_in_bytes), | |
1758 LLVMValue::jint_constant(HeapWordSize)); | |
1759 | |
1760 Value *mark_addr = builder()->CreateAddressOfStructEntry( | |
1761 fast_object, in_ByteSize(oopDesc::mark_offset_in_bytes()), | |
1762 PointerType::getUnqual(SharkType::intptr_type()), | |
1763 "mark_addr"); | |
1764 | |
1765 Value *klass_addr = builder()->CreateAddressOfStructEntry( | |
1766 fast_object, in_ByteSize(oopDesc::klass_offset_in_bytes()), | |
7195 | 1767 PointerType::getUnqual(SharkType::klass_type()), |
1692 | 1768 "klass_addr"); |
1769 | |
1770 // Set the mark | |
1771 intptr_t mark; | |
1772 if (UseBiasedLocking) { | |
1773 Unimplemented(); | |
1774 } | |
1775 else { | |
1776 mark = (intptr_t) markOopDesc::prototype(); | |
1777 } | |
1778 builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr); | |
1779 | |
1780 // Set the class | |
7195 | 1781 Value *rtklass = builder()->CreateInlineMetadata(klass, SharkType::klass_type()); |
1692 | 1782 builder()->CreateStore(rtklass, klass_addr); |
1783 got_fast = builder()->GetInsertBlock(); | |
1784 | |
1785 builder()->CreateBr(push_object); | |
1786 builder()->SetInsertPoint(slow_alloc_and_init); | |
1787 fast_state = current_state()->copy(); | |
1788 } | |
1789 | |
1790 // The slow path | |
1791 call_vm( | |
1792 builder()->new_instance(), | |
1793 LLVMValue::jint_constant(iter()->get_klass_index()), | |
1794 EX_CHECK_FULL); | |
1795 slow_object = get_vm_result(); | |
1796 got_slow = builder()->GetInsertBlock(); | |
1797 | |
1798 // Push the object | |
1799 if (push_object) { | |
1800 builder()->CreateBr(push_object); | |
1801 builder()->SetInsertPoint(push_object); | |
1802 } | |
1803 if (fast_object) { | |
7195 | 1804 PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "object"); |
1692 | 1805 phi->addIncoming(fast_object, got_fast); |
1806 phi->addIncoming(slow_object, got_slow); | |
1807 object = phi; | |
1808 current_state()->merge(fast_state, got_fast, got_slow); | |
1809 } | |
1810 else { | |
1811 object = slow_object; | |
1812 } | |
1813 | |
1814 push(SharkValue::create_jobject(object, true)); | |
1815 } | |
1816 | |
1817 void SharkTopLevelBlock::do_newarray() { | |
1818 BasicType type = (BasicType) iter()->get_index(); | |
1819 | |
1820 call_vm( | |
1821 builder()->newarray(), | |
1822 LLVMValue::jint_constant(type), | |
1823 pop()->jint_value(), | |
1824 EX_CHECK_FULL); | |
1825 | |
1826 ciArrayKlass *array_klass = ciArrayKlass::make(ciType::make(type)); | |
1827 push(SharkValue::create_generic(array_klass, get_vm_result(), true)); | |
1828 } | |
1829 | |
1830 void SharkTopLevelBlock::do_anewarray() { | |
1831 bool will_link; | |
1832 ciKlass *klass = iter()->get_klass(will_link); | |
1833 assert(will_link, "typeflow responsibility"); | |
1834 | |
1835 ciObjArrayKlass *array_klass = ciObjArrayKlass::make(klass); | |
1836 if (!array_klass->is_loaded()) { | |
1837 Unimplemented(); | |
1838 } | |
1839 | |
1840 call_vm( | |
1841 builder()->anewarray(), | |
1842 LLVMValue::jint_constant(iter()->get_klass_index()), | |
1843 pop()->jint_value(), | |
1844 EX_CHECK_FULL); | |
1845 | |
1846 push(SharkValue::create_generic(array_klass, get_vm_result(), true)); | |
1847 } | |
1848 | |
1849 void SharkTopLevelBlock::do_multianewarray() { | |
1850 bool will_link; | |
1851 ciArrayKlass *array_klass = iter()->get_klass(will_link)->as_array_klass(); | |
1852 assert(will_link, "typeflow responsibility"); | |
1853 | |
1854 // The dimensions are stack values, so we use their slots for the | |
1855 // dimensions array. Note that we are storing them in the reverse | |
1856 // of normal stack order. | |
1857 int ndims = iter()->get_dimensions(); | |
1858 | |
1859 Value *dimensions = stack()->slot_addr( | |
1860 stack()->stack_slots_offset() + max_stack() - xstack_depth(), | |
1861 ArrayType::get(SharkType::jint_type(), ndims), | |
1862 "dimensions"); | |
1863 | |
1864 for (int i = 0; i < ndims; i++) { | |
1865 builder()->CreateStore( | |
1866 xstack(ndims - 1 - i)->jint_value(), | |
1867 builder()->CreateStructGEP(dimensions, i)); | |
1868 } | |
1869 | |
1870 call_vm( | |
1871 builder()->multianewarray(), | |
1872 LLVMValue::jint_constant(iter()->get_klass_index()), | |
1873 LLVMValue::jint_constant(ndims), | |
1874 builder()->CreateStructGEP(dimensions, 0), | |
1875 EX_CHECK_FULL); | |
1876 | |
1877 // Now we can pop the dimensions off the stack | |
1878 for (int i = 0; i < ndims; i++) | |
1879 pop(); | |
1880 | |
1881 push(SharkValue::create_generic(array_klass, get_vm_result(), true)); | |
1882 } | |
1883 | |
1884 void SharkTopLevelBlock::acquire_method_lock() { | |
1885 Value *lockee; | |
7195 | 1886 if (target()->is_static()) { |
1692 | 1887 lockee = builder()->CreateInlineOop(target()->holder()->java_mirror()); |
7195 | 1888 } |
1692 | 1889 else |
1890 lockee = local(0)->jobject_value(); | |
1891 | |
1892 iter()->force_bci(start()); // for the decache in acquire_lock | |
1893 acquire_lock(lockee, EX_CHECK_NO_CATCH); | |
1894 } | |
1895 | |
1896 void SharkTopLevelBlock::do_monitorenter() { | |
1897 SharkValue *lockee = pop(); | |
1898 check_null(lockee); | |
1899 acquire_lock(lockee->jobject_value(), EX_CHECK_FULL); | |
1900 } | |
1901 | |
1902 void SharkTopLevelBlock::do_monitorexit() { | |
1903 pop(); // don't need this (monitors are block structured) | |
1904 release_lock(EX_CHECK_NO_CATCH); | |
1905 } | |
1906 | |
1907 void SharkTopLevelBlock::acquire_lock(Value *lockee, int exception_action) { | |
1908 BasicBlock *try_recursive = function()->CreateBlock("try_recursive"); | |
1909 BasicBlock *got_recursive = function()->CreateBlock("got_recursive"); | |
1910 BasicBlock *not_recursive = function()->CreateBlock("not_recursive"); | |
1911 BasicBlock *acquired_fast = function()->CreateBlock("acquired_fast"); | |
1912 BasicBlock *lock_acquired = function()->CreateBlock("lock_acquired"); | |
1913 | |
1914 int monitor = num_monitors(); | |
1915 Value *monitor_addr = stack()->monitor_addr(monitor); | |
1916 Value *monitor_object_addr = stack()->monitor_object_addr(monitor); | |
1917 Value *monitor_header_addr = stack()->monitor_header_addr(monitor); | |
1918 | |
1919 // Store the object and mark the slot as live | |
1920 builder()->CreateStore(lockee, monitor_object_addr); | |
1921 set_num_monitors(monitor + 1); | |
1922 | |
1923 // Try a simple lock | |
1924 Value *mark_addr = builder()->CreateAddressOfStructEntry( | |
1925 lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()), | |
1926 PointerType::getUnqual(SharkType::intptr_type()), | |
1927 "mark_addr"); | |
1928 | |
1929 Value *mark = builder()->CreateLoad(mark_addr, "mark"); | |
1930 Value *disp = builder()->CreateOr( | |
1931 mark, LLVMValue::intptr_constant(markOopDesc::unlocked_value), "disp"); | |
1932 builder()->CreateStore(disp, monitor_header_addr); | |
1933 | |
1934 Value *lock = builder()->CreatePtrToInt( | |
1935 monitor_header_addr, SharkType::intptr_type()); | |
7195 | 1936 Value *check = builder()->CreateAtomicCmpXchg(mark_addr, disp, lock, llvm::Acquire); |
1692 | 1937 builder()->CreateCondBr( |
1938 builder()->CreateICmpEQ(disp, check), | |
1939 acquired_fast, try_recursive); | |
1940 | |
1941 // Locking failed, but maybe this thread already owns it | |
1942 builder()->SetInsertPoint(try_recursive); | |
1943 Value *addr = builder()->CreateAnd( | |
1944 disp, | |
1945 LLVMValue::intptr_constant(~markOopDesc::lock_mask_in_place)); | |
1946 | |
1947 // NB we use the entire stack, but JavaThread::is_lock_owned() | |
1948 // uses a more limited range. I don't think it hurts though... | |
1949 Value *stack_limit = builder()->CreateValueOfStructEntry( | |
1950 thread(), Thread::stack_base_offset(), | |
1951 SharkType::intptr_type(), | |
1952 "stack_limit"); | |
1953 | |
1954 assert(sizeof(size_t) == sizeof(intptr_t), "should be"); | |
1955 Value *stack_size = builder()->CreateValueOfStructEntry( | |
1956 thread(), Thread::stack_size_offset(), | |
1957 SharkType::intptr_type(), | |
1958 "stack_size"); | |
1959 | |
1960 Value *stack_start = | |
1961 builder()->CreateSub(stack_limit, stack_size, "stack_start"); | |
1962 | |
1963 builder()->CreateCondBr( | |
1964 builder()->CreateAnd( | |
1965 builder()->CreateICmpUGE(addr, stack_start), | |
1966 builder()->CreateICmpULT(addr, stack_limit)), | |
1967 got_recursive, not_recursive); | |
1968 | |
1969 builder()->SetInsertPoint(got_recursive); | |
1970 builder()->CreateStore(LLVMValue::intptr_constant(0), monitor_header_addr); | |
1971 builder()->CreateBr(acquired_fast); | |
1972 | |
1973 // Create an edge for the state merge | |
1974 builder()->SetInsertPoint(acquired_fast); | |
1975 SharkState *fast_state = current_state()->copy(); | |
1976 builder()->CreateBr(lock_acquired); | |
1977 | |
1978 // It's not a recursive case so we need to drop into the runtime | |
1979 builder()->SetInsertPoint(not_recursive); | |
1980 call_vm( | |
1981 builder()->monitorenter(), monitor_addr, | |
1982 exception_action | EAM_MONITOR_FUDGE); | |
1983 BasicBlock *acquired_slow = builder()->GetInsertBlock(); | |
1984 builder()->CreateBr(lock_acquired); | |
1985 | |
1986 // All done | |
1987 builder()->SetInsertPoint(lock_acquired); | |
1988 current_state()->merge(fast_state, acquired_fast, acquired_slow); | |
1989 } | |
1990 | |
1991 void SharkTopLevelBlock::release_lock(int exception_action) { | |
1992 BasicBlock *not_recursive = function()->CreateBlock("not_recursive"); | |
1993 BasicBlock *released_fast = function()->CreateBlock("released_fast"); | |
1994 BasicBlock *slow_path = function()->CreateBlock("slow_path"); | |
1995 BasicBlock *lock_released = function()->CreateBlock("lock_released"); | |
1996 | |
1997 int monitor = num_monitors() - 1; | |
1998 Value *monitor_addr = stack()->monitor_addr(monitor); | |
1999 Value *monitor_object_addr = stack()->monitor_object_addr(monitor); | |
2000 Value *monitor_header_addr = stack()->monitor_header_addr(monitor); | |
2001 | |
2002 // If it is recursive then we're already done | |
2003 Value *disp = builder()->CreateLoad(monitor_header_addr); | |
2004 builder()->CreateCondBr( | |
2005 builder()->CreateICmpEQ(disp, LLVMValue::intptr_constant(0)), | |
2006 released_fast, not_recursive); | |
2007 | |
2008 // Try a simple unlock | |
2009 builder()->SetInsertPoint(not_recursive); | |
2010 | |
2011 Value *lock = builder()->CreatePtrToInt( | |
2012 monitor_header_addr, SharkType::intptr_type()); | |
2013 | |
2014 Value *lockee = builder()->CreateLoad(monitor_object_addr); | |
2015 | |
2016 Value *mark_addr = builder()->CreateAddressOfStructEntry( | |
2017 lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()), | |
2018 PointerType::getUnqual(SharkType::intptr_type()), | |
2019 "mark_addr"); | |
2020 | |
7195 | 2021 Value *check = builder()->CreateAtomicCmpXchg(mark_addr, lock, disp, llvm::Release); |
1692 | 2022 builder()->CreateCondBr( |
2023 builder()->CreateICmpEQ(lock, check), | |
2024 released_fast, slow_path); | |
2025 | |
2026 // Create an edge for the state merge | |
2027 builder()->SetInsertPoint(released_fast); | |
2028 SharkState *fast_state = current_state()->copy(); | |
2029 builder()->CreateBr(lock_released); | |
2030 | |
2031 // Need to drop into the runtime to release this one | |
2032 builder()->SetInsertPoint(slow_path); | |
2033 call_vm(builder()->monitorexit(), monitor_addr, exception_action); | |
2034 BasicBlock *released_slow = builder()->GetInsertBlock(); | |
2035 builder()->CreateBr(lock_released); | |
2036 | |
2037 // All done | |
2038 builder()->SetInsertPoint(lock_released); | |
2039 current_state()->merge(fast_state, released_fast, released_slow); | |
2040 | |
2041 // The object slot is now dead | |
2042 set_num_monitors(monitor); | |
2043 } |