hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
changeset 6461 cfc616b49f58
parent 6453 970dc585ab63
child 6756 01ac7b1701eb
equal deleted inserted replaced
6460:6f5143b00f4c 6461:cfc616b49f58
  2469     __ delayed()->nop();
  2469     __ delayed()->nop();
  2470     __ bind(next_test);
  2470     __ bind(next_test);
  2471   }
  2471   }
  2472 }
  2472 }
  2473 
  2473 
  2474 void LIR_Assembler::emit_checkcast(LIR_OpTypeCheck *op) {
  2474 
  2475   assert(op->code() == lir_checkcast, "Invalid operation");
  2475 void LIR_Assembler::setup_md_access(ciMethod* method, int bci,
       
  2476                                     ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias) {
       
  2477   md = method->method_data();
       
  2478   if (md == NULL) {
       
  2479     bailout("out of memory building methodDataOop");
       
  2480     return;
       
  2481   }
       
  2482   data = md->bci_to_data(bci);
       
  2483   assert(data != NULL,       "need data for checkcast");
       
  2484   assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
       
  2485   if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) {
       
  2486     // The offset is large so bias the mdo by the base of the slot so
       
  2487     // that the ld can use simm13s to reference the slots of the data
       
  2488     mdo_offset_bias = md->byte_offset_of_slot(data, DataLayout::header_offset());
       
  2489   }
       
  2490 }
       
  2491 
       
  2492 void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
  2476   // we always need a stub for the failure case.
  2493   // we always need a stub for the failure case.
  2477   CodeStub* stub = op->stub();
  2494   CodeStub* stub = op->stub();
  2478   Register obj = op->object()->as_register();
  2495   Register obj = op->object()->as_register();
  2479   Register k_RInfo = op->tmp1()->as_register();
  2496   Register k_RInfo = op->tmp1()->as_register();
  2480   Register klass_RInfo = op->tmp2()->as_register();
  2497   Register klass_RInfo = op->tmp2()->as_register();
  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);
  2605     }
  2606     }
  2606     Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
  2607     Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
  2607     __ ld_ptr(data_addr, tmp1);
  2608     __ ld_ptr(data_addr, tmp1);
  2608     __ sub(tmp1, DataLayout::counter_increment, tmp1);
  2609     __ sub(tmp1, DataLayout::counter_increment, tmp1);
  2609     __ st_ptr(tmp1, data_addr);
  2610     __ st_ptr(tmp1, data_addr);
  2610     __ ba(false, *stub->entry());
  2611     __ ba(false, *failure);
  2611     __ delayed()->nop();
  2612     __ delayed()->nop();
  2612 
  2613   }
  2613     __ bind(update_done);
  2614   __ ba(false, *success);
  2614   }
  2615   __ delayed()->nop();
  2615 
  2616 }
  2616   __ bind(done_null);
       
  2617   __ mov(obj, dst);
       
  2618 }
       
  2619 
       
  2620 
  2617 
  2621 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
  2618 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
  2622   LIR_Code code = op->code();
  2619   LIR_Code code = op->code();
  2623   if (code == lir_store_check) {
  2620   if (code == lir_store_check) {
  2624     Register value = op->object()->as_register();
  2621     Register value = op->object()->as_register();
  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 }