From b176d7c6c8c01a50317f837a78de5da57ee84fb2 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Wed, 20 May 2015 18:48:31 +0100 Subject: [PATCH] Also encode the InvokeType in an InlineInfo. This will be needed to recover the call stack. Change-Id: I2fe10785eb1167939c8cce1862b2d7f4066e16ec --- compiler/optimizing/code_generator.cc | 6 ++- compiler/optimizing/inliner.cc | 1 + compiler/optimizing/nodes.h | 71 ++++++++++++++++++------------ compiler/optimizing/nodes_test.cc | 8 ++-- compiler/optimizing/optimizing_compiler.cc | 2 +- compiler/optimizing/ssa_builder.cc | 3 +- compiler/optimizing/stack_map_stream.cc | 3 ++ compiler/optimizing/stack_map_stream.h | 2 + compiler/optimizing/stack_map_test.cc | 30 ++++++++----- runtime/stack_map.h | 32 +++++++++++--- 10 files changed, 105 insertions(+), 53 deletions(-) diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 4805ceed2..d71266df8 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -702,8 +702,10 @@ void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slo if (environment->GetParent() != nullptr) { // We emit the parent environment first. EmitEnvironment(environment->GetParent(), slow_path); - stack_map_stream_.BeginInlineInfoEntry( - environment->GetMethodIdx(), environment->GetDexPc(), environment->Size()); + stack_map_stream_.BeginInlineInfoEntry(environment->GetMethodIdx(), + environment->GetDexPc(), + environment->GetInvokeType(), + environment->Size()); } // Walk over the environment, and record the location of dex registers. diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 56d868f11..47c6318c9 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -193,6 +193,7 @@ bool HInliner::TryBuildAndInline(Handle resolved_method, caller_dex_file, method_index, requires_ctor_barrier, + invoke_instruction->GetOriginalInvokeType(), graph_->IsDebuggable(), graph_->GetCurrentInstructionId()); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 680fb477e..71fe290ad 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -60,6 +60,8 @@ static const int kDefaultNumberOfBackEdges = 1; static constexpr uint32_t kMaxIntShiftValue = 0x1f; static constexpr uint64_t kMaxLongShiftValue = 0x3f; +static constexpr InvokeType kInvalidInvokeType = static_cast(-1); + enum IfCondition { kCondEQ, kCondNE, @@ -121,6 +123,7 @@ class HGraph : public ArenaObject { const DexFile& dex_file, uint32_t method_idx, bool should_generate_constructor_barrier, + InvokeType invoke_type = kInvalidInvokeType, bool debuggable = false, int start_instruction_id = 0) : arena_(arena), @@ -138,6 +141,7 @@ class HGraph : public ArenaObject { current_instruction_id_(start_instruction_id), dex_file_(dex_file), method_idx_(method_idx), + invoke_type_(invoke_type), should_generate_constructor_barrier_(should_generate_constructor_barrier), cached_null_constant_(nullptr), cached_int_constants_(std::less(), arena->Adapter()), @@ -283,6 +287,10 @@ class HGraph : public ArenaObject { return method_idx_; } + InvokeType GetInvokeType() const { + return invoke_type_; + } + private: void VisitBlockForDominatorTree(HBasicBlock* block, HBasicBlock* predecessor, @@ -365,6 +373,9 @@ class HGraph : public ArenaObject { // The method index in the dex file. const uint32_t method_idx_; + // If inlined, this encodes how the callee is being invoked. + const InvokeType invoke_type_; + const bool should_generate_constructor_barrier_; // Cached constants. @@ -1101,13 +1112,15 @@ class HEnvironment : public ArenaObject { size_t number_of_vregs, const DexFile& dex_file, uint32_t method_idx, - uint32_t dex_pc) + uint32_t dex_pc, + InvokeType invoke_type) : vregs_(arena, number_of_vregs), locations_(arena, number_of_vregs), parent_(nullptr), dex_file_(dex_file), method_idx_(method_idx), - dex_pc_(dex_pc) { + dex_pc_(dex_pc), + invoke_type_(invoke_type) { vregs_.SetSize(number_of_vregs); for (size_t i = 0; i < number_of_vregs; i++) { vregs_.Put(i, HUserRecord()); @@ -1119,16 +1132,20 @@ class HEnvironment : public ArenaObject { } } + HEnvironment(ArenaAllocator* arena, const HEnvironment& to_copy) + : HEnvironment(arena, + to_copy.Size(), + to_copy.GetDexFile(), + to_copy.GetMethodIdx(), + to_copy.GetDexPc(), + to_copy.GetInvokeType()) {} + void SetAndCopyParentChain(ArenaAllocator* allocator, HEnvironment* parent) { - parent_ = new (allocator) HEnvironment(allocator, - parent->Size(), - parent->GetDexFile(), - parent->GetMethodIdx(), - parent->GetDexPc()); + parent_ = new (allocator) HEnvironment(allocator, *parent); + parent_->CopyFrom(parent); if (parent->GetParent() != nullptr) { parent_->SetAndCopyParentChain(allocator, parent->GetParent()); } - parent_->CopyFrom(parent); } void CopyFrom(const GrowableArray& locals); @@ -1169,6 +1186,10 @@ class HEnvironment : public ArenaObject { return method_idx_; } + InvokeType GetInvokeType() const { + return invoke_type_; + } + const DexFile& GetDexFile() const { return dex_file_; } @@ -1188,6 +1209,7 @@ class HEnvironment : public ArenaObject { const DexFile& dex_file_; const uint32_t method_idx_; const uint32_t dex_pc_; + const InvokeType invoke_type_; friend class HInstruction; @@ -1401,12 +1423,7 @@ class HInstruction : public ArenaObject { // copying, the uses lists are being updated. void CopyEnvironmentFrom(HEnvironment* environment) { ArenaAllocator* allocator = GetBlock()->GetGraph()->GetArena(); - environment_ = new (allocator) HEnvironment( - allocator, - environment->Size(), - environment->GetDexFile(), - environment->GetMethodIdx(), - environment->GetDexPc()); + environment_ = new (allocator) HEnvironment(allocator, *environment); environment_->CopyFrom(environment); if (environment->GetParent() != nullptr) { environment_->SetAndCopyParentChain(allocator, environment->GetParent()); @@ -1416,16 +1433,11 @@ class HInstruction : public ArenaObject { void CopyEnvironmentFromWithLoopPhiAdjustment(HEnvironment* environment, HBasicBlock* block) { ArenaAllocator* allocator = GetBlock()->GetGraph()->GetArena(); - environment_ = new (allocator) HEnvironment( - allocator, - environment->Size(), - environment->GetDexFile(), - environment->GetMethodIdx(), - environment->GetDexPc()); + environment_ = new (allocator) HEnvironment(allocator, *environment); + environment_->CopyFromWithLoopPhiAdjustment(environment, block); if (environment->GetParent() != nullptr) { environment_->SetAndCopyParentChain(allocator, environment->GetParent()); } - environment_->CopyFromWithLoopPhiAdjustment(environment, block); } // Returns the number of entries in the environment. Typically, that is the @@ -2376,6 +2388,8 @@ class HInvoke : public HInstruction { uint32_t GetDexMethodIndex() const { return dex_method_index_; } + InvokeType GetOriginalInvokeType() const { return original_invoke_type_; } + Intrinsics GetIntrinsic() const { return intrinsic_; } @@ -2392,13 +2406,15 @@ class HInvoke : public HInstruction { uint32_t number_of_other_inputs, Primitive::Type return_type, uint32_t dex_pc, - uint32_t dex_method_index) + uint32_t dex_method_index, + InvokeType original_invoke_type) : HInstruction(SideEffects::All()), number_of_arguments_(number_of_arguments), inputs_(arena, number_of_arguments), return_type_(return_type), dex_pc_(dex_pc), dex_method_index_(dex_method_index), + original_invoke_type_(original_invoke_type), intrinsic_(Intrinsics::kNone) { uint32_t number_of_inputs = number_of_arguments + number_of_other_inputs; inputs_.SetSize(number_of_inputs); @@ -2414,6 +2430,7 @@ class HInvoke : public HInstruction { const Primitive::Type return_type_; const uint32_t dex_pc_; const uint32_t dex_method_index_; + const InvokeType original_invoke_type_; Intrinsics intrinsic_; private: @@ -2445,8 +2462,8 @@ class HInvokeStaticOrDirect : public HInvoke { clinit_check_requirement == ClinitCheckRequirement::kExplicit ? 1u : 0u, return_type, dex_pc, - dex_method_index), - original_invoke_type_(original_invoke_type), + dex_method_index, + original_invoke_type), invoke_type_(invoke_type), is_recursive_(is_recursive), clinit_check_requirement_(clinit_check_requirement), @@ -2459,7 +2476,6 @@ class HInvokeStaticOrDirect : public HInvoke { return false; } - InvokeType GetOriginalInvokeType() const { return original_invoke_type_; } InvokeType GetInvokeType() const { return invoke_type_; } bool IsRecursive() const { return is_recursive_; } bool NeedsDexCache() const OVERRIDE { return !IsRecursive(); } @@ -2517,7 +2533,6 @@ class HInvokeStaticOrDirect : public HInvoke { } private: - const InvokeType original_invoke_type_; const InvokeType invoke_type_; const bool is_recursive_; ClinitCheckRequirement clinit_check_requirement_; @@ -2536,7 +2551,7 @@ class HInvokeVirtual : public HInvoke { uint32_t dex_pc, uint32_t dex_method_index, uint32_t vtable_index) - : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index), + : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index, kVirtual), vtable_index_(vtable_index) {} bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE { @@ -2562,7 +2577,7 @@ class HInvokeInterface : public HInvoke { uint32_t dex_pc, uint32_t dex_method_index, uint32_t imt_index) - : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index), + : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index, kInterface), imt_index_(imt_index) {} bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE { diff --git a/compiler/optimizing/nodes_test.cc b/compiler/optimizing/nodes_test.cc index 2736453cc..782cde486 100644 --- a/compiler/optimizing/nodes_test.cc +++ b/compiler/optimizing/nodes_test.cc @@ -51,7 +51,7 @@ TEST(Node, RemoveInstruction) { exit_block->AddInstruction(new (&allocator) HExit()); HEnvironment* environment = new (&allocator) HEnvironment( - &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0); + &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic); null_check->SetRawEnvironment(environment); environment->SetRawEnvAt(0, parameter); parameter->AddEnvUseAt(null_check->GetEnvironment(), 0); @@ -132,7 +132,7 @@ TEST(Node, ParentEnvironment) { ASSERT_TRUE(parameter1->GetUses().HasOnlyOneUse()); HEnvironment* environment = new (&allocator) HEnvironment( - &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0); + &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic); GrowableArray array(&allocator, 1); array.Add(parameter1); @@ -143,13 +143,13 @@ TEST(Node, ParentEnvironment) { ASSERT_TRUE(parameter1->GetEnvUses().HasOnlyOneUse()); HEnvironment* parent1 = new (&allocator) HEnvironment( - &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0); + &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic); parent1->CopyFrom(array); ASSERT_EQ(parameter1->GetEnvUses().SizeSlow(), 2u); HEnvironment* parent2 = new (&allocator) HEnvironment( - &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0); + &allocator, 1, graph->GetDexFile(), graph->GetMethodIdx(), 0, kStatic); parent2->CopyFrom(array); parent1->SetAndCopyParentChain(&allocator, parent2); diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index be9a42425..b2e8ecd74 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -518,7 +518,7 @@ CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_ite dex_compilation_unit.GetClassDefIndex()); ArenaAllocator arena(Runtime::Current()->GetArenaPool()); HGraph* graph = new (&arena) HGraph( - &arena, dex_file, method_idx, requires_barrier, + &arena, dex_file, method_idx, requires_barrier, kInvalidInvokeType, compiler_driver->GetCompilerOptions().GetDebuggable()); // For testing purposes, we put a special marker on method names that should be compiled diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index aac521187..c51d24876 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -547,7 +547,8 @@ void SsaBuilder::VisitInstruction(HInstruction* instruction) { current_locals_->Size(), GetGraph()->GetDexFile(), GetGraph()->GetMethodIdx(), - instruction->GetDexPc()); + instruction->GetDexPc(), + GetGraph()->GetInvokeType()); environment->CopyFrom(*current_locals_); instruction->SetRawEnvironment(environment); } diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc index 89035a368..b44681577 100644 --- a/compiler/optimizing/stack_map_stream.cc +++ b/compiler/optimizing/stack_map_stream.cc @@ -101,11 +101,13 @@ void StackMapStream::AddDexRegisterEntry(DexRegisterLocation::Kind kind, int32_t void StackMapStream::BeginInlineInfoEntry(uint32_t method_index, uint32_t dex_pc, + InvokeType invoke_type, uint32_t num_dex_registers) { DCHECK(!in_inline_frame_); in_inline_frame_ = true; current_inline_info_.method_index = method_index; current_inline_info_.dex_pc = dex_pc; + current_inline_info_.invoke_type = invoke_type; current_inline_info_.num_dex_registers = num_dex_registers; current_inline_info_.dex_register_locations_start_index = dex_register_locations_.Size(); if (num_dex_registers != 0) { @@ -313,6 +315,7 @@ void StackMapStream::FillIn(MemoryRegion region) { InlineInfoEntry inline_entry = inline_infos_.Get(depth + entry.inline_infos_start_index); inline_info.SetMethodIndexAtDepth(depth, inline_entry.method_index); inline_info.SetDexPcAtDepth(depth, inline_entry.dex_pc); + inline_info.SetInvokeTypeAtDepth(depth, inline_entry.invoke_type); if (inline_entry.num_dex_registers == 0) { // No dex map available. inline_info.SetDexRegisterMapOffsetAtDepth(depth, StackMap::kNoDexRegisterMap); diff --git a/compiler/optimizing/stack_map_stream.h b/compiler/optimizing/stack_map_stream.h index 4c03f9f90..0af983b1b 100644 --- a/compiler/optimizing/stack_map_stream.h +++ b/compiler/optimizing/stack_map_stream.h @@ -104,6 +104,7 @@ class StackMapStream : public ValueObject { struct InlineInfoEntry { uint32_t dex_pc; uint32_t method_index; + InvokeType invoke_type; uint32_t num_dex_registers; BitVector* live_dex_registers_mask; size_t dex_register_locations_start_index; @@ -121,6 +122,7 @@ class StackMapStream : public ValueObject { void BeginInlineInfoEntry(uint32_t method_index, uint32_t dex_pc, + InvokeType invoke_type, uint32_t num_dex_registers); void EndInlineInfoEntry(); diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc index e04fa9888..98e14ea9a 100644 --- a/compiler/optimizing/stack_map_test.cc +++ b/compiler/optimizing/stack_map_test.cc @@ -128,9 +128,9 @@ TEST(StackMapTest, Test2) { stream.BeginStackMapEntry(0, 64, 0x3, &sp_mask1, number_of_dex_registers, 2); stream.AddDexRegisterEntry(Kind::kInStack, 0); // Short location. stream.AddDexRegisterEntry(Kind::kConstant, -2); // Large location. - stream.BeginInlineInfoEntry(82, 3, number_of_dex_registers_in_inline_info); + stream.BeginInlineInfoEntry(82, 3, kDirect, number_of_dex_registers_in_inline_info); stream.EndInlineInfoEntry(); - stream.BeginInlineInfoEntry(42, 2, number_of_dex_registers_in_inline_info); + stream.BeginInlineInfoEntry(42, 2, kStatic, number_of_dex_registers_in_inline_info); stream.EndInlineInfoEntry(); stream.EndStackMapEntry(); @@ -218,6 +218,8 @@ TEST(StackMapTest, Test2) { ASSERT_EQ(42u, inline_info.GetMethodIndexAtDepth(1)); ASSERT_EQ(3u, inline_info.GetDexPcAtDepth(0)); ASSERT_EQ(2u, inline_info.GetDexPcAtDepth(1)); + ASSERT_EQ(kDirect, inline_info.GetInvokeTypeAtDepth(0)); + ASSERT_EQ(kStatic, inline_info.GetInvokeTypeAtDepth(1)); } // Second stack map. @@ -519,10 +521,10 @@ TEST(StackMapTest, InlineTest) { stream.AddDexRegisterEntry(Kind::kInStack, 0); stream.AddDexRegisterEntry(Kind::kConstant, 4); - stream.BeginInlineInfoEntry(42, 2, 1); + stream.BeginInlineInfoEntry(42, 2, kStatic, 1); stream.AddDexRegisterEntry(Kind::kInStack, 8); stream.EndInlineInfoEntry(); - stream.BeginInlineInfoEntry(82, 3, 3); + stream.BeginInlineInfoEntry(82, 3, kStatic, 3); stream.AddDexRegisterEntry(Kind::kInStack, 16); stream.AddDexRegisterEntry(Kind::kConstant, 20); stream.AddDexRegisterEntry(Kind::kInRegister, 15); @@ -535,15 +537,15 @@ TEST(StackMapTest, InlineTest) { stream.AddDexRegisterEntry(Kind::kInStack, 56); stream.AddDexRegisterEntry(Kind::kConstant, 0); - stream.BeginInlineInfoEntry(42, 2, 1); + stream.BeginInlineInfoEntry(42, 2, kDirect, 1); stream.AddDexRegisterEntry(Kind::kInStack, 12); stream.EndInlineInfoEntry(); - stream.BeginInlineInfoEntry(82, 3, 3); + stream.BeginInlineInfoEntry(82, 3, kStatic, 3); stream.AddDexRegisterEntry(Kind::kInStack, 80); stream.AddDexRegisterEntry(Kind::kConstant, 10); stream.AddDexRegisterEntry(Kind::kInRegister, 5); stream.EndInlineInfoEntry(); - stream.BeginInlineInfoEntry(52, 5, 0); + stream.BeginInlineInfoEntry(52, 5, kVirtual, 0); stream.EndInlineInfoEntry(); stream.EndStackMapEntry(); @@ -559,12 +561,12 @@ TEST(StackMapTest, InlineTest) { stream.AddDexRegisterEntry(Kind::kInStack, 56); stream.AddDexRegisterEntry(Kind::kConstant, 0); - stream.BeginInlineInfoEntry(42, 2, 0); + stream.BeginInlineInfoEntry(42, 2, kVirtual, 0); stream.EndInlineInfoEntry(); - stream.BeginInlineInfoEntry(52, 5, 1); + stream.BeginInlineInfoEntry(52, 5, kInterface, 1); stream.AddDexRegisterEntry(Kind::kInRegister, 2); stream.EndInlineInfoEntry(); - stream.BeginInlineInfoEntry(52, 10, 2); + stream.BeginInlineInfoEntry(52, 10, kStatic, 2); stream.AddDexRegisterEntry(Kind::kNone, 0); stream.AddDexRegisterEntry(Kind::kInRegister, 3); stream.EndInlineInfoEntry(); @@ -590,8 +592,10 @@ TEST(StackMapTest, InlineTest) { ASSERT_EQ(2u, if0.GetDepth()); ASSERT_EQ(2u, if0.GetDexPcAtDepth(0)); ASSERT_EQ(42u, if0.GetMethodIndexAtDepth(0)); + ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(0)); ASSERT_EQ(3u, if0.GetDexPcAtDepth(1)); ASSERT_EQ(82u, if0.GetMethodIndexAtDepth(1)); + ASSERT_EQ(kStatic, if0.GetInvokeTypeAtDepth(1)); DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if0, 1); ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0, 1, ci)); @@ -614,10 +618,13 @@ TEST(StackMapTest, InlineTest) { ASSERT_EQ(3u, if1.GetDepth()); ASSERT_EQ(2u, if1.GetDexPcAtDepth(0)); ASSERT_EQ(42u, if1.GetMethodIndexAtDepth(0)); + ASSERT_EQ(kDirect, if1.GetInvokeTypeAtDepth(0)); ASSERT_EQ(3u, if1.GetDexPcAtDepth(1)); ASSERT_EQ(82u, if1.GetMethodIndexAtDepth(1)); + ASSERT_EQ(kStatic, if1.GetInvokeTypeAtDepth(1)); ASSERT_EQ(5u, if1.GetDexPcAtDepth(2)); ASSERT_EQ(52u, if1.GetMethodIndexAtDepth(2)); + ASSERT_EQ(kVirtual, if1.GetInvokeTypeAtDepth(2)); DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, if1, 1); ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0, 1, ci)); @@ -652,10 +659,13 @@ TEST(StackMapTest, InlineTest) { ASSERT_EQ(3u, if2.GetDepth()); ASSERT_EQ(2u, if2.GetDexPcAtDepth(0)); ASSERT_EQ(42u, if2.GetMethodIndexAtDepth(0)); + ASSERT_EQ(kVirtual, if2.GetInvokeTypeAtDepth(0)); ASSERT_EQ(5u, if2.GetDexPcAtDepth(1)); ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(1)); + ASSERT_EQ(kInterface, if2.GetInvokeTypeAtDepth(1)); ASSERT_EQ(10u, if2.GetDexPcAtDepth(2)); ASSERT_EQ(52u, if2.GetMethodIndexAtDepth(2)); + ASSERT_EQ(kStatic, if2.GetInvokeTypeAtDepth(2)); ASSERT_FALSE(if2.HasDexRegisterMapAtDepth(0)); diff --git a/runtime/stack_map.h b/runtime/stack_map.h index 16ae772ca..f07fb74eb 100644 --- a/runtime/stack_map.h +++ b/runtime/stack_map.h @@ -735,31 +735,43 @@ class InlineInfo { } uint32_t GetMethodIndexAtDepth(uint8_t depth) const { - return region_.LoadUnaligned(kFixedSize + depth * SingleEntrySize()); + return region_.LoadUnaligned( + kFixedSize + depth * SingleEntrySize() + kMethodIndexOffset); } void SetMethodIndexAtDepth(uint8_t depth, uint32_t index) { - region_.StoreUnaligned(kFixedSize + depth * SingleEntrySize(), index); + region_.StoreUnaligned( + kFixedSize + depth * SingleEntrySize() + kMethodIndexOffset, index); } uint32_t GetDexPcAtDepth(uint8_t depth) const { return region_.LoadUnaligned( - kFixedSize + depth * SingleEntrySize() + sizeof(uint32_t)); + kFixedSize + depth * SingleEntrySize() + kDexPcOffset); } void SetDexPcAtDepth(uint8_t depth, uint32_t dex_pc) { region_.StoreUnaligned( - kFixedSize + depth * SingleEntrySize() + sizeof(uint32_t), dex_pc); + kFixedSize + depth * SingleEntrySize() + kDexPcOffset, dex_pc); + } + + uint8_t GetInvokeTypeAtDepth(uint8_t depth) const { + return region_.LoadUnaligned( + kFixedSize + depth * SingleEntrySize() + kInvokeTypeOffset); + } + + void SetInvokeTypeAtDepth(uint8_t depth, uint8_t invoke_type) { + region_.StoreUnaligned( + kFixedSize + depth * SingleEntrySize() + kInvokeTypeOffset, invoke_type); } uint32_t GetDexRegisterMapOffsetAtDepth(uint8_t depth) const { return region_.LoadUnaligned( - kFixedSize + depth * SingleEntrySize() + sizeof(uint32_t) + sizeof(uint32_t)); + kFixedSize + depth * SingleEntrySize() + kDexRegisterMapOffset); } void SetDexRegisterMapOffsetAtDepth(uint8_t depth, uint32_t offset) { region_.StoreUnaligned( - kFixedSize + depth * SingleEntrySize() + sizeof(uint32_t) + sizeof(uint32_t), offset); + kFixedSize + depth * SingleEntrySize() + kDexRegisterMapOffset, offset); } bool HasDexRegisterMapAtDepth(uint8_t depth) const { @@ -767,7 +779,7 @@ class InlineInfo { } static size_t SingleEntrySize() { - return sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t); + return kFixedEntrySize; } void Dump(std::ostream& os, const CodeInfo& info, uint16_t* number_of_dex_registers) const; @@ -778,6 +790,12 @@ class InlineInfo { static constexpr int kDepthOffset = 0; static constexpr int kFixedSize = kDepthOffset + sizeof(uint8_t); + static constexpr int kMethodIndexOffset = 0; + static constexpr int kDexPcOffset = kMethodIndexOffset + sizeof(uint32_t); + static constexpr int kInvokeTypeOffset = kDexPcOffset + sizeof(uint32_t); + static constexpr int kDexRegisterMapOffset = kInvokeTypeOffset + sizeof(uint8_t); + static constexpr int kFixedEntrySize = kDexRegisterMapOffset + sizeof(uint32_t); + MemoryRegion region_; friend class CodeInfo; -- 2.11.0