diff options
author | Andra Danciu <andradanciu@google.com> | 2020-09-17 09:00:15 +0000 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2020-09-22 11:52:55 +0000 |
commit | d0f71f26f0f23d7a054ccdde552a9c6003fd33a6 (patch) | |
tree | 4a86250064448fc85678969ba70e9c28d487e65a /compiler/optimizing/instruction_builder.cc | |
parent | fdb81da69234b482ddcf5089d6821bb60dc93868 (diff) |
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
Diffstat (limited to 'compiler/optimizing/instruction_builder.cc')
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 34 |
1 files changed, 24 insertions, 10 deletions
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<uint32_t>(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(); } |