summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_builder.cc
diff options
context:
space:
mode:
authorAndra Danciu <andradanciu@google.com>2020-09-17 09:00:15 +0000
committerVladimir Marko <vmarko@google.com>2020-09-22 11:52:55 +0000
commitd0f71f26f0f23d7a054ccdde552a9c6003fd33a6 (patch)
tree4a86250064448fc85678969ba70e9c28d487e65a /compiler/optimizing/instruction_builder.cc
parentfdb81da69234b482ddcf5089d6821bb60dc93868 (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.cc34
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();
}