Do not cache RequiresConstructorBarrier() results.

Avoid caching the results. Caching was broken for JIT in the
presence of class unloading; entries for unloaded dex files
were leaked and potentially used erroneously with a newly
loaded dex file.

Test: m test-art-host-gtest
Test: testrunner.py --host
Test: Pixel 2 XL boots.
Test: m test-art-target-gtest
Test: testrunner.py --target
Bug: 118808764
Change-Id: Ic1163601170364e060c2e3009752f543c9bb37b7
diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc
index 654eccd..e5a6f0e 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 @@
   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