Add JIT
Currently disabled by default unless -Xjit is passed in.
The proposed JIT is a method JIT which works by utilizing interpreter
instrumentation to request compilation of hot methods async during
runtime.
JIT options:
-Xjit / -Xnojit
-Xjitcodecachesize:N
-Xjitthreshold:integervalue
The JIT has a shared copy of a compiler driver which is accessed
by worker threads to compile individual methods.
Added JIT code cache and data cache, currently sized at 2 MB
capacity by default. Most apps will only fill a small fraction of
this cache however.
Added support to the compiler for compiling interpreter quickened
byte codes.
Added test target ART_TEST_JIT=TRUE and --jit for run-test.
TODO:
Clean up code cache.
Delete compiled methods after they are added to code cache.
Add more optimizations related to runtime checks e.g. direct pointers
for invokes.
Add method recompilation.
Move instrumentation to DexFile to improve performance and reduce
memory usage.
Bug: 17950037
Change-Id: Ifa5b2684a2d5059ec5a5210733900aafa3c51bca
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index b756244..24b6f17 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -45,6 +45,10 @@
namespace art {
+namespace mirror {
+class DexCache;
+} // namespace mirror
+
namespace verifier {
class MethodVerifier;
} // namespace verifier
@@ -107,8 +111,11 @@
TimingLogger* timings)
LOCKS_EXCLUDED(Locks::mutator_lock_);
+ CompiledMethod* CompileMethod(Thread* self, mirror::ArtMethod*)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) WARN_UNUSED;
+
// Compile a single Method.
- void CompileOne(mirror::ArtMethod* method, TimingLogger* timings)
+ void CompileOne(Thread* self, mirror::ArtMethod* method, TimingLogger* timings)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
VerificationResults* GetVerificationResults() const {
@@ -172,6 +179,9 @@
size_t GetNonRelativeLinkerPatchCount() const
LOCKS_EXCLUDED(compiled_methods_lock_);
+ // Remove and delete a compiled method.
+ void RemoveCompiledMethod(const MethodReference& method_ref);
+
void AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
uint16_t class_def_index);
bool RequiresConstructorBarrier(Thread* self, const DexFile* dex_file, uint16_t class_def_index);
@@ -226,6 +236,13 @@
uint32_t field_idx, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // Resolve a field with a given dex file.
+ mirror::ArtField* ResolveFieldWithDexFile(
+ const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file,
+ uint32_t field_idx, bool is_static)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// Get declaration location of a resolved field.
void GetResolvedFieldDexFileLocation(
mirror::ArtField* resolved_field, const DexFile** declaring_dex_file,
@@ -235,6 +252,10 @@
bool IsFieldVolatile(mirror::ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
MemberOffset GetFieldOffset(mirror::ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // Find a dex cache for a dex file.
+ inline mirror::DexCache* FindDexCache(const DexFile* dex_file)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// Can we fast-path an IGET/IPUT access to an instance field? If yes, compute the field offset.
std::pair<bool, bool> IsFastInstanceField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
@@ -261,7 +282,7 @@
mirror::ArtMethod* ResolveMethod(
ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
- uint32_t method_idx, InvokeType invoke_type)
+ uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change = true)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get declaration location of a resolved field.
@@ -295,6 +316,13 @@
void ProcessedStaticField(bool resolved, bool local);
void ProcessedInvoke(InvokeType invoke_type, int flags);
+ void ComputeFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
+ const ScopedObjectAccess& soa, bool is_static,
+ mirror::ArtField** resolved_field,
+ mirror::Class** referrer_class,
+ mirror::DexCache** dex_cache)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// Can we fast path instance field access? Computes field's offset and volatility.
bool ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit, bool is_put,
MemberOffset* field_offset, bool* is_volatile)
@@ -380,6 +408,13 @@
return timings_logger_;
}
+ void SetDedupeEnabled(bool dedupe_enabled) {
+ dedupe_enabled_ = dedupe_enabled;
+ }
+ bool DedupeEnabled() const {
+ return dedupe_enabled_;
+ }
+
// Checks if class specified by type_idx is one of the image_classes_
bool IsImageClass(const char* descriptor) const;
@@ -484,7 +519,7 @@
const std::vector<const DexFile*>& dex_files,
ThreadPool* thread_pool, TimingLogger* timings)
LOCKS_EXCLUDED(Locks::mutator_lock_);
- void CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
+ void CompileMethod(Thread* self, const DexFile::CodeItem* code_item, uint32_t access_flags,
InvokeType invoke_type, uint16_t class_def_idx, uint32_t method_idx,
jobject class_loader, const DexFile& dex_file,
DexToDexCompilationLevel dex_to_dex_compilation_level,
@@ -545,6 +580,7 @@
class AOTCompilationStats;
std::unique_ptr<AOTCompilationStats> stats_;
+ bool dedupe_enabled_;
bool dump_stats_;
const bool dump_passes_;
const std::string& dump_cfg_file_name_;