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"); |