Move image class computation to the CompilerDriver
Change-Id: Ia51cdc199cdeaf409755ab8da23323e204ce041e
diff --git a/src/common_test.h b/src/common_test.h
index 3baa77c..0c171a8 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -346,9 +346,11 @@
}
}
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,
- image_classes_.get(), true, true));
+ compiler_driver_.reset(new CompilerDriver(compiler_backend, instruction_set,
+ true, new CompilerDriver::DescriptorSet,
+ 2, false, true, true));
+ // We typically don't generate an image in unit tests, disable this optimization by default.
+ compiler_driver_->SetSupportBootImageFixup(false);
// Create the heap thread pool so that the GC runs in parallel for tests. Normally, the thread
// pool is created by the runtime.
@@ -389,7 +391,6 @@
(*icu_cleanup_fn)();
compiler_driver_.reset();
- image_classes_.reset();
STLDeleteElements(&opened_dex_files_);
Runtime::Current()->GetHeap()->VerifyHeap(); // Check for heap corruption after the test
@@ -522,7 +523,6 @@
// Owned by the runtime
ClassLinker* class_linker_;
UniquePtr<CompilerDriver> compiler_driver_;
- UniquePtr<std::set<std::string> > image_classes_;
private:
std::vector<const DexFile*> opened_dex_files_;
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index 40cc483..186cf0d 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -324,8 +324,8 @@
}
CompilerDriver::CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set,
- bool image, size_t thread_count, bool support_debugging,
- const std::set<std::string>* image_classes,
+ bool image, DescriptorSet* image_classes,
+ size_t thread_count, bool support_debugging,
bool dump_stats, bool dump_timings)
: compiler_backend_(compiler_backend),
instruction_set_(instruction_set),
@@ -333,19 +333,20 @@
compiled_classes_lock_("compiled classes lock"),
compiled_methods_lock_("compiled method lock"),
image_(image),
+ image_classes_(image_classes),
thread_count_(thread_count),
support_debugging_(support_debugging),
start_ns_(0),
stats_(new AOTCompilationStats),
dump_stats_(dump_stats),
dump_timings_(dump_timings),
- image_classes_(image_classes),
compiler_library_(NULL),
compiler_(NULL),
compiler_context_(NULL),
jni_compiler_(NULL),
compiler_enable_auto_elf_loading_(NULL),
- compiler_get_method_code_addr_(NULL)
+ compiler_get_method_code_addr_(NULL),
+ support_boot_image_fixup_(true)
{
std::string compiler_so_name(MakeCompilerSoName(compiler_backend_));
compiler_library_ = dlopen(compiler_so_name.c_str(), RTLD_LAZY);
@@ -380,7 +381,7 @@
CHECK(!Runtime::Current()->IsStarted());
if (!image_) {
- CHECK(image_classes_ == NULL);
+ CHECK(image_classes_.get() == NULL);
}
}
@@ -576,20 +577,199 @@
void CompilerDriver::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
ThreadPool& thread_pool, TimingLogger& timings) {
+ LoadImageClasses(timings);
+
Resolve(class_loader, dex_files, thread_pool, timings);
Verify(class_loader, dex_files, thread_pool, timings);
InitializeClasses(class_loader, dex_files, thread_pool, timings);
+
+ UpdateImageClasses(timings);
}
bool CompilerDriver::IsImageClass(const char* descriptor) const {
- if (image_classes_ == NULL) {
- return false;
+ DCHECK(descriptor != NULL);
+ if (image_classes_.get() == NULL) {
+ return true;
}
return image_classes_->find(descriptor) != image_classes_->end();
}
+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_) {
+ CompilerDriver::DescriptorSet* image_classes =
+ reinterpret_cast<CompilerDriver::DescriptorSet*>(arg);
+ image_classes->insert(ClassHelper(klass).GetDescriptor());
+ return true;
+}
+
+// Make a list of descriptors for classes to include in the image
+void CompilerDriver::LoadImageClasses(TimingLogger& timings)
+ LOCKS_EXCLUDED(Locks::mutator_lock_) {
+ if (image_classes_.get() == NULL) {
+ return;
+ }
+
+ // Make a first class to load all classes explicitly listed in the file
+ Thread* self = Thread::Current();
+ ScopedObjectAccess soa(self);
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ typedef DescriptorSet::iterator It; // TODO: C++0x auto
+ for (It it = image_classes_->begin(), end = image_classes_->end(); it != end;) {
+ std::string descriptor(*it);
+ SirtRef<mirror::Class> klass(self, class_linker->FindSystemClass(descriptor.c_str()));
+ if (klass.get() == NULL) {
+ image_classes_->erase(it++);
+ LOG(WARNING) << "Failed to find class " << descriptor;
+ Thread::Current()->ClearException();
+ } else {
+ ++it;
+ }
+ }
+
+ // 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.
+ class_linker->VisitClasses(RecordImageClassesVisitor, image_classes_.get());
+
+ CHECK_NE(image_classes_->size(), 0U);
+ timings.AddSplit("LoadImageClasses");
+}
+
+static void MaybeAddToImageClasses(mirror::Class* klass, CompilerDriver::DescriptorSet* image_classes)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ while (!klass->IsObjectClass()) {
+ ClassHelper kh(klass);
+ const char* descriptor = kh.GetDescriptor();
+ std::pair<CompilerDriver::DescriptorSet::iterator, bool> result =
+ image_classes->insert(descriptor);
+ if (result.second) {
+ LOG(INFO) << "Adding " << descriptor << " to image classes";
+ } else {
+ return;
+ }
+ for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+ MaybeAddToImageClasses(kh.GetDirectInterface(i), image_classes);
+ }
+ if (klass->IsArrayClass()) {
+ MaybeAddToImageClasses(klass->GetComponentType(), image_classes);
+ }
+ klass = klass->GetSuperClass();
+ }
+}
+
+void CompilerDriver::FindClinitImageClassesCallback(mirror::Object* object, void* arg) {
+ DCHECK(object != NULL);
+ DCHECK(arg != NULL);
+ CompilerDriver* compiler_driver = reinterpret_cast<CompilerDriver*>(arg);
+ MaybeAddToImageClasses(object->GetClass(), compiler_driver->image_classes_.get());
+}
+
+void CompilerDriver::UpdateImageClasses(TimingLogger& timings) {
+ if (image_classes_.get() == NULL) {
+ return;
+ }
+
+ // Update image_classes_ with classes for objects created by <clinit> methods.
+ Thread* self = Thread::Current();
+ const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter");
+ Heap* heap = Runtime::Current()->GetHeap();
+ // TODO: Image spaces only?
+ WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
+ heap->FlushAllocStack();
+ heap->GetLiveBitmap()->Walk(FindClinitImageClassesCallback, this);
+ self->EndAssertNoThreadSuspension(old_cause);
+ timings.AddSplit("UpdateImageClasses");
+}
+
void CompilerDriver::RecordClassStatus(ClassReference ref, CompiledClass* compiled_class) {
MutexLock mu(Thread::Current(), CompilerDriver::compiled_classes_lock_);
compiled_classes_.Put(ref, compiled_class);
@@ -914,8 +1094,7 @@
}
bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
if (compiling_boot) {
- const bool kSupportBootImageFixup = true;
- if (kSupportBootImageFixup) {
+ if (support_boot_image_fixup_) {
MethodHelper mh(method);
if (IsImageClass(mh.GetDeclaringClassDescriptor())) {
// We can only branch directly to Methods that are resolved in the DexCache.
@@ -1617,10 +1796,13 @@
"Ljava/io/ObjectStreamClass;", // Calls to Class.forName -> java.io.FileDescriptor.
"Ljava/io/ObjectStreamConstants;", // Instance of non-image class SerializablePermission.
"Ljava/lang/ClassLoader$SystemClassLoader;", // Calls System.getProperty -> OsConstants.initConstants.
+ "Ljava/lang/HexStringParser;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
+ "Ljava/lang/ProcessManager;", // Calls Thread.currentThread.
"Ljava/lang/Runtime;", // Calls System.getProperty -> OsConstants.initConstants.
"Ljava/lang/System;", // Calls OsConstants.initConstants.
"Ljava/math/BigDecimal;", // Calls native ... -> java.math.NativeBN.BN_new().
"Ljava/math/BigInteger;", // Calls native ... -> java.math.NativeBN.BN_new().
+ "Ljava/math/Primality;", // Calls native ... -> java.math.NativeBN.BN_new().
"Ljava/math/Multiplication;", // Calls native ... -> java.math.NativeBN.BN_new().
"Ljava/net/InetAddress;", // Requires libcore.io.OsConstants.
"Ljava/net/Inet4Address;", // Sub-class of InetAddress.
@@ -1629,23 +1811,57 @@
"Ljava/nio/charset/Charset;", // Calls Charset.getDefaultCharset -> System.getProperty -> OsConstants.initConstants.
"Ljava/nio/charset/CharsetICU;", // Sub-class of Charset.
"Ljava/nio/charset/Charsets;", // Calls Charset.forName.
+ "Ljava/security/AlgorithmParameterGenerator;", // Calls OsConstants.initConstants.
+ "Ljava/security/KeyPairGenerator$KeyPairGeneratorImpl;", // Calls OsConstants.initConstants.
"Ljava/security/KeyPairGenerator;", // Calls OsConstants.initConstants.
"Ljava/security/Security;", // Tries to do disk IO for "security.properties".
+ "Ljava/security/spec/RSAKeyGenParameterSpec;", // java.math.NativeBN.BN_new()
"Ljava/sql/Date;", // Calls OsConstants.initConstants.
+ "Ljava/sql/DriverManager;", // Calls OsConstants.initConstants.
+ "Ljava/sql/Time;", // Calls OsConstants.initConstants.
+ "Ljava/sql/Timestamp;", // Calls OsConstants.initConstants.
"Ljava/util/Date;", // Calls Date.<init> -> System.currentTimeMillis -> OsConstants.initConstants.
+ "Ljava/util/ListResourceBundle;", // Calls OsConstants.initConstants.
"Ljava/util/Locale;", // Calls System.getProperty -> OsConstants.initConstants.
+ "Ljava/util/PropertyResourceBundle;", // Calls OsConstants.initConstants.
+ "Ljava/util/ResourceBundle;", // Calls OsConstants.initConstants.
+ "Ljava/util/ResourceBundle$MissingBundle;", // Calls OsConstants.initConstants.
+ "Ljava/util/Scanner;", // regex.Pattern.compileImpl.
"Ljava/util/SimpleTimeZone;", // Sub-class of TimeZone.
"Ljava/util/TimeZone;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
"Ljava/util/concurrent/ConcurrentHashMap$Segment;", // Calls Runtime.getRuntime().availableProcessors().
+ "Ljava/util/concurrent/ConcurrentSkipListMap;", // Calls OsConstants.initConstants.
+ "Ljava/util/concurrent/Exchanger;", // Calls OsConstants.initConstants.
+ "Ljava/util/concurrent/ForkJoinPool;", // Calls OsConstants.initConstants.
+ "Ljava/util/concurrent/LinkedTransferQueue;", // Calls OsConstants.initConstants.
+ "Ljava/util/concurrent/Phaser;", // Calls OsConstants.initConstants.
+ "Ljava/util/concurrent/ScheduledThreadPoolExecutor;", // Calls AtomicLong.VMSupportsCS8()
+ "Ljava/util/concurrent/SynchronousQueue;", // Calls OsConstants.initConstants.
+ "Ljava/util/concurrent/atomic/AtomicLong;", // Calls AtomicLong.VMSupportsCS8()
"Ljava/util/logging/LogManager;", // Calls System.getProperty -> OsConstants.initConstants.
+ "Ljava/util/prefs/AbstractPreferences;", // Calls OsConstants.initConstants.
+ "Ljava/util/prefs/FilePreferencesImpl;", // Calls OsConstants.initConstants.
+ "Ljava/util/prefs/FilePreferencesFactoryImpl;", // Calls OsConstants.initConstants.
+ "Ljava/util/prefs/Preferences;", // Calls OsConstants.initConstants.
+ "Ljavax/crypto/KeyAgreement;", // Calls OsConstants.initConstants.
+ "Ljavax/crypto/KeyGenerator;", // Calls OsConstants.initConstants.
+ "Ljavax/security/cert/X509Certificate;", // Calls VMClassLoader.getBootClassPathSize.
+ "Ljavax/security/cert/X509Certificate$1;", // Calls VMClassLoader.getBootClassPathSize.
"Ljavax/microedition/khronos/egl/EGL10;", // Requires EGLContext.
"Ljavax/microedition/khronos/egl/EGLContext;", // Requires com.google.android.gles_jni.EGLImpl.
"Ljavax/net/ssl/HttpsURLConnection;", // Calls SSLSocketFactory.getDefault -> java.security.Security.getProperty.
+ "Ljavax/xml/datatype/DatatypeConstants;", // Calls OsConstants.initConstants.
+ "Ljavax/xml/datatype/FactoryFinder;", // Calls OsConstants.initConstants.
+ "Ljavax/xml/namespace/QName;", // Calls OsConstants.initConstants.
+ "Ljavax/xml/validation/SchemaFactoryFinder;", // Calls OsConstants.initConstants.
+ "Ljavax/xml/xpath/XPathConstants;", // Calls OsConstants.initConstants.
+ "Ljavax/xml/xpath/XPathFactoryFinder;", // Calls OsConstants.initConstants.
"Llibcore/icu/LocaleData;", // Requires java.util.Locale.
"Llibcore/icu/TimeZoneNames;", // Requires java.util.TimeZone.
"Llibcore/io/IoUtils;", // Calls Random.<init> -> System.currentTimeMillis -> FileDescriptor -> OsConstants.initConstants.
"Llibcore/io/OsConstants;", // Platform specific.
"Llibcore/net/MimeUtils;", // Calls libcore.net.MimeUtils.getContentTypesPropertiesStream -> System.getProperty.
+ "Llibcore/reflect/Types;", // Calls OsConstants.initConstants.
"Llibcore/util/ZoneInfo;", // Sub-class of TimeZone.
"Llibcore/util/ZoneInfoDB;", // Calls System.getenv -> OsConstants.initConstants.
"Lorg/apache/commons/logging/LogFactory;", // Calls System.getProperty.
@@ -1653,17 +1869,40 @@
"Lorg/apache/harmony/security/provider/cert/X509CertFactoryImpl;", // Requires java.nio.charsets.Charsets.
"Lorg/apache/harmony/security/provider/crypto/RandomBitsSupplier;", // Requires java.io.File.
"Lorg/apache/harmony/security/utils/AlgNameMapper;", // Requires java.util.Locale.
+ "Lorg/apache/harmony/security/pkcs10/CertificationRequest;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/pkcs10/CertificationRequestInfo;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/pkcs7/AuthenticatedAttributes;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/pkcs7/SignedData;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/pkcs7/SignerInfo;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/pkcs8/PrivateKeyInfo;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl;", // Calls OsConstants.initConstants.
"Lorg/apache/harmony/security/x501/AttributeTypeAndValue;", // Calls IntegralToString.convertInt -> Thread.currentThread.
"Lorg/apache/harmony/security/x501/DirectoryString;", // Requires BigInteger.
"Lorg/apache/harmony/security/x501/Name;", // Requires org.apache.harmony.security.x501.AttributeTypeAndValue.
+ "Lorg/apache/harmony/security/x509/AccessDescription;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/AuthorityKeyIdentifier;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/CRLDistributionPoints;", // Calls Thread.currentThread.
"Lorg/apache/harmony/security/x509/Certificate;", // Requires org.apache.harmony.security.x509.TBSCertificate.
- "Lorg/apache/harmony/security/x509/TBSCertificate;", // Requires org.apache.harmony.security.x501.Name.
+ "Lorg/apache/harmony/security/x509/CertificateIssuer;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/CertificateList;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/DistributionPoint;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/DistributionPointName;", // Calls Thread.currentThread.
"Lorg/apache/harmony/security/x509/EDIPartyName;", // Calls native ... -> java.math.NativeBN.BN_new().
"Lorg/apache/harmony/security/x509/GeneralName;", // Requires org.apache.harmony.security.x501.Name.
"Lorg/apache/harmony/security/x509/GeneralNames;", // Requires GeneralName.
+ "Lorg/apache/harmony/security/x509/GeneralSubtree;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/GeneralSubtrees;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/InfoAccessSyntax;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/IssuingDistributionPoint;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/NameConstraints;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/TBSCertList$RevokedCertificate;", // Calls NativeBN.BN_new().
+ "Lorg/apache/harmony/security/x509/TBSCertList;", // Calls Thread.currentThread.
+ "Lorg/apache/harmony/security/x509/TBSCertificate;", // Requires org.apache.harmony.security.x501.Name.
"Lorg/apache/harmony/security/x509/Time;", // Calls native ... -> java.math.NativeBN.BN_new().
"Lorg/apache/harmony/security/x509/Validity;", // Requires x509.Time.
+ "Lorg/apache/harmony/security/x509/tsp/TSTInfo;", // Calls Thread.currentThread.
"Lorg/apache/harmony/xml/ExpatParser;", // Calls native ExpatParser.staticInitialize.
+ "Lorg/apache/harmony/xml/ExpatParser$EntityParser;", // Calls ExpatParser.staticInitialize.
"Lorg/apache/http/conn/params/ConnRouteParams;", // Requires java.util.Locale.
"Lorg/apache/http/conn/ssl/SSLSocketFactory;", // Calls java.security.Security.getProperty.
"Lorg/apache/http/conn/util/InetAddressUtils;", // Calls regex.Pattern.compile -..-> regex.Pattern.compileImpl.
@@ -1693,6 +1932,9 @@
// Only try to initialize classes that were successfully verified.
if (klass->IsVerified()) {
manager->GetClassLinker()->EnsureInitialized(klass, false, can_init_static_fields);
+ if (soa.Self()->IsExceptionPending()) {
+ soa.Self()->GetException(NULL)->Dump();
+ }
if (!klass->IsInitialized()) {
if (can_init_static_fields) {
bool is_black_listed = false;
@@ -1730,7 +1972,7 @@
compiled_class = new CompiledClass(status);
manager->GetCompiler()->RecordClassStatus(ref, compiled_class);
} else {
- DCHECK_EQ(status, compiled_class->GetStatus());
+ DCHECK_GE(status, compiled_class->GetStatus()) << descriptor;
}
}
// Clear any class not found or verification exceptions.
@@ -1854,7 +2096,8 @@
} else if ((access_flags & kAccAbstract) != 0) {
} else {
// In small mode we only compile image classes.
- bool dont_compile = Runtime::Current()->IsSmallMode() && ((image_classes_ == NULL) || (image_classes_->size() == 0));
+ bool dont_compile = (Runtime::Current()->IsSmallMode() &&
+ ((image_classes_.get() == NULL) || (image_classes_->size() == 0)));
// Don't compile class initializers, ever.
if (((access_flags & kAccConstructor) != 0) && ((access_flags & kAccStatic) != 0)) {
diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h
index 4f77bdb..fbfcadb 100644
--- a/src/compiler/driver/compiler_driver.h
+++ b/src/compiler/driver/compiler_driver.h
@@ -61,14 +61,16 @@
class CompilerDriver {
public:
+ typedef std::set<std::string> DescriptorSet;
+
// Create a compiler targeting the requested "instruction_set".
// "image" should be true if image specific optimizations should be
// enabled. "image_classes" lets the compiler know what classes it
// can assume will be in the image, with NULL implying all available
// classes.
- explicit CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set, bool image,
+ explicit CompilerDriver(CompilerBackend compiler_backend, InstructionSet instruction_set,
+ bool image, DescriptorSet* image_classes,
size_t thread_count, bool support_debugging,
- const std::set<std::string>* image_classes,
bool dump_stats, bool dump_timings);
~CompilerDriver();
@@ -96,6 +98,10 @@
return image_;
}
+ DescriptorSet* GetImageClasses() const {
+ return image_classes_.get();
+ }
+
CompilerTls* GetTls();
// Generate the trampolines that are invoked by unresolved direct methods.
@@ -197,6 +203,15 @@
void SetBitcodeFileName(std::string const& filename);
+ bool GetSupportBootImageFixup() const {
+ return support_boot_image_fixup_;
+ }
+
+ void SetSupportBootImageFixup(bool support_boot_image_fixup) {
+ support_boot_image_fixup_ = support_boot_image_fixup;
+ }
+
+
// TODO: remove these Elf wrappers when libart links against LLVM (when separate compiler library is gone)
bool WriteElf(const std::string& android_root,
bool is_host,
@@ -298,6 +313,8 @@
ThreadPool& thread_pool, TimingLogger& timings)
LOCKS_EXCLUDED(Locks::mutator_lock_);
+ void LoadImageClasses(TimingLogger& timings);
+
// Attempt to resolve all type, methods, fields, and strings
// referenced from code in the dex file following PathClassLoader
// ordering semantics.
@@ -321,6 +338,10 @@
ThreadPool& thread_pool, TimingLogger& timings)
LOCKS_EXCLUDED(Locks::mutator_lock_, compiled_classes_lock_);
+ void UpdateImageClasses(TimingLogger& timings);
+ static void FindClinitImageClassesCallback(mirror::Object* object, void* arg)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
void Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
ThreadPool& thread_pool, TimingLogger& timings);
void CompileDexFile(jobject class_loader, const DexFile& dex_file,
@@ -355,7 +376,13 @@
mutable Mutex compiled_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
MethodTable compiled_methods_ GUARDED_BY(compiled_methods_lock_);
- bool image_;
+ const bool image_;
+
+ // If image_ is true, specifies the classes that will be included in
+ // the image. Note if image_classes_ is NULL, all classes are
+ // included in the image.
+ UniquePtr<DescriptorSet> image_classes_;
+
size_t thread_count_;
bool support_debugging_;
uint64_t start_ns_;
@@ -365,8 +392,6 @@
bool dump_stats_;
bool dump_timings_;
- const std::set<std::string>* image_classes_;
-
typedef void (*CompilerCallbackFn)(CompilerDriver& driver);
typedef MutexLock* (*CompilerMutexLockFn)(CompilerDriver& driver);
@@ -395,6 +420,8 @@
(const CompilerDriver& driver, const CompiledMethod* cm, const mirror::AbstractMethod* method);
CompilerGetMethodCodeAddrFn compiler_get_method_code_addr_;
+ bool support_boot_image_fixup_;
+
DISALLOW_COPY_AND_ASSIGN(CompilerDriver);
};
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());
diff --git a/src/image_test.cc b/src/image_test.cc
index cd1a34f..0769e21 100644
--- a/src/image_test.cc
+++ b/src/image_test.cc
@@ -43,28 +43,19 @@
{
std::vector<uint8_t> oat_contents;
{
+ jobject class_loader = NULL;
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath());
+
ScopedObjectAccess soa(Thread::Current());
- std::vector<const DexFile*> dex_files;
- dex_files.push_back(java_lang_dex_file_);
- dex_files.push_back(conscrypt_file_);
VectorOutputStream output_stream(tmp_elf.GetFilename(), oat_contents);
- bool success_oat = OatWriter::Create(output_stream, dex_files, 0, 0, "",
- *compiler_driver_.get());
+ bool success_oat = OatWriter::Create(output_stream, class_linker->GetBootClassPath(),
+ 0, 0, "", *compiler_driver_.get());
ASSERT_TRUE(success_oat);
- // Force all system classes into memory
- for (size_t dex_file_index = 0; dex_file_index < dex_files.size(); ++dex_file_index) {
- const DexFile* dex_file = dex_files[dex_file_index];
- for (size_t class_def_index = 0; class_def_index < dex_file->NumClassDefs(); ++class_def_index) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
- const char* descriptor = dex_file->GetClassDescriptor(class_def);
- mirror::Class* klass = class_linker_->FindSystemClass(descriptor);
- EXPECT_TRUE(klass != NULL) << descriptor;
- }
- }
bool success_elf = compiler_driver_->WriteElf(GetTestAndroidRoot(),
!kIsTargetBuild,
- dex_files,
+ class_linker->GetBootClassPath(),
oat_contents,
tmp_elf.GetFile());
ASSERT_TRUE(success_elf);
@@ -77,10 +68,9 @@
ScratchFile tmp_image;
const uintptr_t requested_image_base = ART_BASE_ADDRESS;
{
- ImageWriter writer(NULL);
+ ImageWriter writer(*compiler_driver_.get());
bool success_image = writer.Write(tmp_image.GetFilename(), requested_image_base,
- tmp_oat->GetPath(), tmp_oat->GetPath(),
- *compiler_driver_.get());
+ tmp_oat->GetPath(), tmp_oat->GetPath());
ASSERT_TRUE(success_image);
bool success_fixup = compiler_driver_->FixupElf(tmp_oat.get(), writer.GetOatDataBegin());
ASSERT_TRUE(success_fixup);
@@ -102,6 +92,9 @@
ASSERT_GE(sizeof(image_header) + space->Size(), static_cast<size_t>(file->GetLength()));
}
+ ASSERT_TRUE(compiler_driver_->GetImageClasses() != NULL);
+ CompilerDriver::DescriptorSet image_classes(*compiler_driver_->GetImageClasses());
+
// Need to delete the compiler since it has worker threads which are attached to runtime.
compiler_driver_.reset();
@@ -149,7 +142,13 @@
mirror::Class* klass = class_linker_->FindSystemClass(descriptor);
EXPECT_TRUE(klass != NULL) << descriptor;
EXPECT_LT(image_begin, reinterpret_cast<byte*>(klass)) << descriptor;
- EXPECT_LT(reinterpret_cast<byte*>(klass), image_end) << descriptor;
+ if (image_classes.find(descriptor) != image_classes.end()) {
+ // image classes should be located before the end of the image.
+ EXPECT_LT(reinterpret_cast<byte*>(klass), image_end) << descriptor;
+ } else {
+ // non image classes should be in a space after the image.
+ EXPECT_GT(reinterpret_cast<byte*>(klass), image_end) << descriptor;
+ }
EXPECT_EQ(*klass->GetRawLockWordAddress(), 0); // address should have been removed from monitor
}
}
diff --git a/src/image_writer.cc b/src/image_writer.cc
index 4ba99fe..5a1ebbb 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -57,8 +57,7 @@
bool ImageWriter::Write(const std::string& image_filename,
uintptr_t image_begin,
const std::string& oat_filename,
- const std::string& oat_location,
- const CompilerDriver& compiler_driver) {
+ const std::string& oat_location) {
CHECK(!image_filename.empty());
CHECK_NE(image_begin, 0U);
@@ -114,10 +113,10 @@
Thread::Current()->TransitionFromSuspendedToRunnable();
size_t oat_loaded_size = 0;
size_t oat_data_offset = 0;
- compiler_driver.GetOatElfInformation(oat_file.get(), oat_loaded_size, oat_data_offset);
+ compiler_driver_.GetOatElfInformation(oat_file.get(), oat_loaded_size, oat_data_offset);
CalculateNewObjectOffsets(oat_loaded_size, oat_data_offset);
CopyAndFixupObjects();
- PatchOatCodeAndMethods(compiler_driver);
+ PatchOatCodeAndMethods();
Thread::Current()->TransitionFromRunnableToSuspended(kNative);
UniquePtr<File> image_file(OS::OpenFile(image_filename.c_str(), true));
@@ -199,42 +198,21 @@
}
bool ImageWriter::IsImageClass(const Class* klass) {
- if (image_classes_ == NULL) {
- return true;
- }
- while (klass->IsArrayClass()) {
- klass = klass->GetComponentType();
- }
- if (klass->IsPrimitive()) {
- return true;
- }
- const std::string descriptor(ClassHelper(klass).GetDescriptor());
- return image_classes_->find(descriptor) != image_classes_->end();
+ return compiler_driver_.IsImageClass(ClassHelper(klass).GetDescriptor());
}
-
struct NonImageClasses {
ImageWriter* image_writer;
std::set<std::string>* non_image_classes;
};
void ImageWriter::PruneNonImageClasses() {
- if (image_classes_ == NULL) {
+ if (compiler_driver_.GetImageClasses() == NULL) {
return;
}
Runtime* runtime = Runtime::Current();
ClassLinker* class_linker = runtime->GetClassLinker();
- // Update image_classes_ with classes for objects created by <clinit> methods.
- Thread* self = Thread::Current();
- const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter");
- Heap* heap = Runtime::Current()->GetHeap();
- // TODO: Image spaces only?
- WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
- heap->FlushAllocStack();
- heap->GetLiveBitmap()->Walk(FindClinitImageClassesCallback, this);
- self->EndAssertNoThreadSuspension(old_cause);
-
// Make a list of classes we would like to prune.
std::set<std::string> non_image_classes;
NonImageClasses context;
@@ -275,28 +253,6 @@
}
}
-void ImageWriter::FindClinitImageClassesCallback(Object* object, void* arg) {
- DCHECK(object != NULL);
- DCHECK(arg != NULL);
- ImageWriter* image_writer = reinterpret_cast<ImageWriter*>(arg);
- Class* klass = object->GetClass();
- while (klass->IsArrayClass()) {
- klass = klass->GetComponentType();
- }
- if (klass->IsPrimitive()) {
- return;
- }
- while (!klass->IsObjectClass()) {
- ClassHelper kh(klass);
- const char* descriptor = kh.GetDescriptor();
- std::pair<DescriptorSet::iterator, bool> result = image_writer->image_classes_->insert(descriptor);
- if (result.second) {
- LOG(INFO) << "Adding " << descriptor << " to image classes";
- }
- klass = klass->GetSuperClass();
- }
-}
-
bool ImageWriter::NonImageClassesVisitor(Class* klass, void* arg) {
NonImageClasses* context = reinterpret_cast<NonImageClasses*>(arg);
if (!context->image_writer->IsImageClass(klass)) {
@@ -307,7 +263,7 @@
void ImageWriter::CheckNonImageClassesRemoved()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (image_classes_ == NULL) {
+ if (compiler_driver_.GetImageClasses() == NULL) {
return;
}
@@ -336,8 +292,10 @@
}
void ImageWriter::DumpImageClasses() {
+ CompilerDriver::DescriptorSet* image_classes = compiler_driver_.GetImageClasses();
+ CHECK(image_classes != NULL);
typedef std::set<std::string>::const_iterator It; // TODO: C++0x auto
- for (It it = image_classes_->begin(), end = image_classes_->end(); it != end; ++it) {
+ for (It it = image_classes->begin(), end = image_classes->end(); it != end; ++it) {
LOG(INFO) << " " << *it;
}
}
@@ -659,13 +617,13 @@
return method;
}
-void ImageWriter::PatchOatCodeAndMethods(const CompilerDriver& compiler) {
+void ImageWriter::PatchOatCodeAndMethods() {
Thread* self = Thread::Current();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter");
typedef std::vector<const CompilerDriver::PatchInformation*> Patches;
- const Patches& code_to_patch = compiler.GetCodeToPatch();
+ const Patches& code_to_patch = compiler_driver_.GetCodeToPatch();
for (size_t i = 0; i < code_to_patch.size(); i++) {
const CompilerDriver::PatchInformation* patch = code_to_patch[i];
AbstractMethod* target = GetTargetMethod(patch);
@@ -675,7 +633,7 @@
SetPatchLocation(patch, reinterpret_cast<uint32_t>(GetOatAddress(code_offset)));
}
- const Patches& methods_to_patch = compiler.GetMethodsToPatch();
+ const Patches& methods_to_patch = compiler_driver_.GetMethodsToPatch();
for (size_t i = 0; i < methods_to_patch.size(); i++) {
const CompilerDriver::PatchInformation* patch = methods_to_patch[i];
AbstractMethod* target = GetTargetMethod(patch);
diff --git a/src/image_writer.h b/src/image_writer.h
index 4628e5a..4507592 100644
--- a/src/image_writer.h
+++ b/src/image_writer.h
@@ -37,9 +37,8 @@
// Write a Space built during compilation for use during execution.
class ImageWriter {
public:
- typedef std::set<std::string> DescriptorSet;
- explicit ImageWriter(DescriptorSet* image_classes)
- : oat_file_(NULL), image_end_(0), image_begin_(NULL), image_classes_(image_classes),
+ explicit ImageWriter(const CompilerDriver& compiler_driver)
+ : compiler_driver_(compiler_driver), oat_file_(NULL), image_end_(0), image_begin_(NULL),
oat_data_begin_(NULL), interpreter_to_interpreter_entry_offset_(0),
interpreter_to_quick_entry_offset_(0), portable_resolution_trampoline_offset_(0),
quick_resolution_trampoline_offset_(0) {}
@@ -49,8 +48,7 @@
bool Write(const std::string& image_filename,
uintptr_t image_begin,
const std::string& oat_filename,
- const std::string& oat_location,
- const CompilerDriver& compiler_driver)
+ const std::string& oat_location)
LOCKS_EXCLUDED(Locks::mutator_lock_);
uintptr_t GetOatDataBegin() {
@@ -132,8 +130,6 @@
// Remove unwanted classes from various roots.
void PruneNonImageClasses() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void FindClinitImageClassesCallback(mirror::Object* object, void* arg)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static bool NonImageClassesVisitor(mirror::Class* c, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -172,12 +168,14 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Patches references in OatFile to expect runtime addresses.
- void PatchOatCodeAndMethods(const CompilerDriver& compiler)
+ void PatchOatCodeAndMethods()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetPatchLocation(const CompilerDriver::PatchInformation* patch, uint32_t value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const CompilerDriver& compiler_driver_;
+
// Map of Object to where it will be at runtime.
SafeMap<const mirror::Object*, size_t> offsets_;
@@ -193,9 +191,6 @@
// Beginning target image address for the output image.
byte* image_begin_;
- // Set of classes to be include in the image, or NULL for all.
- DescriptorSet* image_classes_;
-
// Beginning target oat address for the pointers from the output image to its oat file.
const byte* oat_data_begin_;
diff --git a/src/oat_test.cc b/src/oat_test.cc
index c7c063a..29e2891 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -74,8 +74,8 @@
#else
CompilerBackend compiler_backend = kQuick;
#endif
- compiler_driver_.reset(new CompilerDriver(compiler_backend, kThumb2, false, 2, false,
- NULL, true, true));
+ compiler_driver_.reset(new CompilerDriver(compiler_backend, kThumb2, false, NULL, 2, false,
+ true, true));
jobject class_loader = NULL;
if (compile) {
compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath());