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/dex/mir_method_info.h b/compiler/dex/mir_method_info.h
index 08fb103..e131c96 100644
--- a/compiler/dex/mir_method_info.h
+++ b/compiler/dex/mir_method_info.h
@@ -46,6 +46,9 @@
const DexFile* DeclaringDexFile() const {
return declaring_dex_file_;
}
+ void SetDeclaringDexFile(const DexFile* dex_file) {
+ declaring_dex_file_ = dex_file;
+ }
uint16_t DeclaringClassIndex() const {
return declaring_class_idx_;
@@ -98,11 +101,12 @@
MirMethodLoweringInfo* method_infos, size_t count)
LOCKS_EXCLUDED(Locks::mutator_lock_);
- MirMethodLoweringInfo(uint16_t method_idx, InvokeType type)
+ MirMethodLoweringInfo(uint16_t method_idx, InvokeType type, bool is_quickened)
: MirMethodInfo(method_idx,
((type == kStatic) ? kFlagIsStatic : 0u) |
(static_cast<uint16_t>(type) << kBitInvokeTypeBegin) |
- (static_cast<uint16_t>(type) << kBitSharpTypeBegin)),
+ (static_cast<uint16_t>(type) << kBitSharpTypeBegin) |
+ (is_quickened ? kFlagQuickened : 0u)),
direct_code_(0u),
direct_method_(0u),
target_dex_file_(nullptr),
@@ -131,6 +135,11 @@
return (flags_ & kFlagClassIsInitialized) != 0u;
}
+ // Returns true iff the method invoke is INVOKE_VIRTUAL_QUICK or INVOKE_VIRTUAL_RANGE_QUICK.
+ bool IsQuickened() const {
+ return (flags_ & kFlagQuickened) != 0u;
+ }
+
InvokeType GetInvokeType() const {
return static_cast<InvokeType>((flags_ >> kBitInvokeTypeBegin) & kInvokeTypeMask);
}
@@ -146,6 +155,9 @@
uint16_t VTableIndex() const {
return vtable_idx_;
}
+ void SetVTableIndex(uint16_t index) {
+ vtable_idx_ = index;
+ }
uintptr_t DirectCode() const {
return direct_code_;
@@ -159,6 +171,20 @@
return stats_flags_;
}
+ void CheckEquals(const MirMethodLoweringInfo& info) const {
+ CHECK_EQ(method_idx_, info.method_idx_);
+ CHECK_EQ(flags_, info.flags_);
+ CHECK_EQ(declaring_method_idx_, info.declaring_method_idx_);
+ CHECK_EQ(declaring_class_idx_, info.declaring_class_idx_);
+ CHECK_EQ(declaring_dex_file_, info.declaring_dex_file_);
+ CHECK_EQ(direct_code_, info.direct_code_);
+ CHECK_EQ(direct_method_, info.direct_method_);
+ CHECK_EQ(target_dex_file_, info.target_dex_file_);
+ CHECK_EQ(target_method_idx_, info.target_method_idx_);
+ CHECK_EQ(vtable_idx_, info.vtable_idx_);
+ CHECK_EQ(stats_flags_, info.stats_flags_);
+ }
+
private:
enum {
kBitFastPath = kMethodInfoBitEnd,
@@ -168,12 +194,14 @@
kBitSharpTypeEnd = kBitSharpTypeBegin + 3, // 3 bits for sharp type.
kBitIsReferrersClass = kBitSharpTypeEnd,
kBitClassIsInitialized,
+ kBitQuickened,
kMethodLoweringInfoBitEnd
};
static_assert(kMethodLoweringInfoBitEnd <= 16, "Too many flags");
static constexpr uint16_t kFlagFastPath = 1u << kBitFastPath;
static constexpr uint16_t kFlagIsReferrersClass = 1u << kBitIsReferrersClass;
static constexpr uint16_t kFlagClassIsInitialized = 1u << kBitClassIsInitialized;
+ static constexpr uint16_t kFlagQuickened = 1u << kBitQuickened;
static constexpr uint16_t kInvokeTypeMask = 7u;
static_assert((1u << (kBitInvokeTypeEnd - kBitInvokeTypeBegin)) - 1u == kInvokeTypeMask,
"assert invoke type bits failed");