Move image class computation to the CompilerDriver
Change-Id: Ia51cdc199cdeaf409755ab8da23323e204ce041e
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index 235c068..f678ee9 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -161,18 +161,15 @@
}
- // Make a list of descriptors for classes to include in the image
- std::set<std::string>* GetImageClassDescriptors(const char* image_classes_filename)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ // Reads the class names (java.lang.Object) and returns as set of class descriptors (Ljava/lang/Object;)
+ CompilerDriver::DescriptorSet* ReadImageClasses(const char* image_classes_filename) {
UniquePtr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename, std::ifstream::in));
if (image_classes_file.get() == NULL) {
LOG(ERROR) << "Failed to open image classes file " << image_classes_filename;
return NULL;
}
- // Load all the classes specified in the file
- ClassLinker* class_linker = runtime_->GetClassLinker();
- Thread* self = Thread::Current();
+ UniquePtr<CompilerDriver::DescriptorSet> image_classes(new CompilerDriver::DescriptorSet);
while (image_classes_file->good()) {
std::string dot;
std::getline(*image_classes_file.get(), dot);
@@ -180,51 +177,9 @@
continue;
}
std::string descriptor(DotToDescriptor(dot.c_str()));
- SirtRef<mirror::Class> klass(self, class_linker->FindSystemClass(descriptor.c_str()));
- if (klass.get() == NULL) {
- LOG(WARNING) << "Failed to find class " << descriptor;
- Thread::Current()->ClearException();
- }
+ image_classes->insert(descriptor);
}
image_classes_file->close();
-
- // Resolve exception classes referenced by the loaded classes. The catch logic assumes
- // exceptions are resolved by the verifier when there is a catch block in an interested method.
- // Do this here so that exception classes appear to have been specified image classes.
- std::set<std::pair<uint16_t, const DexFile*> > unresolved_exception_types;
- SirtRef<mirror::Class> java_lang_Throwable(self,
- class_linker->FindSystemClass("Ljava/lang/Throwable;"));
- do {
- unresolved_exception_types.clear();
- class_linker->VisitClasses(ResolveCatchBlockExceptionsClassVisitor,
- &unresolved_exception_types);
- typedef std::set<std::pair<uint16_t, const DexFile*> >::const_iterator It; // TODO: C++0x auto
- for (It it = unresolved_exception_types.begin(),
- end = unresolved_exception_types.end();
- it != end; ++it) {
- uint16_t exception_type_idx = it->first;
- const DexFile* dex_file = it->second;
- mirror::DexCache* dex_cache = class_linker->FindDexCache(*dex_file);
- mirror:: ClassLoader* class_loader = NULL;
- SirtRef<mirror::Class> klass(self, class_linker->ResolveType(*dex_file, exception_type_idx,
- dex_cache, class_loader));
- if (klass.get() == NULL) {
- const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx);
- const char* descriptor = dex_file->GetTypeDescriptor(type_id);
- LOG(FATAL) << "Failed to resolve class " << descriptor;
- }
- DCHECK(java_lang_Throwable->IsAssignableFrom(klass.get()));
- }
- // Resolving exceptions may load classes that reference more exceptions, iterate until no
- // more are found
- } while (!unresolved_exception_types.empty());
-
- // We walk the roots looking for classes so that we'll pick up the
- // above classes plus any classes them depend on such super
- // classes, interfaces, and the required ClassLinker roots.
- UniquePtr<ImageWriter::DescriptorSet> image_classes(new ImageWriter::DescriptorSet);
- class_linker->VisitClasses(RecordImageClassesVisitor, image_classes.get());
- CHECK_NE(image_classes->size(), 0U);
return image_classes.release();
}
@@ -236,7 +191,7 @@
File* oat_file,
const std::string& bitcode_filename,
bool image,
- const ImageWriter::DescriptorSet* image_classes,
+ UniquePtr<CompilerDriver::DescriptorSet>& image_classes,
bool dump_stats,
bool dump_timings)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -260,9 +215,9 @@
UniquePtr<CompilerDriver> driver(new CompilerDriver(compiler_backend_,
instruction_set_,
image,
+ image_classes.release(),
thread_count_,
support_debugging_,
- image_classes,
dump_stats,
dump_timings));
@@ -320,7 +275,6 @@
bool CreateImageFile(const std::string& image_filename,
uintptr_t image_base,
- ImageWriter::DescriptorSet* image_classes,
const std::string& oat_filename,
const std::string& oat_location,
const CompilerDriver& compiler)
@@ -328,8 +282,8 @@
uintptr_t oat_data_begin;
{
// ImageWriter is scoped so it can free memory before doing FixupElf
- ImageWriter image_writer(image_classes);
- if (!image_writer.Write(image_filename, image_base, oat_filename, oat_location, compiler)) {
+ ImageWriter image_writer(compiler);
+ if (!image_writer.Write(image_filename, image_base, oat_filename, oat_location)) {
LOG(ERROR) << "Failed to create image file " << image_filename;
return false;
}
@@ -380,72 +334,6 @@
return true;
}
- static void ResolveExceptionsForMethod(MethodHelper* mh,
- std::set<std::pair<uint16_t, const DexFile*> >& exceptions_to_resolve)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const DexFile::CodeItem* code_item = mh->GetCodeItem();
- if (code_item == NULL) {
- return; // native or abstract method
- }
- if (code_item->tries_size_ == 0) {
- return; // nothing to process
- }
- const byte* encoded_catch_handler_list = DexFile::GetCatchHandlerData(*code_item, 0);
- size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&encoded_catch_handler_list);
- for (size_t i = 0; i < num_encoded_catch_handlers; i++) {
- int32_t encoded_catch_handler_size = DecodeSignedLeb128(&encoded_catch_handler_list);
- bool has_catch_all = false;
- if (encoded_catch_handler_size <= 0) {
- encoded_catch_handler_size = -encoded_catch_handler_size;
- has_catch_all = true;
- }
- for (int32_t j = 0; j < encoded_catch_handler_size; j++) {
- uint16_t encoded_catch_handler_handlers_type_idx =
- DecodeUnsignedLeb128(&encoded_catch_handler_list);
- // Add to set of types to resolve if not already in the dex cache resolved types
- if (!mh->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
- exceptions_to_resolve.insert(
- std::pair<uint16_t, const DexFile*>(encoded_catch_handler_handlers_type_idx,
- &mh->GetDexFile()));
- }
- // ignore address associated with catch handler
- DecodeUnsignedLeb128(&encoded_catch_handler_list);
- }
- if (has_catch_all) {
- // ignore catch all address
- DecodeUnsignedLeb128(&encoded_catch_handler_list);
- }
- }
- }
-
- static bool ResolveCatchBlockExceptionsClassVisitor(mirror::Class* c, void* arg)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::set<std::pair<uint16_t, const DexFile*> >* exceptions_to_resolve =
- reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*> >*>(arg);
- MethodHelper mh;
- for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
- mirror::AbstractMethod* m = c->GetVirtualMethod(i);
- mh.ChangeMethod(m);
- ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
- }
- for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
- mirror::AbstractMethod* m = c->GetDirectMethod(i);
- mh.ChangeMethod(m);
- ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
- }
- return true;
- }
-
- static bool RecordImageClassesVisitor(mirror::Class* klass, void* arg)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ImageWriter::DescriptorSet* image_classes = reinterpret_cast<ImageWriter::DescriptorSet*>(arg);
- if (klass->IsArrayClass() || klass->IsPrimitive()) {
- return true;
- }
- image_classes->insert(ClassHelper(klass).GetDescriptor());
- return true;
- }
-
// Appends to dex_files any elements of class_path that it doesn't already
// contain. This will open those dex files as necessary.
static void OpenClassPathFiles(const std::string& class_path, std::vector<const DexFile*>& dex_files) {
@@ -929,7 +817,7 @@
#endif // ART_SMALL_MODE
Dex2Oat* p_dex2oat;
- if (!Dex2Oat::Create(&p_dex2oat, options, compiler_backend, instruction_set, thread_count,
+ if (!Dex2Oat::Create(&p_dex2oat, options, compiler_backend, instruction_set, thread_count,
support_debugging)) {
LOG(ERROR) << "Failed to create dex2oat";
return EXIT_FAILURE;
@@ -943,9 +831,9 @@
ScopedObjectAccess soa(Thread::Current());
// If --image-classes was specified, calculate the full list of classes to include in the image
- UniquePtr<ImageWriter::DescriptorSet> image_classes(NULL);
+ UniquePtr<CompilerDriver::DescriptorSet> image_classes(NULL);
if (image_classes_filename != NULL) {
- image_classes.reset(dex2oat->GetImageClassDescriptors(image_classes_filename));
+ image_classes.reset(dex2oat->ReadImageClasses(image_classes_filename));
if (image_classes.get() == NULL) {
LOG(ERROR) << "Failed to create list of image classes from " << image_classes_filename;
return EXIT_FAILURE;
@@ -1001,7 +889,7 @@
oat_file.get(),
bitcode_filename,
image,
- image_classes.get(),
+ image_classes,
dump_stats,
dump_timings));
@@ -1066,7 +954,6 @@
Thread::Current()->TransitionFromRunnableToSuspended(kNative);
bool image_creation_success = dex2oat->CreateImageFile(image_filename,
image_base,
- image_classes.get(),
oat_unstripped,
oat_location,
*compiler.get());