diff options
author | 2015-02-17 10:38:49 -0800 | |
---|---|---|
committer | 2015-02-23 16:45:49 -0800 | |
commit | 2535abe7d1fcdd0e6aca782b1f1932a703ed50a4 (patch) | |
tree | 140026ff9638ff34050680b6c706b82fa1740b56 /compiler/driver/compiler_driver-inl.h | |
parent | 38fee8ef4bc0f4dbe2c6d1f5585895f0c4d16984 (diff) |
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
Diffstat (limited to 'compiler/driver/compiler_driver-inl.h')
-rw-r--r-- | compiler/driver/compiler_driver-inl.h | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index 9948c82663..4a35e9fbe7 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -56,14 +56,13 @@ inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( return referrer_class; } -inline mirror::ArtField* CompilerDriver::ResolveField( +inline mirror::ArtField* CompilerDriver::ResolveFieldWithDexFile( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, - Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, + Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file, uint32_t field_idx, bool is_static) { - DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); - DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); - mirror::ArtField* resolved_field = mUnit->GetClassLinker()->ResolveField( - *mUnit->GetDexFile(), field_idx, dex_cache, class_loader, is_static); + DCHECK_EQ(dex_cache->GetDexFile(), dex_file); + mirror::ArtField* resolved_field = Runtime::Current()->GetClassLinker()->ResolveField( + *dex_file, field_idx, dex_cache, class_loader, is_static); DCHECK_EQ(resolved_field == nullptr, soa.Self()->IsExceptionPending()); if (UNLIKELY(resolved_field == nullptr)) { // Clean up any exception left by type resolution. @@ -78,6 +77,19 @@ inline mirror::ArtField* CompilerDriver::ResolveField( return resolved_field; } +inline mirror::DexCache* CompilerDriver::FindDexCache(const DexFile* dex_file) { + return Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file); +} + +inline mirror::ArtField* CompilerDriver::ResolveField( + const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, + uint32_t field_idx, bool is_static) { + DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); + return ResolveFieldWithDexFile(soa, dex_cache, class_loader, mUnit->GetDexFile(), field_idx, + is_static); +} + inline void CompilerDriver::GetResolvedFieldDexFileLocation( mirror::ArtField* resolved_field, const DexFile** declaring_dex_file, uint16_t* declaring_class_idx, uint16_t* declaring_field_idx) { @@ -172,7 +184,7 @@ inline bool CompilerDriver::IsStaticFieldsClassInitialized(mirror::Class* referr inline mirror::ArtMethod* CompilerDriver::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) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); mirror::ArtMethod* resolved_method = mUnit->GetClassLinker()->ResolveMethod( @@ -184,7 +196,8 @@ inline mirror::ArtMethod* CompilerDriver::ResolveMethod( soa.Self()->ClearException(); return nullptr; } - if (UNLIKELY(resolved_method->CheckIncompatibleClassChange(invoke_type))) { + if (check_incompatible_class_change && + UNLIKELY(resolved_method->CheckIncompatibleClassChange(invoke_type))) { // Silently return nullptr on incompatible class change. return nullptr; } @@ -227,14 +240,14 @@ inline int CompilerDriver::IsFastInvoke( target_method->dex_method_index))) { return 0; } - // Sharpen a virtual call into a direct call when the target is known not to have been // overridden (ie is final). - bool can_sharpen_virtual_based_on_type = + const bool same_dex_file = target_method->dex_file == mUnit->GetDexFile(); + bool can_sharpen_virtual_based_on_type = same_dex_file && (*invoke_type == kVirtual) && (resolved_method->IsFinal() || methods_class->IsFinal()); // For invoke-super, ensure the vtable index will be correct to dispatch in the vtable of // the super class. - bool can_sharpen_super_based_on_type = (*invoke_type == kSuper) && + bool can_sharpen_super_based_on_type = same_dex_file && (*invoke_type == kSuper) && (referrer_class != methods_class) && referrer_class->IsSubClass(methods_class) && resolved_method->GetMethodIndex() < methods_class->GetVTableLength() && (methods_class->GetVTableEntry(resolved_method->GetMethodIndex()) == resolved_method) && @@ -243,10 +256,10 @@ inline int CompilerDriver::IsFastInvoke( if (can_sharpen_virtual_based_on_type || can_sharpen_super_based_on_type) { // Sharpen a virtual call into a direct call. The method_idx is into referrer's // dex cache, check that this resolved method is where we expect it. - CHECK(target_method->dex_file == mUnit->GetDexFile()); - DCHECK(dex_cache.Get() == mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())); - CHECK(referrer_class->GetDexCache()->GetResolvedMethod(target_method->dex_method_index) == - resolved_method) << PrettyMethod(resolved_method); + CHECK_EQ(target_method->dex_file, mUnit->GetDexFile()); + DCHECK_EQ(dex_cache.Get(), mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())); + CHECK_EQ(referrer_class->GetDexCache()->GetResolvedMethod(target_method->dex_method_index), + resolved_method) << PrettyMethod(resolved_method); int stats_flags = kFlagMethodResolved; GetCodeAndMethodForDirectCall(/*out*/invoke_type, kDirect, // Sharp type |