diff options
Diffstat (limited to 'compiler/optimizing/intrinsics_arm64.cc')
-rw-r--r-- | compiler/optimizing/intrinsics_arm64.cc | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index 6c3938c1a9..934ba1b9fb 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -853,7 +853,6 @@ static void GenUnsafeGet(HInvoke* invoke, DCHECK((type == Primitive::kPrimInt) || (type == Primitive::kPrimLong) || (type == Primitive::kPrimNot)); - MacroAssembler* masm = codegen->GetVIXLAssembler(); Location base_loc = locations->InAt(1); Register base = WRegisterFrom(base_loc); // Object pointer. Location offset_loc = locations->InAt(2); @@ -863,8 +862,7 @@ static void GenUnsafeGet(HInvoke* invoke, if (type == Primitive::kPrimNot && kEmitCompilerReadBarrier && kUseBakerReadBarrier) { // UnsafeGetObject/UnsafeGetObjectVolatile with Baker's read barrier case. - UseScratchRegisterScope temps(masm); - Register temp = temps.AcquireW(); + Register temp = WRegisterFrom(locations->GetTemp(0)); codegen->GenerateReferenceLoadWithBakerReadBarrier(invoke, trg_loc, base, @@ -901,6 +899,9 @@ static void CreateIntIntIntToIntLocations(ArenaAllocator* arena, HInvoke* invoke kIntrinsified); if (can_call && kUseBakerReadBarrier) { locations->SetCustomSlowPathCallerSaves(RegisterSet::Empty()); // No caller-save registers. + // We need a temporary register for the read barrier marking slow + // path in CodeGeneratorARM64::GenerateReferenceLoadWithBakerReadBarrier. + locations->AddTemp(Location::RequiresRegister()); } locations->SetInAt(0, Location::NoLocation()); // Unused receiver. locations->SetInAt(1, Location::RequiresRegister()); @@ -2381,9 +2382,14 @@ void IntrinsicLocationsBuilderARM64::VisitSystemArrayCopy(HInvoke* invoke) { // Temporary register IP0, obtained from the VIXL scratch register // pool, cannot be used in ReadBarrierSystemArrayCopySlowPathARM64 // (because that register is clobbered by ReadBarrierMarkRegX - // entry points). Get an extra temporary register from the - // register allocator. + // entry points). It cannot be used in calls to + // CodeGeneratorARM64::GenerateFieldLoadWithBakerReadBarrier + // either. For these reasons, get a third extra temporary register + // from the register allocator. locations->AddTemp(Location::RequiresRegister()); + } else { + // Cases other than Baker read barriers: the third temporary will + // be acquired from the VIXL scratch register pool. } } @@ -2494,11 +2500,12 @@ void IntrinsicCodeGeneratorARM64::VisitSystemArrayCopy(HInvoke* invoke) { // We use a block to end the scratch scope before the write barrier, thus // freeing the temporary registers so they can be used in `MarkGCCard`. UseScratchRegisterScope temps(masm); - // Note: Because it is acquired from VIXL's scratch register pool, - // `temp3` might be IP0, and thus cannot be used as `ref` argument - // of CodeGeneratorARM64::GenerateFieldLoadWithBakerReadBarrier - // calls below (see ReadBarrierMarkSlowPathARM64 for more details). - Register temp3 = temps.AcquireW(); + Register temp3; + if (kEmitCompilerReadBarrier && kUseBakerReadBarrier) { + temp3 = WRegisterFrom(locations->GetTemp(2)); + } else { + temp3 = temps.AcquireW(); + } if (!optimizations.GetDoesNotNeedTypeCheck()) { // Check whether all elements of the source array are assignable to the component @@ -2704,19 +2711,7 @@ void IntrinsicCodeGeneratorARM64::VisitSystemArrayCopy(HInvoke* invoke) { Register src_curr_addr = temp1.X(); Register dst_curr_addr = temp2.X(); - Register src_stop_addr; - if (kEmitCompilerReadBarrier && kUseBakerReadBarrier) { - // Temporary register IP0, obtained from the VIXL scratch - // register pool as `temp3`, cannot be used in - // ReadBarrierSystemArrayCopySlowPathARM64 (because that - // register is clobbered by ReadBarrierMarkRegX entry points). - // So another temporary register allocated by the register - // allocator instead. - DCHECK_EQ(LocationFrom(temp3).reg(), IP0); - src_stop_addr = XRegisterFrom(locations->GetTemp(2)); - } else { - src_stop_addr = temp3.X(); - } + Register src_stop_addr = temp3.X(); GenSystemArrayCopyAddresses(masm, Primitive::kPrimNot, @@ -2732,6 +2727,8 @@ void IntrinsicCodeGeneratorARM64::VisitSystemArrayCopy(HInvoke* invoke) { const int32_t element_size = Primitive::ComponentSize(Primitive::kPrimNot); if (kEmitCompilerReadBarrier && kUseBakerReadBarrier) { + // TODO: Also convert this intrinsic to the IsGcMarking strategy? + // SystemArrayCopy implementation for Baker read barriers (see // also CodeGeneratorARM::GenerateReferenceLoadWithBakerReadBarrier): // @@ -2758,10 +2755,11 @@ void IntrinsicCodeGeneratorARM64::VisitSystemArrayCopy(HInvoke* invoke) { __ Cmp(src_curr_addr, src_stop_addr); __ B(&done, eq); - Register tmp = temps.AcquireW(); // Make sure `tmp` is not IP0, as it is clobbered by // ReadBarrierMarkRegX entry points in // ReadBarrierSystemArrayCopySlowPathARM64. + temps.Exclude(ip0); + Register tmp = temps.AcquireW(); DCHECK_NE(LocationFrom(tmp).reg(), IP0); // /* int32_t */ monitor = src->monitor_ |