summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2017-10-24 00:26:43 +0000
committer android-build-merger <android-build-merger@google.com> 2017-10-24 00:26:43 +0000
commitfa3fc51c254d726e9d5e1037726c9b2cf90965fc (patch)
treea17d92231591efac09f471ab5cb0c27e12f50b5b
parent51b44934399b6d97fa88a2a33692e566c2ac3556 (diff)
parent2a96120f0a67838355b2134c6038f29cc4576ba0 (diff)
Merge "ART: Correct static invariant checks"
am: 2a96120f0a Change-Id: I45d088796ae13263a56919c6dced9851cdf8fa1b
-rw-r--r--runtime/common_dex_operations.h16
-rw-r--r--runtime/interpreter/interpreter.cc6
2 files changed, 18 insertions, 4 deletions
diff --git a/runtime/common_dex_operations.h b/runtime/common_dex_operations.h
index 4d5bd3fdce..6a78637ab1 100644
--- a/runtime/common_dex_operations.h
+++ b/runtime/common_dex_operations.h
@@ -71,6 +71,18 @@ inline void PerformCall(Thread* self,
}
}
+template <typename T>
+inline void DCheckStaticState(Thread* self, T* entity) REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (kIsDebugBuild) {
+ ObjPtr<mirror::Class> klass = entity->GetDeclaringClass();
+ if (entity->IsStatic()) {
+ klass->AssertInitializedOrInitializingInThread(self);
+ } else {
+ CHECK(klass->IsInitializing() || klass->IsErroneousResolved());
+ }
+ }
+}
+
template<Primitive::Type field_type>
static ALWAYS_INLINE bool DoFieldGetCommon(Thread* self,
const ShadowFrame& shadow_frame,
@@ -78,7 +90,7 @@ static ALWAYS_INLINE bool DoFieldGetCommon(Thread* self,
ArtField* field,
JValue* result)
REQUIRES_SHARED(Locks::mutator_lock_) {
- field->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
+ DCheckStaticState(self, field);
// Report this field access to instrumentation if needed.
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
@@ -136,7 +148,7 @@ ALWAYS_INLINE bool DoFieldPutCommon(Thread* self,
ArtField* field,
JValue& value)
REQUIRES_SHARED(Locks::mutator_lock_) {
- field->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
+ DCheckStaticState(self, field);
// Report this field access to instrumentation if needed. Since we only have the offset of
// the field from the base of the object, we need to look for it first.
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 68a75b0196..2deb3b7cf5 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -18,6 +18,7 @@
#include <limits>
+#include "common_dex_operations.h"
#include "common_throws.h"
#include "dex_file_types.h"
#include "interpreter_common.h"
@@ -287,11 +288,12 @@ static inline JValue Execute(
}
}
- shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
+ ArtMethod* method = shadow_frame.GetMethod();
+
+ DCheckStaticState(self, method);
// Lock counting is a special version of accessibility checks, and for simplicity and
// reduction of template parameters, we gate it behind access-checks mode.
- ArtMethod* method = shadow_frame.GetMethod();
DCHECK(!method->SkipAccessChecks() || !method->MustCountLocks());
bool transaction_active = Runtime::Current()->IsActiveTransaction();