From 90b936ddda63139ff46a6755c3b83ad6e4ab4ac5 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Tue, 31 Jan 2017 08:58:55 -0800 Subject: [PATCH] ART: Refactor verify_object.h Move the actual VerifyObject check into a new cc file, as we commonly don't enable the check at all. This allows to cut the -inl include from almost all current users. This also exposes missing -inl includes. Also fix up some of our old mess where .h defined functions require -inl.h defined functions. Test: m Change-Id: I3dd821bbe2015564a29bf1ed9be00f7a7276ad61 --- compiler/optimizing/ssa_builder.cc | 2 + compiler/optimizing/stack_map_stream.cc | 2 +- runtime/Android.bp | 1 + runtime/cha.cc | 1 + runtime/entrypoints/quick/quick_jni_entrypoints.cc | 2 +- runtime/gc/collector/concurrent_copying-inl.h | 1 + runtime/gc/heap-inl.h | 2 +- runtime/gc/heap.cc | 1 + runtime/handle_scope-inl.h | 2 +- runtime/handle_scope_test.cc | 2 + runtime/indirect_reference_table-inl.h | 2 +- runtime/indirect_reference_table.cc | 1 - runtime/jdwp/object_registry.cc | 1 + runtime/mirror/class-inl.h | 17 ----- runtime/mirror/class.cc | 21 ++++++ runtime/mirror/class.h | 11 ++- runtime/mirror/method_handle_impl.h | 2 +- runtime/mirror/method_type_test.cc | 7 +- runtime/mirror/object-inl.h | 87 +++++----------------- runtime/mirror/object.h | 34 ++++++++- runtime/native/java_lang_String.cc | 2 +- runtime/native/java_lang_Thread.cc | 2 +- runtime/native/java_lang_reflect_Proxy.cc | 2 +- runtime/oat_file_manager.cc | 3 + runtime/openjdkjvm/OpenjdkJvm.cc | 2 +- runtime/scoped_thread_state_change-inl.h | 4 + runtime/scoped_thread_state_change.h | 8 +- runtime/stack.cc | 2 +- runtime/thread.cc | 2 +- runtime/verify_object-inl.h | 22 ------ runtime/verify_object.cc | 47 ++++++++++++ runtime/verify_object.h | 11 ++- .../clear_dex_cache_types.cc | 3 + 33 files changed, 176 insertions(+), 133 deletions(-) create mode 100644 runtime/verify_object.cc diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index ae1e36999..487e4dd49 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -17,8 +17,10 @@ #include "ssa_builder.h" #include "bytecode_utils.h" +#include "mirror/class-inl.h" #include "nodes.h" #include "reference_type_propagation.h" +#include "scoped_thread_state_change-inl.h" #include "ssa_phi_elimination.h" namespace art { diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc index 668108daa..e4d480061 100644 --- a/compiler/optimizing/stack_map_stream.cc +++ b/compiler/optimizing/stack_map_stream.cc @@ -18,8 +18,8 @@ #include +#include "art_method-inl.h" #include "base/stl_util.h" -#include "art_method.h" #include "runtime.h" #include "scoped_thread_state_change-inl.h" diff --git a/runtime/Android.bp b/runtime/Android.bp index 276f3043d..1bae245b4 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -208,6 +208,7 @@ cc_defaults { "verifier/reg_type_cache.cc", "verifier/register_line.cc", "verifier/verifier_deps.cc", + "verify_object.cc", "well_known_classes.cc", "zip_archive.cc", diff --git a/runtime/cha.cc b/runtime/cha.cc index e726bdbcb..d11b12f70 100644 --- a/runtime/cha.cc +++ b/runtime/cha.cc @@ -16,6 +16,7 @@ #include "cha.h" +#include "art_method-inl.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" #include "runtime.h" diff --git a/runtime/entrypoints/quick/quick_jni_entrypoints.cc b/runtime/entrypoints/quick/quick_jni_entrypoints.cc index 670dadcd4..158c1d634 100644 --- a/runtime/entrypoints/quick/quick_jni_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_jni_entrypoints.cc @@ -20,7 +20,7 @@ #include "indirect_reference_table.h" #include "mirror/object-inl.h" #include "thread-inl.h" -#include "verify_object-inl.h" +#include "verify_object.h" namespace art { diff --git a/runtime/gc/collector/concurrent_copying-inl.h b/runtime/gc/collector/concurrent_copying-inl.h index 7c649525e..854d0a58f 100644 --- a/runtime/gc/collector/concurrent_copying-inl.h +++ b/runtime/gc/collector/concurrent_copying-inl.h @@ -22,6 +22,7 @@ #include "gc/accounting/space_bitmap-inl.h" #include "gc/heap.h" #include "gc/space/region_space.h" +#include "mirror/object-inl.h" #include "lock_word.h" namespace art { diff --git a/runtime/gc/heap-inl.h b/runtime/gc/heap-inl.h index 54f221056..394e541fd 100644 --- a/runtime/gc/heap-inl.h +++ b/runtime/gc/heap-inl.h @@ -34,7 +34,7 @@ #include "handle_scope-inl.h" #include "thread-inl.h" #include "utils.h" -#include "verify_object-inl.h" +#include "verify_object.h" namespace art { namespace gc { diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index aa1571459..fc475b5e5 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -78,6 +78,7 @@ #include "scoped_thread_state_change-inl.h" #include "handle_scope-inl.h" #include "thread_list.h" +#include "verify_object-inl.h" #include "well_known_classes.h" namespace art { diff --git a/runtime/handle_scope-inl.h b/runtime/handle_scope-inl.h index b212d095c..077f45e8f 100644 --- a/runtime/handle_scope-inl.h +++ b/runtime/handle_scope-inl.h @@ -23,7 +23,7 @@ #include "handle.h" #include "obj_ptr-inl.h" #include "thread-inl.h" -#include "verify_object-inl.h" +#include "verify_object.h" namespace art { diff --git a/runtime/handle_scope_test.cc b/runtime/handle_scope_test.cc index aab1d9c22..f888482ae 100644 --- a/runtime/handle_scope_test.cc +++ b/runtime/handle_scope_test.cc @@ -17,10 +17,12 @@ #include #include "base/enums.h" +#include "class_linker-inl.h" #include "common_runtime_test.h" #include "gtest/gtest.h" #include "handle.h" #include "handle_scope-inl.h" +#include "mirror/class-inl.h" #include "mirror/object.h" #include "scoped_thread_state_change-inl.h" #include "thread.h" diff --git a/runtime/indirect_reference_table-inl.h b/runtime/indirect_reference_table-inl.h index 0e66ae96b..24ee22759 100644 --- a/runtime/indirect_reference_table-inl.h +++ b/runtime/indirect_reference_table-inl.h @@ -25,7 +25,7 @@ #include "gc_root-inl.h" #include "obj_ptr-inl.h" #include "runtime-inl.h" -#include "verify_object-inl.h" +#include "verify_object.h" namespace art { namespace mirror { diff --git a/runtime/indirect_reference_table.cc b/runtime/indirect_reference_table.cc index c7371191b..9fbb2e993 100644 --- a/runtime/indirect_reference_table.cc +++ b/runtime/indirect_reference_table.cc @@ -25,7 +25,6 @@ #include "scoped_thread_state_change-inl.h" #include "thread.h" #include "utils.h" -#include "verify_object-inl.h" #include diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc index 170887e39..461557494 100644 --- a/runtime/jdwp/object_registry.cc +++ b/runtime/jdwp/object_registry.cc @@ -19,6 +19,7 @@ #include "handle_scope-inl.h" #include "jni_internal.h" #include "mirror/class.h" +#include "mirror/throwable.h" #include "obj_ptr-inl.h" #include "scoped_thread_state_change-inl.h" diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 6a65e1271..5465e3799 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -635,23 +635,6 @@ inline void Class::SetClinitThreadId(pid_t new_clinit_thread_id) { } } -template -inline uint32_t Class::GetAccessFlags() { - // Check class is loaded/retired or this is java.lang.String that has a - // circularity issue during loading the names of its members - DCHECK(IsIdxLoaded() || IsRetired() || - IsErroneous(kVerifyFlags & ~kVerifyThis)>() || - this == String::GetJavaLangString()) - << "IsIdxLoaded=" << IsIdxLoaded() - << " IsRetired=" << IsRetired() - << " IsErroneous=" << - IsErroneous(kVerifyFlags & ~kVerifyThis)>() - << " IsString=" << (this == String::GetJavaLangString()) - << " status= " << GetStatus() - << " descriptor=" << PrettyDescriptor(); - return GetField32(AccessFlagsOffset()); -} - inline String* Class::GetName() { return GetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, name_)); } diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index f08d4daf9..1b8f3f83e 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -1345,5 +1345,26 @@ std::string Class::PrettyClassAndClassLoader() { return result; } +template void Class::GetAccessFlagsDCheck() { + // Check class is loaded/retired or this is java.lang.String that has a + // circularity issue during loading the names of its members + DCHECK(IsIdxLoaded() || IsRetired() || + IsErroneous(kVerifyFlags & ~kVerifyThis)>() || + this == String::GetJavaLangString()) + << "IsIdxLoaded=" << IsIdxLoaded() + << " IsRetired=" << IsRetired() + << " IsErroneous=" << + IsErroneous(kVerifyFlags & ~kVerifyThis)>() + << " IsString=" << (this == String::GetJavaLangString()) + << " status= " << GetStatus() + << " descriptor=" << PrettyDescriptor(); +} +// Instantiate the common cases. +template void Class::GetAccessFlagsDCheck(); +template void Class::GetAccessFlagsDCheck(); +template void Class::GetAccessFlagsDCheck(); +template void Class::GetAccessFlagsDCheck(); +template void Class::GetAccessFlagsDCheck(); + } // namespace mirror } // namespace art diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index c9f27ad53..f8b8cdeb3 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -231,7 +231,13 @@ class MANAGED Class FINAL : public Object { } template - ALWAYS_INLINE uint32_t GetAccessFlags() REQUIRES_SHARED(Locks::mutator_lock_); + ALWAYS_INLINE uint32_t GetAccessFlags() REQUIRES_SHARED(Locks::mutator_lock_) { + if (kIsDebugBuild) { + GetAccessFlagsDCheck(); + } + return GetField32(AccessFlagsOffset()); + } + static MemberOffset AccessFlagsOffset() { return OFFSET_OF_OBJECT_MEMBER(Class, access_flags_); } @@ -1397,6 +1403,9 @@ class MANAGED Class FINAL : public Object { bool ProxyDescriptorEquals(const char* match) REQUIRES_SHARED(Locks::mutator_lock_); + template + void GetAccessFlagsDCheck() REQUIRES_SHARED(Locks::mutator_lock_); + // Check that the pointer size matches the one in the class linker. ALWAYS_INLINE static void CheckPointerSize(PointerSize pointer_size); diff --git a/runtime/mirror/method_handle_impl.h b/runtime/mirror/method_handle_impl.h index dca30626e..53d267b52 100644 --- a/runtime/mirror/method_handle_impl.h +++ b/runtime/mirror/method_handle_impl.h @@ -19,7 +19,7 @@ #include "class.h" #include "gc_root.h" -#include "object.h" +#include "object-inl.h" #include "method_handles.h" #include "method_type.h" diff --git a/runtime/mirror/method_type_test.cc b/runtime/mirror/method_type_test.cc index 03ab93069..637bafd75 100644 --- a/runtime/mirror/method_type_test.cc +++ b/runtime/mirror/method_type_test.cc @@ -19,12 +19,13 @@ #include #include +#include "class-inl.h" #include "class_linker.h" +#include "class_loader.h" #include "common_runtime_test.h" #include "handle_scope-inl.h" -#include "runtime/mirror/class.h" -#include "runtime/mirror/class_loader.h" -#include "scoped_thread_state_change.h" +#include "object_array-inl.h" +#include "scoped_thread_state_change-inl.h" namespace art { namespace mirror { diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 354410e6b..8e591e443 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -142,8 +142,10 @@ inline void Object::Wait(Thread* self, int64_t ms, int32_t ns) { } inline uint32_t Object::GetReadBarrierState(uintptr_t* fake_address_dependency) { -#ifdef USE_BAKER_READ_BARRIER - CHECK(kUseBakerReadBarrier); + if (!kUseBakerReadBarrier) { + LOG(FATAL) << "Unreachable"; + UNREACHABLE(); + } #if defined(__arm__) uintptr_t obj = reinterpret_cast(this); uintptr_t result; @@ -190,37 +192,29 @@ inline uint32_t Object::GetReadBarrierState(uintptr_t* fake_address_dependency) UNREACHABLE(); UNUSED(fake_address_dependency); #endif -#else // !USE_BAKER_READ_BARRIER - LOG(FATAL) << "Unreachable"; - UNREACHABLE(); - UNUSED(fake_address_dependency); -#endif } inline uint32_t Object::GetReadBarrierState() { -#ifdef USE_BAKER_READ_BARRIER + if (!kUseBakerReadBarrier) { + LOG(FATAL) << "Unreachable"; + UNREACHABLE(); + } DCHECK(kUseBakerReadBarrier); LockWord lw(GetField(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); uint32_t rb_state = lw.ReadBarrierState(); DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state; return rb_state; -#else - LOG(FATAL) << "Unreachable"; - UNREACHABLE(); -#endif } inline uint32_t Object::GetReadBarrierStateAcquire() { -#ifdef USE_BAKER_READ_BARRIER - DCHECK(kUseBakerReadBarrier); + if (!kUseBakerReadBarrier) { + LOG(FATAL) << "Unreachable"; + UNREACHABLE(); + } LockWord lw(GetFieldAcquire(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); uint32_t rb_state = lw.ReadBarrierState(); DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state; return rb_state; -#else - LOG(FATAL) << "Unreachable"; - UNREACHABLE(); -#endif } inline uint32_t Object::GetMarkBit() { @@ -233,23 +227,22 @@ inline uint32_t Object::GetMarkBit() { } inline void Object::SetReadBarrierState(uint32_t rb_state) { -#ifdef USE_BAKER_READ_BARRIER - DCHECK(kUseBakerReadBarrier); + if (!kUseBakerReadBarrier) { + LOG(FATAL) << "Unreachable"; + UNREACHABLE(); + } DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state; LockWord lw = GetLockWord(false); lw.SetReadBarrierState(rb_state); SetLockWord(lw, false); -#else - LOG(FATAL) << "Unreachable"; - UNREACHABLE(); - UNUSED(rb_state); -#endif } template inline bool Object::AtomicSetReadBarrierState(uint32_t expected_rb_state, uint32_t rb_state) { -#ifdef USE_BAKER_READ_BARRIER - DCHECK(kUseBakerReadBarrier); + if (!kUseBakerReadBarrier) { + LOG(FATAL) << "Unreachable"; + UNREACHABLE(); + } DCHECK(ReadBarrier::IsValidReadBarrierState(expected_rb_state)) << expected_rb_state; DCHECK(ReadBarrier::IsValidReadBarrierState(rb_state)) << rb_state; LockWord expected_lw; @@ -272,11 +265,6 @@ inline bool Object::AtomicSetReadBarrierState(uint32_t expected_rb_state, uint32 CasLockWordWeakRelease(expected_lw, new_lw) : CasLockWordWeakRelaxed(expected_lw, new_lw))); return true; -#else - UNUSED(expected_rb_state, rb_state); - LOG(FATAL) << "Unreachable"; - UNREACHABLE(); -#endif } inline bool Object::AtomicSetMarkBit(uint32_t expected_mark_bit, uint32_t mark_bit) { @@ -691,19 +679,6 @@ inline void Object::SetFieldShortVolatile(MemberOffset field_offset, int16_t new field_offset, new_value); } -template -inline int32_t Object::GetField32(MemberOffset field_offset) { - if (kVerifyFlags & kVerifyThis) { - VerifyObject(this); - } - return GetField(field_offset); -} - -template -inline int32_t Object::GetField32Volatile(MemberOffset field_offset) { - return GetField32(field_offset); -} - template inline void Object::SetField32(MemberOffset field_offset, int32_t new_value) { @@ -854,28 +829,6 @@ inline void Object::SetField64Volatile(MemberOffset field_offset, int64_t new_va new_value); } -template -inline void Object::SetField(MemberOffset field_offset, kSize new_value) { - uint8_t* raw_addr = reinterpret_cast(this) + field_offset.Int32Value(); - kSize* addr = reinterpret_cast(raw_addr); - if (kIsVolatile) { - reinterpret_cast*>(addr)->StoreSequentiallyConsistent(new_value); - } else { - reinterpret_cast*>(addr)->StoreJavaData(new_value); - } -} - -template -inline kSize Object::GetField(MemberOffset field_offset) { - const uint8_t* raw_addr = reinterpret_cast(this) + field_offset.Int32Value(); - const kSize* addr = reinterpret_cast(raw_addr); - if (kIsVolatile) { - return reinterpret_cast*>(addr)->LoadSequentiallyConsistent(); - } else { - return reinterpret_cast*>(addr)->LoadJavaData(); - } -} - template inline kSize Object::GetFieldAcquire(MemberOffset field_offset) { const uint8_t* raw_addr = reinterpret_cast(this) + field_offset.Int32Value(); diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index db58a6099..4541ce2a4 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -17,6 +17,7 @@ #ifndef ART_RUNTIME_MIRROR_OBJECT_H_ #define ART_RUNTIME_MIRROR_OBJECT_H_ +#include "atomic.h" #include "base/casts.h" #include "base/enums.h" #include "globals.h" @@ -432,11 +433,18 @@ class MANAGED LOCKABLE Object { template ALWAYS_INLINE int32_t GetField32(MemberOffset field_offset) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_) { + if (kVerifyFlags & kVerifyThis) { + VerifyObject(this); + } + return GetField(field_offset); + } template ALWAYS_INLINE int32_t GetField32Volatile(MemberOffset field_offset) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_) { + return GetField32(field_offset); + } template @@ -611,10 +619,28 @@ class MANAGED LOCKABLE Object { private: template ALWAYS_INLINE void SetField(MemberOffset field_offset, kSize new_value) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_) { + uint8_t* raw_addr = reinterpret_cast(this) + field_offset.Int32Value(); + kSize* addr = reinterpret_cast(raw_addr); + if (kIsVolatile) { + reinterpret_cast*>(addr)->StoreSequentiallyConsistent(new_value); + } else { + reinterpret_cast*>(addr)->StoreJavaData(new_value); + } + } + template ALWAYS_INLINE kSize GetField(MemberOffset field_offset) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_) { + const uint8_t* raw_addr = reinterpret_cast(this) + field_offset.Int32Value(); + const kSize* addr = reinterpret_cast(raw_addr); + if (kIsVolatile) { + return reinterpret_cast*>(addr)->LoadSequentiallyConsistent(); + } else { + return reinterpret_cast*>(addr)->LoadJavaData(); + } + } + // Get a field with acquire semantics. template ALWAYS_INLINE kSize GetFieldAcquire(MemberOffset field_offset) diff --git a/runtime/native/java_lang_String.cc b/runtime/native/java_lang_String.cc index ea266d131..f1d6ff5f7 100644 --- a/runtime/native/java_lang_String.cc +++ b/runtime/native/java_lang_String.cc @@ -25,7 +25,7 @@ #include "scoped_fast_native_object_access-inl.h" #include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" -#include "verify_object-inl.h" +#include "verify_object.h" namespace art { diff --git a/runtime/native/java_lang_Thread.cc b/runtime/native/java_lang_Thread.cc index fcb017545..195091f8a 100644 --- a/runtime/native/java_lang_Thread.cc +++ b/runtime/native/java_lang_Thread.cc @@ -25,7 +25,7 @@ #include "ScopedUtfChars.h" #include "thread.h" #include "thread_list.h" -#include "verify_object-inl.h" +#include "verify_object.h" namespace art { diff --git a/runtime/native/java_lang_reflect_Proxy.cc b/runtime/native/java_lang_reflect_Proxy.cc index ece0338c9..70cd6aaae 100644 --- a/runtime/native/java_lang_reflect_Proxy.cc +++ b/runtime/native/java_lang_reflect_Proxy.cc @@ -22,7 +22,7 @@ #include "mirror/object_array.h" #include "mirror/string.h" #include "scoped_fast_native_object_access-inl.h" -#include "verify_object-inl.h" +#include "verify_object.h" namespace art { diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index 33bd0f311..a46b47075 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -22,6 +22,7 @@ #include "android-base/stringprintf.h" +#include "art_field-inl.h" #include "base/logging.h" #include "base/stl_util.h" #include "base/systrace.h" @@ -32,11 +33,13 @@ #include "handle_scope-inl.h" #include "jni_internal.h" #include "mirror/class_loader.h" +#include "mirror/object-inl.h" #include "oat_file_assistant.h" #include "obj_ptr-inl.h" #include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "thread_list.h" +#include "well_known_classes.h" namespace art { diff --git a/runtime/openjdkjvm/OpenjdkJvm.cc b/runtime/openjdkjvm/OpenjdkJvm.cc index 2f51e27b2..bdaad20d7 100644 --- a/runtime/openjdkjvm/OpenjdkJvm.cc +++ b/runtime/openjdkjvm/OpenjdkJvm.cc @@ -46,7 +46,7 @@ #include "scoped_thread_state_change-inl.h" #include "ScopedUtfChars.h" #include "mirror/class_loader.h" -#include "verify_object-inl.h" +#include "verify_object.h" #include "base/logging.h" #include "base/macros.h" #include "../../libcore/ojluni/src/main/native/jvm.h" // TODO(narayan): fix it diff --git a/runtime/scoped_thread_state_change-inl.h b/runtime/scoped_thread_state_change-inl.h index d4469f435..000da59bd 100644 --- a/runtime/scoped_thread_state_change-inl.h +++ b/runtime/scoped_thread_state_change-inl.h @@ -110,6 +110,10 @@ inline ScopedObjectAccessUnchecked::ScopedObjectAccessUnchecked(Thread* self) Locks::mutator_lock_->AssertSharedHeld(Self()); } +inline ScopedObjectAccess::ScopedObjectAccess(JNIEnv* env) : ScopedObjectAccessUnchecked(env) {} +inline ScopedObjectAccess::ScopedObjectAccess(Thread* self) : ScopedObjectAccessUnchecked(self) {} +inline ScopedObjectAccess::~ScopedObjectAccess() {} + inline ScopedThreadSuspension::ScopedThreadSuspension(Thread* self, ThreadState suspended_state) : self_(self), suspended_state_(suspended_state) { DCHECK(self_ != nullptr); diff --git a/runtime/scoped_thread_state_change.h b/runtime/scoped_thread_state_change.h index b4992586c..24199f76b 100644 --- a/runtime/scoped_thread_state_change.h +++ b/runtime/scoped_thread_state_change.h @@ -159,16 +159,14 @@ class ScopedObjectAccess : public ScopedObjectAccessUnchecked { public: ALWAYS_INLINE explicit ScopedObjectAccess(JNIEnv* env) REQUIRES(!Locks::thread_suspend_count_lock_) - SHARED_LOCK_FUNCTION(Locks::mutator_lock_) - : ScopedObjectAccessUnchecked(env) {} + SHARED_LOCK_FUNCTION(Locks::mutator_lock_); ALWAYS_INLINE explicit ScopedObjectAccess(Thread* self) REQUIRES(!Locks::thread_suspend_count_lock_) - SHARED_LOCK_FUNCTION(Locks::mutator_lock_) - : ScopedObjectAccessUnchecked(self) {} + SHARED_LOCK_FUNCTION(Locks::mutator_lock_); // Base class will release share of lock. Invoked after this destructor. - ~ScopedObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE {} + ~ScopedObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE; private: // TODO: remove this constructor. It is used by check JNI's ScopedCheck to make it believe that diff --git a/runtime/stack.cc b/runtime/stack.cc index 5ad00a4e5..6e0569bb5 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -37,7 +37,7 @@ #include "runtime.h" #include "thread.h" #include "thread_list.h" -#include "verify_object-inl.h" +#include "verify_object.h" namespace art { diff --git a/runtime/thread.cc b/runtime/thread.cc index d843de5e7..632a380bf 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -77,7 +77,7 @@ #include "thread-inl.h" #include "utils.h" #include "verifier/method_verifier.h" -#include "verify_object-inl.h" +#include "verify_object.h" #include "well_known_classes.h" #include "interpreter/interpreter.h" diff --git a/runtime/verify_object-inl.h b/runtime/verify_object-inl.h index 43151dd42..363fde220 100644 --- a/runtime/verify_object-inl.h +++ b/runtime/verify_object-inl.h @@ -19,33 +19,11 @@ #include "verify_object.h" -#include "gc/heap.h" #include "mirror/object-inl.h" #include "obj_ptr-inl.h" namespace art { -inline void VerifyObject(ObjPtr obj) { - if (kVerifyObjectSupport > kVerifyObjectModeDisabled && obj != nullptr) { - if (kVerifyObjectSupport > kVerifyObjectModeFast) { - // Slow object verification, try the heap right away. - Runtime::Current()->GetHeap()->VerifyObjectBody(obj); - } else { - // Fast object verification, only call the heap if our quick sanity tests fail. The heap will - // print the diagnostic message. - bool failed = !IsAligned(obj.Ptr()); - if (!failed) { - mirror::Class* c = obj->GetClass(); - failed = failed || !IsAligned(c); - failed = failed || !VerifyClassClass(c); - } - if (UNLIKELY(failed)) { - Runtime::Current()->GetHeap()->VerifyObjectBody(obj); - } - } - } -} - inline bool VerifyClassClass(ObjPtr c) { if (UNLIKELY(c == nullptr)) { return false; diff --git a/runtime/verify_object.cc b/runtime/verify_object.cc new file mode 100644 index 000000000..a031a07a9 --- /dev/null +++ b/runtime/verify_object.cc @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "verify_object-inl.h" + +#include "base/bit_utils.h" +#include "gc/heap.h" +#include "globals.h" +#include "mirror/object-inl.h" +#include "obj_ptr-inl.h" +#include "runtime.h" + +namespace art { + +void VerifyObjectImpl(ObjPtr obj) { + if (kVerifyObjectSupport > kVerifyObjectModeFast) { + // Slow object verification, try the heap right away. + Runtime::Current()->GetHeap()->VerifyObjectBody(obj); + } else { + // Fast object verification, only call the heap if our quick sanity tests fail. The heap will + // print the diagnostic message. + bool failed = !IsAligned(obj.Ptr()); + if (!failed) { + mirror::Class* c = obj->GetClass(); + failed = failed || !IsAligned(c); + failed = failed || !VerifyClassClass(c); + } + if (UNLIKELY(failed)) { + Runtime::Current()->GetHeap()->VerifyObjectBody(obj); + } + } +} + +} // namespace art diff --git a/runtime/verify_object.h b/runtime/verify_object.h index 384e56f7f..519f7f5f5 100644 --- a/runtime/verify_object.h +++ b/runtime/verify_object.h @@ -53,7 +53,16 @@ static constexpr VerifyObjectFlags kDefaultVerifyFlags = kVerifyNone; static constexpr VerifyObjectMode kVerifyObjectSupport = kDefaultVerifyFlags != 0 ? kVerifyObjectModeFast : kVerifyObjectModeDisabled; -ALWAYS_INLINE void VerifyObject(ObjPtr obj) NO_THREAD_SAFETY_ANALYSIS; +// Implements the actual object checks. +void VerifyObjectImpl(ObjPtr obj) NO_THREAD_SAFETY_ANALYSIS; + +// Is a front to optimize out any calls if no verification is enabled. +ALWAYS_INLINE +static inline void VerifyObject(ObjPtr obj) NO_THREAD_SAFETY_ANALYSIS { + if (kVerifyObjectSupport > kVerifyObjectModeDisabled && obj != nullptr) { + VerifyObjectImpl(obj); + } +} // Check that c.getClass() == c.getClass().getClass(). ALWAYS_INLINE bool VerifyClassClass(ObjPtr c) NO_THREAD_SAFETY_ANALYSIS; diff --git a/test/626-const-class-linking/clear_dex_cache_types.cc b/test/626-const-class-linking/clear_dex_cache_types.cc index b03589616..c0aedc199 100644 --- a/test/626-const-class-linking/clear_dex_cache_types.cc +++ b/test/626-const-class-linking/clear_dex_cache_types.cc @@ -15,6 +15,9 @@ */ #include "jni.h" +#include "mirror/class-inl.h" +#include "mirror/class_loader.h" +#include "mirror/dex_cache-inl.h" #include "object_lock.h" #include "scoped_thread_state_change-inl.h" -- 2.11.0