3144 const Register Rcache = R4_tmp; |
3144 const Register Rcache = R4_tmp; |
3145 const Register Rflagsav = Rtmp_save0; // R4/R19 |
3145 const Register Rflagsav = Rtmp_save0; // R4/R19 |
3146 const Register Rindex = R5_tmp; |
3146 const Register Rindex = R5_tmp; |
3147 const Register Rflags = R5_tmp; |
3147 const Register Rflags = R5_tmp; |
3148 |
3148 |
3149 const bool gen_volatile_check = os::is_MP(); |
|
3150 |
|
3151 resolve_cache_and_index(byte_no, Rcache, Rindex, sizeof(u2)); |
3149 resolve_cache_and_index(byte_no, Rcache, Rindex, sizeof(u2)); |
3152 jvmti_post_field_access(Rcache, Rindex, is_static, false); |
3150 jvmti_post_field_access(Rcache, Rindex, is_static, false); |
3153 load_field_cp_cache_entry(Rcache, Rindex, Roffset, Rflags, Robj, is_static); |
3151 load_field_cp_cache_entry(Rcache, Rindex, Roffset, Rflags, Robj, is_static); |
3154 |
3152 |
3155 if (gen_volatile_check) { |
3153 __ mov(Rflagsav, Rflags); |
3156 __ mov(Rflagsav, Rflags); |
|
3157 } |
|
3158 |
3154 |
3159 if (!is_static) pop_and_check_object(Robj); |
3155 if (!is_static) pop_and_check_object(Robj); |
3160 |
3156 |
3161 Label Done, Lint, Ltable, shouldNotReachHere; |
3157 Label Done, Lint, Ltable, shouldNotReachHere; |
3162 Label Lbtos, Lztos, Lctos, Lstos, Litos, Lltos, Lftos, Ldtos, Latos; |
3158 Label Lbtos, Lztos, Lctos, Lstos, Litos, Lltos, Lftos, Ldtos, Latos; |
3389 patch_bytecode(Bytecodes::_fast_igetfield, R0_tmp, Rtemp); |
3385 patch_bytecode(Bytecodes::_fast_igetfield, R0_tmp, Rtemp); |
3390 } |
3386 } |
3391 |
3387 |
3392 __ bind(Done); |
3388 __ bind(Done); |
3393 |
3389 |
3394 if (gen_volatile_check) { |
3390 // Check for volatile field |
3395 // Check for volatile field |
3391 Label notVolatile; |
3396 Label notVolatile; |
3392 __ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3397 __ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3393 |
3398 |
3394 volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp); |
3399 volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp); |
3395 |
3400 |
3396 __ bind(notVolatile); |
3401 __ bind(notVolatile); |
|
3402 } |
|
3403 |
|
3404 } |
3397 } |
3405 |
3398 |
3406 void TemplateTable::getfield(int byte_no) { |
3399 void TemplateTable::getfield(int byte_no) { |
3407 getfield_or_static(byte_no, false); |
3400 getfield_or_static(byte_no, false); |
3408 } |
3401 } |
3490 const Register Rcache = R4_tmp; |
3483 const Register Rcache = R4_tmp; |
3491 const Register Rflagsav = Rtmp_save0; // R4/R19 |
3484 const Register Rflagsav = Rtmp_save0; // R4/R19 |
3492 const Register Rindex = R5_tmp; |
3485 const Register Rindex = R5_tmp; |
3493 const Register Rflags = R5_tmp; |
3486 const Register Rflags = R5_tmp; |
3494 |
3487 |
3495 const bool gen_volatile_check = os::is_MP(); |
|
3496 |
|
3497 resolve_cache_and_index(byte_no, Rcache, Rindex, sizeof(u2)); |
3488 resolve_cache_and_index(byte_no, Rcache, Rindex, sizeof(u2)); |
3498 jvmti_post_field_mod(Rcache, Rindex, is_static); |
3489 jvmti_post_field_mod(Rcache, Rindex, is_static); |
3499 load_field_cp_cache_entry(Rcache, Rindex, Roffset, Rflags, Robj, is_static); |
3490 load_field_cp_cache_entry(Rcache, Rindex, Roffset, Rflags, Robj, is_static); |
3500 |
3491 |
3501 if (gen_volatile_check) { |
3492 // Check for volatile field |
3502 // Check for volatile field |
3493 Label notVolatile; |
3503 Label notVolatile; |
3494 __ mov(Rflagsav, Rflags); |
3504 __ mov(Rflagsav, Rflags); |
3495 __ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3505 __ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3496 |
3506 |
3497 volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp); |
3507 volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp); |
3498 |
3508 |
3499 __ bind(notVolatile); |
3509 __ bind(notVolatile); |
|
3510 } |
|
3511 |
3500 |
3512 Label Done, Lint, shouldNotReachHere; |
3501 Label Done, Lint, shouldNotReachHere; |
3513 Label Ltable, Lbtos, Lztos, Lctos, Lstos, Litos, Lltos, Lftos, Ldtos, Latos; |
3502 Label Ltable, Lbtos, Lztos, Lctos, Lstos, Litos, Lltos, Lftos, Ldtos, Latos; |
3514 |
3503 |
3515 // compute type |
3504 // compute type |
3731 patch_bytecode(Bytecodes::_fast_iputfield, R0_tmp, Rtemp, true, byte_no); |
3720 patch_bytecode(Bytecodes::_fast_iputfield, R0_tmp, Rtemp, true, byte_no); |
3732 } |
3721 } |
3733 |
3722 |
3734 __ bind(Done); |
3723 __ bind(Done); |
3735 |
3724 |
3736 if (gen_volatile_check) { |
3725 Label notVolatile2; |
3737 Label notVolatile; |
3726 if (is_static) { |
3738 if (is_static) { |
3727 // Just check for volatile. Memory barrier for static final field |
3739 // Just check for volatile. Memory barrier for static final field |
3728 // is handled by class initialization. |
3740 // is handled by class initialization. |
3729 __ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile2); |
3741 __ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3730 volatile_barrier(MacroAssembler::StoreLoad, Rtemp); |
3742 volatile_barrier(MacroAssembler::StoreLoad, Rtemp); |
3731 __ bind(notVolatile2); |
3743 __ bind(notVolatile); |
3732 } else { |
3744 } else { |
3733 // Check for volatile field and final field |
3745 // Check for volatile field and final field |
3734 Label skipMembar; |
3746 Label skipMembar; |
3735 |
3747 |
3736 __ tst(Rflagsav, 1 << ConstantPoolCacheEntry::is_volatile_shift | |
3748 __ tst(Rflagsav, 1 << ConstantPoolCacheEntry::is_volatile_shift | |
3737 1 << ConstantPoolCacheEntry::is_final_shift); |
3749 1 << ConstantPoolCacheEntry::is_final_shift); |
3738 __ b(skipMembar, eq); |
3750 __ b(skipMembar, eq); |
3739 |
3751 |
3740 __ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile2); |
3752 __ tbz(Rflagsav, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3741 |
3753 |
3742 // StoreLoad barrier after volatile field write |
3754 // StoreLoad barrier after volatile field write |
3743 volatile_barrier(MacroAssembler::StoreLoad, Rtemp); |
3755 volatile_barrier(MacroAssembler::StoreLoad, Rtemp); |
3744 __ b(skipMembar); |
3756 __ b(skipMembar); |
3745 |
3757 |
3746 // StoreStore barrier after final field write |
3758 // StoreStore barrier after final field write |
3747 __ bind(notVolatile2); |
3759 __ bind(notVolatile); |
3748 volatile_barrier(MacroAssembler::StoreStore, Rtemp); |
3760 volatile_barrier(MacroAssembler::StoreStore, Rtemp); |
3749 |
3761 |
3750 __ bind(skipMembar); |
3762 __ bind(skipMembar); |
3751 } |
3763 } |
|
3764 } |
|
3765 |
|
3766 } |
3752 } |
3767 |
3753 |
3768 void TemplateTable::putfield(int byte_no) { |
3754 void TemplateTable::putfield(int byte_no) { |
3769 putfield_or_static(byte_no, false); |
3755 putfield_or_static(byte_no, false); |
3770 } |
3756 } |
3830 const Register Rindex = R3_tmp; |
3816 const Register Rindex = R3_tmp; |
3831 const Register Roffset = R3_tmp; |
3817 const Register Roffset = R3_tmp; |
3832 const Register Rflags = Rtmp_save0; // R4/R19 |
3818 const Register Rflags = Rtmp_save0; // R4/R19 |
3833 const Register Robj = R5_tmp; |
3819 const Register Robj = R5_tmp; |
3834 |
3820 |
3835 const bool gen_volatile_check = os::is_MP(); |
|
3836 |
|
3837 // access constant pool cache |
3821 // access constant pool cache |
3838 __ get_cache_and_index_at_bcp(Rcache, Rindex, 1); |
3822 __ get_cache_and_index_at_bcp(Rcache, Rindex, 1); |
3839 |
3823 |
3840 __ add(Rcache, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord)); |
3824 __ add(Rcache, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord)); |
3841 |
3825 |
3842 if (gen_volatile_check) { |
3826 // load flags to test volatile |
3843 // load flags to test volatile |
3827 __ ldr_u32(Rflags, Address(Rcache, base + ConstantPoolCacheEntry::flags_offset())); |
3844 __ ldr_u32(Rflags, Address(Rcache, base + ConstantPoolCacheEntry::flags_offset())); |
|
3845 } |
|
3846 |
3828 |
3847 // replace index with field offset from cache entry |
3829 // replace index with field offset from cache entry |
3848 __ ldr(Roffset, Address(Rcache, base + ConstantPoolCacheEntry::f2_offset())); |
3830 __ ldr(Roffset, Address(Rcache, base + ConstantPoolCacheEntry::f2_offset())); |
3849 |
3831 |
3850 if (gen_volatile_check) { |
3832 // Check for volatile store |
3851 // Check for volatile store |
3833 Label notVolatile; |
3852 Label notVolatile; |
3834 __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3853 __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3835 |
3854 |
3836 // TODO-AARCH64 on AArch64, store-release instructions can be used to get rid of this explict barrier |
3855 // TODO-AARCH64 on AArch64, store-release instructions can be used to get rid of this explict barrier |
3837 volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp); |
3856 volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp); |
3838 |
3857 |
3839 __ bind(notVolatile); |
3858 __ bind(notVolatile); |
|
3859 } |
|
3860 |
3840 |
3861 // Get object from stack |
3841 // Get object from stack |
3862 pop_and_check_object(Robj); |
3842 pop_and_check_object(Robj); |
3863 |
3843 |
3864 Address addr = Address(Robj, Roffset); |
3844 Address addr = Address(Robj, Roffset); |
3901 |
3881 |
3902 default: |
3882 default: |
3903 ShouldNotReachHere(); |
3883 ShouldNotReachHere(); |
3904 } |
3884 } |
3905 |
3885 |
3906 if (gen_volatile_check) { |
3886 Label notVolatile2; |
3907 Label notVolatile; |
3887 Label skipMembar; |
3908 Label skipMembar; |
3888 __ tst(Rflags, 1 << ConstantPoolCacheEntry::is_volatile_shift | |
3909 __ tst(Rflags, 1 << ConstantPoolCacheEntry::is_volatile_shift | |
3889 1 << ConstantPoolCacheEntry::is_final_shift); |
3910 1 << ConstantPoolCacheEntry::is_final_shift); |
3890 __ b(skipMembar, eq); |
3911 __ b(skipMembar, eq); |
3891 |
3912 |
3892 __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile2); |
3913 __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3893 |
3914 |
3894 // StoreLoad barrier after volatile field write |
3915 // StoreLoad barrier after volatile field write |
3895 volatile_barrier(MacroAssembler::StoreLoad, Rtemp); |
3916 volatile_barrier(MacroAssembler::StoreLoad, Rtemp); |
3896 __ b(skipMembar); |
3917 __ b(skipMembar); |
3897 |
3918 |
3898 // StoreStore barrier after final field write |
3919 // StoreStore barrier after final field write |
3899 __ bind(notVolatile2); |
3920 __ bind(notVolatile); |
3900 volatile_barrier(MacroAssembler::StoreStore, Rtemp); |
3921 volatile_barrier(MacroAssembler::StoreStore, Rtemp); |
3901 |
3922 |
3902 __ bind(skipMembar); |
3923 __ bind(skipMembar); |
3903 } |
3924 } |
|
3925 } |
|
3926 |
|
3927 |
3904 |
3928 void TemplateTable::fast_accessfield(TosState state) { |
3905 void TemplateTable::fast_accessfield(TosState state) { |
3929 transition(atos, state); |
3906 transition(atos, state); |
3930 |
3907 |
3931 // do the JVMTI work here to avoid disturbing the register state below |
3908 // do the JVMTI work here to avoid disturbing the register state below |
3952 const Register Rcache = R2_tmp; |
3929 const Register Rcache = R2_tmp; |
3953 const Register Rflags = R2_tmp; |
3930 const Register Rflags = R2_tmp; |
3954 const Register Rindex = R3_tmp; |
3931 const Register Rindex = R3_tmp; |
3955 const Register Roffset = R3_tmp; |
3932 const Register Roffset = R3_tmp; |
3956 |
3933 |
3957 const bool gen_volatile_check = os::is_MP(); |
|
3958 |
|
3959 // access constant pool cache |
3934 // access constant pool cache |
3960 __ get_cache_and_index_at_bcp(Rcache, Rindex, 1); |
3935 __ get_cache_and_index_at_bcp(Rcache, Rindex, 1); |
3961 // replace index with field offset from cache entry |
3936 // replace index with field offset from cache entry |
3962 __ add(Rtemp, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord)); |
3937 __ add(Rtemp, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord)); |
3963 __ ldr(Roffset, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset())); |
3938 __ ldr(Roffset, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset())); |
3964 |
3939 |
3965 if (gen_volatile_check) { |
3940 // load flags to test volatile |
3966 // load flags to test volatile |
3941 __ ldr_u32(Rflags, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); |
3967 __ ldr_u32(Rflags, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); |
|
3968 } |
|
3969 |
3942 |
3970 __ verify_oop(Robj); |
3943 __ verify_oop(Robj); |
3971 __ null_check(Robj, Rtemp); |
3944 __ null_check(Robj, Rtemp); |
3972 |
3945 |
3973 Address addr = Address(Robj, Roffset); |
3946 Address addr = Address(Robj, Roffset); |
4006 break; |
3979 break; |
4007 default: |
3980 default: |
4008 ShouldNotReachHere(); |
3981 ShouldNotReachHere(); |
4009 } |
3982 } |
4010 |
3983 |
4011 if (gen_volatile_check) { |
3984 // Check for volatile load |
4012 // Check for volatile load |
3985 Label notVolatile; |
4013 Label notVolatile; |
3986 __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
4014 __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
3987 |
4015 |
3988 // TODO-AARCH64 on AArch64, load-acquire instructions can be used to get rid of this explict barrier |
4016 // TODO-AARCH64 on AArch64, load-acquire instructions can be used to get rid of this explict barrier |
3989 volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp); |
4017 volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp); |
3990 |
4018 |
3991 __ bind(notVolatile); |
4019 __ bind(notVolatile); |
|
4020 } |
|
4021 } |
3992 } |
4022 |
3993 |
4023 |
3994 |
4024 void TemplateTable::fast_xaccess(TosState state) { |
3995 void TemplateTable::fast_xaccess(TosState state) { |
4025 transition(vtos, state); |
3996 transition(vtos, state); |
4037 // access constant pool cache |
4008 // access constant pool cache |
4038 __ get_cache_and_index_at_bcp(Rcache, Rindex, 2); |
4009 __ get_cache_and_index_at_bcp(Rcache, Rindex, 2); |
4039 __ add(Rtemp, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord)); |
4010 __ add(Rtemp, Rcache, AsmOperand(Rindex, lsl, LogBytesPerWord)); |
4040 __ ldr(Roffset, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset())); |
4011 __ ldr(Roffset, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset())); |
4041 |
4012 |
4042 const bool gen_volatile_check = os::is_MP(); |
4013 // load flags to test volatile |
4043 |
4014 __ ldr_u32(Rflags, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); |
4044 if (gen_volatile_check) { |
|
4045 // load flags to test volatile |
|
4046 __ ldr_u32(Rflags, Address(Rtemp, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); |
|
4047 } |
|
4048 |
4015 |
4049 // make sure exception is reported in correct bcp range (getfield is next instruction) |
4016 // make sure exception is reported in correct bcp range (getfield is next instruction) |
4050 __ add(Rbcp, Rbcp, 1); |
4017 __ add(Rbcp, Rbcp, 1); |
4051 __ null_check(Robj, Rtemp); |
4018 __ null_check(Robj, Rtemp); |
4052 __ sub(Rbcp, Rbcp, 1); |
4019 __ sub(Rbcp, Rbcp, 1); |
4053 |
4020 |
4054 #ifdef AARCH64 |
4021 #ifdef AARCH64 |
4055 if (gen_volatile_check) { |
4022 Label notVolatile; |
4056 Label notVolatile; |
4023 __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
4057 __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile); |
4024 |
4058 |
4025 __ add(Rtemp, Robj, Roffset); |
4059 __ add(Rtemp, Robj, Roffset); |
4026 |
4060 |
4027 if (state == itos) { |
4061 if (state == itos) { |
4028 __ ldar_w(R0_tos, Rtemp); |
|
4029 } else if (state == atos) { |
|
4030 if (UseCompressedOops) { |
4062 __ ldar_w(R0_tos, Rtemp); |
4031 __ ldar_w(R0_tos, Rtemp); |
4063 } else if (state == atos) { |
4032 __ decode_heap_oop(R0_tos); |
4064 if (UseCompressedOops) { |
|
4065 __ ldar_w(R0_tos, Rtemp); |
|
4066 __ decode_heap_oop(R0_tos); |
|
4067 } else { |
|
4068 __ ldar(R0_tos, Rtemp); |
|
4069 } |
|
4070 __ verify_oop(R0_tos); |
|
4071 } else if (state == ftos) { |
|
4072 __ ldar_w(R0_tos, Rtemp); |
|
4073 __ fmov_sw(S0_tos, R0_tos); |
|
4074 } else { |
4033 } else { |
4075 ShouldNotReachHere(); |
4034 __ ldar(R0_tos, Rtemp); |
4076 } |
4035 } |
4077 __ b(done); |
4036 __ verify_oop(R0_tos); |
4078 |
4037 } else if (state == ftos) { |
4079 __ bind(notVolatile); |
4038 __ ldar_w(R0_tos, Rtemp); |
4080 } |
4039 __ fmov_sw(S0_tos, R0_tos); |
|
4040 } else { |
|
4041 ShouldNotReachHere(); |
|
4042 } |
|
4043 __ b(done); |
|
4044 |
|
4045 __ bind(notVolatile); |
4081 #endif // AARCH64 |
4046 #endif // AARCH64 |
4082 |
4047 |
4083 if (state == itos) { |
4048 if (state == itos) { |
4084 __ access_load_at(T_INT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); |
4049 __ access_load_at(T_INT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); |
4085 } else if (state == atos) { |
4050 } else if (state == atos) { |