summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2015-03-03 12:16:13 +0100
committerSebastien Hertz <shertz@google.com>2015-03-03 14:30:46 +0100
commitbd9cf9f6bbf285ec7a5b74ce655a9e68e0f6e434 (patch)
tree04f3b49c2946c99b0aac23552f8c3cfdf8da39f4
parentff9b747588e77f04b07dc76b2d39a82cbfc60441 (diff)
downloadart-bd9cf9f6bbf285ec7a5b74ce655a9e68e0f6e434.zip
art-bd9cf9f6bbf285ec7a5b74ce655a9e68e0f6e434.tar.gz
art-bd9cf9f6bbf285ec7a5b74ce655a9e68e0f6e434.tar.bz2
Follow-up 128393
Avoids false warning when initializing the exception's class by marking the transaction aborted after throwing the InternalError exception. Also uses VLOG(compiler) to print the warning since it's only useful when investigating ahead-of-time class initialization. Bug: 19202032 Change-Id: I3c53639cbb888086ad345d668d1e5b73c5aaf861
-rw-r--r--compiler/driver/compiler_driver.cc3
-rw-r--r--runtime/class_linker.cc4
-rw-r--r--runtime/runtime.cc8
-rw-r--r--runtime/transaction.cc6
-rw-r--r--runtime/transaction.h2
5 files changed, 13 insertions, 10 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 15b3d08..8abd7e0 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1962,8 +1962,7 @@ static void InitializeClass(const ParallelCompilationManager* manager, size_t cl
if (!success) {
CHECK(soa.Self()->IsExceptionPending());
- ThrowLocation throw_location;
- mirror::Throwable* exception = soa.Self()->GetException(&throw_location);
+ mirror::Throwable* exception = soa.Self()->GetException(nullptr);
VLOG(compiler) << "Initialization of " << descriptor << " aborted because of "
<< exception->Dump();
std::ostream* file_log = manager->GetCompiler()->
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index ee5eefb..af6f7a9 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -4240,8 +4240,8 @@ bool ClassLinker::InitializeClass(Thread* self, Handle<mirror::Class> klass,
} else if (Runtime::Current()->IsTransactionAborted()) {
// The exception thrown when the transaction aborted has been caught and cleared
// so we need to throw it again now.
- LOG(WARNING) << "Return from class initializer of " << PrettyDescriptor(klass.Get())
- << " without exception while transaction was aborted: re-throw it now.";
+ VLOG(compiler) << "Return from class initializer of " << PrettyDescriptor(klass.Get())
+ << " without exception while transaction was aborted: re-throw it now.";
Runtime::Current()->ThrowInternalErrorForAbortedTransaction(self);
klass->SetStatus(mirror::Class::kStatusError, self);
success = false;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 8c5827c..824d65f 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1560,15 +1560,17 @@ void Runtime::AbortTransactionAndThrowInternalError(Thread* self,
const std::string& abort_message) {
DCHECK(IsCompiler());
DCHECK(IsActiveTransaction());
+ // Throwing an exception may cause its class initialization. If we mark the transaction
+ // aborted before that, we may warn with a false alarm. Throwing the exception before
+ // marking the transaction aborted avoids that.
+ preinitialization_transaction_->ThrowInternalError(self, false);
preinitialization_transaction_->Abort(abort_message);
- ThrowInternalErrorForAbortedTransaction(self);
}
void Runtime::ThrowInternalErrorForAbortedTransaction(Thread* self) {
DCHECK(IsCompiler());
DCHECK(IsActiveTransaction());
- DCHECK(IsTransactionAborted());
- preinitialization_transaction_->ThrowInternalError(self);
+ preinitialization_transaction_->ThrowInternalError(self, true);
}
void Runtime::RecordWriteFieldBoolean(mirror::Object* obj, MemberOffset field_offset,
diff --git a/runtime/transaction.cc b/runtime/transaction.cc
index e26f955..c0fd7a5 100644
--- a/runtime/transaction.cc
+++ b/runtime/transaction.cc
@@ -70,8 +70,10 @@ void Transaction::Abort(const std::string& abort_message) {
}
}
-void Transaction::ThrowInternalError(Thread* self) {
- DCHECK(IsAborted());
+void Transaction::ThrowInternalError(Thread* self, bool rethrow) {
+ if (kIsDebugBuild && rethrow) {
+ CHECK(IsAborted()) << "Rethrow InternalError while transaction is not aborted";
+ }
std::string abort_msg(GetAbortMessage());
self->ThrowNewException(self->GetCurrentLocationForThrow(), "Ljava/lang/InternalError;",
abort_msg.c_str());
diff --git a/runtime/transaction.h b/runtime/transaction.h
index be614f9..e1b93c9 100644
--- a/runtime/transaction.h
+++ b/runtime/transaction.h
@@ -45,7 +45,7 @@ class Transaction FINAL {
void Abort(const std::string& abort_message)
LOCKS_EXCLUDED(log_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void ThrowInternalError(Thread* self)
+ void ThrowInternalError(Thread* self, bool rethrow)
LOCKS_EXCLUDED(log_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsAborted() LOCKS_EXCLUDED(log_lock_);