229 __ add(base_opr, array_opr, base_opr); |
229 __ add(base_opr, array_opr, base_opr); |
230 } else { |
230 } else { |
231 __ add(index_opr, array_opr, base_opr); |
231 __ add(index_opr, array_opr, base_opr); |
232 } |
232 } |
233 } |
233 } |
234 if (needs_card_mark) { |
234 |
235 LIR_Opr ptr = new_pointer_register(); |
235 return new LIR_Address(base_opr, offset, type); |
236 __ add(base_opr, LIR_OprFact::intptrConst(offset), ptr); |
|
237 return new LIR_Address(ptr, type); |
|
238 } else { |
|
239 return new LIR_Address(base_opr, offset, type); |
|
240 } |
|
241 } |
236 } |
242 |
237 |
243 LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { |
238 LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) { |
244 LIR_Opr r; |
239 LIR_Opr r; |
245 if (type == T_LONG) { |
240 if (type == T_LONG) { |
309 } else { |
304 } else { |
310 __ move(item, new LIR_Address(sp_opr, in_bytes(offset_from_sp), t)); |
305 __ move(item, new LIR_Address(sp_opr, in_bytes(offset_from_sp), t)); |
311 } |
306 } |
312 } |
307 } |
313 |
308 |
|
309 void LIRGenerator::array_store_check(LIR_Opr value, LIR_Opr array, CodeEmitInfo* store_check_info, ciMethod* profiled_method, int profiled_bci) { |
|
310 LIR_Opr tmp1 = FrameMap::G1_opr; |
|
311 LIR_Opr tmp2 = FrameMap::G3_opr; |
|
312 LIR_Opr tmp3 = FrameMap::G5_opr; |
|
313 __ store_check(value, array, tmp1, tmp2, tmp3, store_check_info, profiled_method, profiled_bci); |
|
314 } |
|
315 |
314 //---------------------------------------------------------------------- |
316 //---------------------------------------------------------------------- |
315 // visitor functions |
317 // visitor functions |
316 //---------------------------------------------------------------------- |
318 //---------------------------------------------------------------------- |
317 |
|
318 |
|
319 void LIRGenerator::do_StoreIndexed(StoreIndexed* x) { |
|
320 assert(x->is_pinned(),""); |
|
321 bool needs_range_check = x->compute_needs_range_check(); |
|
322 bool use_length = x->length() != NULL; |
|
323 bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT; |
|
324 bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL || |
|
325 !get_jobject_constant(x->value())->is_null_object() || |
|
326 x->should_profile()); |
|
327 |
|
328 LIRItem array(x->array(), this); |
|
329 LIRItem index(x->index(), this); |
|
330 LIRItem value(x->value(), this); |
|
331 LIRItem length(this); |
|
332 |
|
333 array.load_item(); |
|
334 index.load_nonconstant(); |
|
335 |
|
336 if (use_length && needs_range_check) { |
|
337 length.set_instruction(x->length()); |
|
338 length.load_item(); |
|
339 } |
|
340 if (needs_store_check || x->check_boolean()) { |
|
341 value.load_item(); |
|
342 } else { |
|
343 value.load_for_store(x->elt_type()); |
|
344 } |
|
345 |
|
346 set_no_result(x); |
|
347 |
|
348 // the CodeEmitInfo must be duplicated for each different |
|
349 // LIR-instruction because spilling can occur anywhere between two |
|
350 // instructions and so the debug information must be different |
|
351 CodeEmitInfo* range_check_info = state_for(x); |
|
352 CodeEmitInfo* null_check_info = NULL; |
|
353 if (x->needs_null_check()) { |
|
354 null_check_info = new CodeEmitInfo(range_check_info); |
|
355 } |
|
356 |
|
357 // emit array address setup early so it schedules better |
|
358 LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store); |
|
359 |
|
360 if (GenerateRangeChecks && needs_range_check) { |
|
361 if (use_length) { |
|
362 __ cmp(lir_cond_belowEqual, length.result(), index.result()); |
|
363 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); |
|
364 } else { |
|
365 array_range_check(array.result(), index.result(), null_check_info, range_check_info); |
|
366 // range_check also does the null check |
|
367 null_check_info = NULL; |
|
368 } |
|
369 } |
|
370 |
|
371 if (GenerateArrayStoreCheck && needs_store_check) { |
|
372 LIR_Opr tmp1 = FrameMap::G1_opr; |
|
373 LIR_Opr tmp2 = FrameMap::G3_opr; |
|
374 LIR_Opr tmp3 = FrameMap::G5_opr; |
|
375 |
|
376 CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info); |
|
377 __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci()); |
|
378 } |
|
379 |
|
380 if (obj_store) { |
|
381 // Needs GC write barriers. |
|
382 pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */, |
|
383 true /* do_load */, false /* patch */, NULL); |
|
384 } |
|
385 LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info); |
|
386 __ move(result, array_addr, null_check_info); |
|
387 if (obj_store) { |
|
388 // Precise card mark |
|
389 post_barrier(LIR_OprFact::address(array_addr), value.result()); |
|
390 } |
|
391 } |
|
392 |
|
393 |
319 |
394 void LIRGenerator::do_MonitorEnter(MonitorEnter* x) { |
320 void LIRGenerator::do_MonitorEnter(MonitorEnter* x) { |
395 assert(x->is_pinned(),""); |
321 assert(x->is_pinned(),""); |
396 LIRItem obj(x->obj(), this); |
322 LIRItem obj(x->obj(), this); |
397 obj.load_item(); |
323 obj.load_item(); |
633 } else { |
559 } else { |
634 Unimplemented(); |
560 Unimplemented(); |
635 } |
561 } |
636 } |
562 } |
637 |
563 |
638 |
564 LIR_Opr LIRGenerator::atomic_cmpxchg(BasicType type, LIR_Opr addr, LIRItem& cmp_value, LIRItem& new_value) { |
639 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { |
565 LIR_Opr result = new_register(T_INT); |
640 assert(x->number_of_arguments() == 4, "wrong type"); |
|
641 LIRItem obj (x->argument_at(0), this); // object |
|
642 LIRItem offset(x->argument_at(1), this); // offset of field |
|
643 LIRItem cmp (x->argument_at(2), this); // value to compare with field |
|
644 LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp |
|
645 |
|
646 // Use temps to avoid kills |
|
647 LIR_Opr t1 = FrameMap::G1_opr; |
566 LIR_Opr t1 = FrameMap::G1_opr; |
648 LIR_Opr t2 = FrameMap::G3_opr; |
567 LIR_Opr t2 = FrameMap::G3_opr; |
649 LIR_Opr addr = new_pointer_register(); |
568 cmp_value.load_item(); |
650 |
569 new_value.load_item(); |
651 // get address of field |
570 if (type == T_OBJECT || type == T_ARRAY) { |
652 obj.load_item(); |
571 __ cas_obj(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), t1, t2); |
653 offset.load_item(); |
572 } else if (type == T_INT) { |
654 cmp.load_item(); |
573 __ cas_int(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), t1, t2); |
655 val.load_item(); |
574 } else if (type == T_LONG) { |
656 |
575 __ cas_long(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), t1, t2); |
657 __ add(obj.result(), offset.result(), addr); |
576 } else { |
658 |
577 Unimplemented(); |
659 if (type == objectType) { // Write-barrier needed for Object fields. |
578 } |
660 pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */, |
|
661 true /* do_load */, false /* patch */, NULL); |
|
662 } |
|
663 |
|
664 if (type == objectType) |
|
665 __ cas_obj(addr, cmp.result(), val.result(), t1, t2); |
|
666 else if (type == intType) |
|
667 __ cas_int(addr, cmp.result(), val.result(), t1, t2); |
|
668 else if (type == longType) |
|
669 __ cas_long(addr, cmp.result(), val.result(), t1, t2); |
|
670 else { |
|
671 ShouldNotReachHere(); |
|
672 } |
|
673 // generate conditional move of boolean result |
|
674 LIR_Opr result = rlock_result(x); |
|
675 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), |
579 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), |
676 result, as_BasicType(type)); |
580 result, type); |
677 if (type == objectType) { // Write-barrier needed for Object fields. |
581 return result; |
678 // Precise card mark since could either be object or array |
582 } |
679 post_barrier(addr, val.result()); |
583 |
680 } |
584 LIR_Opr LIRGenerator::atomic_xchg(BasicType type, LIR_Opr addr, LIRItem& value) { |
681 } |
585 bool is_obj = type == T_OBJECT || type == T_ARRAY; |
682 |
586 LIR_Opr result = new_register(type); |
|
587 LIR_Opr tmp = LIR_OprFact::illegalOpr; |
|
588 |
|
589 value.load_item(); |
|
590 |
|
591 if (is_obj) { |
|
592 tmp = FrameMap::G3_opr; |
|
593 } |
|
594 |
|
595 // Because we want a 2-arg form of xchg |
|
596 __ move(value.result(), result); |
|
597 __ xchg(addr, result, result, tmp); |
|
598 return result; |
|
599 } |
|
600 |
|
601 LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) { |
|
602 Unimplemented(); |
|
603 return LIR_OprFact::illegalOpr; |
|
604 } |
683 |
605 |
684 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { |
606 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) { |
685 switch (x->id()) { |
607 switch (x->id()) { |
686 case vmIntrinsics::_dabs: |
608 case vmIntrinsics::_dabs: |
687 case vmIntrinsics::_dsqrt: { |
609 case vmIntrinsics::_dsqrt: { |
1336 |
1258 |
1337 void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result, |
1259 void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result, |
1338 CodeEmitInfo* info) { |
1260 CodeEmitInfo* info) { |
1339 __ load(address, result, info); |
1261 __ load(address, result, info); |
1340 } |
1262 } |
1341 |
|
1342 |
|
1343 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, |
|
1344 BasicType type, bool is_volatile) { |
|
1345 LIR_Opr base_op = src; |
|
1346 LIR_Opr index_op = offset; |
|
1347 |
|
1348 bool is_obj = (type == T_ARRAY || type == T_OBJECT); |
|
1349 { |
|
1350 if (type == T_BOOLEAN) { |
|
1351 type = T_BYTE; |
|
1352 } |
|
1353 LIR_Address* addr; |
|
1354 if (type == T_ARRAY || type == T_OBJECT) { |
|
1355 LIR_Opr tmp = new_pointer_register(); |
|
1356 __ add(base_op, index_op, tmp); |
|
1357 addr = new LIR_Address(tmp, type); |
|
1358 } else { |
|
1359 addr = new LIR_Address(base_op, index_op, type); |
|
1360 } |
|
1361 |
|
1362 if (is_obj) { |
|
1363 pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */, |
|
1364 true /* do_load */, false /* patch */, NULL); |
|
1365 // _bs->c1_write_barrier_pre(this, LIR_OprFact::address(addr)); |
|
1366 } |
|
1367 __ move(data, addr); |
|
1368 if (is_obj) { |
|
1369 // This address is precise |
|
1370 post_barrier(LIR_OprFact::address(addr), data); |
|
1371 } |
|
1372 } |
|
1373 } |
|
1374 |
|
1375 |
|
1376 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset, |
|
1377 BasicType type, bool is_volatile) { |
|
1378 { |
|
1379 LIR_Address* addr = new LIR_Address(src, offset, type); |
|
1380 __ load(addr, dst); |
|
1381 } |
|
1382 } |
|
1383 |
|
1384 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { |
|
1385 BasicType type = x->basic_type(); |
|
1386 LIRItem src(x->object(), this); |
|
1387 LIRItem off(x->offset(), this); |
|
1388 LIRItem value(x->value(), this); |
|
1389 |
|
1390 src.load_item(); |
|
1391 value.load_item(); |
|
1392 off.load_nonconstant(); |
|
1393 |
|
1394 LIR_Opr dst = rlock_result(x, type); |
|
1395 LIR_Opr data = value.result(); |
|
1396 bool is_obj = (type == T_ARRAY || type == T_OBJECT); |
|
1397 LIR_Opr offset = off.result(); |
|
1398 |
|
1399 // Because we want a 2-arg form of xchg |
|
1400 __ move(data, dst); |
|
1401 |
|
1402 assert (!x->is_add() && (type == T_INT || (is_obj && UseCompressedOops)), "unexpected type"); |
|
1403 LIR_Address* addr; |
|
1404 if (offset->is_constant()) { |
|
1405 |
|
1406 jlong l = offset->as_jlong(); |
|
1407 assert((jlong)((jint)l) == l, "offset too large for constant"); |
|
1408 jint c = (jint)l; |
|
1409 addr = new LIR_Address(src.result(), c, type); |
|
1410 } else { |
|
1411 addr = new LIR_Address(src.result(), offset, type); |
|
1412 } |
|
1413 |
|
1414 LIR_Opr tmp = LIR_OprFact::illegalOpr; |
|
1415 LIR_Opr ptr = LIR_OprFact::illegalOpr; |
|
1416 |
|
1417 if (is_obj) { |
|
1418 // Do the pre-write barrier, if any. |
|
1419 // barriers on sparc don't work with a base + index address |
|
1420 tmp = FrameMap::G3_opr; |
|
1421 ptr = new_pointer_register(); |
|
1422 __ add(src.result(), off.result(), ptr); |
|
1423 pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */, |
|
1424 true /* do_load */, false /* patch */, NULL); |
|
1425 } |
|
1426 __ xchg(LIR_OprFact::address(addr), dst, dst, tmp); |
|
1427 if (is_obj) { |
|
1428 // Seems to be a precise address |
|
1429 post_barrier(ptr, data); |
|
1430 } |
|
1431 } |
|