summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/class_linker.cc37
-rw-r--r--runtime/reflection.cc8
-rw-r--r--runtime/thread.cc17
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();
}