From 2535abe7d1fcdd0e6aca782b1f1932a703ed50a4 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Tue, 17 Feb 2015 10:38:49 -0800 Subject: 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 --- compiler/compiled_method.cc | 75 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 15 deletions(-) (limited to 'compiler/compiled_method.cc') diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc index 22be28c4d9..1849e7ef64 100644 --- a/compiler/compiled_method.cc +++ b/compiler/compiled_method.cc @@ -20,16 +20,29 @@ namespace art { CompiledCode::CompiledCode(CompilerDriver* compiler_driver, InstructionSet instruction_set, - const ArrayRef& quick_code) + const ArrayRef& quick_code, bool owns_code_array) : compiler_driver_(compiler_driver), instruction_set_(instruction_set), - quick_code_(nullptr) { + owns_code_array_(owns_code_array), quick_code_(nullptr) { SetCode(&quick_code); } void CompiledCode::SetCode(const ArrayRef* quick_code) { if (quick_code != nullptr) { CHECK(!quick_code->empty()); - quick_code_ = compiler_driver_->DeduplicateCode(*quick_code); + if (owns_code_array_) { + // If we are supposed to own the code, don't deduplicate it. + CHECK(quick_code_ == nullptr); + quick_code_ = new SwapVector(quick_code->begin(), quick_code->end(), + compiler_driver_->GetSwapSpaceAllocator()); + } else { + quick_code_ = compiler_driver_->DeduplicateCode(*quick_code); + } + } +} + +CompiledCode::~CompiledCode() { + if (owns_code_array_) { + delete quick_code_; } } @@ -46,11 +59,11 @@ bool CompiledCode::operator==(const CompiledCode& rhs) const { return (rhs.quick_code_ == nullptr); } -uint32_t CompiledCode::AlignCode(uint32_t offset) const { +size_t CompiledCode::AlignCode(size_t offset) const { return AlignCode(offset, instruction_set_); } -uint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set) { +size_t CompiledCode::AlignCode(size_t offset, InstructionSet instruction_set) { return RoundUp(offset, GetInstructionSetAlignment(instruction_set)); } @@ -120,17 +133,39 @@ CompiledMethod::CompiledMethod(CompilerDriver* driver, const ArrayRef& native_gc_map, const ArrayRef& cfi_info, const ArrayRef& patches) - : CompiledCode(driver, instruction_set, quick_code), frame_size_in_bytes_(frame_size_in_bytes), - core_spill_mask_(core_spill_mask), fp_spill_mask_(fp_spill_mask), - src_mapping_table_(src_mapping_table == nullptr ? - driver->DeduplicateSrcMappingTable(ArrayRef()) : - driver->DeduplicateSrcMappingTable(ArrayRef(src_mapping_table->Arrange()))), - mapping_table_(mapping_table.data() == nullptr ? - nullptr : driver->DeduplicateMappingTable(mapping_table)), - vmap_table_(driver->DeduplicateVMapTable(vmap_table)), - gc_map_(native_gc_map.data() == nullptr ? nullptr : driver->DeduplicateGCMap(native_gc_map)), - cfi_info_(cfi_info.data() == nullptr ? nullptr : driver->DeduplicateCFIInfo(cfi_info)), + : CompiledCode(driver, instruction_set, quick_code, !driver->DedupeEnabled()), + owns_arrays_(!driver->DedupeEnabled()), + frame_size_in_bytes_(frame_size_in_bytes), core_spill_mask_(core_spill_mask), + fp_spill_mask_(fp_spill_mask), patches_(patches.begin(), patches.end(), driver->GetSwapSpaceAllocator()) { + if (owns_arrays_) { + if (src_mapping_table == nullptr) { + src_mapping_table_ = new SwapSrcMap(driver->GetSwapSpaceAllocator()); + } else { + src_mapping_table->Arrange(); + src_mapping_table_ = new SwapSrcMap(src_mapping_table->begin(), src_mapping_table->end(), + driver->GetSwapSpaceAllocator()); + } + mapping_table_ = mapping_table.empty() ? + nullptr : new SwapVector(mapping_table.begin(), mapping_table.end(), + driver->GetSwapSpaceAllocator()); + vmap_table_ = new SwapVector(vmap_table.begin(), vmap_table.end(), + driver->GetSwapSpaceAllocator()); + gc_map_ = native_gc_map.empty() ? nullptr : + new SwapVector(native_gc_map.begin(), native_gc_map.end(), + driver->GetSwapSpaceAllocator()); + cfi_info_ = cfi_info.empty() ? nullptr : + new SwapVector(cfi_info.begin(), cfi_info.end(), driver->GetSwapSpaceAllocator()); + } else { + src_mapping_table_ = src_mapping_table == nullptr ? + driver->DeduplicateSrcMappingTable(ArrayRef()) : + driver->DeduplicateSrcMappingTable(ArrayRef(src_mapping_table->Arrange())); + mapping_table_ = mapping_table.empty() ? + nullptr : driver->DeduplicateMappingTable(mapping_table); + vmap_table_ = driver->DeduplicateVMapTable(vmap_table); + gc_map_ = native_gc_map.empty() ? nullptr : driver->DeduplicateGCMap(native_gc_map); + cfi_info_ = cfi_info.empty() ? nullptr : driver->DeduplicateCFIInfo(cfi_info); + } } CompiledMethod* CompiledMethod::SwapAllocCompiledMethod( @@ -194,4 +229,14 @@ void CompiledMethod::ReleaseSwapAllocatedCompiledMethod(CompilerDriver* driver, alloc.deallocate(m, 1); } +CompiledMethod::~CompiledMethod() { + if (owns_arrays_) { + delete src_mapping_table_; + delete mapping_table_; + delete vmap_table_; + delete gc_map_; + delete cfi_info_; + } +} + } // namespace art -- cgit v1.2.3