comparison src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp @ 1791:3a294e483abc

6919069: client compiler needs to capture more profile information for tiered work Summary: Added profiling of instanceof and aastore. Reviewed-by: kvn, jrose, never
author iveresov
date Mon, 13 Sep 2010 12:10:49 -0700
parents d5d065957597
children a3f7f95b0165
comparison
equal deleted inserted replaced
1790:7f9553bedfd5 1791:3a294e483abc
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 }