diff options
| author | 2015-11-19 16:05:58 -0800 | |
|---|---|---|
| committer | 2015-11-19 16:11:03 -0800 | |
| commit | d37d364c27e74a7b49970a8c970482e273aa7b1a (patch) | |
| tree | ecf910556f7d6e4a0cdfa7dfc271f3894909e601 | |
| parent | 16cabc4acd14d5a61c73cef821162e1827f08788 (diff) | |
Create parent class loader for dex2oat
This means we also put the class loader in the app image so that it
can be used for verifying the dex file order.
Bug: 22858531
Change-Id: I30761b59421c8a24cffd62b469134b25d2929e2e
| -rw-r--r-- | dex2oat/dex2oat.cc | 9 | ||||
| -rw-r--r-- | oatdump/oatdump.cc | 2 | ||||
| -rw-r--r-- | runtime/class_linker.cc | 15 | ||||
| -rw-r--r-- | runtime/class_linker.h | 5 | ||||
| -rw-r--r-- | runtime/common_runtime_test.cc | 3 |
5 files changed, 22 insertions, 12 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 68cf6d9233..89c2a7cbdf 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -1231,6 +1231,7 @@ class Dex2Oat FINAL { // Handle and ClassLoader creation needs to come after Runtime::Create jobject class_loader = nullptr; + jobject class_path_class_loader = nullptr; Thread* self = Thread::Current(); if (!boot_image_option_.empty()) { @@ -1248,10 +1249,12 @@ class Dex2Oat FINAL { key_value_store_->Put(OatHeader::kClassPathKey, OatFile::EncodeDexFileDependencies(class_path_files)); - // Then the dex files we'll compile. Thus we'll resolve the class-path first. - class_path_files.insert(class_path_files.end(), dex_files_.begin(), dex_files_.end()); + class_path_class_loader = class_linker->CreatePathClassLoader(self, + class_path_files, + nullptr); - class_loader = class_linker->CreatePathClassLoader(self, class_path_files); + // Class path loader as parent so that we'll resolve there first. + class_loader = class_linker->CreatePathClassLoader(self, dex_files_, class_path_class_loader); } driver_.reset(new CompilerDriver(compiler_options_.get(), diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index cd83de6265..94eb82b054 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -2412,7 +2412,7 @@ static int DumpOatWithRuntime(Runtime* runtime, OatFile* oat_file, OatDumperOpti // Need a class loader. // Fake that we're a compiler. - jobject class_loader = class_linker->CreatePathClassLoader(self, class_path); + jobject class_loader = class_linker->CreatePathClassLoader(self, class_path, /*parent*/nullptr); // Use the class loader while dumping. StackHandleScope<1> scope(self); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index d5a5ea6797..2dd2a83888 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -6629,7 +6629,9 @@ bool ClassLinker::MayBeCalledWithDirectCodePointer(ArtMethod* m) { } } -jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFile*>& dex_files) { +jobject ClassLinker::CreatePathClassLoader(Thread* self, + std::vector<const DexFile*>& dex_files, + jobject parent_loader) { // SOAAlreadyRunnable is protected, and we need something to add a global reference. // We could move the jobject to the callers, but all call-sites do this... ScopedObjectAccessUnchecked soa(self); @@ -6660,8 +6662,8 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFi for (const DexFile* dex_file : dex_files) { StackHandleScope<3> hs2(self); - // CreatePathClassLoader is only used by gtests. Index 0 of h_long_array is supposed to be the - // oat file but we can leave it null. + // CreatePathClassLoader is only used by gtests and dex2oat. Index 0 of h_long_array is + // supposed to be the oat file but we can leave it null. Handle<mirror::LongArray> h_long_array = hs2.NewHandle(mirror::LongArray::Alloc( self, kDexFileIndexStart + 1)); @@ -6707,9 +6709,10 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFi mirror::Class::FindField(self, hs.NewHandle(h_path_class_loader->GetClass()), "parent", "Ljava/lang/ClassLoader;"); DCHECK(parent_field != nullptr); - mirror::Object* boot_cl = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_BootClassLoader)->AllocObject(self); - parent_field->SetObject<false>(h_path_class_loader.Get(), boot_cl); + mirror::Object* parent = (parent_loader != nullptr) + ? soa.Decode<mirror::ClassLoader*>(parent_loader) + : soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_BootClassLoader)->AllocObject(self); + parent_field->SetObject<false>(h_path_class_loader.Get(), parent); // Make it a global ref and return. ScopedLocalRef<jobject> local_ref( diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 5ba9652c94..29aac312c1 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -514,7 +514,10 @@ class ClassLinker { // Creates a GlobalRef PathClassLoader that can be used to load classes from the given dex files. // Note: the objects are not completely set up. Do not use this outside of tests and the compiler. - jobject CreatePathClassLoader(Thread* self, std::vector<const DexFile*>& dex_files) + // If parent_loader is null then we use the boot class loader. + jobject CreatePathClassLoader(Thread* self, + std::vector<const DexFile*>& dex_files, + jobject parent_loader) SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!dex_lock_); diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc index b6b514177a..f705a50d55 100644 --- a/runtime/common_runtime_test.cc +++ b/runtime/common_runtime_test.cc @@ -553,7 +553,8 @@ jobject CommonRuntimeTest::LoadDex(const char* dex_name) { Thread* self = Thread::Current(); jobject class_loader = Runtime::Current()->GetClassLinker()->CreatePathClassLoader(self, - class_path); + class_path, + nullptr); self->SetClassLoaderOverride(class_loader); return class_loader; } |