diff options
author | Anwar Ghuloum <anwarg@google.com> | 2013-05-01 17:03:05 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-05-01 17:03:06 +0000 |
commit | cf9773a7adff883012dbd519a66e85f1f7aaaa11 (patch) | |
tree | 2202662f22597850bf03c5dbbb0305bfe46816a5 /src | |
parent | 654d91957edb4d1f7534ed5d743cf914db763448 (diff) | |
parent | 8447d84d847d4562d7a7bce62768c27e7d20a9aa (diff) | |
download | art-cf9773a7adff883012dbd519a66e85f1f7aaaa11.tar.gz art-cf9773a7adff883012dbd519a66e85f1f7aaaa11.tar.bz2 art-cf9773a7adff883012dbd519a66e85f1f7aaaa11.zip |
Merge "Compile filter for small applications and methods" into dalvik-dev
Diffstat (limited to 'src')
-rw-r--r-- | src/common_test.h | 2 | ||||
-rw-r--r-- | src/compiler/driver/compiler_driver.cc | 10 | ||||
-rw-r--r-- | src/compiler/driver/compiler_driver.h | 7 | ||||
-rw-r--r-- | src/dex2oat.cc | 49 | ||||
-rw-r--r-- | src/oat_test.cc | 2 | ||||
-rw-r--r-- | src/runtime.cc | 14 | ||||
-rw-r--r-- | src/runtime.h | 27 | ||||
-rw-r--r-- | src/runtime_support.cc | 2 |
8 files changed, 76 insertions, 37 deletions
diff --git a/src/common_test.h b/src/common_test.h index 78d86d2f9..0aac36bfc 100644 --- a/src/common_test.h +++ b/src/common_test.h @@ -366,7 +366,7 @@ class CommonTest : public testing::Test { } class_linker_->FixupDexCaches(runtime_->GetResolutionMethod()); image_classes_.reset(new std::set<std::string>); - compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, true, 2, false, false, + compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set, true, 2, false, image_classes_.get(), true, true)); // Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc index 301d255bb..bc3407302 100644 --- a/src/compiler/driver/compiler_driver.cc +++ b/src/compiler/driver/compiler_driver.cc @@ -283,7 +283,7 @@ static Fn FindFunction(const std::string& compiler_so_name, void* library, const } CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set, - bool image, size_t thread_count, bool support_debugging, bool light_mode, + bool image, size_t thread_count, bool support_debugging, const std::set<std::string>* image_classes, bool dump_stats, bool dump_timings) : compiler_backend_(compiler_backend), @@ -294,7 +294,6 @@ CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet image_(image), thread_count_(thread_count), support_debugging_(support_debugging), - light_mode_(light_mode), start_ns_(0), stats_(new AOTCompilationStats), dump_stats_(dump_stats), @@ -1566,12 +1565,15 @@ void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t CHECK(compiled_method != NULL); } else if ((access_flags & kAccAbstract) != 0) { } else { - // In light mode we only compile image classes. - bool dont_compile = light_mode_ && ((image_classes_ == NULL) || (image_classes_->size() == 0)); + // In small mode we only compile image classes. + bool dont_compile = Runtime::Current()->IsSmallMode() && ((image_classes_ == NULL) || (image_classes_->size() == 0)); // Don't compile class initializers, ever. if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) { dont_compile = true; + } else if (code_item->insns_size_in_code_units_ < Runtime::Current()->GetSmallModeMethodDexSizeLimit()) { + // Do compile small methods. + dont_compile = false; } if (!dont_compile) { diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h index a20e5ef58..7c37c6a08 100644 --- a/src/compiler/driver/compiler_driver.h +++ b/src/compiler/driver/compiler_driver.h @@ -67,7 +67,7 @@ class CompilerDriver { // can assume will be in the image, with NULL implying all available // classes. explicit CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set, bool image, - size_t thread_count, bool support_debugging, bool light_mode, + size_t thread_count, bool support_debugging, const std::set<std::string>* image_classes, bool dump_stats, bool dump_timings); @@ -84,10 +84,6 @@ class CompilerDriver { return support_debugging_; } - bool IsLightMode() const { - return light_mode_; - } - InstructionSet GetInstructionSet() const { return instruction_set_; } @@ -331,7 +327,6 @@ class CompilerDriver { bool image_; size_t thread_count_; bool support_debugging_; - const bool light_mode_; uint64_t start_ns_; UniquePtr<AOTCompilationStats> stats_; diff --git a/src/dex2oat.cc b/src/dex2oat.cc index e41e537ee..37d29961a 100644 --- a/src/dex2oat.cc +++ b/src/dex2oat.cc @@ -137,8 +137,6 @@ static void Usage(const char* fmt, ...) { UsageError(" Use a separate --runtime-arg switch for each argument."); UsageError(" Example: --runtime-arg -Xms256m"); UsageError(""); - UsageError(" --light-mode: compile only if generating image file"); - UsageError(""); std::cerr << "See log for usage error information\n"; exit(EXIT_FAILURE); } @@ -146,15 +144,14 @@ static void Usage(const char* fmt, ...) { class Dex2Oat { public: static bool Create(Dex2Oat** p_dex2oat, Runtime::Options& options, CompilerBackend compiler_backend, - InstructionSet instruction_set, size_t thread_count, bool support_debugging, - bool light_mode) + InstructionSet instruction_set, size_t thread_count, bool support_debugging) SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) { if (!CreateRuntime(options, instruction_set)) { *p_dex2oat = NULL; return false; } *p_dex2oat = new Dex2Oat(Runtime::Current(), compiler_backend, instruction_set, thread_count, - support_debugging, light_mode); + support_debugging); return true; } @@ -265,7 +262,6 @@ class Dex2Oat { image, thread_count_, support_debugging_, - light_mode_, image_classes, dump_stats, dump_timings)); @@ -274,6 +270,7 @@ class Dex2Oat { driver->SetBitcodeFileName(bitcode_filename); } + Thread::Current()->TransitionFromRunnableToSuspended(kNative); driver->CompileAll(class_loader, dex_files); @@ -344,23 +341,14 @@ class Dex2Oat { return true; } - void SetLightMode(bool light_mode) { - light_mode_ = light_mode; - } - - bool GetLightMode() { - return light_mode_; - } - private: explicit Dex2Oat(Runtime* runtime, CompilerBackend compiler_backend, InstructionSet instruction_set, - size_t thread_count, bool support_debugging, bool light_mode) + size_t thread_count, bool support_debugging) : compiler_backend_(compiler_backend), instruction_set_(instruction_set), runtime_(runtime), thread_count_(thread_count), support_debugging_(support_debugging), - light_mode_(light_mode), start_ns_(NanoTime()) { } @@ -486,7 +474,6 @@ class Dex2Oat { Runtime* runtime_; size_t thread_count_; bool support_debugging_; - bool light_mode_; uint64_t start_ns_; DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat); @@ -674,7 +661,6 @@ static int dex2oat(int argc, char** argv) { std::vector<const char*> runtime_args; int thread_count = sysconf(_SC_NPROCESSORS_CONF); bool support_debugging = false; - bool light_mode = false; #if defined(ART_USE_PORTABLE_COMPILER) CompilerBackend compiler_backend = kPortable; #else @@ -694,9 +680,6 @@ static int dex2oat(int argc, char** argv) { bool dump_timings = kIsDebugBuild; bool watch_dog_enabled = !kIsTargetBuild; -#if ART_LIGHT_MODE - light_mode = true; -#endif // ART_LIGHT_MODE for (int i = 0; i < argc; i++) { const StringPiece option(argv[i]); @@ -726,8 +709,6 @@ static int dex2oat(int argc, char** argv) { } } else if (option == "-g") { support_debugging = true; - } else if (option == "--light-mode") { - light_mode = true; } else if (option == "--watch-dog") { watch_dog_enabled = true; } else if (option == "--no-watch-dog") { @@ -932,8 +913,13 @@ static int dex2oat(int argc, char** argv) { options.push_back(std::make_pair(runtime_args[i], reinterpret_cast<void*>(NULL))); } +#if ART_SMALL_MODE + options.push_back(std::make_pair("-small", reinterpret_cast<void*>(NULL))); +#endif // ART_SMALL_MODE + Dex2Oat* p_dex2oat; - if (!Dex2Oat::Create(&p_dex2oat, options, compiler_backend, instruction_set, thread_count, support_debugging, light_mode)) { + if (!Dex2Oat::Create(&p_dex2oat, options, compiler_backend, instruction_set, thread_count, + support_debugging)) { LOG(ERROR) << "Failed to create dex2oat"; return EXIT_FAILURE; } @@ -980,6 +966,21 @@ static int dex2oat(int argc, char** argv) { } } + // If we're in small mode, but the program is small, turn off small mode. + // It doesn't make a difference for the boot image, so let's skip the check + // altogether. + if (Runtime::Current()->IsSmallMode() && !image) { + size_t num_methods = 0; + for (size_t i = 0; i != dex_files.size(); ++i) { + const DexFile* dex_file = dex_files[i]; + CHECK(dex_file != NULL); + num_methods += dex_file->NumMethodIds(); + } + if (num_methods <= Runtime::Current()->GetSmallModeMethodThreshold()) { + Runtime::Current()->SetSmallMode(false); + LOG(INFO) << "Below method threshold, compiling anyways"; + } + } UniquePtr<const CompilerDriver> compiler(dex2oat->CreateOatFile(boot_image_option, host_prefix.get(), diff --git a/src/oat_test.cc b/src/oat_test.cc index a7fbaf14a..dd336d9a9 100644 --- a/src/oat_test.cc +++ b/src/oat_test.cc @@ -76,7 +76,7 @@ TEST_F(OatTest, WriteRead) { #else CompilerBackend compiler_backend = kQuick; #endif - compiler_driver_.reset(new CompilerDriver(compiler_backend, kThumb2, false, 2, false, false, + compiler_driver_.reset(new CompilerDriver(compiler_backend, kThumb2, false, 2, false, NULL, true, true)); compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath()); } diff --git a/src/runtime.cc b/src/runtime.cc index 3cb179357..0caf81d1e 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -364,6 +364,10 @@ Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, b parsed->hook_exit_ = exit; parsed->hook_abort_ = NULL; // We don't call abort(3) by default; see Runtime::Abort. + parsed->small_mode_ = true; + parsed->small_mode_method_threshold_ = Runtime::kDefaultSmallModeMethodThreshold; + parsed->small_mode_method_dex_size_limit_ = Runtime::kDefaultSmallModeMethodDexSizeLimit; + // gLogVerbosity.class_linker = true; // TODO: don't check this in! // gLogVerbosity.compiler = true; // TODO: don't check this in! // gLogVerbosity.heap = true; // TODO: don't check this in! @@ -571,6 +575,12 @@ Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, b Trace::SetDefaultClockSource(kProfilerClockSourceWall); } else if (option == "-Xprofile:dualclock") { Trace::SetDefaultClockSource(kProfilerClockSourceDual); + } else if (option == "-small") { + parsed->small_mode_ = true; + } else if (StartsWith(option, "-small-mode-methods-max:")) { + parsed->small_mode_method_threshold_ = ParseIntegerOrDie(option); + } else if (StartsWith(option, "-small-mode-methods-size-max:")) { + parsed->small_mode_method_dex_size_limit_ = ParseIntegerOrDie(option); } else { if (!ignore_unrecognized) { // TODO: print usage via vfprintf @@ -791,6 +801,10 @@ bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) { is_zygote_ = options->is_zygote_; is_concurrent_gc_enabled_ = options->is_concurrent_gc_enabled_; + small_mode_ = options->small_mode_; + small_mode_method_threshold_ = options->small_mode_method_threshold_; + small_mode_method_dex_size_limit_ = options->small_mode_method_dex_size_limit_; + vfprintf_ = options->hook_vfprintf_; exit_ = options->hook_exit_; abort_ = options->hook_abort_; diff --git a/src/runtime.h b/src/runtime.h index c7ccda187..ac9b50b27 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -61,6 +61,9 @@ class Runtime { public: typedef std::vector<std::pair<std::string, const void*> > Options; + static const size_t kDefaultSmallModeMethodThreshold = 10; + static const size_t kDefaultSmallModeMethodDexSizeLimit = 100; + class ParsedOptions { public: // returns null if problem parsing and ignore_unrecognized is false @@ -95,6 +98,9 @@ class Runtime { void (*hook_exit_)(jint status); void (*hook_abort_)(); std::vector<std::string> properties_; + bool small_mode_; + size_t small_mode_method_threshold_; + size_t small_mode_method_dex_size_limit_; private: ParsedOptions() {} @@ -116,6 +122,23 @@ class Runtime { return is_concurrent_gc_enabled_; } + bool IsSmallMode() const { + return small_mode_; + } + + + void SetSmallMode(bool small_mode) { + small_mode_ = small_mode; + } + + size_t GetSmallModeMethodThreshold() const { + return small_mode_method_threshold_; + } + + size_t GetSmallModeMethodDexSizeLimit() const { + return small_mode_method_dex_size_limit_; + } + const std::string& GetHostPrefix() const { DCHECK(!IsStarted()); return host_prefix_; @@ -339,6 +362,10 @@ class Runtime { bool is_zygote_; bool is_concurrent_gc_enabled_; + bool small_mode_; + size_t small_mode_method_threshold_; + size_t small_mode_method_dex_size_limit_; + // The host prefix is used during cross compilation. It is removed // from the start of host paths such as: // $ANDROID_PRODUCT_OUT/system/framework/boot.oat diff --git a/src/runtime_support.cc b/src/runtime_support.cc index 6ea05b48e..d9b369bac 100644 --- a/src/runtime_support.cc +++ b/src/runtime_support.cc @@ -211,7 +211,7 @@ mirror::Field* FindFieldFromCode(uint32_t field_idx, const mirror::AbstractMetho if (fields_class->IsInitialized()) { return resolved_field; } else if (Runtime::Current()->GetClassLinker()->EnsureInitialized(fields_class, true, true)) { - // otherwise let's ensure the class is initialized before resolving the field + // Otherwise let's ensure the class is initialized before resolving the field. return resolved_field; } else { DCHECK(self->IsExceptionPending()); // Throw exception and unwind |