diff options
Diffstat (limited to 'compiler/driver')
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 67 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.h | 2 |
2 files changed, 30 insertions, 39 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 0ad30be3fe..e5decc5924 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -905,13 +905,14 @@ bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_id bool CompilerDriver::CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx, bool* is_type_initialized, bool* use_direct_type_ptr, - uintptr_t* direct_type_ptr) { + uintptr_t* direct_type_ptr, bool* out_is_finalizable) { ScopedObjectAccess soa(Thread::Current()); mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); if (resolved_class == nullptr) { return false; } + *out_is_finalizable = resolved_class->IsFinalizable(); const bool compiling_boot = Runtime::Current()->GetHeap()->IsCompilingBoot(); if (compiling_boot) { // boot -> boot class pointers. @@ -1699,44 +1700,34 @@ static void InitializeClass(const ParallelCompilationManager* manager, size_t cl !StringPiece(descriptor).ends_with("$NoPreloadHolder;"); if (can_init_static_fields) { VLOG(compiler) << "Initializing: " << descriptor; - if (strcmp("Ljava/lang/Void;", descriptor) == 0) { - // Hand initialize j.l.Void to avoid Dex file operations in un-started runtime. - ObjectLock<mirror::Class> lock(soa.Self(), &klass); - mirror::ObjectArray<mirror::ArtField>* fields = klass->GetSFields(); - CHECK_EQ(fields->GetLength(), 1); - fields->Get(0)->SetObj<false>(klass.get(), - manager->GetClassLinker()->FindPrimitiveClass('V')); - klass->SetStatus(mirror::Class::kStatusInitialized, soa.Self()); - } else { - // TODO multithreading support. We should ensure the current compilation thread has - // exclusive access to the runtime and the transaction. To achieve this, we could use - // a ReaderWriterMutex but we're holding the mutator lock so we fail mutex sanity - // checks in Thread::AssertThreadSuspensionIsAllowable. - Runtime* const runtime = Runtime::Current(); - Transaction transaction; - - // Run the class initializer in transaction mode. - runtime->EnterTransactionMode(&transaction); - const mirror::Class::Status old_status = klass->GetStatus(); - bool success = manager->GetClassLinker()->EnsureInitialized(klass, true, true); - // TODO we detach transaction from runtime to indicate we quit the transactional - // mode which prevents the GC from visiting objects modified during the transaction. - // Ensure GC is not run so don't access freed objects when aborting transaction. - const char* old_casue = soa.Self()->StartAssertNoThreadSuspension("Transaction end"); - runtime->ExitTransactionMode(); - - if (!success) { - CHECK(soa.Self()->IsExceptionPending()); - ThrowLocation throw_location; - mirror::Throwable* exception = soa.Self()->GetException(&throw_location); - VLOG(compiler) << "Initialization of " << descriptor << " aborted because of " - << exception->Dump(); - soa.Self()->ClearException(); - transaction.Abort(); - CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored"; - } - soa.Self()->EndAssertNoThreadSuspension(old_casue); + // TODO multithreading support. We should ensure the current compilation thread has + // exclusive access to the runtime and the transaction. To achieve this, we could use + // a ReaderWriterMutex but we're holding the mutator lock so we fail mutex sanity + // checks in Thread::AssertThreadSuspensionIsAllowable. + Runtime* const runtime = Runtime::Current(); + Transaction transaction; + + // Run the class initializer in transaction mode. + runtime->EnterTransactionMode(&transaction); + const mirror::Class::Status old_status = klass->GetStatus(); + bool success = manager->GetClassLinker()->EnsureInitialized(klass, true, true); + // TODO we detach transaction from runtime to indicate we quit the transactional + // mode which prevents the GC from visiting objects modified during the transaction. + // Ensure GC is not run so don't access freed objects when aborting transaction. + const char* old_casue = soa.Self()->StartAssertNoThreadSuspension("Transaction end"); + runtime->ExitTransactionMode(); + + if (!success) { + CHECK(soa.Self()->IsExceptionPending()); + ThrowLocation throw_location; + mirror::Throwable* exception = soa.Self()->GetException(&throw_location); + VLOG(compiler) << "Initialization of " << descriptor << " aborted because of " + << exception->Dump(); + soa.Self()->ClearException(); + transaction.Abort(); + CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored"; } + soa.Self()->EndAssertNoThreadSuspension(old_casue); } } soa.Self()->AssertNoPendingException(); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index d7d40d554a..6ac9cf751a 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -210,7 +210,7 @@ class CompilerDriver { bool CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx, bool* is_type_initialized, bool* use_direct_type_ptr, - uintptr_t* direct_type_ptr); + uintptr_t* direct_type_ptr, bool* out_is_finalizable); // Get the DexCache for the mirror::DexCache* GetDexCache(const DexCompilationUnit* mUnit) |