summaryrefslogtreecommitdiff
path: root/compiler/optimizing/intrinsics_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/intrinsics_utils.h')
-rw-r--r--compiler/optimizing/intrinsics_utils.h23
1 files changed, 23 insertions, 0 deletions
diff --git a/compiler/optimizing/intrinsics_utils.h b/compiler/optimizing/intrinsics_utils.h
index f24454786e..19f5e332a8 100644
--- a/compiler/optimizing/intrinsics_utils.h
+++ b/compiler/optimizing/intrinsics_utils.h
@@ -19,6 +19,7 @@
#include "base/casts.h"
#include "base/macros.h"
+#include "class_root-inl.h"
#include "code_generator.h"
#include "data_type-inl.h"
#include "dex/dex_file-inl.h"
@@ -196,6 +197,28 @@ static inline DataType::Type GetVarHandleExpectedValueType(HInvoke* invoke,
}
}
+static inline ArtField* GetBootImageVarHandleField(HInvoke* invoke)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ DCHECK_LE(GetExpectedVarHandleCoordinatesCount(invoke), 1u);
+ DCHECK(VarHandleOptimizations(invoke).GetUseKnownBootImageVarHandle());
+ HInstruction* var_handle_instruction = invoke->InputAt(0);
+ if (var_handle_instruction->IsNullCheck()) {
+ var_handle_instruction = var_handle_instruction->InputAt(0);
+ }
+ DCHECK(var_handle_instruction->IsStaticFieldGet());
+ ArtField* field = var_handle_instruction->AsStaticFieldGet()->GetFieldInfo().GetField();
+ DCHECK(field->IsStatic());
+ DCHECK(field->IsFinal());
+ DCHECK(var_handle_instruction->InputAt(0)->AsLoadClass()->IsInBootImage());
+ ObjPtr<mirror::Object> var_handle = field->GetObject(field->GetDeclaringClass());
+ DCHECK(var_handle->GetClass() ==
+ (GetExpectedVarHandleCoordinatesCount(invoke) == 0u
+ ? GetClassRoot<mirror::StaticFieldVarHandle>()
+ : GetClassRoot<mirror::FieldVarHandle>()));
+ static_assert(std::is_base_of_v<mirror::FieldVarHandle, mirror::StaticFieldVarHandle>);
+ return ObjPtr<mirror::FieldVarHandle>::DownCast(var_handle)->GetArtField();
+}
+
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_INTRINSICS_UTILS_H_