diff options
30 files changed, 69 insertions, 430 deletions
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index 4824763288..87197becf9 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -65,23 +65,17 @@ void CommonCompilerTest::MakeExecutable(ArtMethod* method) { ArrayRef<const uint8_t> vmap_table = compiled_method->GetVmapTable(); const uint32_t vmap_table_offset = vmap_table.empty() ? 0u : sizeof(OatQuickMethodHeader) + vmap_table.size(); - // The method info is directly before the vmap table. - ArrayRef<const uint8_t> method_info = compiled_method->GetMethodInfo(); - const uint32_t method_info_offset = method_info.empty() ? 0u - : vmap_table_offset + method_info.size(); - - OatQuickMethodHeader method_header(vmap_table_offset, method_info_offset, code_size); + OatQuickMethodHeader method_header(vmap_table_offset, code_size); header_code_and_maps_chunks_.push_back(std::vector<uint8_t>()); std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back(); const size_t max_padding = GetInstructionSetAlignment(compiled_method->GetInstructionSet()); - const size_t size = method_info.size() + vmap_table.size() + sizeof(method_header) + code_size; + const size_t size = vmap_table.size() + sizeof(method_header) + code_size; chunk->reserve(size + max_padding); chunk->resize(sizeof(method_header)); static_assert(std::is_trivially_copyable<OatQuickMethodHeader>::value, "Cannot use memcpy"); memcpy(&(*chunk)[0], &method_header, sizeof(method_header)); chunk->insert(chunk->begin(), vmap_table.begin(), vmap_table.end()); - chunk->insert(chunk->begin(), method_info.begin(), method_info.end()); chunk->insert(chunk->end(), code.begin(), code.end()); CHECK_EQ(chunk->size(), size); const void* unaligned_code_ptr = chunk->data() + (size - code_size); diff --git a/compiler/compiled_method-inl.h b/compiler/compiled_method-inl.h index c43274782e..e60b30fed2 100644 --- a/compiler/compiled_method-inl.h +++ b/compiler/compiled_method-inl.h @@ -38,10 +38,6 @@ inline ArrayRef<const T> CompiledCode::GetArray(const LengthPrefixedArray<T>* ar return ArrayRef<const T>(&array->At(0), array->size()); } -inline ArrayRef<const uint8_t> CompiledMethod::GetMethodInfo() const { - return GetArray(method_info_); -} - inline ArrayRef<const uint8_t> CompiledMethod::GetVmapTable() const { return GetArray(vmap_table_); } diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc index 5b93316b87..29f004cf87 100644 --- a/compiler/compiled_method.cc +++ b/compiler/compiled_method.cc @@ -102,12 +102,10 @@ const void* CompiledCode::CodePointer(const void* code_pointer, InstructionSet i CompiledMethod::CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, const ArrayRef<const uint8_t>& quick_code, - const ArrayRef<const uint8_t>& method_info, const ArrayRef<const uint8_t>& vmap_table, const ArrayRef<const uint8_t>& cfi_info, const ArrayRef<const linker::LinkerPatch>& patches) : CompiledCode(driver, instruction_set, quick_code), - method_info_(driver->GetCompiledMethodStorage()->DeduplicateMethodInfo(method_info)), vmap_table_(driver->GetCompiledMethodStorage()->DeduplicateVMapTable(vmap_table)), cfi_info_(driver->GetCompiledMethodStorage()->DeduplicateCFIInfo(cfi_info)), patches_(driver->GetCompiledMethodStorage()->DeduplicateLinkerPatches(patches)) { @@ -117,7 +115,6 @@ CompiledMethod* CompiledMethod::SwapAllocCompiledMethod( CompilerDriver* driver, InstructionSet instruction_set, const ArrayRef<const uint8_t>& quick_code, - const ArrayRef<const uint8_t>& method_info, const ArrayRef<const uint8_t>& vmap_table, const ArrayRef<const uint8_t>& cfi_info, const ArrayRef<const linker::LinkerPatch>& patches) { @@ -127,7 +124,6 @@ CompiledMethod* CompiledMethod::SwapAllocCompiledMethod( driver, instruction_set, quick_code, - method_info, vmap_table, cfi_info, patches); return ret; @@ -144,7 +140,6 @@ CompiledMethod::~CompiledMethod() { storage->ReleaseLinkerPatches(patches_); storage->ReleaseCFIInfo(cfi_info_); storage->ReleaseVMapTable(vmap_table_); - storage->ReleaseMethodInfo(method_info_); } } // namespace art diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h index aa6fd3e655..f88028034d 100644 --- a/compiler/compiled_method.h +++ b/compiler/compiled_method.h @@ -112,7 +112,6 @@ class CompiledMethod FINAL : public CompiledCode { CompiledMethod(CompilerDriver* driver, InstructionSet instruction_set, const ArrayRef<const uint8_t>& quick_code, - const ArrayRef<const uint8_t>& method_info, const ArrayRef<const uint8_t>& vmap_table, const ArrayRef<const uint8_t>& cfi_info, const ArrayRef<const linker::LinkerPatch>& patches); @@ -123,7 +122,6 @@ class CompiledMethod FINAL : public CompiledCode { CompilerDriver* driver, InstructionSet instruction_set, const ArrayRef<const uint8_t>& quick_code, - const ArrayRef<const uint8_t>& method_info, const ArrayRef<const uint8_t>& vmap_table, const ArrayRef<const uint8_t>& cfi_info, const ArrayRef<const linker::LinkerPatch>& patches); @@ -142,8 +140,6 @@ class CompiledMethod FINAL : public CompiledCode { SetPackedField<IsIntrinsicField>(/* value */ true); } - ArrayRef<const uint8_t> GetMethodInfo() const; - ArrayRef<const uint8_t> GetVmapTable() const; ArrayRef<const uint8_t> GetCFIInfo() const; @@ -159,8 +155,6 @@ class CompiledMethod FINAL : public CompiledCode { using IsIntrinsicField = BitField<bool, kIsIntrinsicLsb, kIsIntrinsicSize>; - // For quick code, method specific information that is not very dedupe friendly (method indices). - const LengthPrefixedArray<uint8_t>* const method_info_; // For quick code, holds code infos which contain stack maps, inline information, and etc. const LengthPrefixedArray<uint8_t>* const vmap_table_; // For quick code, a FDE entry for the debug_frame section. diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index 0800ab3d41..ad9a30f8d4 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -619,7 +619,6 @@ CompiledMethod* DexToDexCompiler::CompileMethod( driver_, instruction_set, ArrayRef<const uint8_t>(), // no code - ArrayRef<const uint8_t>(), // method_info ArrayRef<const uint8_t>(quicken_data), // vmap_table ArrayRef<const uint8_t>(), // cfi data ArrayRef<const linker::LinkerPatch>()); diff --git a/compiler/driver/compiled_method_storage.cc b/compiler/driver/compiled_method_storage.cc index d56b135aca..31062fb390 100644 --- a/compiler/driver/compiled_method_storage.cc +++ b/compiler/driver/compiled_method_storage.cc @@ -148,8 +148,6 @@ CompiledMethodStorage::CompiledMethodStorage(int swap_fd) : swap_space_(swap_fd == -1 ? nullptr : new SwapSpace(swap_fd, 10 * MB)), dedupe_enabled_(true), dedupe_code_("dedupe code", LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())), - dedupe_method_info_("dedupe method info", - LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())), dedupe_vmap_table_("dedupe vmap table", LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())), dedupe_cfi_info_("dedupe cfi info", LengthPrefixedArrayAlloc<uint8_t>(swap_space_.get())), @@ -185,15 +183,6 @@ void CompiledMethodStorage::ReleaseCode(const LengthPrefixedArray<uint8_t>* code ReleaseArrayIfNotDeduplicated(code); } -const LengthPrefixedArray<uint8_t>* CompiledMethodStorage::DeduplicateMethodInfo( - const ArrayRef<const uint8_t>& src_map) { - return AllocateOrDeduplicateArray(src_map, &dedupe_method_info_); -} - -void CompiledMethodStorage::ReleaseMethodInfo(const LengthPrefixedArray<uint8_t>* method_info) { - ReleaseArrayIfNotDeduplicated(method_info); -} - const LengthPrefixedArray<uint8_t>* CompiledMethodStorage::DeduplicateVMapTable( const ArrayRef<const uint8_t>& table) { return AllocateOrDeduplicateArray(table, &dedupe_vmap_table_); diff --git a/compiler/driver/compiled_method_storage.h b/compiler/driver/compiled_method_storage.h index 1634facb7c..a5a7691e12 100644 --- a/compiler/driver/compiled_method_storage.h +++ b/compiler/driver/compiled_method_storage.h @@ -54,10 +54,6 @@ class CompiledMethodStorage { const LengthPrefixedArray<uint8_t>* DeduplicateCode(const ArrayRef<const uint8_t>& code); void ReleaseCode(const LengthPrefixedArray<uint8_t>* code); - const LengthPrefixedArray<uint8_t>* DeduplicateMethodInfo( - const ArrayRef<const uint8_t>& method_info); - void ReleaseMethodInfo(const LengthPrefixedArray<uint8_t>* method_info); - const LengthPrefixedArray<uint8_t>* DeduplicateVMapTable(const ArrayRef<const uint8_t>& table); void ReleaseVMapTable(const LengthPrefixedArray<uint8_t>* table); @@ -120,7 +116,6 @@ class CompiledMethodStorage { bool dedupe_enabled_; ArrayDedupeSet<uint8_t> dedupe_code_; - ArrayDedupeSet<uint8_t> dedupe_method_info_; ArrayDedupeSet<uint8_t> dedupe_vmap_table_; ArrayDedupeSet<uint8_t> dedupe_cfi_info_; ArrayDedupeSet<linker::LinkerPatch> dedupe_linker_patches_; diff --git a/compiler/driver/compiled_method_storage_test.cc b/compiler/driver/compiled_method_storage_test.cc index 14d1e191ca..5e2f444a24 100644 --- a/compiler/driver/compiled_method_storage_test.cc +++ b/compiler/driver/compiled_method_storage_test.cc @@ -45,12 +45,6 @@ TEST(CompiledMethodStorage, Deduplicate) { ArrayRef<const uint8_t>(raw_code1), ArrayRef<const uint8_t>(raw_code2), }; - const uint8_t raw_method_info_map1[] = { 1u, 2u, 3u, 4u, 5u, 6u }; - const uint8_t raw_method_info_map2[] = { 8u, 7u, 6u, 5u, 4u, 3u, 2u, 1u }; - ArrayRef<const uint8_t> method_info[] = { - ArrayRef<const uint8_t>(raw_method_info_map1), - ArrayRef<const uint8_t>(raw_method_info_map2), - }; const uint8_t raw_vmap_table1[] = { 2, 4, 6 }; const uint8_t raw_vmap_table2[] = { 7, 5, 3, 1 }; ArrayRef<const uint8_t> vmap_table[] = { @@ -77,38 +71,32 @@ TEST(CompiledMethodStorage, Deduplicate) { }; std::vector<CompiledMethod*> compiled_methods; - compiled_methods.reserve(1u << 7); + compiled_methods.reserve(1u << 4); for (auto&& c : code) { - for (auto&& s : method_info) { - for (auto&& v : vmap_table) { - for (auto&& f : cfi_info) { - for (auto&& p : patches) { - compiled_methods.push_back(CompiledMethod::SwapAllocCompiledMethod( - &driver, InstructionSet::kNone, c, s, v, f, p)); - } + for (auto&& v : vmap_table) { + for (auto&& f : cfi_info) { + for (auto&& p : patches) { + compiled_methods.push_back(CompiledMethod::SwapAllocCompiledMethod( + &driver, InstructionSet::kNone, c, v, f, p)); } } } } - constexpr size_t code_bit = 1u << 4; - constexpr size_t src_map_bit = 1u << 3; + constexpr size_t code_bit = 1u << 3; constexpr size_t vmap_table_bit = 1u << 2; constexpr size_t cfi_info_bit = 1u << 1; constexpr size_t patches_bit = 1u << 0; - CHECK_EQ(compiled_methods.size(), 1u << 5); + CHECK_EQ(compiled_methods.size(), 1u << 4); for (size_t i = 0; i != compiled_methods.size(); ++i) { for (size_t j = 0; j != compiled_methods.size(); ++j) { CompiledMethod* lhs = compiled_methods[i]; CompiledMethod* rhs = compiled_methods[j]; bool same_code = ((i ^ j) & code_bit) == 0u; - bool same_src_map = ((i ^ j) & src_map_bit) == 0u; bool same_vmap_table = ((i ^ j) & vmap_table_bit) == 0u; bool same_cfi_info = ((i ^ j) & cfi_info_bit) == 0u; bool same_patches = ((i ^ j) & patches_bit) == 0u; ASSERT_EQ(same_code, lhs->GetQuickCode().data() == rhs->GetQuickCode().data()) << i << " " << j; - ASSERT_EQ(same_src_map, lhs->GetMethodInfo().data() == rhs->GetMethodInfo().data()) - << i << " " << j; ASSERT_EQ(same_vmap_table, lhs->GetVmapTable().data() == rhs->GetVmapTable().data()) << i << " " << j; ASSERT_EQ(same_cfi_info, lhs->GetCFIInfo().data() == rhs->GetCFIInfo().data()) diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc index 6d952035c9..b0e03374a0 100644 --- a/compiler/exception_test.cc +++ b/compiler/exception_test.cc @@ -92,7 +92,7 @@ class ExceptionTest : public CommonRuntimeTest { MemoryRegion stack_maps_region(&fake_header_code_and_maps_[0], stack_maps_size); stack_maps.FillInCodeInfo(stack_maps_region); - OatQuickMethodHeader method_header(code_ptr - stack_maps_region.begin(), 0u, code_size); + OatQuickMethodHeader method_header(code_ptr - stack_maps_region.begin(), code_size); static_assert(std::is_trivially_copyable<OatQuickMethodHeader>::value, "Cannot use memcpy"); memcpy(code_ptr - header_size, &method_header, header_size); memcpy(code_ptr, fake_code_.data(), fake_code_.size()); diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 0ebf4bec0a..b0a05da0b1 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -963,13 +963,10 @@ CodeGenerator::CodeGenerator(HGraph* graph, CodeGenerator::~CodeGenerator() {} -void CodeGenerator::ComputeStackMapAndMethodInfoSize(size_t* stack_map_size, - size_t* method_info_size) { +void CodeGenerator::ComputeStackMapSize(size_t* stack_map_size) { DCHECK(stack_map_size != nullptr); - DCHECK(method_info_size != nullptr); StackMapStream* stack_map_stream = GetStackMapStream(); *stack_map_size = stack_map_stream->PrepareForFillIn(); - *method_info_size = stack_map_stream->ComputeMethodInfoSize(); } size_t CodeGenerator::GetNumberOfJitRoots() const { @@ -1039,11 +1036,9 @@ static void CheckLoopEntriesCanBeUsedForOsr(const HGraph& graph, } void CodeGenerator::BuildStackMaps(MemoryRegion stack_map_region, - MemoryRegion method_info_region, const DexFile::CodeItem* code_item_for_osr_check) { StackMapStream* stack_map_stream = GetStackMapStream(); stack_map_stream->FillInCodeInfo(stack_map_region); - stack_map_stream->FillInMethodInfo(method_info_region); if (kIsDebugBuild && code_item_for_osr_check != nullptr) { CheckLoopEntriesCanBeUsedForOsr(*graph_, CodeInfo(stack_map_region), *code_item_for_osr_check); } diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 59f858ea52..3d58d29648 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -351,9 +351,8 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { void AddSlowPath(SlowPathCode* slow_path); void BuildStackMaps(MemoryRegion stack_map_region, - MemoryRegion method_info_region, const DexFile::CodeItem* code_item_for_osr_check); - void ComputeStackMapAndMethodInfoSize(size_t* stack_map_size, size_t* method_info_size); + void ComputeStackMapSize(size_t* stack_map_size); size_t GetNumberOfJitRoots() const; // Fills the `literals` array with literals collected during code generation. diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 939802626c..d96746fdd7 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -715,18 +715,16 @@ CompiledMethod* OptimizingCompiler::Emit(ArenaAllocator* allocator, ArenaVector<uint8_t> method_info(allocator->Adapter(kArenaAllocStackMaps)); size_t stack_map_size = 0; size_t method_info_size = 0; - codegen->ComputeStackMapAndMethodInfoSize(&stack_map_size, &method_info_size); + codegen->ComputeStackMapSize(&stack_map_size); stack_map.resize(stack_map_size); method_info.resize(method_info_size); codegen->BuildStackMaps(MemoryRegion(stack_map.data(), stack_map.size()), - MemoryRegion(method_info.data(), method_info.size()), code_item_for_osr_check); CompiledMethod* compiled_method = CompiledMethod::SwapAllocCompiledMethod( GetCompilerDriver(), codegen->GetInstructionSet(), code_allocator->GetMemory(), - ArrayRef<const uint8_t>(method_info), ArrayRef<const uint8_t>(stack_map), ArrayRef<const uint8_t>(*codegen->GetAssembler()->cfi().data()), ArrayRef<const linker::LinkerPatch>(linker_patches)); @@ -1101,8 +1099,7 @@ CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item, static void CreateJniStackMap(ArenaStack* arena_stack, const JniCompiledMethod& jni_compiled_method, - /* out */ ArenaVector<uint8_t>* stack_map, - /* out */ ArenaVector<uint8_t>* method_info) { + /* out */ ArenaVector<uint8_t>* stack_map) { ScopedArenaAllocator allocator(arena_stack); StackMapStream stack_map_stream(&allocator, jni_compiled_method.GetInstructionSet()); stack_map_stream.BeginMethod( @@ -1112,9 +1109,7 @@ static void CreateJniStackMap(ArenaStack* arena_stack, /* num_dex_registers */ 0); stack_map_stream.EndMethod(); stack_map->resize(stack_map_stream.PrepareForFillIn()); - method_info->resize(stack_map_stream.ComputeMethodInfoSize()); stack_map_stream.FillInCodeInfo(MemoryRegion(stack_map->data(), stack_map->size())); - stack_map_stream.FillInMethodInfo(MemoryRegion(method_info->data(), method_info->size())); } CompiledMethod* OptimizingCompiler::JniCompile(uint32_t access_flags, @@ -1169,13 +1164,11 @@ CompiledMethod* OptimizingCompiler::JniCompile(uint32_t access_flags, MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kCompiledNativeStub); ArenaVector<uint8_t> stack_map(allocator.Adapter(kArenaAllocStackMaps)); - ArenaVector<uint8_t> method_info(allocator.Adapter(kArenaAllocStackMaps)); - CreateJniStackMap(&arena_stack, jni_compiled_method, &stack_map, &method_info); + CreateJniStackMap(&arena_stack, jni_compiled_method, &stack_map); return CompiledMethod::SwapAllocCompiledMethod( GetCompilerDriver(), jni_compiled_method.GetInstructionSet(), jni_compiled_method.GetCode(), - ArrayRef<const uint8_t>(method_info), ArrayRef<const uint8_t>(stack_map), jni_compiled_method.GetCfi(), /* patches */ ArrayRef<const linker::LinkerPatch>()); @@ -1237,34 +1230,28 @@ bool OptimizingCompiler::JitCompile(Thread* self, ArenaSet<ArtMethod*, std::less<ArtMethod*>> cha_single_implementation_list( allocator.Adapter(kArenaAllocCHA)); ArenaVector<uint8_t> stack_map(allocator.Adapter(kArenaAllocStackMaps)); - ArenaVector<uint8_t> method_info(allocator.Adapter(kArenaAllocStackMaps)); ArenaStack arena_stack(runtime->GetJitArenaPool()); // StackMapStream is large and it does not fit into this frame, so we need helper method. // TODO: Try to avoid the extra memory copy that results from this. - CreateJniStackMap(&arena_stack, jni_compiled_method, &stack_map, &method_info); + CreateJniStackMap(&arena_stack, jni_compiled_method, &stack_map); uint8_t* stack_map_data = nullptr; - uint8_t* method_info_data = nullptr; uint8_t* roots_data = nullptr; uint32_t data_size = code_cache->ReserveData(self, stack_map.size(), - method_info.size(), /* number_of_roots */ 0, method, &stack_map_data, - &method_info_data, &roots_data); if (stack_map_data == nullptr || roots_data == nullptr) { MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kJitOutOfMemoryForCommit); return false; } memcpy(stack_map_data, stack_map.data(), stack_map.size()); - memcpy(method_info_data, method_info.data(), method_info.size()); const void* code = code_cache->CommitCode( self, method, stack_map_data, - method_info_data, roots_data, jni_compiled_method.GetCode().data(), jni_compiled_method.GetCode().size(), @@ -1340,8 +1327,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, } size_t stack_map_size = 0; - size_t method_info_size = 0; - codegen->ComputeStackMapAndMethodInfoSize(&stack_map_size, &method_info_size); + codegen->ComputeStackMapSize(&stack_map_size); size_t number_of_roots = codegen->GetNumberOfJitRoots(); // We allocate an object array to ensure the JIT roots that we will collect in EmitJitRoots // will be visible by the GC between EmitLiterals and CommitCode. Once CommitCode is @@ -1357,30 +1343,24 @@ bool OptimizingCompiler::JitCompile(Thread* self, return false; } uint8_t* stack_map_data = nullptr; - uint8_t* method_info_data = nullptr; uint8_t* roots_data = nullptr; uint32_t data_size = code_cache->ReserveData(self, stack_map_size, - method_info_size, number_of_roots, method, &stack_map_data, - &method_info_data, &roots_data); if (stack_map_data == nullptr || roots_data == nullptr) { MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kJitOutOfMemoryForCommit); return false; } - codegen->BuildStackMaps(MemoryRegion(stack_map_data, stack_map_size), - MemoryRegion(method_info_data, method_info_size), - code_item); + codegen->BuildStackMaps(MemoryRegion(stack_map_data, stack_map_size), code_item); codegen->EmitJitRoots(code_allocator.GetData(), roots, roots_data); const void* code = code_cache->CommitCode( self, method, stack_map_data, - method_info_data, roots_data, code_allocator.GetMemory().data(), code_allocator.GetMemory().size(), diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc index e1b657554f..429054cec7 100644 --- a/compiler/optimizing/stack_map_stream.cc +++ b/compiler/optimizing/stack_map_stream.cc @@ -196,7 +196,7 @@ void StackMapStream::BeginInlineInfoEntry(ArtMethod* method, if (encode_art_method) { CHECK_EQ(inline_info.GetArtMethod(), method); } else { - CHECK_EQ(method_infos_[inline_info.GetMethodInfoIndex()][0], method->GetDexMethodIndex()); + CHECK_EQ(code_info.GetMethodIndexOf(inline_info), method->GetDexMethodIndex()); } }); } @@ -274,24 +274,6 @@ void StackMapStream::CreateDexRegisterMap() { } } -void StackMapStream::FillInMethodInfo(MemoryRegion region) { - { - MethodInfo info(region.begin(), method_infos_.size()); - for (size_t i = 0; i < method_infos_.size(); ++i) { - info.SetMethodIndex(i, method_infos_[i][0]); - } - } - if (kVerifyStackMaps) { - // Check the data matches. - MethodInfo info(region.begin()); - const size_t count = info.NumMethodIndices(); - DCHECK_EQ(count, method_infos_.size()); - for (size_t i = 0; i < count; ++i) { - DCHECK_EQ(info.GetMethodIndex(i), method_infos_[i][0]); - } - } -} - template<typename Writer, typename Builder> ALWAYS_INLINE static void EncodeTable(Writer& out, const Builder& bit_table) { out.WriteBit(false); // Is not deduped. @@ -317,6 +299,7 @@ size_t StackMapStream::PrepareForFillIn() { BitMemoryWriter<ScopedArenaVector<uint8_t>> out(&out_, out_.size() * kBitsPerByte); EncodeTable(out, stack_maps_); EncodeTable(out, inline_infos_); + EncodeTable(out, method_infos_); EncodeTable(out, register_masks_); EncodeTable(out, stack_masks_); EncodeTable(out, dex_register_masks_); @@ -347,9 +330,4 @@ void StackMapStream::FillInCodeInfo(MemoryRegion region) { } } -size_t StackMapStream::ComputeMethodInfoSize() const { - DCHECK_NE(0u, out_.size()) << "PrepareForFillIn not called before " << __FUNCTION__; - return MethodInfo::ComputeSize(method_infos_.size()); -} - } // namespace art diff --git a/compiler/optimizing/stack_map_stream.h b/compiler/optimizing/stack_map_stream.h index 203c2cdf84..de79f4921e 100644 --- a/compiler/optimizing/stack_map_stream.h +++ b/compiler/optimizing/stack_map_stream.h @@ -25,7 +25,6 @@ #include "base/scoped_arena_containers.h" #include "base/value_object.h" #include "dex_register_location.h" -#include "method_info.h" #include "nodes.h" #include "stack_map.h" @@ -40,14 +39,14 @@ class StackMapStream : public ValueObject { explicit StackMapStream(ScopedArenaAllocator* allocator, InstructionSet instruction_set) : instruction_set_(instruction_set), stack_maps_(allocator), + inline_infos_(allocator), + method_infos_(allocator), register_masks_(allocator), stack_masks_(allocator), - inline_infos_(allocator), dex_register_masks_(allocator), dex_register_maps_(allocator), dex_register_catalog_(allocator), out_(allocator->Adapter(kArenaAllocStackMapStream)), - method_infos_(allocator), lazy_stack_masks_(allocator->Adapter(kArenaAllocStackMapStream)), current_stack_map_(), current_inline_infos_(allocator->Adapter(kArenaAllocStackMapStream)), @@ -92,9 +91,6 @@ class StackMapStream : public ValueObject { // Returns the size (in bytes) needed to store this stream. size_t PrepareForFillIn(); void FillInCodeInfo(MemoryRegion region); - void FillInMethodInfo(MemoryRegion region); - - size_t ComputeMethodInfoSize() const; private: static constexpr uint32_t kNoValue = -1; @@ -107,16 +103,15 @@ class StackMapStream : public ValueObject { uint32_t fp_spill_mask_ = 0; uint32_t num_dex_registers_ = 0; BitTableBuilder<StackMap> stack_maps_; + BitTableBuilder<InlineInfo> inline_infos_; + BitTableBuilder<MethodInfo> method_infos_; BitTableBuilder<RegisterMask> register_masks_; BitmapTableBuilder stack_masks_; - BitTableBuilder<InlineInfo> inline_infos_; BitmapTableBuilder dex_register_masks_; BitTableBuilder<MaskInfo> dex_register_maps_; BitTableBuilder<DexRegisterInfo> dex_register_catalog_; ScopedArenaVector<uint8_t> out_; - BitTableBuilderBase<1> method_infos_; - ScopedArenaVector<BitVector*> lazy_stack_masks_; // Variables which track the current state between Begin/End calls; diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index d34f7b5337..a1a547c8e5 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -1316,7 +1316,6 @@ class OatWriter::LayoutReserveOffsetCodeMethodVisitor : public OrderedMethodVisi DCHECK_LT(method_offsets_index_, oat_class->method_headers_.size()); OatQuickMethodHeader* method_header = &oat_class->method_headers_[method_offsets_index_]; uint32_t vmap_table_offset = method_header->GetVmapTableOffset(); - uint32_t method_info_offset = method_header->GetMethodInfoOffset(); // The code offset was 0 when the mapping/vmap table offset was set, so it's set // to 0-offset and we need to adjust it by code_offset. uint32_t code_offset = quick_code_offset - thumb_offset; @@ -1327,11 +1326,7 @@ class OatWriter::LayoutReserveOffsetCodeMethodVisitor : public OrderedMethodVisi vmap_table_offset += code_offset; DCHECK_LT(vmap_table_offset, code_offset); } - if (method_info_offset != 0u) { - method_info_offset += code_offset; - DCHECK_LT(method_info_offset, code_offset); - } - *method_header = OatQuickMethodHeader(vmap_table_offset, method_info_offset, code_size); + *method_header = OatQuickMethodHeader(vmap_table_offset, code_size); if (!deduped) { // Update offsets. (Checksum is updated when writing.) @@ -1403,9 +1398,6 @@ class OatWriter::LayoutReserveOffsetCodeMethodVisitor : public OrderedMethodVisi if (UNLIKELY(lhs->GetVmapTable().data() != rhs->GetVmapTable().data())) { return lhs->GetVmapTable().data() < rhs->GetVmapTable().data(); } - if (UNLIKELY(lhs->GetMethodInfo().data() != rhs->GetMethodInfo().data())) { - return lhs->GetMethodInfo().data() < rhs->GetMethodInfo().data(); - } if (UNLIKELY(lhs->GetPatches().data() != rhs->GetPatches().data())) { return lhs->GetPatches().data() < rhs->GetPatches().data(); } @@ -1467,13 +1459,12 @@ class OatWriter::InitMapMethodVisitor : public OatDexMethodVisitor { size_t deduped_offset = CodeInfo::Dedupe(data, map.data(), &dedupe_bit_table_); if (kDebugVerifyDedupedCodeInfo) { InstructionSet isa = writer_->GetCompilerOptions().GetInstructionSet(); - MethodInfo method_info(compiled_method->GetMethodInfo().data()); std::stringstream old_code_info; VariableIndentationOutputStream old_vios(&old_code_info); std::stringstream new_code_info; VariableIndentationOutputStream new_vios(&new_code_info); - CodeInfo(map.data()).Dump(&old_vios, 0, true, isa, method_info); - CodeInfo(data->data() + deduped_offset).Dump(&new_vios, 0, true, isa, method_info); + CodeInfo(map.data()).Dump(&old_vios, 0, true, isa); + CodeInfo(data->data() + deduped_offset).Dump(&new_vios, 0, true, isa); DCHECK_EQ(old_code_info.str(), new_code_info.str()); } return offset_ + deduped_offset; @@ -1498,44 +1489,6 @@ class OatWriter::InitMapMethodVisitor : public OatDexMethodVisitor { std::map<BitMemoryRegion, uint32_t, BitMemoryRegion::Less> dedupe_bit_table_; }; -class OatWriter::InitMethodInfoVisitor : public OatDexMethodVisitor { - public: - InitMethodInfoVisitor(OatWriter* writer, size_t offset) : OatDexMethodVisitor(writer, offset) {} - - bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it ATTRIBUTE_UNUSED) - OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) { - OatClass* oat_class = &writer_->oat_classes_[oat_class_index_]; - CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); - - if (HasCompiledCode(compiled_method)) { - DCHECK_LT(method_offsets_index_, oat_class->method_offsets_.size()); - DCHECK_EQ(oat_class->method_headers_[method_offsets_index_].GetMethodInfoOffset(), 0u); - ArrayRef<const uint8_t> map = compiled_method->GetMethodInfo(); - const uint32_t map_size = map.size() * sizeof(map[0]); - if (map_size != 0u) { - size_t offset = dedupe_map_.GetOrCreate( - map.data(), - [this, map_size]() { - uint32_t new_offset = offset_; - offset_ += map_size; - return new_offset; - }); - // Code offset is not initialized yet, so set the map offset to 0u-offset. - DCHECK_EQ(oat_class->method_offsets_[method_offsets_index_].code_offset_, 0u); - oat_class->method_headers_[method_offsets_index_].SetMethodInfoOffset(0u - offset); - } - ++method_offsets_index_; - } - - return true; - } - - private: - // Deduplication is already done on a pointer basis by the compiler driver, - // so we can simply compare the pointers to find out if things are duplicated. - SafeMap<const uint8_t*, uint32_t> dedupe_map_; -}; - class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor { public: InitImageMethodVisitor(OatWriter* writer, @@ -2045,63 +1998,6 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor { } }; -class OatWriter::WriteMethodInfoVisitor : public OatDexMethodVisitor { - public: - WriteMethodInfoVisitor(OatWriter* writer, - OutputStream* out, - const size_t file_offset, - size_t relative_offset) - : OatDexMethodVisitor(writer, relative_offset), - out_(out), - file_offset_(file_offset) {} - - bool VisitMethod(size_t class_def_method_index, const ClassDataItemIterator& it) OVERRIDE { - OatClass* oat_class = &writer_->oat_classes_[oat_class_index_]; - const CompiledMethod* compiled_method = oat_class->GetCompiledMethod(class_def_method_index); - - if (HasCompiledCode(compiled_method)) { - size_t file_offset = file_offset_; - OutputStream* out = out_; - uint32_t map_offset = oat_class->method_headers_[method_offsets_index_].GetMethodInfoOffset(); - uint32_t code_offset = oat_class->method_offsets_[method_offsets_index_].code_offset_; - ++method_offsets_index_; - DCHECK((compiled_method->GetMethodInfo().size() == 0u && map_offset == 0u) || - (compiled_method->GetMethodInfo().size() != 0u && map_offset != 0u)) - << compiled_method->GetMethodInfo().size() << " " << map_offset << " " - << dex_file_->PrettyMethod(it.GetMemberIndex()); - if (map_offset != 0u) { - // Transform map_offset to actual oat data offset. - map_offset = (code_offset - compiled_method->CodeDelta()) - map_offset; - DCHECK_NE(map_offset, 0u); - DCHECK_LE(map_offset, offset_) << dex_file_->PrettyMethod(it.GetMemberIndex()); - - ArrayRef<const uint8_t> map = compiled_method->GetMethodInfo(); - size_t map_size = map.size() * sizeof(map[0]); - if (map_offset == offset_) { - // Write deduplicated map (code info for Optimizing or transformation info for dex2dex). - if (UNLIKELY(!out->WriteFully(map.data(), map_size))) { - ReportWriteFailure(it); - return false; - } - offset_ += map_size; - } - } - DCHECK_OFFSET_(); - } - - return true; - } - - private: - OutputStream* const out_; - size_t const file_offset_; - - void ReportWriteFailure(const ClassDataItemIterator& it) { - PLOG(ERROR) << "Failed to write map for " - << dex_file_->PrettyMethod(it.GetMemberIndex()) << " to " << out_->GetLocation(); - } -}; - // Visit all methods from all classes in all dex files with the specified visitor. bool OatWriter::VisitDexMethods(DexMethodVisitor* visitor) { for (const DexFile* dex_file : *dex_files_) { @@ -2193,12 +2089,6 @@ size_t OatWriter::InitOatMaps(size_t offset) { DCHECK(success); offset += code_info_data_.size(); } - { - InitMethodInfoVisitor visitor(this, offset); - bool success = VisitDexMethods(&visitor); - DCHECK(success); - offset = visitor.GetOffset(); - } return offset; } @@ -3050,15 +2940,7 @@ size_t OatWriter::WriteMaps(OutputStream* out, size_t file_offset, size_t relati } relative_offset += code_info_data_.size(); size_vmap_table_ = code_info_data_.size(); - } - { - size_t method_infos_offset = relative_offset; - WriteMethodInfoVisitor visitor(this, out, file_offset, relative_offset); - if (UNLIKELY(!VisitDexMethods(&visitor))) { - return 0; - } - relative_offset = visitor.GetOffset(); - size_method_info_ = relative_offset - method_infos_offset; + DCHECK_OFFSET(); } return relative_offset; diff --git a/dex2oat/linker/oat_writer.h b/dex2oat/linker/oat_writer.h index d14ddaba86..9470f8c874 100644 --- a/dex2oat/linker/oat_writer.h +++ b/dex2oat/linker/oat_writer.h @@ -96,11 +96,6 @@ enum class CopyOption { // ... // VmapTable // -// MethodInfo one variable sized blob with MethodInfo. -// MethodInfo MethodInfos are deduplicated. -// ... -// MethodInfo -// // OatDexFile[0] one variable sized OatDexFile with offsets to Dex and OatClasses // OatDexFile[1] // ... @@ -284,11 +279,9 @@ class OatWriter { class OrderedMethodVisitor; class InitCodeMethodVisitor; class InitMapMethodVisitor; - class InitMethodInfoVisitor; class InitImageMethodVisitor; class WriteCodeMethodVisitor; class WriteMapMethodVisitor; - class WriteMethodInfoVisitor; class WriteQuickeningInfoMethodVisitor; class WriteQuickeningInfoOffsetsMethodVisitor; diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc index 37d0a3f5ce..bb27e8c80b 100644 --- a/dex2oat/linker/oat_writer_test.cc +++ b/dex2oat/linker/oat_writer_test.cc @@ -472,7 +472,7 @@ TEST_F(OatTest, OatHeaderSizeCheck) { // it is time to update OatHeader::kOatVersion EXPECT_EQ(76U, sizeof(OatHeader)); EXPECT_EQ(4U, sizeof(OatMethodOffsets)); - EXPECT_EQ(12U, sizeof(OatQuickMethodHeader)); + EXPECT_EQ(8U, sizeof(OatQuickMethodHeader)); EXPECT_EQ(166 * static_cast<size_t>(GetInstructionSetPointerSize(kRuntimeISA)), sizeof(QuickEntryPoints)); } diff --git a/dex2oat/linker/relative_patcher_test.h b/dex2oat/linker/relative_patcher_test.h index 075771d152..9556c5f557 100644 --- a/dex2oat/linker/relative_patcher_test.h +++ b/dex2oat/linker/relative_patcher_test.h @@ -87,7 +87,6 @@ class RelativePatcherTest : public CommonCompilerTest { compiler_driver_.get(), instruction_set_, code, - /* method_info */ ArrayRef<const uint8_t>(), /* vmap_table */ ArrayRef<const uint8_t>(), /* cfi_info */ ArrayRef<const uint8_t>(), patches)); diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 271d37dce7..9d73879979 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -1315,8 +1315,7 @@ class OatDumper { CodeInfo code_info(raw_code_info); DCHECK(code_item_accessor.HasCodeItem()); ScopedIndentation indent1(vios); - MethodInfo method_info = oat_method.GetOatQuickMethodHeader()->GetOptimizedMethodInfo(); - DumpCodeInfo(vios, code_info, oat_method, method_info); + DumpCodeInfo(vios, code_info, oat_method); } } else if (IsMethodGeneratedByDexToDexCompiler(oat_method, code_item_accessor)) { // We don't encode the size in the table, so just emit that we have quickened @@ -1331,13 +1330,11 @@ class OatDumper { // Display a CodeInfo object emitted by the optimizing compiler. void DumpCodeInfo(VariableIndentationOutputStream* vios, const CodeInfo& code_info, - const OatFile::OatMethod& oat_method, - const MethodInfo& method_info) { + const OatFile::OatMethod& oat_method) { code_info.Dump(vios, oat_method.GetCodeOffset(), options_.dump_code_info_stack_maps_, - instruction_set_, - method_info); + instruction_set_); } static int GetOutVROffset(uint16_t out_num, InstructionSet isa) { @@ -1579,16 +1576,10 @@ class OatDumper { } else if (!bad_input && IsMethodGeneratedByOptimizingCompiler(oat_method, code_item_accessor)) { // The optimizing compiler outputs its CodeInfo data in the vmap table. - const OatQuickMethodHeader* method_header = oat_method.GetOatQuickMethodHeader(); StackMapsHelper helper(oat_method.GetVmapTable(), instruction_set_); if (AddStatsObject(oat_method.GetVmapTable())) { helper.GetCodeInfo().AddSizeStats(&stats_); } - MethodInfo method_info(method_header->GetOptimizedMethodInfo()); - if (AddStatsObject(method_header->GetOptimizedMethodInfoPtr())) { - size_t method_info_size = MethodInfo::ComputeSize(method_info.NumMethodIndices()); - stats_.Child("MethodInfo")->AddBytes(method_info_size); - } const uint8_t* quick_native_pc = reinterpret_cast<const uint8_t*>(quick_code); size_t offset = 0; while (offset < code_size) { @@ -1599,7 +1590,6 @@ class OatDumper { DCHECK(stack_map.IsValid()); stack_map.Dump(vios, helper.GetCodeInfo(), - method_info, oat_method.GetCodeOffset(), instruction_set_); do { diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 0ed26d37c0..e6f3d0b0d5 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -45,7 +45,7 @@ namespace art { inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method, - const MethodInfo& method_info, + const CodeInfo& code_info, const BitTableRange<InlineInfo>& inline_infos) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(!outer_method->IsObsolete()); @@ -62,7 +62,7 @@ inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method, return inline_info.GetArtMethod(); } - uint32_t method_index = inline_info.GetMethodIndex(method_info); + uint32_t method_index = code_info.GetMethodIndexOf(inline_info); if (inline_info.GetDexPc() == static_cast<uint32_t>(-1)) { // "charAt" special case. It is the only non-leaf method we inline across dex files. ArtMethod* inlined_method = jni::DecodeArtMethod(WellKnownClasses::java_lang_String_charAt); @@ -77,7 +77,7 @@ inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method, for (InlineInfo inline_info : inline_infos) { DCHECK(!inline_info.EncodesArtMethod()); DCHECK_NE(inline_info.GetDexPc(), static_cast<uint32_t>(-1)); - uint32_t method_index = inline_info.GetMethodIndex(method_info); + uint32_t method_index = code_info.GetMethodIndexOf(inline_info); ArtMethod* inlined_method = class_linker->LookupResolvedMethod(method_index, method->GetDexCache(), method->GetClassLoader()); diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index a5ebce5f5b..5421f69fbd 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -202,12 +202,11 @@ static inline ArtMethod* DoGetCalleeSaveMethodCaller(ArtMethod* outer_method, DCHECK(current_code->IsOptimized()); uintptr_t native_pc_offset = current_code->NativeQuickPcOffset(caller_pc); CodeInfo code_info(current_code, CodeInfo::DecodeFlags::InlineInfoOnly); - MethodInfo method_info = current_code->GetOptimizedMethodInfo(); StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset); DCHECK(stack_map.IsValid()); BitTableRange<InlineInfo> inline_infos = code_info.GetInlineInfosOf(stack_map); if (!inline_infos.empty()) { - caller = GetResolvedMethod(outer_method, method_info, inline_infos); + caller = GetResolvedMethod(outer_method, code_info, inline_infos); } } if (kIsDebugBuild && do_caller_check) { diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index be4e4e613c..aca169b924 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -1236,7 +1236,6 @@ static void DumpB74410240DebugData(ArtMethod** sp) REQUIRES_SHARED(Locks::mutato CHECK(current_code->IsOptimized()); uintptr_t native_pc_offset = current_code->NativeQuickPcOffset(caller_pc); CodeInfo code_info(current_code); - MethodInfo method_info = current_code->GetOptimizedMethodInfo(); StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset); CHECK(stack_map.IsValid()); uint32_t dex_pc = stack_map.GetDexPc(); @@ -1261,7 +1260,7 @@ static void DumpB74410240DebugData(ArtMethod** sp) REQUIRES_SHARED(Locks::mutato tag = "encoded "; caller = inline_info.GetArtMethod(); } else { - uint32_t method_index = inline_info.GetMethodIndex(method_info); + uint32_t method_index = code_info.GetMethodIndexOf(inline_info); if (dex_pc == static_cast<uint32_t>(-1)) { tag = "special "; CHECK(inline_info.Equals(inline_infos.back())); diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 9aa05561f0..b92affa26e 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -411,7 +411,6 @@ class ScopedCodeCacheWrite : ScopedTrace { uint8_t* JitCodeCache::CommitCode(Thread* self, ArtMethod* method, uint8_t* stack_map, - uint8_t* method_info, uint8_t* roots_data, const uint8_t* code, size_t code_size, @@ -423,7 +422,6 @@ uint8_t* JitCodeCache::CommitCode(Thread* self, uint8_t* result = CommitCodeInternal(self, method, stack_map, - method_info, roots_data, code, code_size, @@ -438,7 +436,6 @@ uint8_t* JitCodeCache::CommitCode(Thread* self, result = CommitCodeInternal(self, method, stack_map, - method_info, roots_data, code, code_size, @@ -748,7 +745,6 @@ static void ClearMethodCounter(ArtMethod* method, bool was_warm) { uint8_t* JitCodeCache::CommitCodeInternal(Thread* self, ArtMethod* method, uint8_t* stack_map, - uint8_t* method_info, uint8_t* roots_data, const uint8_t* code, size_t code_size, @@ -783,7 +779,6 @@ uint8_t* JitCodeCache::CommitCodeInternal(Thread* self, method_header = OatQuickMethodHeader::FromCodePointer(code_ptr); new (method_header) OatQuickMethodHeader( (stack_map != nullptr) ? code_ptr - stack_map : 0u, - (method_info != nullptr) ? code_ptr - method_info : 0u, code_size); // Flush caches before we remove write permission because some ARMv8 Qualcomm kernels may // trigger a segfault if a page fault occurs when requesting a cache maintenance operation. @@ -1046,14 +1041,12 @@ void JitCodeCache::ClearData(Thread* self, size_t JitCodeCache::ReserveData(Thread* self, size_t stack_map_size, - size_t method_info_size, size_t number_of_roots, ArtMethod* method, uint8_t** stack_map_data, - uint8_t** method_info_data, uint8_t** roots_data) { size_t table_size = ComputeRootTableSize(number_of_roots); - size_t size = RoundUp(stack_map_size + method_info_size + table_size, sizeof(void*)); + size_t size = RoundUp(stack_map_size + table_size, sizeof(void*)); uint8_t* result = nullptr; { @@ -1083,13 +1076,11 @@ size_t JitCodeCache::ReserveData(Thread* self, if (result != nullptr) { *roots_data = result; *stack_map_data = result + table_size; - *method_info_data = *stack_map_data + stack_map_size; FillRootTableLength(*roots_data, number_of_roots); return size; } else { *roots_data = nullptr; *stack_map_data = nullptr; - *method_info_data = nullptr; return 0; } } diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h index d17fb261b6..29f9c9cf43 100644 --- a/runtime/jit/jit_code_cache.h +++ b/runtime/jit/jit_code_cache.h @@ -136,7 +136,6 @@ class JitCodeCache { uint8_t* CommitCode(Thread* self, ArtMethod* method, uint8_t* stack_map, - uint8_t* method_info, uint8_t* roots_data, const uint8_t* code, size_t code_size, @@ -166,11 +165,9 @@ class JitCodeCache { // Return the number of bytes allocated. size_t ReserveData(Thread* self, size_t stack_map_size, - size_t method_info_size, size_t number_of_roots, ArtMethod* method, uint8_t** stack_map_data, - uint8_t** method_info_data, uint8_t** roots_data) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!lock_); @@ -295,7 +292,6 @@ class JitCodeCache { uint8_t* CommitCodeInternal(Thread* self, ArtMethod* method, uint8_t* stack_map, - uint8_t* method_info, uint8_t* roots_data, const uint8_t* code, size_t code_size, diff --git a/runtime/method_info.h b/runtime/method_info.h deleted file mode 100644 index 6f74678e42..0000000000 --- a/runtime/method_info.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_RUNTIME_METHOD_INFO_H_ -#define ART_RUNTIME_METHOD_INFO_H_ - -#include <android-base/logging.h> - -#include "base/leb128.h" -#include "base/macros.h" -#include "base/bit_memory_region.h" - -namespace art { - -// Method info is for not dedupe friendly data of a method. Currently it only holds methods indices. -// Putting this data in MethodInfo instead of code infos saves ~5% oat size. -class MethodInfo { - using MethodIndexType = uint16_t; - - public: - // Reading mode - explicit MethodInfo(const uint8_t* ptr) { - if (ptr != nullptr) { - num_method_indices_ = DecodeUnsignedLeb128(&ptr); - region_ = BitMemoryRegion( - MemoryRegion(const_cast<uint8_t*>(ptr), num_method_indices_ * sizeof(MethodIndexType))); - } - } - - // Writing mode - MethodInfo(uint8_t* ptr, size_t num_method_indices) : num_method_indices_(num_method_indices) { - DCHECK(ptr != nullptr); - ptr = EncodeUnsignedLeb128(ptr, num_method_indices_); - region_ = BitMemoryRegion(MemoryRegion(ptr, num_method_indices_ * sizeof(MethodIndexType))); - } - - static size_t ComputeSize(size_t num_method_indices) { - uint8_t temp[8]; - uint8_t* ptr = temp; - ptr = EncodeUnsignedLeb128(ptr, num_method_indices); - return (ptr - temp) + num_method_indices * sizeof(MethodIndexType); - } - - ALWAYS_INLINE MethodIndexType GetMethodIndex(size_t index) const { - // Use bit functions to avoid pesky alignment requirements. - return region_.LoadBits(index * BitSizeOf<MethodIndexType>(), BitSizeOf<MethodIndexType>()); - } - - void SetMethodIndex(size_t index, MethodIndexType method_index) { - region_.StoreBits(index * BitSizeOf<MethodIndexType>(), - method_index, - BitSizeOf<MethodIndexType>()); - } - - size_t NumMethodIndices() const { - return num_method_indices_; - } - - private: - size_t num_method_indices_ = 0u; - BitMemoryRegion region_; -}; - -} // namespace art - -#endif // ART_RUNTIME_METHOD_INFO_H_ diff --git a/runtime/oat.h b/runtime/oat.h index c286f466f2..69aacebe1c 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -32,8 +32,8 @@ class InstructionSetFeatures; class PACKED(4) OatHeader { public: static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' }; - // Last oat version changed reason: Deduplicate stackmaps at BitTable level. - static constexpr uint8_t kOatVersion[] = { '1', '5', '7', '\0' }; + // Last oat version changed reason: Move MethodInfo into CodeInfo. + static constexpr uint8_t kOatVersion[] = { '1', '5', '8', '\0' }; static constexpr const char* kImageLocationKey = "image-location"; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; diff --git a/runtime/oat_quick_method_header.h b/runtime/oat_quick_method_header.h index 3b9f466220..8798c6968c 100644 --- a/runtime/oat_quick_method_header.h +++ b/runtime/oat_quick_method_header.h @@ -20,7 +20,6 @@ #include "arch/instruction_set.h" #include "base/macros.h" #include "base/utils.h" -#include "method_info.h" #include "quick/quick_method_frame_info.h" #include "stack_map.h" @@ -33,10 +32,8 @@ class PACKED(4) OatQuickMethodHeader { public: OatQuickMethodHeader() = default; OatQuickMethodHeader(uint32_t vmap_table_offset, - uint32_t method_info_offset, uint32_t code_size) : vmap_table_offset_(vmap_table_offset), - method_info_offset_(method_info_offset), code_size_(code_size) { } @@ -74,20 +71,6 @@ class PACKED(4) OatQuickMethodHeader { return code_ - vmap_table_offset_; } - const void* GetOptimizedMethodInfoPtr() const { - DCHECK(IsOptimized()); - return reinterpret_cast<const void*>(code_ - method_info_offset_); - } - - uint8_t* GetOptimizedMethodInfoPtr() { - DCHECK(IsOptimized()); - return code_ - method_info_offset_; - } - - MethodInfo GetOptimizedMethodInfo() const { - return MethodInfo(reinterpret_cast<const uint8_t*>(GetOptimizedMethodInfoPtr())); - } - const uint8_t* GetCode() const { return code_; } @@ -112,18 +95,6 @@ class PACKED(4) OatQuickMethodHeader { return &vmap_table_offset_; } - uint32_t GetMethodInfoOffset() const { - return method_info_offset_; - } - - void SetMethodInfoOffset(uint32_t offset) { - method_info_offset_ = offset; - } - - const uint32_t* GetMethodInfoOffsetAddr() const { - return &method_info_offset_; - } - const uint8_t* GetVmapTable() const { CHECK(!IsOptimized()) << "Unimplemented vmap table for optimizing compiler"; return (vmap_table_offset_ == 0) ? nullptr : code_ - vmap_table_offset_; @@ -186,11 +157,6 @@ class PACKED(4) OatQuickMethodHeader { // The offset in bytes from the start of the vmap table to the end of the header. uint32_t vmap_table_offset_ = 0u; - // The offset in bytes from the start of the method info to the end of the header. - // The method info offset is not in the CodeInfo since CodeInfo has good dedupe properties that - // would be lost from doing so. The method info memory region contains method indices since they - // are hard to dedupe. - uint32_t method_info_offset_ = 0u; // The code size in bytes. The highest bit is used to signify if the compiled // code with the method header has should_deoptimize flag. uint32_t code_size_ = 0u; diff --git a/runtime/stack.cc b/runtime/stack.cc index 85b1ea0524..ce99fb9591 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -81,9 +81,9 @@ ArtMethod* StackVisitor::GetMethod() const { } else if (cur_quick_frame_ != nullptr) { if (IsInInlinedFrame()) { const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader(); - MethodInfo method_info = method_header->GetOptimizedMethodInfo(); + CodeInfo code_info(method_header); DCHECK(walk_kind_ != StackWalkKind::kSkipInlinedFrames); - return GetResolvedMethod(*GetCurrentQuickFrame(), method_info, current_inline_frames_); + return GetResolvedMethod(*GetCurrentQuickFrame(), code_info, current_inline_frames_); } else { return *cur_quick_frame_; } diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc index e8746bc7f1..cd82284a9a 100644 --- a/runtime/stack_map.cc +++ b/runtime/stack_map.cc @@ -58,6 +58,7 @@ void CodeInfo::Decode(const uint8_t* data, DecodeFlags flags) { BitMemoryReader reader(data, /* bit_offset */ 0); DecodeTable(stack_maps_, reader, data); DecodeTable(inline_infos_, reader, data); + DecodeTable(method_infos_, reader, data); if (flags & DecodeFlags::InlineInfoOnly) { return; } @@ -99,6 +100,7 @@ size_t CodeInfo::Dedupe(std::vector<uint8_t>* out, const uint8_t* in, DedupeMap* BitMemoryWriter<std::vector<uint8_t>> writer(out, /* bit_offset */ out->size() * kBitsPerByte); DedupeTable<StackMap>(writer, reader, dedupe_map); DedupeTable<InlineInfo>(writer, reader, dedupe_map); + DedupeTable<MethodInfo>(writer, reader, dedupe_map); DedupeTable<RegisterMask>(writer, reader, dedupe_map); DedupeTable<MaskInfo>(writer, reader, dedupe_map); DedupeTable<MaskInfo>(writer, reader, dedupe_map); @@ -211,9 +213,10 @@ void CodeInfo::AddSizeStats(/*out*/ Stats* parent) const { Stats* stats = parent->Child("CodeInfo"); stats->AddBytes(Size()); AddTableSizeStats<StackMap>("StackMaps", stack_maps_, stats); + AddTableSizeStats<InlineInfo>("InlineInfos", inline_infos_, stats); + AddTableSizeStats<MethodInfo>("MethodInfo", method_infos_, stats); AddTableSizeStats<RegisterMask>("RegisterMasks", register_masks_, stats); AddTableSizeStats<MaskInfo>("StackMasks", stack_masks_, stats); - AddTableSizeStats<InlineInfo>("InlineInfos", inline_infos_, stats); AddTableSizeStats<MaskInfo>("DexRegisterMasks", dex_register_masks_, stats); AddTableSizeStats<DexRegisterMapInfo>("DexRegisterMaps", dex_register_maps_, stats); AddTableSizeStats<DexRegisterInfo>("DexRegisterCatalog", dex_register_catalog_, stats); @@ -271,14 +274,14 @@ static void DumpTable(VariableIndentationOutputStream* vios, void CodeInfo::Dump(VariableIndentationOutputStream* vios, uint32_t code_offset, bool verbose, - InstructionSet instruction_set, - const MethodInfo& method_info) const { + InstructionSet instruction_set) const { vios->Stream() << "CodeInfo\n"; ScopedIndentation indent1(vios); DumpTable<StackMap>(vios, "StackMaps", stack_maps_, verbose); + DumpTable<InlineInfo>(vios, "InlineInfos", inline_infos_, verbose); + DumpTable<MethodInfo>(vios, "MethodInfo", method_infos_, verbose); DumpTable<RegisterMask>(vios, "RegisterMasks", register_masks_, verbose); DumpTable<MaskInfo>(vios, "StackMasks", stack_masks_, verbose, true /* is_mask */); - DumpTable<InlineInfo>(vios, "InlineInfos", inline_infos_, verbose); DumpTable<MaskInfo>(vios, "DexRegisterMasks", dex_register_masks_, verbose, true /* is_mask */); DumpTable<DexRegisterMapInfo>(vios, "DexRegisterMaps", dex_register_maps_, verbose); DumpTable<DexRegisterInfo>(vios, "DexRegisterCatalog", dex_register_catalog_, verbose); @@ -286,14 +289,13 @@ void CodeInfo::Dump(VariableIndentationOutputStream* vios, // Display stack maps along with (live) Dex register maps. if (verbose) { for (StackMap stack_map : stack_maps_) { - stack_map.Dump(vios, *this, method_info, code_offset, instruction_set); + stack_map.Dump(vios, *this, code_offset, instruction_set); } } } void StackMap::Dump(VariableIndentationOutputStream* vios, const CodeInfo& code_info, - const MethodInfo& method_info, uint32_t code_offset, InstructionSet instruction_set) const { const uint32_t pc_offset = GetNativePcOffset(instruction_set); @@ -312,14 +314,13 @@ void StackMap::Dump(VariableIndentationOutputStream* vios, vios->Stream() << ")\n"; code_info.GetDexRegisterMapOf(*this).Dump(vios); for (InlineInfo inline_info : code_info.GetInlineInfosOf(*this)) { - inline_info.Dump(vios, code_info, *this, method_info); + inline_info.Dump(vios, code_info, *this); } } void InlineInfo::Dump(VariableIndentationOutputStream* vios, const CodeInfo& code_info, - const StackMap& stack_map, - const MethodInfo& method_info) const { + const StackMap& stack_map) const { uint32_t depth = Row() - stack_map.GetInlineInfoIndex(); vios->Stream() << "InlineInfo[" << Row() << "]" @@ -332,7 +333,7 @@ void InlineInfo::Dump(VariableIndentationOutputStream* vios, } else { vios->Stream() << std::dec - << ", method_index=" << GetMethodIndex(method_info); + << ", method_index=" << code_info.GetMethodIndexOf(*this); } vios->Stream() << ")\n"; code_info.GetInlineDexRegisterMapOf(stack_map, *this).Dump(vios); diff --git a/runtime/stack_map.h b/runtime/stack_map.h index 909aaa5576..8bfae7c39f 100644 --- a/runtime/stack_map.h +++ b/runtime/stack_map.h @@ -28,7 +28,6 @@ #include "base/memory_region.h" #include "dex/dex_file_types.h" #include "dex_register_location.h" -#include "method_info.h" #include "quick/quick_method_frame_info.h" namespace art { @@ -164,7 +163,6 @@ class StackMap : public BitTableAccessor<8> { void Dump(VariableIndentationOutputStream* vios, const CodeInfo& code_info, - const MethodInfo& method_info, uint32_t code_offset, InstructionSet instruction_set) const; }; @@ -188,10 +186,6 @@ class InlineInfo : public BitTableAccessor<6> { static constexpr uint32_t kLast = -1; static constexpr uint32_t kMore = 0; - uint32_t GetMethodIndex(const MethodInfo& method_info) const { - return method_info.GetMethodIndex(GetMethodInfoIndex()); - } - bool EncodesArtMethod() const { return HasArtMethodLo(); } @@ -204,8 +198,7 @@ class InlineInfo : public BitTableAccessor<6> { void Dump(VariableIndentationOutputStream* vios, const CodeInfo& info, - const StackMap& stack_map, - const MethodInfo& method_info) const; + const StackMap& stack_map) const; }; class MaskInfo : public BitTableAccessor<1> { @@ -262,6 +255,14 @@ class RegisterMask : public BitTableAccessor<2> { } }; +// Method indices are not very dedup friendly. +// Separating them greatly improves dedup efficiency of the other tables. +class MethodInfo : public BitTableAccessor<1> { + public: + BIT_TABLE_HEADER() + BIT_TABLE_COLUMN(0, MethodIndex) +}; + /** * Wrapper around all compiler information collected for a method. * See the Decode method at the end for the precise binary format. @@ -329,6 +330,10 @@ class CodeInfo { return stack_maps_.NumRows(); } + uint32_t GetMethodIndexOf(InlineInfo inline_info) const { + return method_infos_.GetRow(inline_info.GetMethodInfoIndex()).GetMethodIndex(); + } + ALWAYS_INLINE DexRegisterMap GetDexRegisterMapOf(StackMap stack_map) const { if (stack_map.HasDexRegisterMap()) { DexRegisterMap map(number_of_dex_registers_, DexRegisterLocation::Invalid()); @@ -405,8 +410,7 @@ class CodeInfo { void Dump(VariableIndentationOutputStream* vios, uint32_t code_offset, bool verbose, - InstructionSet instruction_set, - const MethodInfo& method_info) const; + InstructionSet instruction_set) const; // Accumulate code info size statistics into the given Stats tree. void AddSizeStats(/*out*/ Stats* parent) const; @@ -446,6 +450,7 @@ class CodeInfo { uint32_t number_of_dex_registers_; BitTable<StackMap> stack_maps_; BitTable<InlineInfo> inline_infos_; + BitTable<MethodInfo> method_infos_; BitTable<RegisterMask> register_masks_; BitTable<MaskInfo> stack_masks_; BitTable<MaskInfo> dex_register_masks_; |