diff options
author | 2023-12-13 16:16:41 +0000 | |
---|---|---|
committer | 2024-01-05 09:06:45 +0000 | |
commit | 853bebba8b6bb910f55894b9b9b0101953678b6c (patch) | |
tree | f77790b265149654273fa020f7a0f146f082b5e4 /compiler/optimizing/intrinsics_riscv64.cc | |
parent | cd8e7be022465b0845cde65a6563f471d7e2a572 (diff) |
riscv64: Fix heap poisoning.
Fix heap poisoning for stubs, nterp, codegen and some
intrinsics and disable a few intrinsics broken for the
heap poisoning configuration.
Note that this fixes heap poisoning only for the CC GC.
The heap poisoning is pobably still broken for CMC GC.
Test: Build with `ART_HEAP_POISONING=true`, then
testrunner.py --target --64 --ndebug --optimizing --interpreter
Bug: 283082089
Change-Id: I386235f6379722e1b2355150ab7d14f2ffb0da85
Diffstat (limited to 'compiler/optimizing/intrinsics_riscv64.cc')
-rw-r--r-- | compiler/optimizing/intrinsics_riscv64.cc | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/compiler/optimizing/intrinsics_riscv64.cc b/compiler/optimizing/intrinsics_riscv64.cc index 7f99f91374..8b85ea4538 100644 --- a/compiler/optimizing/intrinsics_riscv64.cc +++ b/compiler/optimizing/intrinsics_riscv64.cc @@ -2022,6 +2022,9 @@ static void CreateUnsafePutLocations(ArenaAllocator* allocator, HInvoke* invoke) locations->SetInAt(1, Location::RequiresRegister()); locations->SetInAt(2, Location::RequiresRegister()); locations->SetInAt(3, Location::RequiresRegister()); + if (kPoisonHeapReferences && invoke->InputAt(3)->GetType() == DataType::Type::kReference) { + locations->AddTemp(Location::RequiresRegister()); + } } static void GenUnsafePut(HInvoke* invoke, @@ -2038,7 +2041,10 @@ static void GenUnsafePut(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()`. ScratchRegisterScope srs(assembler); - XRegister address = srs.AllocateXRegister(); + // Heap poisoning needs two scratch registers in `Store()`. + XRegister address = (kPoisonHeapReferences && type == DataType::Type::kReference) + ? locations->GetTemp(0).AsRegister<XRegister>() + : srs.AllocateXRegister(); __ Add(address, base, offset); GenerateSet(codegen, order, value, address, /*offset=*/ 0, type); } @@ -2411,6 +2417,11 @@ void IntrinsicLocationsBuilderRISCV64::VisitJdkUnsafeCompareAndSetReference(HInv return; } + // TODO(riscv64): Fix this intrinsic for heap poisoning configuration. + if (kPoisonHeapReferences) { + return; + } + CreateUnsafeCASLocations(allocator_, invoke, codegen_); if (codegen_->EmitReadBarrier()) { DCHECK(kUseBakerReadBarrier); @@ -2572,6 +2583,11 @@ void IntrinsicCodeGeneratorRISCV64::VisitJdkUnsafeGetAndSetLong(HInvoke* invoke) } void IntrinsicLocationsBuilderRISCV64::VisitJdkUnsafeGetAndSetReference(HInvoke* invoke) { + // TODO(riscv64): Fix this intrinsic for heap poisoning configuration. + if (kPoisonHeapReferences) { + return; + } + CreateUnsafeGetAndUpdateLocations(allocator_, invoke, codegen_); } @@ -3184,6 +3200,14 @@ static void CreateVarHandleSetLocations(HInvoke* invoke, CodeGeneratorRISCV64* c } CreateVarHandleCommonLocations(invoke, codegen); + if (kPoisonHeapReferences && invoke->GetLocations() != nullptr) { + LocationSummary* locations = invoke->GetLocations(); + uint32_t value_index = invoke->GetNumberOfArguments() - 1; + DataType::Type value_type = GetDataTypeFromShorty(invoke, value_index); + if (value_type == DataType::Type::kReference && !locations->InAt(value_index).IsConstant()) { + locations->AddTemp(Location::RequiresRegister()); + } + } } static void GenerateVarHandleSet(HInvoke* invoke, @@ -3208,7 +3232,11 @@ static void GenerateVarHandleSet(HInvoke* invoke, { ScratchRegisterScope srs(assembler); - XRegister address = srs.AllocateXRegister(); + // Heap poisoning needs two scratch registers in `Store()`, except for null constants. + XRegister address = + (kPoisonHeapReferences && value_type == DataType::Type::kReference && !value.IsConstant()) + ? invoke->GetLocations()->GetTemp(0).AsRegister<XRegister>() + : srs.AllocateXRegister(); __ Add(address, target.object, target.offset); if (byte_swap) { @@ -3302,6 +3330,11 @@ static void CreateVarHandleCompareAndSetOrExchangeLocations(HInvoke* invoke, return; } + // TODO(riscv64): Fix this intrinsic for heap poisoning configuration. + if (kPoisonHeapReferences && value_type == DataType::Type::kReference) { + return; + } + LocationSummary* locations = CreateVarHandleCommonLocations(invoke, codegen); DCHECK_EQ(expected_index, 1u + GetExpectedVarHandleCoordinatesCount(invoke)); @@ -3716,6 +3749,11 @@ static void CreateVarHandleGetAndUpdateLocations(HInvoke* invoke, return; } + // TODO(riscv64): Fix this intrinsic for heap poisoning configuration. + if (kPoisonHeapReferences && invoke->GetType() == DataType::Type::kReference) { + return; + } + LocationSummary* locations = CreateVarHandleCommonLocations(invoke, codegen); uint32_t arg_index = invoke->GetNumberOfArguments() - 1; DCHECK_EQ(arg_index, 1u + GetExpectedVarHandleCoordinatesCount(invoke)); |