comparison src/cpu/sparc/vm/sharedRuntime_sparc.cpp @ 116:018d5b58dd4f

6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes Summary: Initial checkin of JSDT code Reviewed-by: acorn, sbohne
author kamg
date Thu, 17 Apr 2008 22:18:15 -0400
parents ba764ed4b6f2
children 437d03ea40b1 6b648fefb395 37f87013dfd8
comparison
equal deleted inserted replaced
115:e7a91a357527 116:018d5b58dd4f
1635 split_long_move(masm, split, dst); 1635 split_long_move(masm, split, dst);
1636 } 1636 }
1637 } 1637 }
1638 } else if (dst.is_single_phys_reg()) { 1638 } else if (dst.is_single_phys_reg()) {
1639 if (src.is_adjacent_aligned_on_stack(2)) { 1639 if (src.is_adjacent_aligned_on_stack(2)) {
1640 __ ldd(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register()); 1640 __ ld_long(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register());
1641 } else { 1641 } else {
1642 // dst is a single reg. 1642 // dst is a single reg.
1643 // Remember lo is low address not msb for stack slots 1643 // Remember lo is low address not msb for stack slots
1644 // and lo is the "real" register for registers 1644 // and lo is the "real" register for registers
1645 // src is 1645 // src is
2499 oop_maps); 2499 oop_maps);
2500 return nm; 2500 return nm;
2501 2501
2502 } 2502 }
2503 2503
2504 #ifdef HAVE_DTRACE_H
2505 // ---------------------------------------------------------------------------
2506 // Generate a dtrace nmethod for a given signature. The method takes arguments
2507 // in the Java compiled code convention, marshals them to the native
2508 // abi and then leaves nops at the position you would expect to call a native
2509 // function. When the probe is enabled the nops are replaced with a trap
2510 // instruction that dtrace inserts and the trace will cause a notification
2511 // to dtrace.
2512 //
2513 // The probes are only able to take primitive types and java/lang/String as
2514 // arguments. No other java types are allowed. Strings are converted to utf8
2515 // strings so that from dtrace point of view java strings are converted to C
2516 // strings. There is an arbitrary fixed limit on the total space that a method
2517 // can use for converting the strings. (256 chars per string in the signature).
2518 // So any java string larger then this is truncated.
2519
2520 static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 };
2521 static bool offsets_initialized = false;
2522
2523 static VMRegPair reg64_to_VMRegPair(Register r) {
2524 VMRegPair ret;
2525 if (wordSize == 8) {
2526 ret.set2(r->as_VMReg());
2527 } else {
2528 ret.set_pair(r->successor()->as_VMReg(), r->as_VMReg());
2529 }
2530 return ret;
2531 }
2532
2533
2534 nmethod *SharedRuntime::generate_dtrace_nmethod(
2535 MacroAssembler *masm, methodHandle method) {
2536
2537
2538 // generate_dtrace_nmethod is guarded by a mutex so we are sure to
2539 // be single threaded in this method.
2540 assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be");
2541
2542 // Fill in the signature array, for the calling-convention call.
2543 int total_args_passed = method->size_of_parameters();
2544
2545 BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
2546 VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
2547
2548 // The signature we are going to use for the trap that dtrace will see
2549 // java/lang/String is converted. We drop "this" and any other object
2550 // is converted to NULL. (A one-slot java/lang/Long object reference
2551 // is converted to a two-slot long, which is why we double the allocation).
2552 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2);
2553 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2);
2554
2555 int i=0;
2556 int total_strings = 0;
2557 int first_arg_to_pass = 0;
2558 int total_c_args = 0;
2559 int box_offset = java_lang_boxing_object::value_offset_in_bytes();
2560
2561 // Skip the receiver as dtrace doesn't want to see it
2562 if( !method->is_static() ) {
2563 in_sig_bt[i++] = T_OBJECT;
2564 first_arg_to_pass = 1;
2565 }
2566
2567 SignatureStream ss(method->signature());
2568 for ( ; !ss.at_return_type(); ss.next()) {
2569 BasicType bt = ss.type();
2570 in_sig_bt[i++] = bt; // Collect remaining bits of signature
2571 out_sig_bt[total_c_args++] = bt;
2572 if( bt == T_OBJECT) {
2573 symbolOop s = ss.as_symbol_or_null();
2574 if (s == vmSymbols::java_lang_String()) {
2575 total_strings++;
2576 out_sig_bt[total_c_args-1] = T_ADDRESS;
2577 } else if (s == vmSymbols::java_lang_Boolean() ||
2578 s == vmSymbols::java_lang_Byte()) {
2579 out_sig_bt[total_c_args-1] = T_BYTE;
2580 } else if (s == vmSymbols::java_lang_Character() ||
2581 s == vmSymbols::java_lang_Short()) {
2582 out_sig_bt[total_c_args-1] = T_SHORT;
2583 } else if (s == vmSymbols::java_lang_Integer() ||
2584 s == vmSymbols::java_lang_Float()) {
2585 out_sig_bt[total_c_args-1] = T_INT;
2586 } else if (s == vmSymbols::java_lang_Long() ||
2587 s == vmSymbols::java_lang_Double()) {
2588 out_sig_bt[total_c_args-1] = T_LONG;
2589 out_sig_bt[total_c_args++] = T_VOID;
2590 }
2591 } else if ( bt == T_LONG || bt == T_DOUBLE ) {
2592 in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots
2593 // We convert double to long
2594 out_sig_bt[total_c_args-1] = T_LONG;
2595 out_sig_bt[total_c_args++] = T_VOID;
2596 } else if ( bt == T_FLOAT) {
2597 // We convert float to int
2598 out_sig_bt[total_c_args-1] = T_INT;
2599 }
2600 }
2601
2602 assert(i==total_args_passed, "validly parsed signature");
2603
2604 // Now get the compiled-Java layout as input arguments
2605 int comp_args_on_stack;
2606 comp_args_on_stack = SharedRuntime::java_calling_convention(
2607 in_sig_bt, in_regs, total_args_passed, false);
2608
2609 // We have received a description of where all the java arg are located
2610 // on entry to the wrapper. We need to convert these args to where
2611 // the a native (non-jni) function would expect them. To figure out
2612 // where they go we convert the java signature to a C signature and remove
2613 // T_VOID for any long/double we might have received.
2614
2615
2616 // Now figure out where the args must be stored and how much stack space
2617 // they require (neglecting out_preserve_stack_slots but space for storing
2618 // the 1st six register arguments). It's weird see int_stk_helper.
2619 //
2620 int out_arg_slots;
2621 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args);
2622
2623 // Calculate the total number of stack slots we will need.
2624
2625 // First count the abi requirement plus all of the outgoing args
2626 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots;
2627
2628 // Plus a temp for possible converion of float/double/long register args
2629
2630 int conversion_temp = stack_slots;
2631 stack_slots += 2;
2632
2633
2634 // Now space for the string(s) we must convert
2635
2636 int string_locs = stack_slots;
2637 stack_slots += total_strings *
2638 (max_dtrace_string_size / VMRegImpl::stack_slot_size);
2639
2640 // Ok The space we have allocated will look like:
2641 //
2642 //
2643 // FP-> | |
2644 // |---------------------|
2645 // | string[n] |
2646 // |---------------------| <- string_locs[n]
2647 // | string[n-1] |
2648 // |---------------------| <- string_locs[n-1]
2649 // | ... |
2650 // | ... |
2651 // |---------------------| <- string_locs[1]
2652 // | string[0] |
2653 // |---------------------| <- string_locs[0]
2654 // | temp |
2655 // |---------------------| <- conversion_temp
2656 // | outbound memory |
2657 // | based arguments |
2658 // | |
2659 // |---------------------|
2660 // | |
2661 // SP-> | out_preserved_slots |
2662 //
2663 //
2664
2665 // Now compute actual number of stack words we need rounding to make
2666 // stack properly aligned.
2667 stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word);
2668
2669 int stack_size = stack_slots * VMRegImpl::stack_slot_size;
2670
2671 intptr_t start = (intptr_t)__ pc();
2672
2673 // First thing make an ic check to see if we should even be here
2674
2675 {
2676 Label L;
2677 const Register temp_reg = G3_scratch;
2678 Address ic_miss(temp_reg, SharedRuntime::get_ic_miss_stub());
2679 __ verify_oop(O0);
2680 __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
2681 __ cmp(temp_reg, G5_inline_cache_reg);
2682 __ brx(Assembler::equal, true, Assembler::pt, L);
2683 __ delayed()->nop();
2684
2685 __ jump_to(ic_miss, 0);
2686 __ delayed()->nop();
2687 __ align(CodeEntryAlignment);
2688 __ bind(L);
2689 }
2690
2691 int vep_offset = ((intptr_t)__ pc()) - start;
2692
2693
2694 // The instruction at the verified entry point must be 5 bytes or longer
2695 // because it can be patched on the fly by make_non_entrant. The stack bang
2696 // instruction fits that requirement.
2697
2698 // Generate stack overflow check before creating frame
2699 __ generate_stack_overflow_check(stack_size);
2700
2701 assert(((intptr_t)__ pc() - start - vep_offset) >= 5,
2702 "valid size for make_non_entrant");
2703
2704 // Generate a new frame for the wrapper.
2705 __ save(SP, -stack_size, SP);
2706
2707 // Frame is now completed as far a size and linkage.
2708
2709 int frame_complete = ((intptr_t)__ pc()) - start;
2710
2711 #ifdef ASSERT
2712 bool reg_destroyed[RegisterImpl::number_of_registers];
2713 bool freg_destroyed[FloatRegisterImpl::number_of_registers];
2714 for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) {
2715 reg_destroyed[r] = false;
2716 }
2717 for ( int f = 0 ; f < FloatRegisterImpl::number_of_registers ; f++ ) {
2718 freg_destroyed[f] = false;
2719 }
2720
2721 #endif /* ASSERT */
2722
2723 VMRegPair zero;
2724 zero.set2(G0->as_VMReg());
2725
2726 int c_arg, j_arg;
2727
2728 Register conversion_off = noreg;
2729
2730 for (j_arg = first_arg_to_pass, c_arg = 0 ;
2731 j_arg < total_args_passed ; j_arg++, c_arg++ ) {
2732
2733 VMRegPair src = in_regs[j_arg];
2734 VMRegPair dst = out_regs[c_arg];
2735
2736 #ifdef ASSERT
2737 if (src.first()->is_Register()) {
2738 assert(!reg_destroyed[src.first()->as_Register()->encoding()], "ack!");
2739 } else if (src.first()->is_FloatRegister()) {
2740 assert(!freg_destroyed[src.first()->as_FloatRegister()->encoding(
2741 FloatRegisterImpl::S)], "ack!");
2742 }
2743 if (dst.first()->is_Register()) {
2744 reg_destroyed[dst.first()->as_Register()->encoding()] = true;
2745 } else if (dst.first()->is_FloatRegister()) {
2746 freg_destroyed[dst.first()->as_FloatRegister()->encoding(
2747 FloatRegisterImpl::S)] = true;
2748 }
2749 #endif /* ASSERT */
2750
2751 switch (in_sig_bt[j_arg]) {
2752 case T_ARRAY:
2753 case T_OBJECT:
2754 {
2755 if (out_sig_bt[c_arg] == T_BYTE || out_sig_bt[c_arg] == T_SHORT ||
2756 out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) {
2757 // need to unbox a one-slot value
2758 Register in_reg = L0;
2759 Register tmp = L2;
2760 if ( src.first()->is_reg() ) {
2761 in_reg = src.first()->as_Register();
2762 } else {
2763 assert(Assembler::is_simm13(reg2offset(src.first()) + STACK_BIAS),
2764 "must be");
2765 __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, in_reg);
2766 }
2767 // If the final destination is an acceptable register
2768 if ( dst.first()->is_reg() ) {
2769 if ( dst.is_single_phys_reg() || out_sig_bt[c_arg] != T_LONG ) {
2770 tmp = dst.first()->as_Register();
2771 }
2772 }
2773
2774 Label skipUnbox;
2775 if ( wordSize == 4 && out_sig_bt[c_arg] == T_LONG ) {
2776 __ mov(G0, tmp->successor());
2777 }
2778 __ br_null(in_reg, true, Assembler::pn, skipUnbox);
2779 __ delayed()->mov(G0, tmp);
2780
2781 switch (out_sig_bt[c_arg]) {
2782 case T_BYTE:
2783 __ ldub(in_reg, box_offset, tmp); break;
2784 case T_SHORT:
2785 __ lduh(in_reg, box_offset, tmp); break;
2786 case T_INT:
2787 __ ld(in_reg, box_offset, tmp); break;
2788 case T_LONG:
2789 __ ld_long(in_reg, box_offset, tmp); break;
2790 default: ShouldNotReachHere();
2791 }
2792
2793 __ bind(skipUnbox);
2794 // If tmp wasn't final destination copy to final destination
2795 if (tmp == L2) {
2796 VMRegPair tmp_as_VM = reg64_to_VMRegPair(L2);
2797 if (out_sig_bt[c_arg] == T_LONG) {
2798 long_move(masm, tmp_as_VM, dst);
2799 } else {
2800 move32_64(masm, tmp_as_VM, out_regs[c_arg]);
2801 }
2802 }
2803 if (out_sig_bt[c_arg] == T_LONG) {
2804 assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
2805 ++c_arg; // move over the T_VOID to keep the loop indices in sync
2806 }
2807 } else if (out_sig_bt[c_arg] == T_ADDRESS) {
2808 Register s =
2809 src.first()->is_reg() ? src.first()->as_Register() : L2;
2810 Register d =
2811 dst.first()->is_reg() ? dst.first()->as_Register() : L2;
2812
2813 // We store the oop now so that the conversion pass can reach
2814 // while in the inner frame. This will be the only store if
2815 // the oop is NULL.
2816 if (s != L2) {
2817 // src is register
2818 if (d != L2) {
2819 // dst is register
2820 __ mov(s, d);
2821 } else {
2822 assert(Assembler::is_simm13(reg2offset(dst.first()) +
2823 STACK_BIAS), "must be");
2824 __ st_ptr(s, SP, reg2offset(dst.first()) + STACK_BIAS);
2825 }
2826 } else {
2827 // src not a register
2828 assert(Assembler::is_simm13(reg2offset(src.first()) +
2829 STACK_BIAS), "must be");
2830 __ ld_ptr(FP, reg2offset(src.first()) + STACK_BIAS, d);
2831 if (d == L2) {
2832 assert(Assembler::is_simm13(reg2offset(dst.first()) +
2833 STACK_BIAS), "must be");
2834 __ st_ptr(d, SP, reg2offset(dst.first()) + STACK_BIAS);
2835 }
2836 }
2837 } else if (out_sig_bt[c_arg] != T_VOID) {
2838 // Convert the arg to NULL
2839 if (dst.first()->is_reg()) {
2840 __ mov(G0, dst.first()->as_Register());
2841 } else {
2842 assert(Assembler::is_simm13(reg2offset(dst.first()) +
2843 STACK_BIAS), "must be");
2844 __ st_ptr(G0, SP, reg2offset(dst.first()) + STACK_BIAS);
2845 }
2846 }
2847 }
2848 break;
2849 case T_VOID:
2850 break;
2851
2852 case T_FLOAT:
2853 if (src.first()->is_stack()) {
2854 // Stack to stack/reg is simple
2855 move32_64(masm, src, dst);
2856 } else {
2857 if (dst.first()->is_reg()) {
2858 // freg -> reg
2859 int off =
2860 STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
2861 Register d = dst.first()->as_Register();
2862 if (Assembler::is_simm13(off)) {
2863 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
2864 SP, off);
2865 __ ld(SP, off, d);
2866 } else {
2867 if (conversion_off == noreg) {
2868 __ set(off, L6);
2869 conversion_off = L6;
2870 }
2871 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
2872 SP, conversion_off);
2873 __ ld(SP, conversion_off , d);
2874 }
2875 } else {
2876 // freg -> mem
2877 int off = STACK_BIAS + reg2offset(dst.first());
2878 if (Assembler::is_simm13(off)) {
2879 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
2880 SP, off);
2881 } else {
2882 if (conversion_off == noreg) {
2883 __ set(off, L6);
2884 conversion_off = L6;
2885 }
2886 __ stf(FloatRegisterImpl::S, src.first()->as_FloatRegister(),
2887 SP, conversion_off);
2888 }
2889 }
2890 }
2891 break;
2892
2893 case T_DOUBLE:
2894 assert( j_arg + 1 < total_args_passed &&
2895 in_sig_bt[j_arg + 1] == T_VOID &&
2896 out_sig_bt[c_arg+1] == T_VOID, "bad arg list");
2897 if (src.first()->is_stack()) {
2898 // Stack to stack/reg is simple
2899 long_move(masm, src, dst);
2900 } else {
2901 Register d = dst.first()->is_reg() ? dst.first()->as_Register() : L2;
2902
2903 // Destination could be an odd reg on 32bit in which case
2904 // we can't load direct to the destination.
2905
2906 if (!d->is_even() && wordSize == 4) {
2907 d = L2;
2908 }
2909 int off = STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
2910 if (Assembler::is_simm13(off)) {
2911 __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(),
2912 SP, off);
2913 __ ld_long(SP, off, d);
2914 } else {
2915 if (conversion_off == noreg) {
2916 __ set(off, L6);
2917 conversion_off = L6;
2918 }
2919 __ stf(FloatRegisterImpl::D, src.first()->as_FloatRegister(),
2920 SP, conversion_off);
2921 __ ld_long(SP, conversion_off, d);
2922 }
2923 if (d == L2) {
2924 long_move(masm, reg64_to_VMRegPair(L2), dst);
2925 }
2926 }
2927 break;
2928
2929 case T_LONG :
2930 // 32bit can't do a split move of something like g1 -> O0, O1
2931 // so use a memory temp
2932 if (src.is_single_phys_reg() && wordSize == 4) {
2933 Register tmp = L2;
2934 if (dst.first()->is_reg() &&
2935 (wordSize == 8 || dst.first()->as_Register()->is_even())) {
2936 tmp = dst.first()->as_Register();
2937 }
2938
2939 int off = STACK_BIAS + conversion_temp * VMRegImpl::stack_slot_size;
2940 if (Assembler::is_simm13(off)) {
2941 __ stx(src.first()->as_Register(), SP, off);
2942 __ ld_long(SP, off, tmp);
2943 } else {
2944 if (conversion_off == noreg) {
2945 __ set(off, L6);
2946 conversion_off = L6;
2947 }
2948 __ stx(src.first()->as_Register(), SP, conversion_off);
2949 __ ld_long(SP, conversion_off, tmp);
2950 }
2951
2952 if (tmp == L2) {
2953 long_move(masm, reg64_to_VMRegPair(L2), dst);
2954 }
2955 } else {
2956 long_move(masm, src, dst);
2957 }
2958 break;
2959
2960 case T_ADDRESS: assert(false, "found T_ADDRESS in java args");
2961
2962 default:
2963 move32_64(masm, src, dst);
2964 }
2965 }
2966
2967
2968 // If we have any strings we must store any register based arg to the stack
2969 // This includes any still live xmm registers too.
2970
2971 if (total_strings > 0 ) {
2972
2973 // protect all the arg registers
2974 __ save_frame(0);
2975 __ mov(G2_thread, L7_thread_cache);
2976 const Register L2_string_off = L2;
2977
2978 // Get first string offset
2979 __ set(string_locs * VMRegImpl::stack_slot_size, L2_string_off);
2980
2981 for (c_arg = 0 ; c_arg < total_c_args ; c_arg++ ) {
2982 if (out_sig_bt[c_arg] == T_ADDRESS) {
2983
2984 VMRegPair dst = out_regs[c_arg];
2985 const Register d = dst.first()->is_reg() ?
2986 dst.first()->as_Register()->after_save() : noreg;
2987
2988 // It's a string the oop and it was already copied to the out arg
2989 // position
2990 if (d != noreg) {
2991 __ mov(d, O0);
2992 } else {
2993 assert(Assembler::is_simm13(reg2offset(dst.first()) + STACK_BIAS),
2994 "must be");
2995 __ ld_ptr(FP, reg2offset(dst.first()) + STACK_BIAS, O0);
2996 }
2997 Label skip;
2998
2999 __ br_null(O0, false, Assembler::pn, skip);
3000 __ delayed()->add(FP, L2_string_off, O1);
3001
3002 if (d != noreg) {
3003 __ mov(O1, d);
3004 } else {
3005 assert(Assembler::is_simm13(reg2offset(dst.first()) + STACK_BIAS),
3006 "must be");
3007 __ st_ptr(O1, FP, reg2offset(dst.first()) + STACK_BIAS);
3008 }
3009
3010 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::get_utf),
3011 relocInfo::runtime_call_type);
3012 __ delayed()->add(L2_string_off, max_dtrace_string_size, L2_string_off);
3013
3014 __ bind(skip);
3015
3016 }
3017
3018 }
3019 __ mov(L7_thread_cache, G2_thread);
3020 __ restore();
3021
3022 }
3023
3024
3025 // Ok now we are done. Need to place the nop that dtrace wants in order to
3026 // patch in the trap
3027
3028 int patch_offset = ((intptr_t)__ pc()) - start;
3029
3030 __ nop();
3031
3032
3033 // Return
3034
3035 __ ret();
3036 __ delayed()->restore();
3037
3038 __ flush();
3039
3040 nmethod *nm = nmethod::new_dtrace_nmethod(
3041 method, masm->code(), vep_offset, patch_offset, frame_complete,
3042 stack_slots / VMRegImpl::slots_per_word);
3043 return nm;
3044
3045 }
3046
3047 #endif // HAVE_DTRACE_H
3048
2504 // this function returns the adjust size (in number of words) to a c2i adapter 3049 // this function returns the adjust size (in number of words) to a c2i adapter
2505 // activation for use during deoptimization 3050 // activation for use during deoptimization
2506 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) { 3051 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
2507 assert(callee_locals >= callee_parameters, 3052 assert(callee_locals >= callee_parameters,
2508 "test and remove; got more parms than locals"); 3053 "test and remove; got more parms than locals");