src/cpu/mips/vm/templateTable_mips_64.cpp

changeset 6883
57b216e5c8e3
parent 6881
633080c2ba82
child 6884
37fd1c756f31
equal deleted inserted replaced
6882:5bef3df0c689 6883:57b216e5c8e3
2668 // the call to the VM 2668 // the call to the VM
2669 if (JvmtiExport::can_post_field_access()) { 2669 if (JvmtiExport::can_post_field_access()) {
2670 // Check to see if a field access watch has been set before we 2670 // Check to see if a field access watch has been set before we
2671 // take the time to call into the VM. 2671 // take the time to call into the VM.
2672 Label L1; 2672 Label L1;
2673 assert_different_registers(cache, index, FSR); 2673 // kill FSR
2674 Register tmp1 = T2;
2675 Register tmp2 = T1;
2676 Register tmp3 = T3;
2677 assert_different_registers(cache, index, AT);
2674 __ li(AT, (intptr_t)JvmtiExport::get_field_access_count_addr()); 2678 __ li(AT, (intptr_t)JvmtiExport::get_field_access_count_addr());
2675 __ lw(FSR, AT, 0); 2679 __ lw(AT, AT, 0);
2676 __ beq(FSR, R0, L1); 2680 __ beq(AT, R0, L1);
2677 __ delayed()->nop(); 2681 __ delayed()->nop();
2678 2682
2679 // We rely on the bytecode being resolved and the cpCache entry filled in. 2683 __ get_cache_and_index_at_bcp(tmp2, tmp3, 1);
2684
2680 // cache entry pointer 2685 // cache entry pointer
2681 __ daddi(cache, cache, in_bytes(ConstantPoolCache::base_offset())); 2686 __ daddi(tmp2, tmp2, in_bytes(ConstantPoolCache::base_offset()));
2682 __ shl(index, 4); 2687 __ shl(tmp3, LogBytesPerWord);
2683 __ dadd(cache, cache, index); 2688 __ dadd(tmp2, tmp2, tmp3);
2684 if (is_static) { 2689 if (is_static) {
2685 __ move(FSR, R0); 2690 __ move(tmp1, R0);
2686 } else { 2691 } else {
2687 __ lw(FSR, SP, 0); 2692 __ ld(tmp1, SP, 0);
2688 __ verify_oop(FSR); 2693 __ verify_oop(tmp1);
2689 } 2694 }
2690 // FSR: object pointer or NULL 2695 // tmp1: object pointer or NULL
2691 // cache: cache entry pointer 2696 // tmp2: cache entry pointer
2697 // tmp3: jvalue object on the stack
2692 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, 2698 __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
2693 InterpreterRuntime::post_field_access), FSR, cache); 2699 InterpreterRuntime::post_field_access),
2700 tmp1, tmp2, tmp3);
2694 __ get_cache_and_index_at_bcp(cache, index, 1); 2701 __ get_cache_and_index_at_bcp(cache, index, 1);
2695 __ bind(L1); 2702 __ bind(L1);
2696 } 2703 }
2697 } 2704 }
2698 2705
2727 2734
2728 const Register obj = T3; 2735 const Register obj = T3;
2729 const Register off = T2; 2736 const Register off = T2;
2730 const Register flags = T1; 2737 const Register flags = T1;
2731 resolve_cache_and_index(byte_no, cache, index, sizeof(u2)); 2738 resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
2732 //jvmti_post_field_access(cache, index, is_static, false); 2739 jvmti_post_field_access(cache, index, is_static, false);
2733 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static); 2740 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
2734 2741
2735 if (!is_static) pop_and_check_object(obj); 2742 if (!is_static) pop_and_check_object(obj);
2736 __ dadd(index, obj, off); 2743 __ dadd(index, obj, off);
2737 2744
2883 } 2890 }
2884 2891
2885 // The registers cache and index expected to be set before call. 2892 // The registers cache and index expected to be set before call.
2886 // The function may destroy various registers, just not the cache and index registers. 2893 // The function may destroy various registers, just not the cache and index registers.
2887 void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is_static) { 2894 void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is_static) {
2895 transition(vtos, vtos);
2896
2888 ByteSize cp_base_offset = ConstantPoolCache::base_offset(); 2897 ByteSize cp_base_offset = ConstantPoolCache::base_offset();
2889 2898
2890 if (JvmtiExport::can_post_field_modification()) { 2899 if (JvmtiExport::can_post_field_modification()) {
2891 // Check to see if a field modification watch has been set before we take 2900 // Check to see if a field modification watch has been set before
2892 // the time to call into the VM. 2901 // we take the time to call into the VM.
2893 Label L1; 2902 Label L1;
2894 assert_different_registers(cache, index, AT); 2903 //kill AT, T1, T2, T3, T9
2904 Register tmp1 = T2;
2905 Register tmp2 = T1;
2906 Register tmp3 = T3;
2907 Register tmp4 = T9;
2908 assert_different_registers(cache, index, tmp4);
2895 2909
2896 __ li(AT, JvmtiExport::get_field_modification_count_addr()); 2910 __ li(AT, JvmtiExport::get_field_modification_count_addr());
2897 __ lw(FSR, AT, 0); 2911 __ lw(AT, AT, 0);
2898 __ beq(FSR, R0, L1); 2912 __ beq(AT, R0, L1);
2899 __ delayed()->nop(); 2913 __ delayed()->nop();
2900 2914
2901 /* // We rely on the bytecode being resolved and the cpCache entry filled in. 2915 __ get_cache_and_index_at_bcp(tmp2, tmp4, 1);
2902 resolve_cache_and_index(byte_no, T1, T1);
2903 */
2904 // The cache and index registers have been already set.
2905 // This allows to eliminate this call but the cache and index
2906 // registers have to be correspondingly used after this line.
2907 __ get_cache_and_index_at_bcp(T1, T9, 1);
2908 2916
2909 if (is_static) { 2917 if (is_static) {
2910 __ move(T2, R0); 2918 __ move(tmp1, R0);
2911 } else { 2919 } else {
2912 // Life is harder. The stack holds the value on top, 2920 // Life is harder. The stack holds the value on top, followed by
2913 // followed by the object. 2921 // the object. We don't know the size of the value, though; it
2914 // We don't know the size of the value, though; 2922 // could be one or two words depending on its type. As a result,
2915 // it could be one or two words 2923 // we must find the type to determine where the object is.
2916 // depending on its type. As a result, we must find
2917 // the type to determine where the object is.
2918 Label two_word, valsize_known; 2924 Label two_word, valsize_known;
2919 __ dsll(AT, T1, 4); 2925 __ dsll(AT, tmp4, Address::times_8);
2920 __ dadd(AT, T1, AT); 2926 __ dadd(AT, tmp2, AT);
2921 __ lw(T3, AT, in_bytes(cp_base_offset 2927 __ ld(tmp3, AT, in_bytes(cp_base_offset +
2922 + ConstantPoolCacheEntry::flags_offset())); 2928 ConstantPoolCacheEntry::flags_offset()));
2923 __ move(T2, SP); 2929 __ shr(tmp3, ConstantPoolCacheEntry::tos_state_shift);
2924 __ shr(T3, ConstantPoolCacheEntry::tos_state_shift);
2925 2930
2926 // Make sure we don't need to mask ecx for tos_state_shift 2931 // Make sure we don't need to mask ecx for tos_state_shift
2927 // after the above shift 2932 // after the above shift
2928 ConstantPoolCacheEntry::verify_tos_state_shift(); 2933 ConstantPoolCacheEntry::verify_tos_state_shift();
2934 __ move(tmp1, SP);
2929 __ move(AT, ltos); 2935 __ move(AT, ltos);
2930 __ beq(T3, AT, two_word); 2936 __ beq(tmp3, AT, two_word);
2931 __ delayed()->nop(); 2937 __ delayed()->nop();
2932 __ move(AT, dtos); 2938 __ move(AT, dtos);
2933 __ beq(T3, AT, two_word); 2939 __ beq(tmp3, AT, two_word);
2934 __ delayed()->nop(); 2940 __ delayed()->nop();
2935 __ b(valsize_known); 2941 __ b(valsize_known);
2936 __ delayed()->daddi(T2, T2,Interpreter::expr_offset_in_bytes(1) ); 2942 __ delayed()->daddi(tmp1, tmp1, Interpreter::expr_offset_in_bytes(1) );
2937 2943
2938 __ bind(two_word); 2944 __ bind(two_word);
2939 __ daddi(T2, T2,Interpreter::expr_offset_in_bytes(2)); 2945 __ daddi(tmp1, tmp1, Interpreter::expr_offset_in_bytes(2));
2940 2946
2941 __ bind(valsize_known); 2947 __ bind(valsize_known);
2942 // setup object pointer 2948 // setup object pointer
2943 __ lw(T2, T2, 0*wordSize); 2949 __ ld(tmp1, tmp1, 0*wordSize);
2944 } 2950 }
2945 // cache entry pointer 2951 // cache entry pointer
2946 __ daddi(T1, T1, in_bytes(cp_base_offset)); 2952 __ daddi(tmp2, tmp2, in_bytes(cp_base_offset));
2947 __ shl(T1, 4); 2953 __ shl(tmp4, LogBytesPerWord);
2948 __ daddu(T1, T1, T1); 2954 __ daddu(tmp2, tmp2, tmp4);
2949 // object (tos) 2955 // object (tos)
2950 __ move(T3, SP); 2956 __ move(tmp3, SP);
2951 // T2: object pointer set up above (NULL if static) 2957 // tmp1: object pointer set up above (NULL if static)
2952 // T1: cache entry pointer 2958 // tmp2: cache entry pointer
2953 // T3: jvalue object on the stack 2959 // tmp3: jvalue object on the stack
2954 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, 2960 __ call_VM(NOREG,
2955 InterpreterRuntime::post_field_modification), T2, T1, T3); 2961 CAST_FROM_FN_PTR(address,
2962 InterpreterRuntime::post_field_modification),
2963 tmp1, tmp2, tmp3);
2956 __ get_cache_and_index_at_bcp(cache, index, 1); 2964 __ get_cache_and_index_at_bcp(cache, index, 1);
2957 __ bind(L1); 2965 __ bind(L1);
2958 } 2966 }
2959 } 2967 }
2960 2968
2973 const Register off = T2; 2981 const Register off = T2;
2974 const Register flags = T1; 2982 const Register flags = T1;
2975 const Register bc = T3; 2983 const Register bc = T3;
2976 2984
2977 resolve_cache_and_index(byte_no, cache, index, sizeof(u2)); 2985 resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
2978 //jvmti_post_field_mod(cache, index, is_static); 2986 jvmti_post_field_mod(cache, index, is_static);
2979 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static); 2987 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
2980 2988
2981 Label notVolatile, Done; 2989 Label notVolatile, Done;
2982 __ move(AT, 1<<ConstantPoolCacheEntry::is_volatile_shift); 2990 __ move(AT, 1<<ConstantPoolCacheEntry::is_volatile_shift);
2983 __ andr(T8, flags, AT); 2991 __ andr(T8, flags, AT);
3194 void TemplateTable::jvmti_post_fast_field_mod() { 3202 void TemplateTable::jvmti_post_fast_field_mod() {
3195 if (JvmtiExport::can_post_field_modification()) { 3203 if (JvmtiExport::can_post_field_modification()) {
3196 // Check to see if a field modification watch has been set before 3204 // Check to see if a field modification watch has been set before
3197 // we take the time to call into the VM. 3205 // we take the time to call into the VM.
3198 Label L2; 3206 Label L2;
3207 //kill AT, T1, T2, T3, T9
3208 Register tmp1 = T2;
3209 Register tmp2 = T1;
3210 Register tmp3 = T3;
3211 Register tmp4 = T9;
3199 __ li(AT, JvmtiExport::get_field_modification_count_addr()); 3212 __ li(AT, JvmtiExport::get_field_modification_count_addr());
3200 __ lw(T3, AT, 0); 3213 __ lw(tmp3, AT, 0);
3201 __ beq(T3, R0, L2); 3214 __ beq(tmp3, R0, L2);
3202 __ delayed()->nop(); 3215 __ delayed()->nop();
3203 __ pop_ptr(T2); 3216 __ pop_ptr(tmp1);
3204 __ verify_oop(T2); 3217 __ verify_oop(tmp1);
3205 __ push_ptr(T2); 3218 __ push_ptr(tmp1);
3206 __ li(AT, -sizeof(jvalue));
3207 __ daddu(SP, SP, AT);
3208 __ move(T3, SP);
3209
3210 switch (bytecode()) { // load values into the jvalue object 3219 switch (bytecode()) { // load values into the jvalue object
3211 case Bytecodes::_fast_bputfield: 3220 case Bytecodes::_fast_aputfield: __ push_ptr(FSR); break;
3212 __ sb(FSR, SP, 0); 3221 case Bytecodes::_fast_bputfield: // fall through
3213 break; 3222 case Bytecodes::_fast_sputfield: // fall through
3214 case Bytecodes::_fast_sputfield: 3223 case Bytecodes::_fast_cputfield: // fall through
3215 __ sh(FSR, SP, 0); 3224 case Bytecodes::_fast_iputfield: __ push_i(FSR); break;
3216 break; 3225 case Bytecodes::_fast_dputfield: __ push_d(FSF); break;
3217 case Bytecodes::_fast_cputfield: 3226 case Bytecodes::_fast_fputfield: __ push_f(); break;
3218 __ sh(FSR, SP, 0); 3227 case Bytecodes::_fast_lputfield: __ push_l(FSR); break;
3219 break;
3220 case Bytecodes::_fast_iputfield:
3221 __ sw(FSR, SP, 0);
3222 break;
3223 case Bytecodes::_fast_lputfield:
3224 __ sd(FSR, SP, 0);
3225 break;
3226 case Bytecodes::_fast_fputfield:
3227 __ swc1(FSF, SP, 0);
3228 break;
3229 case Bytecodes::_fast_dputfield:
3230 __ sdc1(FSF, SP, 0);
3231 break;
3232 case Bytecodes::_fast_aputfield:
3233 __ sd(FSR, SP, 0);
3234 break;
3235 default: ShouldNotReachHere(); 3228 default: ShouldNotReachHere();
3236 } 3229 }
3237 3230 __ move(tmp3, SP);
3238 // Save eax and sometimes edx because call_VM() will clobber them,
3239 // then use them for JVM/DI purposes
3240 __ push(FSR);
3241 if (bytecode() == Bytecodes::_fast_lputfield) __ push(SSR);
3242 // access constant pool cache entry 3231 // access constant pool cache entry
3243 __ get_cache_entry_pointer_at_bcp(T1, T2, 1); 3232 __ get_cache_entry_pointer_at_bcp(tmp2, FSR, 1);
3244 // no need, verified ahead 3233 __ verify_oop(tmp1);
3245 __ verify_oop(T2); 3234 // tmp1: object pointer copied above
3246 3235 // tmp2: cache entry pointer
3247 // ebx: object pointer copied above 3236 // tmp3: jvalue object on the stack
3248 // eax: cache entry pointer 3237 __ call_VM(NOREG,
3249 // ecx: jvalue object on the stack 3238 CAST_FROM_FN_PTR(address,
3250 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, 3239 InterpreterRuntime::post_field_modification),
3251 InterpreterRuntime::post_field_modification), T2, T1, T3); 3240 tmp1, tmp2, tmp3);
3252 if (bytecode() == Bytecodes::_fast_lputfield) __ pop(SSR); // restore high value 3241
3253 __ lw(FSR, SP, 0); 3242 switch (bytecode()) { // restore tos values
3254 __ daddiu(SP, SP, sizeof(jvalue) + 1 * wordSize); 3243 case Bytecodes::_fast_aputfield: __ pop_ptr(FSR); break;
3244 case Bytecodes::_fast_bputfield: // fall through
3245 case Bytecodes::_fast_sputfield: // fall through
3246 case Bytecodes::_fast_cputfield: // fall through
3247 case Bytecodes::_fast_iputfield: __ pop_i(FSR); break;
3248 case Bytecodes::_fast_dputfield: __ pop_d(); break;
3249 case Bytecodes::_fast_fputfield: __ pop_f(); break;
3250 case Bytecodes::_fast_lputfield: __ pop_l(FSR); break;
3251 }
3255 __ bind(L2); 3252 __ bind(L2);
3256 } 3253 }
3257 } 3254 }
3258 3255
3259 // used registers : T2, T3, T1 3256 // used registers : T2, T3, T1

mercurial