2492 ciProfileData* data; |
2509 ciProfileData* data; |
2493 int mdo_offset_bias = 0; |
2510 int mdo_offset_bias = 0; |
2494 if (op->should_profile()) { |
2511 if (op->should_profile()) { |
2495 ciMethod* method = op->profiled_method(); |
2512 ciMethod* method = op->profiled_method(); |
2496 assert(method != NULL, "Should have method"); |
2513 assert(method != NULL, "Should have method"); |
2497 int bci = op->profiled_bci(); |
2514 setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias); |
2498 md = method->method_data(); |
2515 |
2499 if (md == NULL) { |
2516 Label not_null; |
2500 bailout("out of memory building methodDataOop"); |
2517 __ br_notnull(obj, false, Assembler::pn, not_null); |
2501 return; |
|
2502 } |
|
2503 data = md->bci_to_data(bci); |
|
2504 assert(data != NULL, "need data for checkcast"); |
|
2505 assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for checkcast"); |
|
2506 if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) { |
|
2507 // The offset is large so bias the mdo by the base of the slot so |
|
2508 // that the ld can use simm13s to reference the slots of the data |
|
2509 mdo_offset_bias = md->byte_offset_of_slot(data, DataLayout::header_offset()); |
|
2510 } |
|
2511 |
|
2512 // We need two temporaries to perform this operation on SPARC, |
|
2513 // so to keep things simple we perform a redundant test here |
|
2514 Label profile_done; |
|
2515 __ br_notnull(obj, false, Assembler::pn, profile_done); |
|
2516 __ delayed()->nop(); |
2518 __ delayed()->nop(); |
2517 Register mdo = k_RInfo; |
2519 Register mdo = k_RInfo; |
2518 Register data_val = Rtmp1; |
2520 Register data_val = Rtmp1; |
2519 jobject2reg(md->constant_encoding(), mdo); |
2521 jobject2reg(md->constant_encoding(), mdo); |
2520 if (mdo_offset_bias > 0) { |
2522 if (mdo_offset_bias > 0) { |
2523 } |
2525 } |
2524 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); |
2526 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); |
2525 __ ldub(flags_addr, data_val); |
2527 __ ldub(flags_addr, data_val); |
2526 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); |
2528 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); |
2527 __ stb(data_val, flags_addr); |
2529 __ stb(data_val, flags_addr); |
2528 __ bind(profile_done); |
2530 __ ba(false, *obj_is_null); |
2529 } |
2531 __ delayed()->nop(); |
2530 Label profile_cast_failure; |
2532 __ bind(not_null); |
2531 |
2533 } else { |
2532 Label done, done_null; |
2534 __ br_null(obj, false, Assembler::pn, *obj_is_null); |
2533 // Where to go in case of cast failure |
2535 __ delayed()->nop(); |
2534 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); |
2536 } |
|
2537 |
|
2538 Label profile_cast_failure, profile_cast_success; |
|
2539 Label *failure_target = op->should_profile() ? &profile_cast_failure : failure; |
|
2540 Label *success_target = op->should_profile() ? &profile_cast_success : success; |
2535 |
2541 |
2536 // patching may screw with our temporaries on sparc, |
2542 // patching may screw with our temporaries on sparc, |
2537 // so let's do it before loading the class |
2543 // so let's do it before loading the class |
2538 if (k->is_loaded()) { |
2544 if (k->is_loaded()) { |
2539 jobject2reg(k->constant_encoding(), k_RInfo); |
2545 jobject2reg(k->constant_encoding(), k_RInfo); |
2540 } else { |
2546 } else { |
2541 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); |
2547 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); |
2542 } |
2548 } |
2543 assert(obj != k_RInfo, "must be different"); |
2549 assert(obj != k_RInfo, "must be different"); |
2544 __ br_null(obj, false, Assembler::pn, done_null); |
|
2545 __ delayed()->nop(); |
|
2546 |
2550 |
2547 // get object class |
2551 // get object class |
2548 // not a safepoint as obj null check happens earlier |
2552 // not a safepoint as obj null check happens earlier |
2549 load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); |
2553 load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); |
2550 if (op->fast_check()) { |
2554 if (op->fast_check()) { |
2557 if (k->is_loaded()) { |
2561 if (k->is_loaded()) { |
2558 if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()) |
2562 if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()) |
2559 need_slow_path = false; |
2563 need_slow_path = false; |
2560 // perform the fast part of the checking logic |
2564 // perform the fast part of the checking logic |
2561 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg, |
2565 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg, |
2562 (need_slow_path ? &done : NULL), |
2566 (need_slow_path ? success_target : NULL), |
2563 failure_target, NULL, |
2567 failure_target, NULL, |
2564 RegisterOrConstant(k->super_check_offset())); |
2568 RegisterOrConstant(k->super_check_offset())); |
2565 } else { |
2569 } else { |
2566 // perform the fast part of the checking logic |
2570 // perform the fast part of the checking logic |
2567 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, &done, |
2571 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, |
2568 failure_target, NULL); |
2572 failure_target, NULL); |
2569 } |
2573 } |
2570 if (need_slow_path) { |
2574 if (need_slow_path) { |
2571 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
2575 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
2572 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
2576 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
2573 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2577 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2574 __ delayed()->nop(); |
2578 __ delayed()->nop(); |
2575 __ cmp(G3, 0); |
2579 __ cmp(G3, 0); |
2576 __ br(Assembler::equal, false, Assembler::pn, *failure_target); |
2580 __ br(Assembler::equal, false, Assembler::pn, *failure_target); |
2577 __ delayed()->nop(); |
2581 __ delayed()->nop(); |
2578 } |
2582 // Fall through to success case |
2579 } |
2583 } |
2580 __ bind(done); |
2584 } |
2581 |
2585 |
2582 if (op->should_profile()) { |
2586 if (op->should_profile()) { |
2583 Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1; |
2587 Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1; |
2584 assert_different_registers(obj, mdo, recv, tmp1); |
2588 assert_different_registers(obj, mdo, recv, tmp1); |
2585 |
2589 __ bind(profile_cast_success); |
2586 jobject2reg(md->constant_encoding(), mdo); |
2590 jobject2reg(md->constant_encoding(), mdo); |
2587 if (mdo_offset_bias > 0) { |
2591 if (mdo_offset_bias > 0) { |
2588 __ set(mdo_offset_bias, tmp1); |
2592 __ set(mdo_offset_bias, tmp1); |
2589 __ add(mdo, tmp1, mdo); |
2593 __ add(mdo, tmp1, mdo); |
2590 } |
2594 } |
2591 Label update_done; |
|
2592 load(Address(obj, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); |
2595 load(Address(obj, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); |
2593 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done); |
2596 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success); |
2594 // Jump over the failure case |
2597 // Jump over the failure case |
2595 __ ba(false, update_done); |
2598 __ ba(false, *success); |
2596 __ delayed()->nop(); |
2599 __ delayed()->nop(); |
2597 |
|
2598 |
|
2599 // Cast failure case |
2600 // Cast failure case |
2600 __ bind(profile_cast_failure); |
2601 __ bind(profile_cast_failure); |
2601 jobject2reg(md->constant_encoding(), mdo); |
2602 jobject2reg(md->constant_encoding(), mdo); |
2602 if (mdo_offset_bias > 0) { |
2603 if (mdo_offset_bias > 0) { |
2603 __ set(mdo_offset_bias, tmp1); |
2604 __ set(mdo_offset_bias, tmp1); |
2626 Register k_RInfo = op->tmp1()->as_register(); |
2623 Register k_RInfo = op->tmp1()->as_register(); |
2627 Register klass_RInfo = op->tmp2()->as_register(); |
2624 Register klass_RInfo = op->tmp2()->as_register(); |
2628 Register Rtmp1 = op->tmp3()->as_register(); |
2625 Register Rtmp1 = op->tmp3()->as_register(); |
2629 |
2626 |
2630 __ verify_oop(value); |
2627 __ verify_oop(value); |
2631 |
|
2632 CodeStub* stub = op->stub(); |
2628 CodeStub* stub = op->stub(); |
2633 Label done; |
2629 // check if it needs to be profiled |
2634 __ br_null(value, false, Assembler::pn, done); |
2630 ciMethodData* md; |
2635 __ delayed()->nop(); |
2631 ciProfileData* data; |
|
2632 int mdo_offset_bias = 0; |
|
2633 if (op->should_profile()) { |
|
2634 ciMethod* method = op->profiled_method(); |
|
2635 assert(method != NULL, "Should have method"); |
|
2636 setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias); |
|
2637 } |
|
2638 Label profile_cast_success, profile_cast_failure, done; |
|
2639 Label *success_target = op->should_profile() ? &profile_cast_success : &done; |
|
2640 Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); |
|
2641 |
|
2642 if (op->should_profile()) { |
|
2643 Label not_null; |
|
2644 __ br_notnull(value, false, Assembler::pn, not_null); |
|
2645 __ delayed()->nop(); |
|
2646 Register mdo = k_RInfo; |
|
2647 Register data_val = Rtmp1; |
|
2648 jobject2reg(md->constant_encoding(), mdo); |
|
2649 if (mdo_offset_bias > 0) { |
|
2650 __ set(mdo_offset_bias, data_val); |
|
2651 __ add(mdo, data_val, mdo); |
|
2652 } |
|
2653 Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias); |
|
2654 __ ldub(flags_addr, data_val); |
|
2655 __ or3(data_val, BitData::null_seen_byte_constant(), data_val); |
|
2656 __ stb(data_val, flags_addr); |
|
2657 __ ba(false, done); |
|
2658 __ delayed()->nop(); |
|
2659 __ bind(not_null); |
|
2660 } else { |
|
2661 __ br_null(value, false, Assembler::pn, done); |
|
2662 __ delayed()->nop(); |
|
2663 } |
2636 load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception()); |
2664 load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception()); |
2637 load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); |
2665 load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); |
2638 |
2666 |
2639 // get instance klass |
2667 // get instance klass |
2640 load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL); |
2668 load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL); |
2641 // perform the fast part of the checking logic |
2669 // perform the fast part of the checking logic |
2642 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, &done, stub->entry(), NULL); |
2670 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL); |
2643 |
2671 |
2644 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
2672 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
2645 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
2673 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
2646 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2674 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
2647 __ delayed()->nop(); |
2675 __ delayed()->nop(); |
2648 __ cmp(G3, 0); |
2676 __ cmp(G3, 0); |
2649 __ br(Assembler::equal, false, Assembler::pn, *stub->entry()); |
2677 __ br(Assembler::equal, false, Assembler::pn, *failure_target); |
2650 __ delayed()->nop(); |
2678 __ delayed()->nop(); |
|
2679 // fall through to the success case |
|
2680 |
|
2681 if (op->should_profile()) { |
|
2682 Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1; |
|
2683 assert_different_registers(value, mdo, recv, tmp1); |
|
2684 __ bind(profile_cast_success); |
|
2685 jobject2reg(md->constant_encoding(), mdo); |
|
2686 if (mdo_offset_bias > 0) { |
|
2687 __ set(mdo_offset_bias, tmp1); |
|
2688 __ add(mdo, tmp1, mdo); |
|
2689 } |
|
2690 load(Address(value, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT); |
|
2691 type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done); |
|
2692 __ ba(false, done); |
|
2693 __ delayed()->nop(); |
|
2694 // Cast failure case |
|
2695 __ bind(profile_cast_failure); |
|
2696 jobject2reg(md->constant_encoding(), mdo); |
|
2697 if (mdo_offset_bias > 0) { |
|
2698 __ set(mdo_offset_bias, tmp1); |
|
2699 __ add(mdo, tmp1, mdo); |
|
2700 } |
|
2701 Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias); |
|
2702 __ ld_ptr(data_addr, tmp1); |
|
2703 __ sub(tmp1, DataLayout::counter_increment, tmp1); |
|
2704 __ st_ptr(tmp1, data_addr); |
|
2705 __ ba(false, *stub->entry()); |
|
2706 __ delayed()->nop(); |
|
2707 } |
2651 __ bind(done); |
2708 __ bind(done); |
|
2709 } else if (code == lir_checkcast) { |
|
2710 Register obj = op->object()->as_register(); |
|
2711 Register dst = op->result_opr()->as_register(); |
|
2712 Label success; |
|
2713 emit_typecheck_helper(op, &success, op->stub()->entry(), &success); |
|
2714 __ bind(success); |
|
2715 __ mov(obj, dst); |
2652 } else if (code == lir_instanceof) { |
2716 } else if (code == lir_instanceof) { |
2653 Register obj = op->object()->as_register(); |
2717 Register obj = op->object()->as_register(); |
2654 Register k_RInfo = op->tmp1()->as_register(); |
|
2655 Register klass_RInfo = op->tmp2()->as_register(); |
|
2656 Register dst = op->result_opr()->as_register(); |
2718 Register dst = op->result_opr()->as_register(); |
2657 Register Rtmp1 = op->tmp3()->as_register(); |
2719 Label success, failure, done; |
2658 ciKlass* k = op->klass(); |
2720 emit_typecheck_helper(op, &success, &failure, &failure); |
2659 |
2721 __ bind(failure); |
2660 Label done; |
2722 __ set(0, dst); |
2661 if (obj == k_RInfo) { |
2723 __ ba(false, done); |
2662 k_RInfo = klass_RInfo; |
2724 __ delayed()->nop(); |
2663 klass_RInfo = obj; |
2725 __ bind(success); |
2664 } |
2726 __ set(1, dst); |
2665 // patching may screw with our temporaries on sparc, |
2727 __ bind(done); |
2666 // so let's do it before loading the class |
|
2667 if (k->is_loaded()) { |
|
2668 jobject2reg(k->constant_encoding(), k_RInfo); |
|
2669 } else { |
|
2670 jobject2reg_with_patching(k_RInfo, op->info_for_patch()); |
|
2671 } |
|
2672 assert(obj != k_RInfo, "must be different"); |
|
2673 __ br_null(obj, true, Assembler::pn, done); |
|
2674 __ delayed()->set(0, dst); |
|
2675 |
|
2676 // get object class |
|
2677 // not a safepoint as obj null check happens earlier |
|
2678 load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL); |
|
2679 if (op->fast_check()) { |
|
2680 __ cmp(k_RInfo, klass_RInfo); |
|
2681 __ brx(Assembler::equal, true, Assembler::pt, done); |
|
2682 __ delayed()->set(1, dst); |
|
2683 __ set(0, dst); |
|
2684 __ bind(done); |
|
2685 } else { |
|
2686 bool need_slow_path = true; |
|
2687 if (k->is_loaded()) { |
|
2688 if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()) |
|
2689 need_slow_path = false; |
|
2690 // perform the fast part of the checking logic |
|
2691 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, noreg, |
|
2692 (need_slow_path ? &done : NULL), |
|
2693 (need_slow_path ? &done : NULL), NULL, |
|
2694 RegisterOrConstant(k->super_check_offset()), |
|
2695 dst); |
|
2696 } else { |
|
2697 assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers"); |
|
2698 // perform the fast part of the checking logic |
|
2699 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, dst, |
|
2700 &done, &done, NULL, |
|
2701 RegisterOrConstant(-1), |
|
2702 dst); |
|
2703 } |
|
2704 if (need_slow_path) { |
|
2705 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
|
2706 assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup"); |
|
2707 __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); |
|
2708 __ delayed()->nop(); |
|
2709 __ mov(G3, dst); |
|
2710 } |
|
2711 __ bind(done); |
|
2712 } |
|
2713 } else { |
2728 } else { |
2714 ShouldNotReachHere(); |
2729 ShouldNotReachHere(); |
2715 } |
2730 } |
2716 |
2731 |
2717 } |
2732 } |