comparison src/cpu/sparc/vm/assembler_sparc.cpp @ 644:c517646eef23

6813212: factor duplicated assembly code for general subclass check (for 6655638) Summary: Code in interp_masm, stubGenerator, c1_LIRAssembler, and AD files moved into MacroAssembler. Reviewed-by: kvn
author jrose
date Fri, 13 Mar 2009 18:39:22 -0700
parents 660978a2a31a
children c89f86385056 96b229c54d1e
comparison
equal deleted inserted replaced
643:c771b7f43bbf 644:c517646eef23
2763 // scan_temp[-scan_step] points to the vtable offset we need 2763 // scan_temp[-scan_step] points to the vtable offset we need
2764 ito_offset -= scan_step; 2764 ito_offset -= scan_step;
2765 lduw(scan_temp, ito_offset, scan_temp); 2765 lduw(scan_temp, ito_offset, scan_temp);
2766 ld_ptr(recv_klass, scan_temp, method_result); 2766 ld_ptr(recv_klass, scan_temp, method_result);
2767 } 2767 }
2768
2769
2770 void MacroAssembler::check_klass_subtype(Register sub_klass,
2771 Register super_klass,
2772 Register temp_reg,
2773 Register temp2_reg,
2774 Label& L_success) {
2775 Label L_failure, L_pop_to_failure;
2776 check_klass_subtype_fast_path(sub_klass, super_klass,
2777 temp_reg, temp2_reg,
2778 &L_success, &L_failure, NULL);
2779 Register sub_2 = sub_klass;
2780 Register sup_2 = super_klass;
2781 if (!sub_2->is_global()) sub_2 = L0;
2782 if (!sup_2->is_global()) sup_2 = L1;
2783
2784 save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2);
2785 check_klass_subtype_slow_path(sub_2, sup_2,
2786 L2, L3, L4, L5,
2787 NULL, &L_pop_to_failure);
2788
2789 // on success:
2790 restore();
2791 ba(false, L_success);
2792 delayed()->nop();
2793
2794 // on failure:
2795 bind(L_pop_to_failure);
2796 restore();
2797 bind(L_failure);
2798 }
2799
2800
2801 void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
2802 Register super_klass,
2803 Register temp_reg,
2804 Register temp2_reg,
2805 Label* L_success,
2806 Label* L_failure,
2807 Label* L_slow_path,
2808 RegisterConstant super_check_offset,
2809 Register instanceof_hack) {
2810 int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
2811 Klass::secondary_super_cache_offset_in_bytes());
2812 int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
2813 Klass::super_check_offset_offset_in_bytes());
2814
2815 bool must_load_sco = (super_check_offset.constant_or_zero() == -1);
2816 bool need_slow_path = (must_load_sco ||
2817 super_check_offset.constant_or_zero() == sco_offset);
2818
2819 assert_different_registers(sub_klass, super_klass, temp_reg);
2820 if (super_check_offset.is_register()) {
2821 assert_different_registers(sub_klass, super_klass,
2822 super_check_offset.as_register());
2823 } else if (must_load_sco) {
2824 assert(temp2_reg != noreg, "supply either a temp or a register offset");
2825 }
2826
2827 Label L_fallthrough;
2828 int label_nulls = 0;
2829 if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; }
2830 if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; }
2831 if (L_slow_path == NULL) { L_slow_path = &L_fallthrough; label_nulls++; }
2832 assert(label_nulls <= 1 || instanceof_hack != noreg ||
2833 (L_slow_path == &L_fallthrough && label_nulls <= 2 && !need_slow_path),
2834 "at most one NULL in the batch, usually");
2835
2836 // Support for the instanceof hack, which uses delay slots to
2837 // set a destination register to zero or one.
2838 bool do_bool_sets = (instanceof_hack != noreg);
2839 #define BOOL_SET(bool_value) \
2840 if (do_bool_sets && bool_value >= 0) \
2841 set(bool_value, instanceof_hack)
2842 #define DELAYED_BOOL_SET(bool_value) \
2843 if (do_bool_sets && bool_value >= 0) \
2844 delayed()->set(bool_value, instanceof_hack); \
2845 else delayed()->nop()
2846 // Hacked ba(), which may only be used just before L_fallthrough.
2847 #define FINAL_JUMP(label, bool_value) \
2848 if (&(label) == &L_fallthrough) { \
2849 BOOL_SET(bool_value); \
2850 } else { \
2851 ba((do_bool_sets && bool_value >= 0), label); \
2852 DELAYED_BOOL_SET(bool_value); \
2853 }
2854
2855 // If the pointers are equal, we are done (e.g., String[] elements).
2856 // This self-check enables sharing of secondary supertype arrays among
2857 // non-primary types such as array-of-interface. Otherwise, each such
2858 // type would need its own customized SSA.
2859 // We move this check to the front of the fast path because many
2860 // type checks are in fact trivially successful in this manner,
2861 // so we get a nicely predicted branch right at the start of the check.
2862 cmp(super_klass, sub_klass);
2863 brx(Assembler::equal, do_bool_sets, Assembler::pn, *L_success);
2864 DELAYED_BOOL_SET(1);
2865
2866 // Check the supertype display:
2867 if (must_load_sco) {
2868 // The super check offset is always positive...
2869 lduw(super_klass, sco_offset, temp2_reg);
2870 super_check_offset = RegisterConstant(temp2_reg);
2871 }
2872 ld_ptr(sub_klass, super_check_offset, temp_reg);
2873 cmp(super_klass, temp_reg);
2874
2875 // This check has worked decisively for primary supers.
2876 // Secondary supers are sought in the super_cache ('super_cache_addr').
2877 // (Secondary supers are interfaces and very deeply nested subtypes.)
2878 // This works in the same check above because of a tricky aliasing
2879 // between the super_cache and the primary super display elements.
2880 // (The 'super_check_addr' can address either, as the case requires.)
2881 // Note that the cache is updated below if it does not help us find
2882 // what we need immediately.
2883 // So if it was a primary super, we can just fail immediately.
2884 // Otherwise, it's the slow path for us (no success at this point).
2885
2886 if (super_check_offset.is_register()) {
2887 brx(Assembler::equal, do_bool_sets, Assembler::pn, *L_success);
2888 delayed(); if (do_bool_sets) BOOL_SET(1);
2889 // if !do_bool_sets, sneak the next cmp into the delay slot:
2890 cmp(super_check_offset.as_register(), sc_offset);
2891
2892 if (L_failure == &L_fallthrough) {
2893 brx(Assembler::equal, do_bool_sets, Assembler::pt, *L_slow_path);
2894 delayed()->nop();
2895 BOOL_SET(0); // fallthrough on failure
2896 } else {
2897 brx(Assembler::notEqual, do_bool_sets, Assembler::pn, *L_failure);
2898 DELAYED_BOOL_SET(0);
2899 FINAL_JUMP(*L_slow_path, -1); // -1 => vanilla delay slot
2900 }
2901 } else if (super_check_offset.as_constant() == sc_offset) {
2902 // Need a slow path; fast failure is impossible.
2903 if (L_slow_path == &L_fallthrough) {
2904 brx(Assembler::equal, do_bool_sets, Assembler::pt, *L_success);
2905 DELAYED_BOOL_SET(1);
2906 } else {
2907 brx(Assembler::notEqual, false, Assembler::pn, *L_slow_path);
2908 delayed()->nop();
2909 FINAL_JUMP(*L_success, 1);
2910 }
2911 } else {
2912 // No slow path; it's a fast decision.
2913 if (L_failure == &L_fallthrough) {
2914 brx(Assembler::equal, do_bool_sets, Assembler::pt, *L_success);
2915 DELAYED_BOOL_SET(1);
2916 BOOL_SET(0);
2917 } else {
2918 brx(Assembler::notEqual, do_bool_sets, Assembler::pn, *L_failure);
2919 DELAYED_BOOL_SET(0);
2920 FINAL_JUMP(*L_success, 1);
2921 }
2922 }
2923
2924 bind(L_fallthrough);
2925
2926 #undef final_jump
2927 #undef bool_set
2928 #undef DELAYED_BOOL_SET
2929 #undef final_jump
2930 }
2931
2932
2933 void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
2934 Register super_klass,
2935 Register count_temp,
2936 Register scan_temp,
2937 Register scratch_reg,
2938 Register coop_reg,
2939 Label* L_success,
2940 Label* L_failure) {
2941 assert_different_registers(sub_klass, super_klass,
2942 count_temp, scan_temp, scratch_reg, coop_reg);
2943
2944 Label L_fallthrough, L_loop;
2945 int label_nulls = 0;
2946 if (L_success == NULL) { L_success = &L_fallthrough; label_nulls++; }
2947 if (L_failure == NULL) { L_failure = &L_fallthrough; label_nulls++; }
2948 assert(label_nulls <= 1, "at most one NULL in the batch");
2949
2950 // a couple of useful fields in sub_klass:
2951 int ss_offset = (klassOopDesc::header_size() * HeapWordSize +
2952 Klass::secondary_supers_offset_in_bytes());
2953 int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
2954 Klass::secondary_super_cache_offset_in_bytes());
2955
2956 // Do a linear scan of the secondary super-klass chain.
2957 // This code is rarely used, so simplicity is a virtue here.
2958
2959 #ifndef PRODUCT
2960 int* pst_counter = &SharedRuntime::_partial_subtype_ctr;
2961 inc_counter((address) pst_counter, count_temp, scan_temp);
2962 #endif
2963
2964 // We will consult the secondary-super array.
2965 ld_ptr(sub_klass, ss_offset, scan_temp);
2966
2967 // Compress superclass if necessary.
2968 Register search_key = super_klass;
2969 bool decode_super_klass = false;
2970 if (UseCompressedOops) {
2971 if (coop_reg != noreg) {
2972 encode_heap_oop_not_null(super_klass, coop_reg);
2973 search_key = coop_reg;
2974 } else {
2975 encode_heap_oop_not_null(super_klass);
2976 decode_super_klass = true; // scarce temps!
2977 }
2978 // The superclass is never null; it would be a basic system error if a null
2979 // pointer were to sneak in here. Note that we have already loaded the
2980 // Klass::super_check_offset from the super_klass in the fast path,
2981 // so if there is a null in that register, we are already in the afterlife.
2982 }
2983
2984 // Load the array length. (Positive movl does right thing on LP64.)
2985 lduw(scan_temp, arrayOopDesc::length_offset_in_bytes(), count_temp);
2986
2987 // Check for empty secondary super list
2988 tst(count_temp);
2989
2990 // Top of search loop
2991 bind(L_loop);
2992 br(Assembler::equal, false, Assembler::pn, *L_failure);
2993 delayed()->add(scan_temp, heapOopSize, scan_temp);
2994 assert(heapOopSize != 0, "heapOopSize should be initialized");
2995
2996 // Skip the array header in all array accesses.
2997 int elem_offset = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
2998 elem_offset -= heapOopSize; // the scan pointer was pre-incremented also
2999
3000 // Load next super to check
3001 if (UseCompressedOops) {
3002 // Don't use load_heap_oop; we don't want to decode the element.
3003 lduw( scan_temp, elem_offset, scratch_reg );
3004 } else {
3005 ld_ptr( scan_temp, elem_offset, scratch_reg );
3006 }
3007
3008 // Look for Rsuper_klass on Rsub_klass's secondary super-class-overflow list
3009 cmp(scratch_reg, search_key);
3010
3011 // A miss means we are NOT a subtype and need to keep looping
3012 brx(Assembler::notEqual, false, Assembler::pn, L_loop);
3013 delayed()->deccc(count_temp); // decrement trip counter in delay slot
3014
3015 // Falling out the bottom means we found a hit; we ARE a subtype
3016 if (decode_super_klass) decode_heap_oop(super_klass);
3017
3018 // Success. Cache the super we found and proceed in triumph.
3019 st_ptr(super_klass, sub_klass, sc_offset);
3020
3021 if (L_success != &L_fallthrough) {
3022 ba(false, *L_success);
3023 delayed()->nop();
3024 }
3025
3026 bind(L_fallthrough);
3027 }
3028
3029
2768 3030
2769 3031
2770 void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, 3032 void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg,
2771 Register temp_reg, 3033 Register temp_reg,
2772 Label& done, Label* slow_case, 3034 Label& done, Label* slow_case,