diff options
author | Steve Kondik <steve@cyngn.com> | 2015-12-08 03:20:54 -0800 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2015-12-08 03:20:54 -0800 |
commit | 875ffee6f23971466f3655a9e1e73ba6a1dc0393 (patch) | |
tree | 07b88bebf3229933589c6f98fe8ff2ae051c1181 /runtime | |
parent | 29bd42b5eb0382360e3a8cb646ccf4de4b3b1d5a (diff) | |
parent | 1dff62f822392dd3f95ec23ba578bf42430ba112 (diff) | |
download | art-875ffee6f23971466f3655a9e1e73ba6a1dc0393.zip art-875ffee6f23971466f3655a9e1e73ba6a1dc0393.tar.gz art-875ffee6f23971466f3655a9e1e73ba6a1dc0393.tar.bz2 |
Merge tag 'android-6.0.1_r3' of https://android.googlesource.com/platform/art into HEAD
Android 6.0.1 release 3
Change-Id: I23fd56f2c1a3e8e8b993a151a794e18f3569912e
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/class_linker.cc | 37 | ||||
-rw-r--r-- | runtime/reflection.cc | 8 | ||||
-rw-r--r-- | runtime/thread.cc | 17 |
3 files changed, 45 insertions, 17 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 9ca6492..d0e8e68 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2334,15 +2334,22 @@ void ClassLinker::LoadClassMembers(Thread* self, const DexFile& dex_file, klass->SetIFields(ifields); klass->SetNumInstanceFields(num_ifields); DCHECK_EQ(klass->NumInstanceFields(), num_ifields); - // Load methods. - if (it.NumDirectMethods() != 0) { - klass->SetDirectMethodsPtr(AllocArtMethodArray(self, it.NumDirectMethods())); - } - klass->SetNumDirectMethods(it.NumDirectMethods()); - if (it.NumVirtualMethods() != 0) { - klass->SetVirtualMethodsPtr(AllocArtMethodArray(self, it.NumVirtualMethods())); + ArtMethod* const direct_methods = (it.NumDirectMethods() != 0) + ? AllocArtMethodArray(self, it.NumDirectMethods()) + : nullptr; + ArtMethod* const virtual_methods = (it.NumVirtualMethods() != 0) + ? AllocArtMethodArray(self, it.NumVirtualMethods()) + : nullptr; + { + // Used to get exclusion between with VisitNativeRoots so that no thread sees a length for + // one array with a pointer for a different array. + WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); + // Load methods. + klass->SetDirectMethodsPtr(direct_methods); + klass->SetNumDirectMethods(it.NumDirectMethods()); + klass->SetVirtualMethodsPtr(virtual_methods); + klass->SetNumVirtualMethods(it.NumVirtualMethods()); } - klass->SetNumVirtualMethods(it.NumVirtualMethods()); size_t class_def_method_index = 0; uint32_t last_dex_method_index = DexFile::kDexNoIndex; size_t last_class_def_method_index = 0; @@ -3321,8 +3328,11 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& self->AssertPendingOOMException(); return nullptr; } - klass->SetDirectMethodsPtr(directs); - klass->SetNumDirectMethods(1u); + { + WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); + klass->SetDirectMethodsPtr(directs); + klass->SetNumDirectMethods(1u); + } CreateProxyConstructor(klass, klass->GetDirectMethodUnchecked(0, image_pointer_size_)); // Create virtual method using specified prototypes. @@ -3337,8 +3347,11 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& self->AssertPendingOOMException(); return nullptr; } - klass->SetVirtualMethodsPtr(virtuals); - klass->SetNumVirtualMethods(num_virtual_methods); + { + WriterMutexLock mu(self, *Locks::classlinker_classes_lock_); + klass->SetVirtualMethodsPtr(virtuals); + klass->SetNumVirtualMethods(num_virtual_methods); + } for (size_t i = 0; i < num_virtual_methods; ++i) { auto* virtual_method = klass->GetVirtualMethodUnchecked(i, image_pointer_size_); auto* prototype = h_methods->Get(i)->GetArtMethod(); diff --git a/runtime/reflection.cc b/runtime/reflection.cc index 11522d9..db09afb 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -453,7 +453,7 @@ JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject o } mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj); uint32_t shorty_len = 0; - const char* shorty = method->GetShorty(&shorty_len); + const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len); JValue result; ArgArray arg_array(shorty, shorty_len); arg_array.BuildArgArrayFromVarArgs(soa, receiver, args); @@ -483,7 +483,7 @@ JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, jobject o } mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj); uint32_t shorty_len = 0; - const char* shorty = method->GetShorty(&shorty_len); + const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len); JValue result; ArgArray arg_array(shorty, shorty_len); arg_array.BuildArgArrayFromJValues(soa, receiver, args); @@ -514,7 +514,7 @@ JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnab receiver = nullptr; } uint32_t shorty_len = 0; - const char* shorty = method->GetShorty(&shorty_len); + const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len); JValue result; ArgArray arg_array(shorty, shorty_len); arg_array.BuildArgArrayFromJValues(soa, receiver, args); @@ -545,7 +545,7 @@ JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnab receiver = nullptr; } uint32_t shorty_len = 0; - const char* shorty = method->GetShorty(&shorty_len); + const char* shorty = method->GetInterfaceMethodIfProxy(sizeof(void*))->GetShorty(&shorty_len); JValue result; ArgArray arg_array(shorty, shorty_len); arg_array.BuildArgArrayFromVarArgs(soa, receiver, args); diff --git a/runtime/thread.cc b/runtime/thread.cc index 5274f9e..6e8f89c 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -546,6 +546,18 @@ Thread* Thread::Attach(const char* thread_name, bool as_daemon, jobject thread_g // a native peer! if (create_peer) { self->CreatePeer(thread_name, as_daemon, thread_group); + if (self->IsExceptionPending()) { + // We cannot keep the exception around, as we're deleting self. Try to be helpful and log it. + { + ScopedObjectAccess soa(self); + LOG(ERROR) << "Exception creating thread peer:"; + LOG(ERROR) << self->GetException()->Dump(); + self->ClearException(); + } + runtime->GetThreadList()->Unregister(self); + // Unregister deletes self, no need to do this here. + return nullptr; + } } else { // These aren't necessary, but they improve diagnostics for unit tests & command-line tools. if (thread_name != nullptr) { @@ -594,7 +606,9 @@ void Thread::CreatePeer(const char* name, bool as_daemon, jobject thread_group) WellKnownClasses::java_lang_Thread, WellKnownClasses::java_lang_Thread_init, thread_group, thread_name.get(), thread_priority, thread_is_daemon); - AssertNoPendingException(); + if (IsExceptionPending()) { + return; + } Thread* self = this; DCHECK_EQ(self, Thread::Current()); @@ -1256,6 +1270,7 @@ void Thread::FinishStartup() { // Finish attaching the main thread. ScopedObjectAccess soa(Thread::Current()); Thread::Current()->CreatePeer("main", false, runtime->GetMainThreadGroup()); + Thread::Current()->AssertNoPendingException(); Runtime::Current()->GetClassLinker()->RunRootClinits(); } |