diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/class_linker.cc | 20 | ||||
| -rw-r--r-- | src/class_linker.h | 5 | ||||
| -rw-r--r-- | src/jni_internal.cc | 8 | ||||
| -rw-r--r-- | src/thread.cc | 2 |
4 files changed, 26 insertions, 9 deletions
diff --git a/src/class_linker.cc b/src/class_linker.cc index a7d10f4a13..448a5425f1 100644 --- a/src/class_linker.cc +++ b/src/class_linker.cc @@ -884,7 +884,6 @@ bool ClassLinker::InitializeClass(Class* klass) { Method* clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V"); if (clinit != NULL) { - } else { // JValue unused; // TODO: dvmCallMethod(self, method, NULL, &unused); // UNIMPLEMENTED(FATAL); @@ -913,7 +912,7 @@ bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) { klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) { const Class* super = klass->GetSuperClass(); for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) { - const Method* method = klass->GetVirtualMethod(i); + const Method* method = super->GetVirtualMethod(i); if (method != super->GetVirtualMethod(i) && !HasSameMethodDescriptorClasses(method, super, klass)) { LG << "Classes resolve differently in superclass"; @@ -995,7 +994,6 @@ bool ClassLinker::HasSameDescriptorClasses(const char* descriptor, bool ClassLinker::InitializeSuperClass(Class* klass) { CHECK(klass != NULL); - MutexLock mu(classes_lock_); if (!klass->IsInterface() && klass->HasSuperClass()) { Class* super_class = klass->GetSuperClass(); if (super_class->GetStatus() != Class::kStatusInitialized) { @@ -1014,6 +1012,18 @@ bool ClassLinker::InitializeSuperClass(Class* klass) { return true; } +bool ClassLinker::EnsureInitialized(Class* c) { + CHECK(c != NULL); + if (c->IsInitialized()) { + return true; + } + + c->MonitorExit(); + InitializeClass(c); + c->MonitorEnter(); + return !Thread::Current()->IsExceptionPending(); +} + void ClassLinker::InitializeStaticFields(Class* klass) { size_t num_static_fields = klass->NumStaticFields(); if (num_static_fields == 0) { @@ -1028,6 +1038,10 @@ void ClassLinker::InitializeStaticFields(Class* klass) { const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor); CHECK(dex_class_def != NULL); const byte* addr = dex_file.GetEncodedArray(*dex_class_def); + if (addr == NULL) { + // All this class' static fields have default values. + return; + } size_t array_size = DecodeUnsignedLeb128(&addr); for (size_t i = 0; i < array_size; ++i) { Field* field = klass->GetStaticField(i); diff --git a/src/class_linker.h b/src/class_linker.h index 90ac6780f8..e83c850a77 100644 --- a/src/class_linker.h +++ b/src/class_linker.h @@ -39,7 +39,8 @@ class ClassLinker { return FindClass(descriptor, NULL); } - bool InitializeClass(Class* klass); + // Returns true on success, false if there's an exception pending. + bool EnsureInitialized(Class* c); void RegisterDexFile(const DexFile* dex_file); @@ -53,6 +54,8 @@ class ClassLinker { void Init(const std::vector<DexFile*>& boot_class_path_); + bool InitializeClass(Class* klass); + // For early bootstrapping by Init Class* AllocClass(Class* java_lang_Class); diff --git a/src/jni_internal.cc b/src/jni_internal.cc index 733a307e4e..8e8ecd3d81 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -454,8 +454,8 @@ std::string NormalizeJniClassDescriptor(const char* name) { jmethodID FindMethodID(ScopedJniThreadState& ts, jclass jni_class, const char* name, const char* sig, bool is_static) { Class* c = Decode<Class*>(ts, jni_class); - if (!c->IsInitialized()) { - // TODO: initialize the class + if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) { + return NULL; } Method* method = NULL; @@ -492,8 +492,8 @@ jmethodID FindMethodID(ScopedJniThreadState& ts, jclass jni_class, const char* n jfieldID FindFieldID(ScopedJniThreadState& ts, jclass jni_class, const char* name, const char* sig, bool is_static) { Class* c = Decode<Class*>(ts, jni_class); - if (!c->IsInitialized()) { - // TODO: initialize the class + if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) { + return NULL; } Field* field = NULL; diff --git a/src/thread.cc b/src/thread.cc index 1cb037e436..44f0946ac7 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -46,7 +46,7 @@ void Mutex::Unlock() { CHECK(GetOwner() == Thread::Current()); int result = pthread_mutex_unlock(&lock_impl_); CHECK_EQ(result, 0); - SetOwner(Thread::Current()); + SetOwner(NULL); } void* ThreadStart(void *arg) { |