From 27e0d1f3da2e0b7046dacb40794739d739e454a3 Mon Sep 17 00:00:00 2001 From: Calin Juravle Date: Wed, 26 Jul 2017 00:16:07 -0700 Subject: Pass the class loader context to dex2oat when optimizing at runtime Until now we always passed the special shared library symbol "&" when we called dex2oat at runtime without an explicit class path. This CL changes that and passes the class loader context inferred from the runtime class loaders to dex2oat. If any of the runtime class loaders is not supported we continue to pass the special library symbol. Bug: 38138251 Test: m test-art-host Change-Id: Ica43ee8a3f36dab2d9ed0e634a9f6341379c8e1c --- runtime/class_loader_context.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'runtime/class_loader_context.h') diff --git a/runtime/class_loader_context.h b/runtime/class_loader_context.h index 37dd02b07f..85299d41c0 100644 --- a/runtime/class_loader_context.h +++ b/runtime/class_loader_context.h @@ -82,9 +82,16 @@ class ClassLoaderContext { // (so that it can be read and verified at runtime against the actual class // loader hierarchy). // Should only be called if OpenDexFiles() returned true. - // E.g. if the context is PCL[a.dex:b.dex] this will return "a.dex*a_checksum*b.dex*a_checksum". + // E.g. if the context is PCL[a.dex:b.dex] this will return + // "PCL[a.dex*a_checksum*b.dex*a_checksum]". std::string EncodeContextForOatFile(const std::string& base_dir) const; + // Encodes the context as a string suitable to be passed to dex2oat. + // This is the same as EncodeContextForOatFile but without adding the checksums + // and only adding each dex files once (no multidex). + // Should only be called if OpenDexFiles() returned true. + std::string EncodeContextForDex2oat(const std::string& base_dir) const; + // Flattens the opened dex files into the given vector. // Should only be called if OpenDexFiles() returned true. std::vector FlattenOpenedDexFiles() const; @@ -94,7 +101,7 @@ class ClassLoaderContext { // - the number and type of the class loaders from the chain matches // - the class loader from the same position have the same classpath // (the order and checksum of the dex files matches) - bool VerifyClassLoaderContextMatch(const std::string& context_spec); + bool VerifyClassLoaderContextMatch(const std::string& context_spec) const; // Creates the class loader context from the given string. // The format: ClassLoaderType1[ClasspathElem1:ClasspathElem2...];ClassLoaderType2[...]... @@ -173,7 +180,15 @@ class ClassLoaderContext { bool AddInfoToContextFromClassLoader(ScopedObjectAccessAlreadyRunnable& soa, Handle class_loader, Handle> dex_elements) - REQUIRES_SHARED(Locks::mutator_lock_); + REQUIRES_SHARED(Locks::mutator_lock_); + + // Encodes the context as a string suitable to be passed to dex2oat or to be added to the + // oat file as the class path key. + // If for_dex2oat is true, the encoding adds each file once (i.e. it does not add multidex + // location). Otherwise, for oat files, the encoding adds all the dex files (including multidex) + // together with their checksums. + // Should only be called if OpenDexFiles() returned true. + std::string EncodeContext(const std::string& base_dir, bool for_dex2oat) const; // Extracts the class loader type from the given spec. // Return ClassLoaderContext::kInvalidClassLoader if the class loader type is not -- cgit v1.2.3-59-g8ed1b From 84f82b9972ec29bd05b1575ae6d638255be2f285 Mon Sep 17 00:00:00 2001 From: Calin Juravle Date: Wed, 2 Aug 2017 18:28:08 -0700 Subject: Stop using the runtime classpath in dex2oat Use only --class-loader-context to infer the classpath that should be used for compilation. The tests and benchmarks no longer rely on --runtime-arg --classpath being passed to dex2oat. Bug: 36044779 Test: m test-art-host Change-Id: Iba4cb3489f4a1a4a421071e1889d806d6c1d0738 --- dex2oat/dex2oat.cc | 18 +++++------------- runtime/class_loader_context.cc | 4 ++++ runtime/class_loader_context.h | 10 +++++++--- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'runtime/class_loader_context.h') diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 0826fa1488..fd22dcdcc4 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -1304,7 +1304,7 @@ class Dex2Oat FINAL { } else if (option.starts_with("--class-loader-context=")) { class_loader_context_ = ClassLoaderContext::Create( option.substr(strlen("--class-loader-context=")).data()); - if (class_loader_context_== nullptr) { + if (class_loader_context_ == nullptr) { Usage("Option --class-loader-context has an incorrect format: %s", option.data()); } } else if (!compiler_options_->ParseCompilerOption(option, Usage)) { @@ -1569,20 +1569,12 @@ class Dex2Oat FINAL { } // Open dex files for class path. + if (class_loader_context_ == nullptr) { - // TODO(calin): Temporary workaround while we transition to use - // --class-loader-context instead of --runtime-arg -cp - if (runtime_->GetClassPathString().empty()) { - class_loader_context_ = std::unique_ptr( - new ClassLoaderContext()); - } else { - std::string spec = runtime_->GetClassPathString() == OatFile::kSpecialSharedLibrary - ? OatFile::kSpecialSharedLibrary - : "PCL[" + runtime_->GetClassPathString() + "]"; - class_loader_context_ = ClassLoaderContext::Create(spec); - } + // If no context was specified use the default one (which is an empty PathClassLoader). + class_loader_context_ = std::unique_ptr(ClassLoaderContext::Default()); } - CHECK(class_loader_context_ != nullptr); + DCHECK_EQ(oat_writers_.size(), 1u); // Note: Ideally we would reject context where the source dex files are also diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc index b50aec0b63..e7051b35d8 100644 --- a/runtime/class_loader_context.cc +++ b/runtime/class_loader_context.cc @@ -68,6 +68,10 @@ ClassLoaderContext::~ClassLoaderContext() { } } +std::unique_ptr ClassLoaderContext::Default() { + return Create(""); +} + std::unique_ptr ClassLoaderContext::Create(const std::string& spec) { std::unique_ptr result(new ClassLoaderContext()); if (result->Parse(spec)) { diff --git a/runtime/class_loader_context.h b/runtime/class_loader_context.h index 85299d41c0..9afa880da4 100644 --- a/runtime/class_loader_context.h +++ b/runtime/class_loader_context.h @@ -34,9 +34,6 @@ class OatFile; // Utility class which holds the class loader context used during compilation/verification. class ClassLoaderContext { public: - // Creates an empty context (with no class loaders). - ClassLoaderContext(); - ~ClassLoaderContext(); // Opens requested class path files and appends them to ClassLoaderInfo::opened_dex_files. @@ -126,6 +123,10 @@ class ClassLoaderContext { static std::unique_ptr CreateContextForClassLoader(jobject class_loader, jobjectArray dex_elements); + // Returns the default class loader context to be used when none is specified. + // This will return a context with a single and empty PathClassLoader. + static std::unique_ptr Default(); + private: enum ClassLoaderType { kInvalidClassLoader = 0, @@ -151,6 +152,9 @@ class ClassLoaderContext { explicit ClassLoaderInfo(ClassLoaderType cl_type) : type(cl_type) {} }; + // Creates an empty context (with no class loaders). + ClassLoaderContext(); + // Constructs an empty context. // `owns_the_dex_files` specifies whether or not the context will own the opened dex files // present in the class loader chain. If `owns_the_dex_files` is true then OpenDexFiles cannot -- cgit v1.2.3-59-g8ed1b