diff options
author | 2017-01-17 09:32:18 -0800 | |
---|---|---|
committer | 2017-02-15 14:46:15 -0800 | |
commit | d776ff08e07494327716f0d2ea1a774b2ebfbca9 (patch) | |
tree | cedf874dd494d881adc572a10a9d14bca852add6 /compiler/optimizing/stack_map_stream.cc | |
parent | 3fb852a88d2a8ffaa87089752f4b1d5f9d6ce3c1 (diff) |
Add invoke infos to stack maps
Invoke info records the invoke type and dex method index for invokes
that may reach artQuickResolutionTrampoline. Having this information
recorded allows the runtime to avoid reading the dex code and pulling
in extra pages.
Code size increase for a large app:
93886360 -> 95811480 (2.05% increase)
1/2 of the code size increase is from making less stack maps deduped.
I suspect there is less deduping because of the invoke info method
index.
Merged disabled until we measure the RAM savings.
Test: test-art-host, N6P boots
Bug: 34109702
Change-Id: I6c5e4a60675a1d7c76dee0561a12909e4ab6d5d9
Diffstat (limited to 'compiler/optimizing/stack_map_stream.cc')
-rw-r--r-- | compiler/optimizing/stack_map_stream.cc | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc index 1bcc8e1ace..eeae96e6c2 100644 --- a/compiler/optimizing/stack_map_stream.cc +++ b/compiler/optimizing/stack_map_stream.cc @@ -41,12 +41,12 @@ void StackMapStream::BeginStackMapEntry(uint32_t dex_pc, current_entry_.inlining_depth = inlining_depth; current_entry_.inline_infos_start_index = inline_infos_.size(); current_entry_.stack_mask_index = 0; + current_entry_.dex_method_index = DexFile::kDexNoIndex; current_entry_.dex_register_entry.num_dex_registers = num_dex_registers; current_entry_.dex_register_entry.locations_start_index = dex_register_locations_.size(); current_entry_.dex_register_entry.live_dex_registers_mask = (num_dex_registers != 0) ? ArenaBitVector::Create(allocator_, num_dex_registers, true, kArenaAllocStackMapStream) : nullptr; - if (sp_mask != nullptr) { stack_mask_max_ = std::max(stack_mask_max_, sp_mask->GetHighestBitSet()); } @@ -99,6 +99,11 @@ void StackMapStream::AddDexRegisterEntry(DexRegisterLocation::Kind kind, int32_t current_dex_register_++; } +void StackMapStream::AddInvoke(InvokeType invoke_type, uint32_t dex_method_index) { + current_entry_.invoke_type = invoke_type; + current_entry_.dex_method_index = dex_method_index; +} + void StackMapStream::BeginInlineInfoEntry(ArtMethod* method, uint32_t dex_pc, uint32_t num_dex_registers, @@ -166,6 +171,7 @@ size_t StackMapStream::PrepareForFillIn() { encoding.inline_info.num_entries, encoding.register_mask.num_entries, encoding.stack_mask.num_entries); + ComputeInvokeInfoEncoding(&encoding); DCHECK_EQ(code_info_encoding_.size(), 0u); encoding.Compress(&code_info_encoding_); encoding.ComputeTableOffsets(); @@ -212,6 +218,24 @@ size_t StackMapStream::ComputeDexRegisterMapsSize() const { return size; } +void StackMapStream::ComputeInvokeInfoEncoding(CodeInfoEncoding* encoding) { + DCHECK(encoding != nullptr); + uint32_t native_pc_max = 0; + uint16_t method_index_max = 0; + size_t invoke_infos_count = 0; + size_t invoke_type_max = 0; + for (const StackMapEntry& entry : stack_maps_) { + if (entry.dex_method_index != DexFile::kDexNoIndex) { + native_pc_max = std::max(native_pc_max, entry.native_pc_code_offset.CompressedValue()); + method_index_max = std::max(method_index_max, static_cast<uint16_t>(entry.dex_method_index)); + invoke_type_max = std::max(invoke_type_max, static_cast<size_t>(entry.invoke_type)); + ++invoke_infos_count; + } + } + encoding->invoke_info.num_entries = invoke_infos_count; + encoding->invoke_info.encoding.SetFromSizes(native_pc_max, invoke_type_max, method_index_max); +} + void StackMapStream::ComputeInlineInfoEncoding(InlineInfoEncoding* encoding, size_t dex_register_maps_bytes) { uint32_t method_index_max = 0; @@ -304,6 +328,7 @@ void StackMapStream::FillIn(MemoryRegion region) { ArenaBitVector empty_bitmask(allocator_, 0, /* expandable */ false, kArenaAllocStackMapStream); uintptr_t next_dex_register_map_offset = 0; uintptr_t next_inline_info_index = 0; + size_t invoke_info_idx = 0; for (size_t i = 0, e = stack_maps_.size(); i < e; ++i) { StackMap stack_map = code_info.GetStackMapAt(i, encoding); StackMapEntry entry = stack_maps_[i]; @@ -318,6 +343,14 @@ void StackMapStream::FillIn(MemoryRegion region) { dex_register_locations_region); stack_map.SetDexRegisterMapOffset(encoding.stack_map.encoding, offset); + if (entry.dex_method_index != DexFile::kDexNoIndex) { + InvokeInfo invoke_info(code_info.GetInvokeInfo(encoding, invoke_info_idx)); + invoke_info.SetNativePcCodeOffset(encoding.invoke_info.encoding, entry.native_pc_code_offset); + invoke_info.SetInvokeType(encoding.invoke_info.encoding, entry.invoke_type); + invoke_info.SetMethodIndex(encoding.invoke_info.encoding, entry.dex_method_index); + ++invoke_info_idx; + } + // Set the inlining info. if (entry.inlining_depth != 0) { InlineInfo inline_info = code_info.GetInlineInfo(next_inline_info_index, encoding); @@ -528,6 +561,7 @@ void StackMapStream::CheckCodeInfo(MemoryRegion region) const { CodeInfo code_info(region); CodeInfoEncoding encoding = code_info.ExtractEncoding(); DCHECK_EQ(code_info.GetNumberOfStackMaps(encoding), stack_maps_.size()); + size_t invoke_info_index = 0; for (size_t s = 0; s < stack_maps_.size(); ++s) { const StackMap stack_map = code_info.GetStackMapAt(s, encoding); const StackMapEncoding& stack_map_encoding = encoding.stack_map.encoding; @@ -552,7 +586,14 @@ void StackMapStream::CheckCodeInfo(MemoryRegion region) const { DCHECK_EQ(stack_mask.LoadBit(b), 0u); } } - + if (entry.dex_method_index != DexFile::kDexNoIndex) { + InvokeInfo invoke_info = code_info.GetInvokeInfo(encoding, invoke_info_index); + DCHECK_EQ(invoke_info.GetNativePcOffset(encoding.invoke_info.encoding, instruction_set_), + entry.native_pc_code_offset.Uint32Value(instruction_set_)); + DCHECK_EQ(invoke_info.GetInvokeType(encoding.invoke_info.encoding), entry.invoke_type); + DCHECK_EQ(invoke_info.GetMethodIndex(encoding.invoke_info.encoding), entry.dex_method_index); + invoke_info_index++; + } CheckDexRegisterMap(code_info, code_info.GetDexRegisterMapOf( stack_map, encoding, entry.dex_register_entry.num_dex_registers), |