summaryrefslogtreecommitdiff
path: root/compiler/driver/dex_compilation_unit.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/driver/dex_compilation_unit.cc')
-rw-r--r--compiler/driver/dex_compilation_unit.cc32
1 files changed, 32 insertions, 0 deletions
diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc
index 654eccdad6..e5a6f0e177 100644
--- a/compiler/driver/dex_compilation_unit.cc
+++ b/compiler/driver/dex_compilation_unit.cc
@@ -16,10 +16,14 @@
#include "dex_compilation_unit.h"
+#include "art_field.h"
#include "base/utils.h"
+#include "dex/class_accessor-inl.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/descriptors_names.h"
+#include "mirror/class-inl.h"
#include "mirror/dex_cache.h"
+#include "scoped_thread_state_change-inl.h"
namespace art {
@@ -53,4 +57,32 @@ const std::string& DexCompilationUnit::GetSymbol() {
return symbol_;
}
+bool DexCompilationUnit::RequiresConstructorBarrier() const {
+ // Constructor barriers are applicable only for <init> methods.
+ DCHECK(!IsStatic());
+ DCHECK(IsConstructor());
+
+ // We require a constructor barrier if there are final instance fields.
+ if (GetCompilingClass().GetReference() != nullptr && !GetCompilingClass().IsNull()) {
+ // Decoding class data can be slow, so iterate over fields of the compiling class if resolved.
+ ScopedObjectAccess soa(Thread::Current());
+ ObjPtr<mirror::Class> compiling_class = GetCompilingClass().Get();
+ for (size_t i = 0, size = compiling_class->NumInstanceFields(); i != size; ++i) {
+ ArtField* field = compiling_class->GetInstanceField(i);
+ if (field->IsFinal()) {
+ return true;
+ }
+ }
+ } else {
+ // Iterate over field definitions in the class data.
+ ClassAccessor accessor(*GetDexFile(), GetClassDefIndex());
+ for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) {
+ if (field.IsFinal()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
} // namespace art