diff options
-rw-r--r-- | compiler/dex/quick/gen_common.cc | 4 | ||||
-rw-r--r-- | compiler/llvm/gbc_expander.cc | 4 | ||||
-rw-r--r-- | runtime/mirror/class.cc | 6 | ||||
-rw-r--r-- | runtime/mirror/class.h | 3 |
4 files changed, 13 insertions, 4 deletions
diff --git a/compiler/dex/quick/gen_common.cc b/compiler/dex/quick/gen_common.cc index 4f2a87672a..03edf2ac39 100644 --- a/compiler/dex/quick/gen_common.cc +++ b/compiler/dex/quick/gen_common.cc @@ -603,6 +603,8 @@ void Mir2Lir::GenSput(MIR* mir, RegLocation rl_src, bool is_long_or_double, field_info.StorageIndex(), r_base)); FreeTemp(r_tmp); + // Ensure load of status and load of value don't re-order. + GenMemBarrier(kLoadLoad); } FreeTemp(r_method); } @@ -694,6 +696,8 @@ void Mir2Lir::GenSget(MIR* mir, RegLocation rl_dest, field_info.StorageIndex(), r_base)); FreeTemp(r_tmp); + // Ensure load of status and load of value don't re-order. + GenMemBarrier(kLoadLoad); } FreeTemp(r_method); } diff --git a/compiler/llvm/gbc_expander.cc b/compiler/llvm/gbc_expander.cc index 25c9b20514..f8dca66de0 100644 --- a/compiler/llvm/gbc_expander.cc +++ b/compiler/llvm/gbc_expander.cc @@ -1868,6 +1868,10 @@ llvm::Value* GBCExpanderPass::EmitLoadStaticStorage(uint32_t dex_pc, phi->addIncoming(storage_object_addr, block_check_init); phi->addIncoming(loaded_storage_object_addr, block_after_load_static); + + // Ensure load of status and load of value don't re-order. + irb_.CreateMemoryBarrier(art::kLoadLoad); + return phi; } diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index 4869b454fe..4b02c0ff60 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -105,11 +105,11 @@ void Class::SetStatus(Status new_status, Thread* self) { 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 40c9975cdd..90381a7dec 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -125,7 +125,8 @@ class MANAGED Class : public Object { 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_); |