diff options
Diffstat (limited to 'dex2oat/dex2oat.cc')
| -rw-r--r-- | dex2oat/dex2oat.cc | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 1e4ed58c8c..fe927bbc1c 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -428,6 +428,10 @@ NO_RETURN static void Usage(const char* fmt, ...) { UsageError(" --class-loader-context=<string spec>: a string specifying the intended"); UsageError(" runtime loading context for the compiled dex files."); UsageError(""); + UsageError(" --stored-class-loader-context=<string spec>: a string specifying the intended"); + UsageError(" runtime loading context that is stored in the oat file. Overrides"); + UsageError(" --class-loader-context. Note that this ignores the classpath_dir arg."); + UsageError(""); UsageError(" It describes how the class loader chain should be built in order to ensure"); UsageError(" classes are resolved during dex2aot as they would be resolved at runtime."); UsageError(" This spec will be encoded in the oat file. If at runtime the dex file is"); @@ -1260,11 +1264,31 @@ class Dex2Oat FINAL { ParseInstructionSetFeatures(*args.Get(M::TargetInstructionSetFeatures), parser_options.get()); } if (args.Exists(M::ClassLoaderContext)) { - class_loader_context_ = ClassLoaderContext::Create(*args.Get(M::ClassLoaderContext)); + std::string class_loader_context_arg = *args.Get(M::ClassLoaderContext); + class_loader_context_ = ClassLoaderContext::Create(class_loader_context_arg); if (class_loader_context_ == nullptr) { Usage("Option --class-loader-context has an incorrect format: %s", - args.Get(M::ClassLoaderContext)->c_str()); + class_loader_context_arg.c_str()); + } + if (args.Exists(M::StoredClassLoaderContext)) { + const std::string stored_context_arg = *args.Get(M::StoredClassLoaderContext); + stored_class_loader_context_ = ClassLoaderContext::Create(stored_context_arg); + if (stored_class_loader_context_ == nullptr) { + Usage("Option --stored-class-loader-context has an incorrect format: %s", + stored_context_arg.c_str()); + } else if (!class_loader_context_->VerifyClassLoaderContextMatch( + stored_context_arg, + /*verify_names*/ false, + /*verify_checksums*/ false)) { + Usage( + "Option --stored-class-loader-context '%s' mismatches --class-loader-context '%s'", + stored_context_arg.c_str(), + class_loader_context_arg.c_str()); + } } + } else if (args.Exists(M::StoredClassLoaderContext)) { + Usage("Option --stored-class-loader-context should only be used if " + "--class-loader-context is also specified"); } if (!ReadCompilerOptions(args, compiler_options_.get(), &error_msg)) { @@ -1579,7 +1603,7 @@ class Dex2Oat FINAL { if (class_loader_context_ == nullptr) { // If no context was specified use the default one (which is an empty PathClassLoader). - class_loader_context_ = std::unique_ptr<ClassLoaderContext>(ClassLoaderContext::Default()); + class_loader_context_ = ClassLoaderContext::Default(); } DCHECK_EQ(oat_writers_.size(), 1u); @@ -1605,8 +1629,12 @@ class Dex2Oat FINAL { } // Store the class loader context in the oat header. - key_value_store_->Put(OatHeader::kClassPathKey, - class_loader_context_->EncodeContextForOatFile(classpath_dir_)); + // TODO: deprecate this since store_class_loader_context should be enough to cover the users + // of classpath_dir as well. + std::string class_path_key = + class_loader_context_->EncodeContextForOatFile(classpath_dir_, + stored_class_loader_context_.get()); + key_value_store_->Put(OatHeader::kClassPathKey, class_path_key); } // Now that we have finalized key_value_store_, start writing the oat file. @@ -2845,6 +2873,9 @@ class Dex2Oat FINAL { // The spec describing how the class loader should be setup for compilation. std::unique_ptr<ClassLoaderContext> class_loader_context_; + // The class loader context stored in the oat file. May be equal to class_loader_context_. + std::unique_ptr<ClassLoaderContext> stored_class_loader_context_; + size_t thread_count_; uint64_t start_ns_; uint64_t start_cputime_ns_; |