diff options
-rw-r--r-- | dex2oat/driver/compiler_driver.cc | 8 | ||||
-rw-r--r-- | runtime/common_throws.h | 3 | ||||
-rw-r--r-- | runtime/interpreter/active_transaction_checker.h | 29 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.cc | 1 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_common.h | 17 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl-inl.h | 3 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 7 | ||||
-rw-r--r-- | runtime/interpreter/unstarted_runtime_test.cc | 4 | ||||
-rw-r--r-- | runtime/transaction.cc | 9 | ||||
-rw-r--r-- | runtime/transaction.h | 2 | ||||
-rw-r--r-- | runtime/transaction_test.cc | 4 |
11 files changed, 49 insertions, 38 deletions
diff --git a/dex2oat/driver/compiler_driver.cc b/dex2oat/driver/compiler_driver.cc index e830e86d90..9ee7e64cad 100644 --- a/dex2oat/driver/compiler_driver.cc +++ b/dex2oat/driver/compiler_driver.cc @@ -43,6 +43,7 @@ #include "base/timing_logger.h" #include "class_linker-inl.h" #include "class_root-inl.h" +#include "common_throws.h" #include "compiled_method-inl.h" #include "compiler.h" #include "compiler_callbacks.h" @@ -82,7 +83,6 @@ #include "thread_list.h" #include "thread_pool.h" #include "trampolines/trampoline_compiler.h" -#include "transaction.h" #include "utils/atomic_dex_ref_map-inl.h" #include "utils/swap_space.h" #include "vdex_file.h" @@ -2329,10 +2329,8 @@ class InitializeClassVisitor : public CompilationVisitor { // the transaction aborts and cannot resolve the type. // TransactionAbortError is not initialized ant not in boot image, needed only by // compiler and will be pruned by ImageWriter. - Handle<mirror::Class> exception_class = - hs.NewHandle(class_linker->FindClass(self, - Transaction::kAbortExceptionDescriptor, - class_loader)); + Handle<mirror::Class> exception_class = hs.NewHandle( + class_linker->FindClass(self, kTransactionAbortErrorDescriptor, class_loader)); bool exception_initialized = class_linker->EnsureInitialized(self, exception_class, true, true); DCHECK(exception_initialized); diff --git a/runtime/common_throws.h b/runtime/common_throws.h index aeba3bb1bb..71b0968fc0 100644 --- a/runtime/common_throws.h +++ b/runtime/common_throws.h @@ -35,6 +35,9 @@ class DexFile; enum InvokeType : uint32_t; class Signature; +// The descriptor of the transaction abort exception. +constexpr const char kTransactionAbortErrorDescriptor[] = "Ldalvik/system/TransactionAbortError;"; + // AbstractMethodError void ThrowAbstractMethodError(ArtMethod* method) diff --git a/runtime/interpreter/active_transaction_checker.h b/runtime/interpreter/active_transaction_checker.h index 867dc251eb..16fa6b1829 100644 --- a/runtime/interpreter/active_transaction_checker.h +++ b/runtime/interpreter/active_transaction_checker.h @@ -33,10 +33,9 @@ class ActiveTransactionChecker { Runtime* runtime = Runtime::Current(); if (runtime->GetTransaction()->WriteConstraint(obj)) { DCHECK(runtime->GetHeap()->ObjectIsInBootImageSpace(obj) || obj->IsClass()); - const char* base_msg = runtime->GetHeap()->ObjectIsInBootImageSpace(obj) - ? "Can't set fields of boot image " - : "Can't set fields of "; - runtime->AbortTransactionAndThrowAbortError(self, base_msg + obj->PrettyTypeOf()); + const char* extra = runtime->GetHeap()->ObjectIsInBootImageSpace(obj) ? "boot image " : ""; + runtime->AbortTransactionF( + self, "Can't set fields of %s%s", extra, obj->PrettyTypeOf().c_str()); return true; } return false; @@ -47,10 +46,24 @@ class ActiveTransactionChecker { Runtime* runtime = Runtime::Current(); if (runtime->GetTransaction()->WriteValueConstraint(value)) { DCHECK(value != nullptr); - std::string msg = value->IsClass() - ? "Can't store reference to class " + value->AsClass()->PrettyDescriptor() - : "Can't store reference to instance of " + value->GetClass()->PrettyDescriptor(); - runtime->AbortTransactionAndThrowAbortError(self, msg); + const char* description = value->IsClass() ? "class" : "instance of"; + ObjPtr<mirror::Class> klass = value->IsClass() ? value->AsClass() : value->GetClass(); + runtime->AbortTransactionF( + self, "Can't store reference to %s %s", description, klass->PrettyDescriptor().c_str()); + return true; + } + return false; + } + + static inline bool ReadConstraint(Thread* self, ObjPtr<mirror::Object> obj) + REQUIRES_SHARED(Locks::mutator_lock_) { + DCHECK(obj->IsClass()); + Runtime* runtime = Runtime::Current(); + if (runtime->GetTransaction()->ReadConstraint(obj)) { + runtime->AbortTransactionF( + self, + "Can't read static fields of %s since it does not belong to clinit's class.", + obj->PrettyTypeOf().c_str()); return true; } return false; diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index ded500fd78..080b32f3d5 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -46,7 +46,6 @@ #include "shadow_frame-inl.h" #include "stack.h" #include "thread-inl.h" -#include "transaction.h" #include "var_handles.h" #include "well_known_classes.h" diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index d2238d1d23..24fb8a83c4 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -20,7 +20,6 @@ #include "android-base/macros.h" #include "instrumentation.h" #include "interpreter.h" -#include "transaction.h" #include <math.h> @@ -86,6 +85,12 @@ class InactiveTransactionChecker { return false; } + ALWAYS_INLINE static bool ReadConstraint([[maybe_unused]] Thread* self, + [[maybe_unused]] ObjPtr<mirror::Object> value) + REQUIRES_SHARED(Locks::mutator_lock_) { + return false; + } + ALWAYS_INLINE static bool AllocationConstraint([[maybe_unused]] Thread* self, [[maybe_unused]] ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) { @@ -397,12 +402,10 @@ ALWAYS_INLINE bool DoFieldGet(Thread* self, ObjPtr<mirror::Object> obj; if (is_static) { obj = field->GetDeclaringClass(); - if (transaction_active) { - if (Runtime::Current()->GetTransaction()->ReadConstraint(obj)) { - Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Can't read static fields of " - + obj->PrettyTypeOf() + " since it does not belong to clinit's class."); - return false; - } + using TransactionChecker = typename std::conditional_t< + transaction_active, ActiveTransactionChecker, InactiveTransactionChecker>; + if (TransactionChecker::ReadConstraint(self, obj)) { + return false; } } else { obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data)); diff --git a/runtime/interpreter/interpreter_switch_impl-inl.h b/runtime/interpreter/interpreter_switch_impl-inl.h index 0c50238e48..8ff6a897f8 100644 --- a/runtime/interpreter/interpreter_switch_impl-inl.h +++ b/runtime/interpreter/interpreter_switch_impl-inl.h @@ -23,6 +23,7 @@ #include "base/memory_tool.h" #include "base/pointer_size.h" #include "base/quasi_atomic.h" +#include "common_throws.h" #include "dex/dex_file_types.h" #include "dex/dex_instruction_list.h" #include "experimental_flags.h" @@ -65,7 +66,7 @@ class InstructionHandler { StackHandleScope<1u> hs(Self()); Handle<mirror::Throwable> abort_exception = hs.NewHandle(Self()->GetException()); DCHECK(abort_exception != nullptr); - DCHECK(abort_exception->GetClass()->DescriptorEquals(Transaction::kAbortExceptionDescriptor)); + DCHECK(abort_exception->GetClass()->DescriptorEquals(kTransactionAbortErrorDescriptor)); Self()->ClearException(); PerformNonStandardReturn( Self(), shadow_frame_, ctx_->result, Instrumentation(), Accessor().InsSize()); diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index 2bdb5900b8..d865327473 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -62,7 +62,6 @@ #include "nth_caller_visitor.h" #include "reflection.h" #include "thread-inl.h" -#include "transaction.h" #include "unstarted_runtime_list.h" #include "well_known_classes-inl.h" @@ -167,8 +166,7 @@ static void CheckExceptionGenerateClassNotFound(Thread* self) if (self->IsExceptionPending()) { Runtime* runtime = Runtime::Current(); DCHECK_EQ(runtime->IsTransactionAborted(), - self->GetException()->GetClass()->DescriptorEquals( - Transaction::kAbortExceptionDescriptor)) + self->GetException()->GetClass()->DescriptorEquals(kTransactionAbortErrorDescriptor)) << self->GetException()->GetClass()->PrettyDescriptor(); if (runtime->IsActiveTransaction()) { // The boot class path at run time may contain additional dex files with @@ -764,8 +762,7 @@ void UnstartedRuntime::UnstartedVmClassLoaderFindLoadedClass( if (self->IsExceptionPending()) { Runtime* runtime = Runtime::Current(); DCHECK_EQ(runtime->IsTransactionAborted(), - self->GetException()->GetClass()->DescriptorEquals( - Transaction::kAbortExceptionDescriptor)) + self->GetException()->GetClass()->DescriptorEquals(kTransactionAbortErrorDescriptor)) << self->GetException()->GetClass()->PrettyDescriptor(); if (runtime->IsActiveTransaction()) { // If we're not aborting the transaction yet, abort now. b/183691501 diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc index 494eb756a4..44c1e2627a 100644 --- a/runtime/interpreter/unstarted_runtime_test.cc +++ b/runtime/interpreter/unstarted_runtime_test.cc @@ -25,6 +25,7 @@ #include "class_linker.h" #include "class_root-inl.h" #include "common_runtime_test.h" +#include "common_throws.h" #include "dex/descriptors_names.h" #include "dex/dex_instruction.h" #include "handle.h" @@ -42,7 +43,6 @@ #include "scoped_thread_state_change-inl.h" #include "shadow_frame-inl.h" #include "thread.h" -#include "transaction.h" #include "unstarted_runtime_list.h" namespace art HIDDEN { @@ -216,7 +216,7 @@ class UnstartedRuntimeTest : public CommonRuntimeTest { void PrepareForAborts() REQUIRES_SHARED(Locks::mutator_lock_) { ObjPtr<mirror::Object> result = Runtime::Current()->GetClassLinker()->FindClass( Thread::Current(), - Transaction::kAbortExceptionDescriptor, + kTransactionAbortErrorDescriptor, ScopedNullHandle<mirror::ClassLoader>()); CHECK(result != nullptr); } diff --git a/runtime/transaction.cc b/runtime/transaction.cc index d320c4d940..9a8fcd9739 100644 --- a/runtime/transaction.cc +++ b/runtime/transaction.cc @@ -20,6 +20,7 @@ #include "base/mutex-inl.h" #include "base/stl_util.h" +#include "common_throws.h" #include "dex/descriptors_names.h" #include "gc/accounting/card_table-inl.h" #include "gc/heap.h" @@ -104,17 +105,15 @@ void Transaction::Abort(const std::string& abort_message) { void Transaction::ThrowAbortError(Thread* self, const std::string* abort_message) { const bool rethrow = (abort_message == nullptr); if (kIsDebugBuild && rethrow) { - CHECK(IsAborted()) << "Rethrow " << DescriptorToDot(Transaction::kAbortExceptionDescriptor) + CHECK(IsAborted()) << "Rethrow " << DescriptorToDot(kTransactionAbortErrorDescriptor) << " while transaction is not aborted"; } if (rethrow) { // Rethrow an exception with the earlier abort message stored in the transaction. - self->ThrowNewWrappedException(Transaction::kAbortExceptionDescriptor, - GetAbortMessage().c_str()); + self->ThrowNewWrappedException(kTransactionAbortErrorDescriptor, GetAbortMessage().c_str()); } else { // Throw an exception with the given abort message. - self->ThrowNewWrappedException(Transaction::kAbortExceptionDescriptor, - abort_message->c_str()); + self->ThrowNewWrappedException(kTransactionAbortErrorDescriptor, abort_message->c_str()); } } diff --git a/runtime/transaction.h b/runtime/transaction.h index 9f3282f8d9..847120234d 100644 --- a/runtime/transaction.h +++ b/runtime/transaction.h @@ -46,8 +46,6 @@ template<class MirrorType> class ObjPtr; class Transaction final { public: - static constexpr const char* kAbortExceptionDescriptor = "Ldalvik/system/TransactionAbortError;"; - Transaction(bool strict, mirror::Class* root, ArenaStack* arena_stack, ArenaPool* arena_pool); ~Transaction(); diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc index c4eb7e808b..db9d123521 100644 --- a/runtime/transaction_test.cc +++ b/runtime/transaction_test.cc @@ -20,6 +20,7 @@ #include "art_method-inl.h" #include "class_linker-inl.h" #include "common_runtime_test.h" +#include "common_throws.h" #include "dex/dex_file.h" #include "mirror/array-alloc-inl.h" #include "mirror/class-alloc-inl.h" @@ -52,8 +53,7 @@ class TransactionTest : public CommonRuntimeTest { class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true); ASSERT_TRUE(h_klass->IsInitialized()); - h_klass.Assign(class_linker_->FindSystemClass(soa.Self(), - Transaction::kAbortExceptionDescriptor)); + h_klass.Assign(class_linker_->FindSystemClass(soa.Self(), kTransactionAbortErrorDescriptor)); ASSERT_TRUE(h_klass != nullptr); class_linker_->EnsureInitialized(soa.Self(), h_klass, true, true); ASSERT_TRUE(h_klass->IsInitialized()); |