Dex2oat support for multiple oat file and image file outputs.
Multiple changes to dex2oat and the runtime to support a --multi-image
option. This generates a separate oat file and image file output for
each dex file input.
Change-Id: Ie1d6f0b8afa8aed5790065b8c2eb177990c60129
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index 53ac77b..025e35e 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -716,6 +716,14 @@
bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it)
SHARED_REQUIRES(Locks::mutator_lock_) {
+ const DexFile::TypeId& type_id =
+ dex_file_->GetTypeId(dex_file_->GetClassDef(class_def_index_).class_idx_);
+ const char* class_descriptor = dex_file_->GetTypeDescriptor(type_id);
+ // Skip methods that are not in the image.
+ if (!writer_->GetCompilerDriver()->IsImageClass(class_descriptor)) {
+ return true;
+ }
+
OatClass* oat_class = &writer_->oat_classes_[oat_class_index_];
CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index);
@@ -958,7 +966,9 @@
if (writer_->HasBootImage()) {
auto* element = writer_->image_writer_->GetDexCacheArrayElementImageAddress<const uint8_t*>(
patch.TargetDexCacheDexFile(), patch.TargetDexCacheElementOffset());
- const uint8_t* oat_data = writer_->image_writer_->GetOatFileBegin() + file_offset_;
+ const char* oat_filename = writer_->image_writer_->GetOatFilenameForDexCache(dex_cache_);
+ const uint8_t* oat_data =
+ writer_->image_writer_->GetOatFileBegin(oat_filename) + file_offset_;
return element - oat_data;
} else {
size_t start = writer_->dex_cache_arrays_offsets_.Get(patch.TargetDexCacheDexFile());
@@ -994,9 +1004,15 @@
// NOTE: We're using linker patches for app->boot references when the image can
// be relocated and therefore we need to emit .oat_patches. We're not using this
// for app->app references, so check that the method is an image method.
- gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetBootImageSpace();
- size_t method_offset = reinterpret_cast<const uint8_t*>(method) - image_space->Begin();
- CHECK(image_space->GetImageHeader().GetMethodsSection().Contains(method_offset));
+ std::vector<gc::space::ImageSpace*> image_spaces =
+ Runtime::Current()->GetHeap()->GetBootImageSpaces();
+ bool contains_method = false;
+ for (gc::space::ImageSpace* image_space : image_spaces) {
+ size_t method_offset = reinterpret_cast<const uint8_t*>(method) - image_space->Begin();
+ contains_method |=
+ image_space->GetImageHeader().GetMethodsSection().Contains(method_offset);
+ }
+ CHECK(contains_method);
}
// Note: We only patch targeting ArtMethods in image which is in the low 4gb.
uint32_t address = PointerToLowMemUInt32(method);
@@ -1012,7 +1028,8 @@
SHARED_REQUIRES(Locks::mutator_lock_) {
uint32_t address = target_offset;
if (writer_->HasBootImage()) {
- address = PointerToLowMemUInt32(writer_->image_writer_->GetOatFileBegin() +
+ const char* oat_filename = writer_->image_writer_->GetOatFilenameForDexCache(dex_cache_);
+ address = PointerToLowMemUInt32(writer_->image_writer_->GetOatFileBegin(oat_filename) +
writer_->oat_data_offset_ + target_offset);
}
DCHECK_LE(offset + 4, code->size());