Created
June 11, 2014 08:49
-
-
Save 3Nigma/eded1949ca36f51c6bc8 to your computer and use it in GitHub Desktop.
Revisions
-
3Nigma created this gist
Jun 11, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,108 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager, size_t class_def_index) LOCKS_EXCLUDED(Locks::mutator_lock_) { ATRACE_CALL(); Thread* self = Thread::Current(); jobject jclass_loader = manager->GetClassLoader(); const DexFile& dex_file = *manager->GetDexFile(); ClassLinker* class_linker = manager->GetClassLinker(); // If an instance field is final then we need to have a barrier on the return, static final // fields are assigned within the lock held for class initialization. Conservatively assume // constructor barriers are always required. bool requires_constructor_barrier = true; // Method and Field are the worst. We can't resolve without either // context from the code use (to disambiguate virtual vs direct // method and instance vs static field) or from class // definitions. While the compiler will resolve what it can as it // needs it, here we try to resolve fields and methods used in class // definitions, since many of them many never be referenced by // generated code. const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); if (!SkipClass(class_linker, jclass_loader, dex_file, class_def)) { ScopedObjectAccess soa(self); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file))); // Resolve the class. mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache, class_loader); bool resolve_fields_and_methods; if (klass == NULL) { // Class couldn't be resolved, for example, super-class is in a different dex file. Don't // attempt to resolve methods and fields when there is no declaring class. CHECK(soa.Self()->IsExceptionPending()); soa.Self()->ClearException(); resolve_fields_and_methods = false; } else { resolve_fields_and_methods = manager->GetCompiler()->IsImage(); } // Note the class_data pointer advances through the headers, // static fields, instance fields, direct methods, and virtual // methods. const byte* class_data = dex_file.GetClassData(class_def); if (class_data == NULL) { // Empty class such as a marker interface. requires_constructor_barrier = false; } else { ClassDataItemIterator it(dex_file, class_data); while (it.HasNextStaticField()) { if (resolve_fields_and_methods) { mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, true); if (field == NULL) { CHECK(soa.Self()->IsExceptionPending()); soa.Self()->ClearException(); } } it.Next(); } // We require a constructor barrier if there are final instance fields. requires_constructor_barrier = false; while (it.HasNextInstanceField()) { if ((it.GetMemberAccessFlags() & kAccFinal) != 0) { requires_constructor_barrier = true; } if (resolve_fields_and_methods) { mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache, class_loader, false); if (field == NULL) { CHECK(soa.Self()->IsExceptionPending()); soa.Self()->ClearException(); } } it.Next(); } if (resolve_fields_and_methods) { while (it.HasNextDirectMethod()) { mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, class_loader, NullHandle<mirror::ArtMethod>(), it.GetMethodInvokeType(class_def)); if (method == NULL) { CHECK(soa.Self()->IsExceptionPending()); soa.Self()->ClearException(); } it.Next(); } while (it.HasNextVirtualMethod()) { mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache, class_loader, NullHandle<mirror::ArtMethod>(), it.GetMethodInvokeType(class_def)); if (method == NULL) { CHECK(soa.Self()->IsExceptionPending()); soa.Self()->ClearException(); } it.Next(); } DCHECK(!it.HasNext()); } } } if (requires_constructor_barrier) { manager->GetCompiler()->AddRequiresConstructorBarrier(self, &dex_file, class_def_index); } }