summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2014-11-13 21:26:09 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2014-11-13 21:26:09 +0000
commit3225b83903329ba7745f6785127e09ff040492cf (patch)
treebf97adf68ec9f39be03075664eef5c53576bd72c
parent67ab6192a9cf1781521692212fa48889a8d36e94 (diff)
parent4bf3ae9930a155f238dfd471413c866912b2579e (diff)
Merge "ART: Compiled-classes list for compiler-driver"
-rw-r--r--compiler/common_compiler_test.cc2
-rw-r--r--compiler/driver/compiler_driver.cc33
-rw-r--r--compiler/driver/compiler_driver.h12
-rw-r--r--compiler/oat_test.cc4
-rw-r--r--dex2oat/dex2oat.cc41
5 files changed, 82 insertions, 10 deletions
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index bfdb537427..085d169c6d 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -156,7 +156,7 @@ void CommonCompilerTest::SetUp() {
method_inliner_map_.get(),
compiler_kind, instruction_set,
instruction_set_features_.get(),
- true, new std::set<std::string>,
+ true, new std::set<std::string>, nullptr,
2, true, true, timer_.get(), ""));
}
// We typically don't generate an image in unit tests, disable this optimization by default.
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index aab94c000f..08041e8f24 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -330,7 +330,8 @@ CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options,
Compiler::Kind compiler_kind,
InstructionSet instruction_set,
const InstructionSetFeatures* instruction_set_features,
- bool image, std::set<std::string>* image_classes, size_t thread_count,
+ bool image, std::set<std::string>* image_classes,
+ std::set<std::string>* compiled_classes, size_t thread_count,
bool dump_stats, bool dump_passes, CumulativeLogger* timer,
const std::string& profile_file)
: profile_present_(false), compiler_options_(compiler_options),
@@ -346,6 +347,7 @@ CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options,
non_relative_linker_patch_count_(0u),
image_(image),
image_classes_(image_classes),
+ classes_to_compile_(compiled_classes),
thread_count_(thread_count),
stats_(new AOTCompilationStats),
dump_stats_(dump_stats),
@@ -570,7 +572,7 @@ void CompilerDriver::CompileOne(mirror::ArtMethod* method, TimingLogger* timings
class_def);
}
CompileMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx, jclass_loader,
- *dex_file, dex_to_dex_compilation_level);
+ *dex_file, dex_to_dex_compilation_level, true);
self->GetJniEnv()->DeleteGlobalRef(jclass_loader);
@@ -613,6 +615,17 @@ bool CompilerDriver::IsImageClass(const char* descriptor) const {
}
}
+bool CompilerDriver::IsClassToCompile(const char* descriptor) const {
+ if (!IsImage()) {
+ return true;
+ } else {
+ if (classes_to_compile_ == nullptr) {
+ return true;
+ }
+ return classes_to_compile_->find(descriptor) != classes_to_compile_->end();
+ }
+}
+
static void ResolveExceptionsForMethod(MutableMethodHelper* mh,
std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -1916,6 +1929,10 @@ void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, siz
it.Next();
}
CompilerDriver* driver = manager->GetCompiler();
+
+ bool compilation_enabled = driver->IsClassToCompile(
+ dex_file.StringByTypeIdx(class_def.class_idx_));
+
// Compile direct methods
int64_t previous_direct_method_idx = -1;
while (it.HasNextDirectMethod()) {
@@ -1929,7 +1946,8 @@ void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, siz
previous_direct_method_idx = method_idx;
driver->CompileMethod(it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
it.GetMethodInvokeType(class_def), class_def_index,
- method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
+ method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
+ compilation_enabled);
it.Next();
}
// Compile virtual methods
@@ -1945,7 +1963,8 @@ void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, siz
previous_virtual_method_idx = method_idx;
driver->CompileMethod(it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
it.GetMethodInvokeType(class_def), class_def_index,
- method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
+ method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
+ compilation_enabled);
it.Next();
}
DCHECK(!it.HasNext());
@@ -1977,7 +1996,8 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t
InvokeType invoke_type, uint16_t class_def_idx,
uint32_t method_idx, jobject class_loader,
const DexFile& dex_file,
- DexToDexCompilationLevel dex_to_dex_compilation_level) {
+ DexToDexCompilationLevel dex_to_dex_compilation_level,
+ bool compilation_enabled) {
CompiledMethod* compiled_method = nullptr;
uint64_t start_ns = kTimeCompileMethod ? NanoTime() : 0;
@@ -1994,7 +2014,8 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t
// Abstract methods don't have code.
} else {
MethodReference method_ref(&dex_file, method_idx);
- bool compile = verification_results_->IsCandidateForCompilation(method_ref, access_flags);
+ bool compile = compilation_enabled &&
+ verification_results_->IsCandidateForCompilation(method_ref, access_flags);
if (compile) {
// NOTE: if compiler declines to compile this method, it will return nullptr.
compiled_method = compiler_->Compile(code_item, access_flags, invoke_type, class_def_idx,
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index 682b17a7d1..ddb2342b42 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -91,6 +91,7 @@ class CompilerDriver {
InstructionSet instruction_set,
const InstructionSetFeatures* instruction_set_features,
bool image, std::set<std::string>* image_classes,
+ std::set<std::string>* compiled_classes,
size_t thread_count, bool dump_stats, bool dump_passes,
CumulativeLogger* timer, const std::string& profile_file);
@@ -374,6 +375,9 @@ class CompilerDriver {
// Checks if class specified by type_idx is one of the image_classes_
bool IsImageClass(const char* descriptor) const;
+ // Checks if the provided class should be compiled, i.e., is in classes_to_compile_.
+ bool IsClassToCompile(const char* descriptor) const;
+
void RecordClassStatus(ClassReference ref, mirror::Class::Status status)
LOCKS_EXCLUDED(compiled_classes_lock_);
@@ -475,7 +479,8 @@ class CompilerDriver {
void CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx,
jobject class_loader, const DexFile& dex_file,
- DexToDexCompilationLevel dex_to_dex_compilation_level)
+ DexToDexCompilationLevel dex_to_dex_compilation_level,
+ bool compilation_enabled)
LOCKS_EXCLUDED(compiled_methods_lock_);
static void CompileClass(const ParallelCompilationManager* context, size_t class_def_index)
@@ -514,6 +519,11 @@ class CompilerDriver {
// included in the image.
std::unique_ptr<std::set<std::string>> image_classes_;
+ // If image_ is true, specifies the classes that will be compiled in
+ // the image. Note if classes_to_compile_ is nullptr, all classes are
+ // included in the image.
+ std::unique_ptr<std::set<std::string>> classes_to_compile_;
+
size_t thread_count_;
class AOTCompilationStats;
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 97b7cc90dd..c384c57c3a 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -109,8 +109,8 @@ TEST_F(OatTest, WriteRead) {
verification_results_.get(),
method_inliner_map_.get(),
compiler_kind, insn_set,
- insn_features.get(), false, nullptr, 2, true, true,
- timer_.get(), ""));
+ insn_features.get(), false, nullptr, nullptr, 2, true,
+ true, timer_.get(), ""));
jobject class_loader = nullptr;
if (kCompile) {
TimingLogger timings2("OatTest::WriteRead", false, false);
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 4951b1f412..47b492ae7c 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -430,6 +430,8 @@ class Dex2Oat FINAL {
image_base_(0U),
image_classes_zip_filename_(nullptr),
image_classes_filename_(nullptr),
+ compiled_classes_zip_filename_(nullptr),
+ compiled_classes_filename_(nullptr),
image_(false),
is_host_(false),
dump_stats_(false),
@@ -540,6 +542,10 @@ class Dex2Oat FINAL {
image_classes_filename_ = option.substr(strlen("--image-classes=")).data();
} else if (option.starts_with("--image-classes-zip=")) {
image_classes_zip_filename_ = option.substr(strlen("--image-classes-zip=")).data();
+ } else if (option.starts_with("--compiled-classes=")) {
+ compiled_classes_filename_ = option.substr(strlen("--compiled-classes=")).data();
+ } else if (option.starts_with("--compiled-classes-zip=")) {
+ compiled_classes_zip_filename_ = option.substr(strlen("--compiled-classes-zip=")).data();
} else if (option.starts_with("--base=")) {
const char* image_base_str = option.substr(strlen("--base=")).data();
char* end;
@@ -743,6 +749,18 @@ class Dex2Oat FINAL {
Usage("--image-classes-zip should be used with --image-classes");
}
+ if (compiled_classes_filename_ != nullptr && !image_) {
+ Usage("--compiled-classes should only be used with --image");
+ }
+
+ if (compiled_classes_filename_ != nullptr && !boot_image_option_.empty()) {
+ Usage("--compiled-classes should not be used with --boot-image");
+ }
+
+ if (compiled_classes_zip_filename_ != nullptr && compiled_classes_filename_ == nullptr) {
+ Usage("--compiled-classes-zip should be used with --compiled-classes");
+ }
+
if (dex_filenames_.empty() && zip_fd_ == -1) {
Usage("Input must be supplied with either --dex-file or --zip-fd");
}
@@ -986,6 +1004,25 @@ class Dex2Oat FINAL {
} else if (image_) {
image_classes_.reset(new std::set<std::string>);
}
+ // If --compiled-classes was specified, calculate the full list of classes to compile in the
+ // image.
+ if (compiled_classes_filename_ != nullptr) {
+ std::string error_msg;
+ if (compiled_classes_zip_filename_ != nullptr) {
+ compiled_classes_.reset(ReadImageClassesFromZip(compiled_classes_zip_filename_,
+ compiled_classes_filename_,
+ &error_msg));
+ } else {
+ compiled_classes_.reset(ReadImageClassesFromFile(compiled_classes_filename_));
+ }
+ if (compiled_classes_.get() == nullptr) {
+ LOG(ERROR) << "Failed to create list of compiled classes from '"
+ << compiled_classes_filename_ << "': " << error_msg;
+ return false;
+ }
+ } else if (image_) {
+ compiled_classes_.reset(nullptr); // By default compile everything.
+ }
if (boot_image_option_.empty()) {
dex_files_ = Runtime::Current()->GetClassLinker()->GetBootClassPath();
@@ -1089,6 +1126,7 @@ class Dex2Oat FINAL {
instruction_set_features_.get(),
image_,
image_classes_.release(),
+ compiled_classes_.release(),
thread_count_,
dump_stats_,
dump_passes_,
@@ -1514,7 +1552,10 @@ class Dex2Oat FINAL {
uintptr_t image_base_;
const char* image_classes_zip_filename_;
const char* image_classes_filename_;
+ const char* compiled_classes_zip_filename_;
+ const char* compiled_classes_filename_;
std::unique_ptr<std::set<std::string>> image_classes_;
+ std::unique_ptr<std::set<std::string>> compiled_classes_;
bool image_;
std::unique_ptr<ImageWriter> image_writer_;
bool is_host_;