Support running without a boot image.
Bug: 17000769
Change-Id: I6404d5050c8a2f4ee6e70d58532eb25ee9de248e
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index ba53c43..233c9d4 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -102,6 +102,7 @@
is_concurrent_gc_enabled_(true),
is_explicit_gc_disabled_(false),
dex2oat_enabled_(true),
+ image_dex2oat_enabled_(true),
default_stack_size_(0),
heap_(nullptr),
max_spins_before_thin_lock_inflation_(Monitor::kDefaultMaxSpinsBeforeThinLockInflation),
@@ -396,10 +397,18 @@
// Restore main thread state to kNative as expected by native code.
Thread* self = Thread::Current();
+
self->TransitionFromRunnableToSuspended(kNative);
started_ = true;
+ if (!IsImageDex2OatEnabled() || !Runtime::Current()->GetHeap()->HasImageSpace()) {
+ ScopedObjectAccess soa(Thread::Current());
+ StackHandleScope<1> hs(soa.Self());
+ auto klass(hs.NewHandle<mirror::Class>(mirror::Class::GetJavaLangClass()));
+ class_linker_->EnsureInitialized(klass, true, true);
+ }
+
// InitNativeMethods needs to be after started_ so that the classes
// it touches will have methods linked to the oat file if necessary.
InitNativeMethods();
@@ -535,6 +544,24 @@
VLOG(startup) << "Runtime::StartDaemonThreads exiting";
}
+static size_t OpenDexFiles(const std::vector<std::string>& dex_filenames,
+ std::vector<const DexFile*>& dex_files) {
+ size_t failure_count = 0;
+ for (size_t i = 0; i < dex_filenames.size(); i++) {
+ const char* dex_filename = dex_filenames[i].c_str();
+ std::string error_msg;
+ if (!OS::FileExists(dex_filename)) {
+ LOG(WARNING) << "Skipping non-existent dex file '" << dex_filename << "'";
+ continue;
+ }
+ if (!DexFile::Open(dex_filename, dex_filename, &error_msg, &dex_files)) {
+ LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "': " << error_msg;
+ ++failure_count;
+ }
+ }
+ return failure_count;
+}
+
bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) {
CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);
@@ -559,6 +586,7 @@
is_zygote_ = options->is_zygote_;
is_explicit_gc_disabled_ = options->is_explicit_gc_disabled_;
dex2oat_enabled_ = options->dex2oat_enabled_;
+ image_dex2oat_enabled_ = options->image_dex2oat_enabled_;
vfprintf_ = options->hook_vfprintf_;
exit_ = options->hook_exit_;
@@ -677,10 +705,24 @@
if (kIsDebugBuild) {
GetHeap()->GetImageSpace()->VerifyImageAllocations();
}
+ } else if (!IsCompiler() || !image_dex2oat_enabled_) {
+ std::vector<std::string> dex_filenames;
+ Split(boot_class_path_string_, ':', dex_filenames);
+ std::vector<const DexFile*> boot_class_path;
+ OpenDexFiles(dex_filenames, boot_class_path);
+ class_linker_->InitWithoutImage(boot_class_path);
+ // TODO: Should we move the following to InitWithoutImage?
+ SetInstructionSet(kRuntimeISA);
+ for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
+ Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
+ if (!HasCalleeSaveMethod(type)) {
+ SetCalleeSaveMethod(CreateCalleeSaveMethod(type), type);
+ }
+ }
} else {
CHECK(options->boot_class_path_ != NULL);
CHECK_NE(options->boot_class_path_->size(), 0U);
- class_linker_->InitFromCompiler(*options->boot_class_path_);
+ class_linker_->InitWithoutImage(*options->boot_class_path_);
}
CHECK(class_linker_ != NULL);
verifier::MethodVerifier::Init();