Make class status volatile.
Discourage loads and stores from reordering around the status being updated.
Bug: 15347354
Change-Id: Ice805cb834617747c8209e98a142d3e5c7585719
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 4869b45..4b02c0f 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -105,11 +105,11 @@
self->SetException(gc_safe_throw_location, old_exception.Get());
}
- CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this);
+ COMPILE_ASSERT(sizeof(Status) == sizeof(uint32_t), size_of_status_not_uint32);
if (Runtime::Current()->IsActiveTransaction()) {
- SetField32<true>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
+ SetField32Volatile<true>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
} else {
- SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
+ SetField32Volatile<false>(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status);
}
// Classes that are being resolved or initialized need to notify waiters that the class status
// changed. See ClassLinker::EnsureResolved and ClassLinker::WaitForInitializeClass.
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 40c9975..90381a7 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -125,7 +125,8 @@
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Status GetStatus() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
COMPILE_ASSERT(sizeof(Status) == sizeof(uint32_t), size_of_status_not_uint32);
- return static_cast<Status>(GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, status_)));
+ return static_cast<Status>(
+ GetField32Volatile<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Class, status_)));
}
void SetStatus(Status new_status, Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);