diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/entrypoints/quick/callee_save_frame.h | 15 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc | 4 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 5 | ||||
-rw-r--r-- | runtime/mirror/array-inl.h | 4 | ||||
-rw-r--r-- | runtime/mirror/array.h | 4 | ||||
-rw-r--r-- | runtime/mirror/object-inl.h | 12 | ||||
-rw-r--r-- | runtime/mirror/object.h | 2 |
7 files changed, 31 insertions, 15 deletions
diff --git a/runtime/entrypoints/quick/callee_save_frame.h b/runtime/entrypoints/quick/callee_save_frame.h index 8cd6ca6777..3bcaf93e6d 100644 --- a/runtime/entrypoints/quick/callee_save_frame.h +++ b/runtime/entrypoints/quick/callee_save_frame.h @@ -38,22 +38,24 @@ class ArtMethod; class ScopedQuickEntrypointChecks { public: - explicit ScopedQuickEntrypointChecks(Thread *self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : self_(self) { - if (kIsDebugBuild) { + explicit ScopedQuickEntrypointChecks(Thread *self, + bool entry_check = kIsDebugBuild, + bool exit_check = kIsDebugBuild) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : self_(self), exit_check_(exit_check) { + if (entry_check) { TestsOnEntry(); } } - explicit ScopedQuickEntrypointChecks() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) - : self_(kIsDebugBuild ? Thread::Current() : nullptr) { + ScopedQuickEntrypointChecks() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) + : self_(kIsDebugBuild ? Thread::Current() : nullptr), exit_check_(kIsDebugBuild) { if (kIsDebugBuild) { TestsOnEntry(); } } ~ScopedQuickEntrypointChecks() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - if (kIsDebugBuild) { + if (exit_check_) { TestsOnExit(); } } @@ -70,6 +72,7 @@ class ScopedQuickEntrypointChecks { } Thread* const self_; + bool exit_check_; }; static constexpr size_t GetCalleeSaveFrameSize(InstructionSet isa, Runtime::CalleeSaveType type) { diff --git a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc index eb1b1056a4..2bb73efa2f 100644 --- a/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_instrumentation_entrypoints.cc @@ -29,7 +29,9 @@ extern "C" const void* artInstrumentationMethodEntryFromCode(mirror::ArtMethod* Thread* self, uintptr_t lr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); + // Instrumentation changes the stack. Thus, when exiting, the stack cannot be verified, so skip + // that part. + ScopedQuickEntrypointChecks sqec(self, kIsDebugBuild, false); instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); const void* result; if (instrumentation->IsDeoptimized(method)) { diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index 838427fcb6..227c5b0417 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -823,7 +823,10 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called, Thread* self, StackReference<mirror::ArtMethod>* sp) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - ScopedQuickEntrypointChecks sqec(self); + // The resolution trampoline stashes the resolved method into the callee-save frame to transport + // it. Thus, when exiting, the stack cannot be verified (as the resolved method most likely + // does not have the same stack layout as the callee-save method). + ScopedQuickEntrypointChecks sqec(self, kIsDebugBuild, false); // Start new JNI local reference state JNIEnvExt* env = self->GetJniEnv(); ScopedObjectAccessUnchecked soa(env); diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index 8b3418d6be..9696dcd754 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -237,7 +237,7 @@ inline void PrimitiveArray<T>::Set(int32_t i, T value) { } template<typename T> -template<bool kTransactionActive, bool kCheckTransaction> +template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> inline void PrimitiveArray<T>::SetWithoutChecks(int32_t i, T value) { if (kCheckTransaction) { DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); @@ -245,7 +245,7 @@ inline void PrimitiveArray<T>::SetWithoutChecks(int32_t i, T value) { if (kTransactionActive) { Runtime::Current()->RecordWriteArray(this, i, GetWithoutChecks(i)); } - DCHECK(CheckIsValidIndex(i)); + DCHECK(CheckIsValidIndex<kVerifyFlags>(i)); GetData()[i] = value; } // Backward copy where elements are of aligned appropriately for T. Count is in T sized units. diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h index 832ad68dcd..167f824d14 100644 --- a/runtime/mirror/array.h +++ b/runtime/mirror/array.h @@ -131,7 +131,9 @@ class MANAGED PrimitiveArray : public Array { // TODO fix thread safety analysis broken by the use of template. This should be // SHARED_LOCKS_REQUIRED(Locks::mutator_lock_). - template<bool kTransactionActive, bool kCheckTransaction = true> + template<bool kTransactionActive, + bool kCheckTransaction = true, + VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> void SetWithoutChecks(int32_t i, T value) ALWAYS_INLINE NO_THREAD_SAFETY_ANALYSIS; /* diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 39d0f5664f..7760ea2cfd 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -59,19 +59,23 @@ inline void Object::SetClass(Class* new_klass) { OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass); } +template<VerifyObjectFlags kVerifyFlags> inline LockWord Object::GetLockWord(bool as_volatile) { if (as_volatile) { - return LockWord(GetField32Volatile(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); + return LockWord(GetField32Volatile<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); } - return LockWord(GetField32(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); + return LockWord(GetField32<kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_))); } +template<VerifyObjectFlags kVerifyFlags> inline void Object::SetLockWord(LockWord new_val, bool as_volatile) { // Force use of non-transactional mode and do not check. if (as_volatile) { - SetField32Volatile<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue()); + SetField32Volatile<false, false, kVerifyFlags>( + OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue()); } else { - SetField32<false, false>(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue()); + SetField32<false, false, kVerifyFlags>( + OFFSET_OF_OBJECT_MEMBER(Object, monitor_), new_val.GetValue()); } } diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h index 5afe99f3f8..2c0e626771 100644 --- a/runtime/mirror/object.h +++ b/runtime/mirror/object.h @@ -125,7 +125,9 @@ class MANAGED LOCKABLE Object { // As_volatile can be false if the mutators are suspended. This is an optimization since it // avoids the barriers. + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> LockWord GetLockWord(bool as_volatile) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags> void SetLockWord(LockWord new_val, bool as_volatile) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); bool CasLockWordWeakSequentiallyConsistent(LockWord old_val, LockWord new_val) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); |