summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAnwar Ghuloum <anwarg@google.com>2013-04-30 17:27:40 -0700
committerAnwar Ghuloum <anwarg@google.com>2013-04-30 20:32:59 -0700
commit8447d84d847d4562d7a7bce62768c27e7d20a9aa (patch)
tree46aad5bf1bc3d3ce28b24ef1fcc5463224083991 /src
parent88fc036842eb3c48acd5d3b01e75b3012c996d90 (diff)
downloadandroid_art-8447d84d847d4562d7a7bce62768c27e7d20a9aa.tar.gz
android_art-8447d84d847d4562d7a7bce62768c27e7d20a9aa.tar.bz2
android_art-8447d84d847d4562d7a7bce62768c27e7d20a9aa.zip
Compile filter for small applications and methods
Adds a filter per method and program size (in method count). Right now, options are treated as runtime options...but we might want to change this and separate options for compilers and runtime. Change-Id: I8c3e925116119af8ffa95ff09f77bcfdd173767b
Diffstat (limited to 'src')
-rw-r--r--src/common_test.h2
-rw-r--r--src/compiler/driver/compiler_driver.cc10
-rw-r--r--src/compiler/driver/compiler_driver.h7
-rw-r--r--src/dex2oat.cc49
-rw-r--r--src/oat_test.cc2
-rw-r--r--src/runtime.cc14
-rw-r--r--src/runtime.h27
-rw-r--r--src/runtime_support.cc2
8 files changed, 76 insertions, 37 deletions
diff --git a/src/common_test.h b/src/common_test.h
index 6876274b7b..cc68f44afb 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -364,7 +364,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 1660914ce3..3075a54988 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 a20e5ef585..7c37c6a083 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 e41e537ee0..37d29961a7 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 5d6edf2e98..7c702e2481 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 25d26b8005..d886fe3d09 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 c7ccda1877..ac9b50b278 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 6ea05b48e9..d9b369bac3 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