From d0f71f26f0f23d7a054ccdde552a9c6003fd33a6 Mon Sep 17 00:00:00 2001 From: Andra Danciu Date: Thu, 17 Sep 2020 09:00:15 +0000 Subject: X86: Add the other get VarHandles (getVolatile, getAcquire, getOpaque) This commit implements VarHandle.getVolatile, getAcquire and getOpaque intrinsics. Test: ART_HEAP_POISONING=true art/test.py --host -r -t 712-varhandle-invocation --32 Test: ART_HEAP_POISONING=false art/test.py --host -r -t 712-varhandle-invocation --32 Test: ART_USE_READ_BARRIER=true art/test.py --host -r -t 712-varhandle-invocation --32 Test: ART_USE_READ_BARRIER=false art/test.py --host -r -t 712-varhandle-invocation --32 Bug: 65872996 Change-Id: I38501c226c9d5af0a9e5a1230abcb3114aad4737 --- compiler/optimizing/instruction_builder.cc | 34 +++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'compiler/optimizing/instruction_builder.cc') diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 9fb9c4e7fe..4615342da7 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -29,6 +29,8 @@ #include "driver/dex_compilation_unit.h" #include "driver/compiler_options.h" #include "imtable-inl.h" +#include "intrinsics.h" +#include "intrinsics_utils.h" #include "jit/jit.h" #include "mirror/dex_cache.h" #include "oat_file.h" @@ -1148,6 +1150,21 @@ bool HInstructionBuilder::BuildInvoke(const Instruction& instruction, return HandleInvoke(invoke, operands, shorty, /* is_unresolved= */ false); } +static bool VarHandleAccessorNeedsReturnTypeCheck(HInvoke* invoke, DataType::Type return_type) { + mirror::VarHandle::AccessModeTemplate access_mode_template = + mirror::VarHandle::GetAccessModeTemplateByIntrinsic(invoke->GetIntrinsic()); + + switch (access_mode_template) { + case mirror::VarHandle::AccessModeTemplate::kGet: + case mirror::VarHandle::AccessModeTemplate::kGetAndUpdate: + case mirror::VarHandle::AccessModeTemplate::kCompareAndExchange: + return return_type == DataType::Type::kReference; + case mirror::VarHandle::AccessModeTemplate::kSet: + case mirror::VarHandle::AccessModeTemplate::kCompareAndSet: + return false; + } +} + bool HInstructionBuilder::BuildInvokePolymorphic(uint32_t dex_pc, uint32_t method_idx, dex::ProtoIndex proto_idx, @@ -1180,19 +1197,16 @@ bool HInstructionBuilder::BuildInvokePolymorphic(uint32_t dex_pc, return false; } - bool needs_ret_type_check = - resolved_method->GetIntrinsic() == static_cast(Intrinsics::kVarHandleGet) && - return_type == DataType::Type::kReference && - // VarHandle.get() is only implemented for fields now. - number_of_arguments < 3u; - if (needs_ret_type_check) { + if (invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvoke && + invoke->GetIntrinsic() != Intrinsics::kMethodHandleInvokeExact && + VarHandleAccessorNeedsReturnTypeCheck(invoke, return_type)) { + // Type check is needed because VarHandle intrinsics do not type check the retrieved reference. ScopedObjectAccess soa(Thread::Current()); ArtMethod* referrer = graph_->GetArtMethod(); - dex::TypeIndex ret_type_index = referrer->GetDexFile()->GetProtoId(proto_idx).return_type_idx_; + dex::TypeIndex return_type_index = + referrer->GetDexFile()->GetProtoId(proto_idx).return_type_idx_; - // Type check is needed because intrinsic implementations do not type check the retrieved - // reference. - BuildTypeCheck(/* is_instance_of= */ false, invoke, ret_type_index, dex_pc); + BuildTypeCheck(/* is_instance_of= */ false, invoke, return_type_index, dex_pc); latest_result_ = current_block_->GetLastInstruction(); } -- cgit v1.2.3-59-g8ed1b