src/hotspot/cpu/arm/templateTable_arm.cpp
changeset 51996 84743156e780
parent 51948 5ba442f14818
child 52351 0ecb4e520110
equal deleted inserted replaced
51995:f7babf9d1592 51996:84743156e780
  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) {
  4098   } else {
  4063   } else {
  4099     ShouldNotReachHere();
  4064     ShouldNotReachHere();
  4100   }
  4065   }
  4101 
  4066 
  4102 #ifndef AARCH64
  4067 #ifndef AARCH64
  4103   if (gen_volatile_check) {
  4068   // Check for volatile load
  4104     // Check for volatile load
  4069   Label notVolatile;
  4105     Label notVolatile;
  4070   __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
  4106     __ tbz(Rflags, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
  4071 
  4107 
  4072   volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);
  4108     volatile_barrier(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);
  4073 
  4109 
  4074   __ bind(notVolatile);
  4110     __ bind(notVolatile);
       
  4111   }
       
  4112 #endif // !AARCH64
  4075 #endif // !AARCH64
  4113 
  4076 
  4114   __ bind(done);
  4077   __ bind(done);
  4115 }
  4078 }
  4116 
  4079