Use iterators to access stack map data.
Try to simplify the code using the recently added iterators.
Test: test-art-host-gtest-stack_map_test
Change-Id: I0b9f54df01749ee6ec3a67cfb07ba636a2489c89
diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h
index f2a942f..bda7108 100644
--- a/compiler/debug/elf_debug_info_writer.h
+++ b/compiler/debug/elf_debug_info_writer.h
@@ -208,8 +208,7 @@
std::vector<DexRegisterMap> dex_reg_maps;
if (accessor.HasCodeItem() && mi->code_info != nullptr) {
code_info.reset(new CodeInfo(mi->code_info));
- for (size_t s = 0; s < code_info->GetNumberOfStackMaps(); ++s) {
- const StackMap stack_map = code_info->GetStackMapAt(s);
+ for (StackMap stack_map : code_info->GetStackMaps()) {
dex_reg_maps.push_back(code_info->GetDexRegisterMapOf(stack_map));
}
}
diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h
index a7adab5..3d78943 100644
--- a/compiler/debug/elf_debug_line_writer.h
+++ b/compiler/debug/elf_debug_line_writer.h
@@ -101,9 +101,7 @@
// Use stack maps to create mapping table from pc to dex.
const CodeInfo code_info(mi->code_info);
pc2dex_map.reserve(code_info.GetNumberOfStackMaps());
- for (uint32_t s = 0; s < code_info.GetNumberOfStackMaps(); s++) {
- StackMap stack_map = code_info.GetStackMapAt(s);
- DCHECK(stack_map.IsValid());
+ for (StackMap stack_map : code_info.GetStackMaps()) {
const uint32_t pc = stack_map.GetNativePcOffset(isa);
const int32_t dex = stack_map.GetDexPc();
pc2dex_map.push_back({pc, dex});
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc
index 5d361953..3e1a36d 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -151,7 +151,7 @@
StackMap stack_map = code_info.GetStackMapAt(stack_map_index);
CHECK_EQ(stack_map.HasDexRegisterMap(), (num_dex_registers != 0));
CHECK_EQ(stack_map.HasInlineInfo(), (inlining_depth != 0));
- CHECK_EQ(code_info.GetInlineDepthOf(stack_map), inlining_depth);
+ CHECK_EQ(code_info.GetInlineInfosOf(stack_map).size(), inlining_depth);
});
}
}
@@ -209,7 +209,7 @@
size_t depth = current_inline_infos_.size() - 1;
dchecks_.emplace_back([=](const CodeInfo& code_info) {
StackMap stack_map = code_info.GetStackMapAt(stack_map_index);
- InlineInfo inline_info = code_info.GetInlineInfoAtDepth(stack_map, depth);
+ InlineInfo inline_info = code_info.GetInlineInfosOf(stack_map)[depth];
CHECK_EQ(inline_info.GetDexPc(), dex_pc);
bool encode_art_method = EncodeArtMethodInInlineInfo(method);
CHECK_EQ(inline_info.EncodesArtMethod(), encode_art_method);
@@ -275,7 +275,6 @@
if (kVerifyStackMaps) {
size_t stack_map_index = stack_maps_.size();
- uint32_t depth = current_inline_infos_.size();
// We need to make copy of the current registers for later (when the check is run).
auto expected_dex_registers = std::make_shared<dchecked_vector<DexRegisterLocation>>(
current_dex_registers_.begin(), current_dex_registers_.end());
@@ -285,8 +284,9 @@
for (DexRegisterLocation reg : code_info.GetDexRegisterMapOf(stack_map)) {
CHECK_EQ((*expected_dex_registers)[expected_reg++], reg);
}
- for (uint32_t d = 0; d < depth; d++) {
- for (DexRegisterLocation reg : code_info.GetDexRegisterMapAtDepth(d, stack_map)) {
+ for (InlineInfo inline_info : code_info.GetInlineInfosOf(stack_map)) {
+ DexRegisterMap map = code_info.GetInlineDexRegisterMapOf(stack_map, inline_info);
+ for (DexRegisterLocation reg : map) {
CHECK_EQ((*expected_dex_registers)[expected_reg++], reg);
}
}
diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc
index 6241e0c..9ed90a4 100644
--- a/compiler/optimizing/stack_map_test.cc
+++ b/compiler/optimizing/stack_map_test.cc
@@ -193,13 +193,12 @@
ASSERT_EQ(-2, location1.GetValue());
ASSERT_TRUE(stack_map.HasInlineInfo());
- InlineInfo inline_info0 = code_info.GetInlineInfoAtDepth(stack_map, 0);
- InlineInfo inline_info1 = code_info.GetInlineInfoAtDepth(stack_map, 1);
- ASSERT_EQ(2u, code_info.GetInlineDepthOf(stack_map));
- ASSERT_EQ(3u, inline_info0.GetDexPc());
- ASSERT_EQ(2u, inline_info1.GetDexPc());
- ASSERT_TRUE(inline_info0.EncodesArtMethod());
- ASSERT_TRUE(inline_info1.EncodesArtMethod());
+ auto inline_infos = code_info.GetInlineInfosOf(stack_map);
+ ASSERT_EQ(2u, inline_infos.size());
+ ASSERT_EQ(3u, inline_infos[0].GetDexPc());
+ ASSERT_EQ(2u, inline_infos[1].GetDexPc());
+ ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
+ ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
}
// Second stack map.
@@ -614,19 +613,18 @@
ASSERT_EQ(0, dex_registers0[0].GetStackOffsetInBytes());
ASSERT_EQ(4, dex_registers0[1].GetConstant());
- InlineInfo if0_0 = ci.GetInlineInfoAtDepth(sm0, 0);
- InlineInfo if0_1 = ci.GetInlineInfoAtDepth(sm0, 1);
- ASSERT_EQ(2u, ci.GetInlineDepthOf(sm0));
- ASSERT_EQ(2u, if0_0.GetDexPc());
- ASSERT_TRUE(if0_0.EncodesArtMethod());
- ASSERT_EQ(3u, if0_1.GetDexPc());
- ASSERT_TRUE(if0_1.EncodesArtMethod());
+ auto inline_infos = ci.GetInlineInfosOf(sm0);
+ ASSERT_EQ(2u, inline_infos.size());
+ ASSERT_EQ(2u, inline_infos[0].GetDexPc());
+ ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
+ ASSERT_EQ(3u, inline_infos[1].GetDexPc());
+ ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
- DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, sm0);
+ DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm0, inline_infos[0]);
ASSERT_EQ(1u, dex_registers1.size());
ASSERT_EQ(8, dex_registers1[0].GetStackOffsetInBytes());
- DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, sm0);
+ DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm0, inline_infos[1]);
ASSERT_EQ(3u, dex_registers2.size());
ASSERT_EQ(16, dex_registers2[0].GetStackOffsetInBytes());
ASSERT_EQ(20, dex_registers2[1].GetConstant());
@@ -642,22 +640,20 @@
ASSERT_EQ(56, dex_registers0[0].GetStackOffsetInBytes());
ASSERT_EQ(0, dex_registers0[1].GetConstant());
- InlineInfo if1_0 = ci.GetInlineInfoAtDepth(sm1, 0);
- InlineInfo if1_1 = ci.GetInlineInfoAtDepth(sm1, 1);
- InlineInfo if1_2 = ci.GetInlineInfoAtDepth(sm1, 2);
- ASSERT_EQ(3u, ci.GetInlineDepthOf(sm1));
- ASSERT_EQ(2u, if1_0.GetDexPc());
- ASSERT_TRUE(if1_0.EncodesArtMethod());
- ASSERT_EQ(3u, if1_1.GetDexPc());
- ASSERT_TRUE(if1_1.EncodesArtMethod());
- ASSERT_EQ(5u, if1_2.GetDexPc());
- ASSERT_TRUE(if1_2.EncodesArtMethod());
+ auto inline_infos = ci.GetInlineInfosOf(sm1);
+ ASSERT_EQ(3u, inline_infos.size());
+ ASSERT_EQ(2u, inline_infos[0].GetDexPc());
+ ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
+ ASSERT_EQ(3u, inline_infos[1].GetDexPc());
+ ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
+ ASSERT_EQ(5u, inline_infos[2].GetDexPc());
+ ASSERT_TRUE(inline_infos[2].EncodesArtMethod());
- DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, sm1);
+ DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm1, inline_infos[0]);
ASSERT_EQ(1u, dex_registers1.size());
ASSERT_EQ(12, dex_registers1[0].GetStackOffsetInBytes());
- DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, sm1);
+ DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm1, inline_infos[1]);
ASSERT_EQ(3u, dex_registers2.size());
ASSERT_EQ(80, dex_registers2[0].GetStackOffsetInBytes());
ASSERT_EQ(10, dex_registers2[1].GetConstant());
@@ -684,22 +680,20 @@
ASSERT_EQ(56, dex_registers0[0].GetStackOffsetInBytes());
ASSERT_EQ(0, dex_registers0[1].GetConstant());
- InlineInfo if2_0 = ci.GetInlineInfoAtDepth(sm3, 0);
- InlineInfo if2_1 = ci.GetInlineInfoAtDepth(sm3, 1);
- InlineInfo if2_2 = ci.GetInlineInfoAtDepth(sm3, 2);
- ASSERT_EQ(3u, ci.GetInlineDepthOf(sm3));
- ASSERT_EQ(2u, if2_0.GetDexPc());
- ASSERT_TRUE(if2_0.EncodesArtMethod());
- ASSERT_EQ(5u, if2_1.GetDexPc());
- ASSERT_TRUE(if2_1.EncodesArtMethod());
- ASSERT_EQ(10u, if2_2.GetDexPc());
- ASSERT_TRUE(if2_2.EncodesArtMethod());
+ auto inline_infos = ci.GetInlineInfosOf(sm3);
+ ASSERT_EQ(3u, inline_infos.size());
+ ASSERT_EQ(2u, inline_infos[0].GetDexPc());
+ ASSERT_TRUE(inline_infos[0].EncodesArtMethod());
+ ASSERT_EQ(5u, inline_infos[1].GetDexPc());
+ ASSERT_TRUE(inline_infos[1].EncodesArtMethod());
+ ASSERT_EQ(10u, inline_infos[2].GetDexPc());
+ ASSERT_TRUE(inline_infos[2].EncodesArtMethod());
- DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, sm3);
+ DexRegisterMap dex_registers1 = ci.GetInlineDexRegisterMapOf(sm3, inline_infos[1]);
ASSERT_EQ(1u, dex_registers1.size());
ASSERT_EQ(2, dex_registers1[0].GetMachineRegister());
- DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, sm3);
+ DexRegisterMap dex_registers2 = ci.GetInlineDexRegisterMapOf(sm3, inline_infos[2]);
ASSERT_EQ(2u, dex_registers2.size());
ASSERT_FALSE(dex_registers2[0].IsLive());
ASSERT_EQ(3, dex_registers2[1].GetMachineRegister());
diff --git a/libartbase/base/bit_table.h b/libartbase/base/bit_table.h
index b0fc4d1..218203f 100644
--- a/libartbase/base/bit_table.h
+++ b/libartbase/base/bit_table.h
@@ -26,6 +26,7 @@
#include "base/bit_memory_region.h"
#include "base/casts.h"
+#include "base/iteration_range.h"
#include "base/memory_region.h"
#include "base/scoped_arena_containers.h"
#include "base/stl_util.h"
@@ -207,9 +208,18 @@
bool operator>=(const_iterator i) const { DCHECK(table_ == i.table_); return row_ >= i.row_; }
bool operator<(const_iterator i) const { DCHECK(table_ == i.table_); return row_ < i.row_; }
bool operator>(const_iterator i) const { DCHECK(table_ == i.table_); return row_ > i.row_; }
- Accessor operator*() { return Accessor(table_, row_); }
- Accessor operator->() { return Accessor(table_, row_); }
- Accessor operator[](size_t index) { return Accessor(table_, row_ + index); }
+ Accessor operator*() {
+ DCHECK_LT(row_, table_->NumRows());
+ return Accessor(table_, row_);
+ }
+ Accessor operator->() {
+ DCHECK_LT(row_, table_->NumRows());
+ return Accessor(table_, row_);
+ }
+ Accessor operator[](size_t index) {
+ DCHECK_LT(row_ + index, table_->NumRows());
+ return Accessor(table_, row_ + index);
+ }
private:
const BitTable* table_ = nullptr;
uint32_t row_ = 0;
@@ -236,6 +246,34 @@
return a + n;
}
+template<typename Accessor>
+class BitTableRange : public IterationRange<typename BitTable<Accessor>::const_iterator> {
+ public:
+ typedef typename BitTable<Accessor>::const_iterator const_iterator;
+
+ using IterationRange<const_iterator>::IterationRange;
+ BitTableRange() : IterationRange<const_iterator>(const_iterator(), const_iterator()) { }
+
+ bool empty() const { return this->begin() == this->end(); }
+ size_t size() const { return this->end() - this->begin(); }
+
+ Accessor operator[](size_t index) const {
+ const_iterator it = this->begin() + index;
+ DCHECK(it < this->end());
+ return *it;
+ }
+
+ Accessor back() const {
+ DCHECK(!empty());
+ return *(this->end() - 1);
+ }
+
+ void pop_back() {
+ DCHECK(!empty());
+ --this->last_;
+ }
+};
+
// Helper class for encoding BitTable. It can optionally de-duplicate the inputs.
template<uint32_t kNumColumns>
class BitTableBuilderBase {
diff --git a/libartbase/base/iteration_range.h b/libartbase/base/iteration_range.h
index 76049a7..cd87d85 100644
--- a/libartbase/base/iteration_range.h
+++ b/libartbase/base/iteration_range.h
@@ -39,9 +39,9 @@
iterator cbegin() const { return first_; }
iterator cend() const { return last_; }
- private:
- const iterator first_;
- const iterator last_;
+ protected:
+ iterator first_;
+ iterator last_;
};
template <typename Iter>
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 4a3d3b0..40ef10f 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -46,38 +46,38 @@
inline ArtMethod* GetResolvedMethod(ArtMethod* outer_method,
const MethodInfo& method_info,
- const CodeInfo& code_info,
- const StackMap& stack_map,
- uint8_t inlining_depth)
+ const BitTableRange<InlineInfo>& inline_infos)
REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(!outer_method->IsObsolete());
- InlineInfo inline_info = code_info.GetInlineInfoAtDepth(stack_map, inlining_depth);
// This method is being used by artQuickResolutionTrampoline, before it sets up
// the passed parameters in a GC friendly way. Therefore we must never be
// suspended while executing it.
ScopedAssertNoThreadSuspension sants(__FUNCTION__);
- if (inline_info.EncodesArtMethod()) {
- return inline_info.GetArtMethod();
- }
+ {
+ InlineInfo inline_info = inline_infos.back();
- uint32_t method_index = inline_info.GetMethodIndex(method_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);
- DCHECK_EQ(inlined_method->GetDexMethodIndex(), method_index);
- return inlined_method;
+ if (inline_info.EncodesArtMethod()) {
+ return inline_info.GetArtMethod();
+ }
+
+ uint32_t method_index = inline_info.GetMethodIndex(method_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);
+ DCHECK_EQ(inlined_method->GetDexMethodIndex(), method_index);
+ return inlined_method;
+ }
}
// Find which method did the call in the inlining hierarchy.
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
ArtMethod* method = outer_method;
- for (uint32_t depth = 0, end = inlining_depth + 1u; depth != end; ++depth) {
- inline_info = code_info.GetInlineInfoAtDepth(stack_map, depth);
+ for (InlineInfo inline_info : inline_infos) {
DCHECK(!inline_info.EncodesArtMethod());
DCHECK_NE(inline_info.GetDexPc(), static_cast<uint32_t>(-1));
- method_index = inline_info.GetMethodIndex(method_info);
+ uint32_t method_index = inline_info.GetMethodIndex(method_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 e71d1fa..9e6c642 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -205,9 +205,9 @@
MethodInfo method_info = current_code->GetOptimizedMethodInfo();
StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
DCHECK(stack_map.IsValid());
- uint32_t depth = code_info.GetInlineDepthOf(stack_map);
- if (depth != 0) {
- caller = GetResolvedMethod(outer_method, method_info, code_info, stack_map, depth - 1);
+ BitTableRange<InlineInfo> inline_infos = code_info.GetInlineInfosOf(stack_map);
+ if (!inline_infos.empty()) {
+ caller = GetResolvedMethod(outer_method, method_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 3ccfa55..c894406 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -345,10 +345,9 @@
CodeInfo code_info(current_code);
StackMap stack_map = code_info.GetStackMapForNativePcOffset(outer_pc_offset);
DCHECK(stack_map.IsValid());
- uint32_t depth = code_info.GetInlineDepthOf(stack_map);
- if (depth != 0) {
- InlineInfo inline_info = code_info.GetInlineInfoAtDepth(stack_map, depth - 1);
- return inline_info.GetDexPc();
+ BitTableRange<InlineInfo> inline_infos = code_info.GetInlineInfosOf(stack_map);
+ if (!inline_infos.empty()) {
+ return inline_infos.back().GetDexPc();
} else {
return stack_map.GetDexPc();
}
@@ -1236,37 +1235,35 @@
LOG(FATAL_WITHOUT_ABORT) << " instruction: " << DumpInstruction(outer_method, dex_pc);
ArtMethod* caller = outer_method;
- uint32_t depth = code_info.GetInlineDepthOf(stack_map);
- if (depth != 0) {
- for (size_t d = 0; d < depth; ++d) {
- InlineInfo inline_info = code_info.GetInlineInfoAtDepth(stack_map, d);
- const char* tag = "";
- dex_pc = inline_info.GetDexPc();
- if (inline_info.EncodesArtMethod()) {
- tag = "encoded ";
- caller = inline_info.GetArtMethod();
+ BitTableRange<InlineInfo> inline_infos = code_info.GetInlineInfosOf(stack_map);
+ for (InlineInfo inline_info : inline_infos) {
+ const char* tag = "";
+ dex_pc = inline_info.GetDexPc();
+ if (inline_info.EncodesArtMethod()) {
+ tag = "encoded ";
+ caller = inline_info.GetArtMethod();
+ } else {
+ uint32_t method_index = inline_info.GetMethodIndex(method_info);
+ if (dex_pc == static_cast<uint32_t>(-1)) {
+ tag = "special ";
+ CHECK(inline_info.Equals(inline_infos.back()));
+ caller = jni::DecodeArtMethod(WellKnownClasses::java_lang_String_charAt);
+ CHECK_EQ(caller->GetDexMethodIndex(), method_index);
} else {
- uint32_t method_index = inline_info.GetMethodIndex(method_info);
- if (dex_pc == static_cast<uint32_t>(-1)) {
- tag = "special ";
- CHECK_EQ(d + 1u, depth);
- caller = jni::DecodeArtMethod(WellKnownClasses::java_lang_String_charAt);
- CHECK_EQ(caller->GetDexMethodIndex(), method_index);
- } else {
- ObjPtr<mirror::DexCache> dex_cache = caller->GetDexCache();
- ObjPtr<mirror::ClassLoader> class_loader = caller->GetClassLoader();
- caller = class_linker->LookupResolvedMethod(method_index, dex_cache, class_loader);
- CHECK(caller != nullptr);
- }
+ ObjPtr<mirror::DexCache> dex_cache = caller->GetDexCache();
+ ObjPtr<mirror::ClassLoader> class_loader = caller->GetClassLoader();
+ caller = class_linker->LookupResolvedMethod(method_index, dex_cache, class_loader);
+ CHECK(caller != nullptr);
}
- LOG(FATAL_WITHOUT_ABORT) << "Inlined method #" << d << ": " << tag << caller->PrettyMethod()
- << " dex pc: " << dex_pc
- << " dex file: " << caller->GetDexFile()->GetLocation()
- << " class table: "
- << class_linker->ClassTableForClassLoader(caller->GetClassLoader());
- DumpB74410240ClassData(caller->GetDeclaringClass());
- LOG(FATAL_WITHOUT_ABORT) << " instruction: " << DumpInstruction(caller, dex_pc);
}
+ LOG(FATAL_WITHOUT_ABORT) << "InlineInfo #" << inline_info.Row()
+ << ": " << tag << caller->PrettyMethod()
+ << " dex pc: " << dex_pc
+ << " dex file: " << caller->GetDexFile()->GetLocation()
+ << " class table: "
+ << class_linker->ClassTableForClassLoader(caller->GetClassLoader());
+ DumpB74410240ClassData(caller->GetDeclaringClass());
+ LOG(FATAL_WITHOUT_ABORT) << " instruction: " << DumpInstruction(caller, dex_pc);
}
}
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 8b99b9f..28fcd87 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -404,7 +404,7 @@
uint32_t register_mask = code_info.GetRegisterMaskOf(stack_map);
BitMemoryRegion stack_mask = code_info.GetStackMaskOf(stack_map);
DexRegisterMap vreg_map = IsInInlinedFrame()
- ? code_info.GetDexRegisterMapAtDepth(GetCurrentInliningDepth() - 1, stack_map)
+ ? code_info.GetInlineDexRegisterMapOf(stack_map, GetCurrentInlinedFrame())
: code_info.GetDexRegisterMapOf(stack_map);
if (vreg_map.empty()) {
return;
diff --git a/runtime/stack.cc b/runtime/stack.cc
index a181bfe..97d077f 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -68,7 +68,6 @@
cur_oat_quick_method_header_(nullptr),
num_frames_(num_frames),
cur_depth_(0),
- current_inlining_depth_(0),
context_(context),
check_suspended_(check_suspended) {
if (check_suspended_) {
@@ -76,32 +75,15 @@
}
}
-static StackMap GetCurrentStackMap(CodeInfo& code_info,
- const OatQuickMethodHeader* method_header,
- uintptr_t cur_quick_frame_pc)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- uint32_t native_pc_offset = method_header->NativeQuickPcOffset(cur_quick_frame_pc);
- StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
- DCHECK(stack_map.IsValid());
- return stack_map;
-}
-
ArtMethod* StackVisitor::GetMethod() const {
if (cur_shadow_frame_ != nullptr) {
return cur_shadow_frame_->GetMethod();
} else if (cur_quick_frame_ != nullptr) {
if (IsInInlinedFrame()) {
- size_t depth_in_stack_map = current_inlining_depth_ - 1;
const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
- CodeInfo code_info(method_header);
- StackMap stack_map = GetCurrentStackMap(code_info, method_header, cur_quick_frame_pc_);
MethodInfo method_info = method_header->GetOptimizedMethodInfo();
DCHECK(walk_kind_ != StackWalkKind::kSkipInlinedFrames);
- return GetResolvedMethod(*GetCurrentQuickFrame(),
- method_info,
- code_info,
- stack_map,
- depth_in_stack_map);
+ return GetResolvedMethod(*GetCurrentQuickFrame(), method_info, current_inline_frames_);
} else {
return *cur_quick_frame_;
}
@@ -114,11 +96,7 @@
return cur_shadow_frame_->GetDexPC();
} else if (cur_quick_frame_ != nullptr) {
if (IsInInlinedFrame()) {
- const OatQuickMethodHeader* method_header = GetCurrentOatQuickMethodHeader();
- CodeInfo code_info(method_header);
- size_t depth_in_stack_map = current_inlining_depth_ - 1;
- StackMap stack_map = GetCurrentStackMap(code_info, method_header, cur_quick_frame_pc_);
- return code_info.GetInlineInfoAtDepth(stack_map, depth_in_stack_map).GetDexPc();
+ return current_inline_frames_.back().GetDexPc();
} else if (cur_oat_quick_method_header_ == nullptr) {
return dex::kDexNoIndex;
} else {
@@ -233,10 +211,9 @@
uint32_t native_pc_offset = method_header->NativeQuickPcOffset(cur_quick_frame_pc_);
StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
DCHECK(stack_map.IsValid());
- size_t depth_in_stack_map = current_inlining_depth_ - 1;
DexRegisterMap dex_register_map = IsInInlinedFrame()
- ? code_info.GetDexRegisterMapAtDepth(depth_in_stack_map, stack_map)
+ ? code_info.GetInlineDexRegisterMapOf(stack_map, current_inline_frames_.back())
: code_info.GetDexRegisterMapOf(stack_map);
if (dex_register_map.empty()) {
return false;
@@ -820,10 +797,10 @@
cur_oat_quick_method_header_->NativeQuickPcOffset(cur_quick_frame_pc_);
StackMap stack_map = code_info.GetStackMapForNativePcOffset(native_pc_offset);
if (stack_map.IsValid() && stack_map.HasInlineInfo()) {
- DCHECK_EQ(current_inlining_depth_, 0u);
- for (current_inlining_depth_ = code_info.GetInlineDepthOf(stack_map);
- current_inlining_depth_ != 0;
- --current_inlining_depth_) {
+ DCHECK_EQ(current_inline_frames_.size(), 0u);
+ for (current_inline_frames_ = code_info.GetInlineInfosOf(stack_map);
+ !current_inline_frames_.empty();
+ current_inline_frames_.pop_back()) {
bool should_continue = VisitFrame();
if (UNLIKELY(!should_continue)) {
return;
diff --git a/runtime/stack.h b/runtime/stack.h
index a16930b..02578d2 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -23,6 +23,7 @@
#include "base/macros.h"
#include "base/mutex.h"
#include "quick/quick_method_frame_info.h"
+#include "stack_map.h"
namespace art {
@@ -219,11 +220,11 @@
void SetReturnPc(uintptr_t new_ret_pc) REQUIRES_SHARED(Locks::mutator_lock_);
bool IsInInlinedFrame() const {
- return current_inlining_depth_ != 0;
+ return !current_inline_frames_.empty();
}
- size_t GetCurrentInliningDepth() const {
- return current_inlining_depth_;
+ InlineInfo GetCurrentInlinedFrame() const {
+ return current_inline_frames_.back();
}
uintptr_t GetCurrentQuickFramePc() const {
@@ -309,9 +310,9 @@
size_t num_frames_;
// Depth of the frame we're currently at.
size_t cur_depth_;
- // Current inlining depth of the method we are currently at.
- // 0 if there is no inlined frame.
- size_t current_inlining_depth_;
+ // Current inlined frames of the method we are currently at.
+ // We keep poping frames from the end as we visit the frames.
+ BitTableRange<InlineInfo> current_inline_frames_;
protected:
Context* const context_;
diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc
index a3c6e05..7e46eb7 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -232,8 +232,7 @@
// Display stack maps along with (live) Dex register maps.
if (verbose) {
- for (size_t i = 0; i < GetNumberOfStackMaps(); ++i) {
- StackMap stack_map = GetStackMapAt(i);
+ for (StackMap stack_map : stack_maps_) {
stack_map.Dump(vios, *this, method_info, code_offset, instruction_set);
}
}
@@ -259,9 +258,7 @@
}
vios->Stream() << ")\n";
code_info.GetDexRegisterMapOf(*this).Dump(vios);
- uint32_t depth = code_info.GetInlineDepthOf(*this);
- for (size_t d = 0; d < depth; d++) {
- InlineInfo inline_info = code_info.GetInlineInfoAtDepth(*this, d);
+ for (InlineInfo inline_info : code_info.GetInlineInfosOf(*this)) {
inline_info.Dump(vios, code_info, *this, method_info);
}
}
@@ -285,7 +282,7 @@
<< ", method_index=" << GetMethodIndex(method_info);
}
vios->Stream() << ")\n";
- code_info.GetDexRegisterMapAtDepth(depth, stack_map).Dump(vios);
+ code_info.GetInlineDexRegisterMapOf(stack_map, *this).Dump(vios);
}
} // namespace art
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index ad52f37..2f2053a 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -298,8 +298,8 @@
return BitsToBytesRoundUp(size_in_bits_);
}
- bool HasInlineInfo() const {
- return inline_infos_.NumRows() > 0;
+ ALWAYS_INLINE const BitTable<StackMap>& GetStackMaps() const {
+ return stack_maps_;
}
ALWAYS_INLINE StackMap GetStackMapAt(size_t index) const {
@@ -330,6 +330,10 @@
: dex_register_catalog_.GetRow(index).GetLocation();
}
+ bool HasInlineInfo() const {
+ return inline_infos_.NumRows() > 0;
+ }
+
uint32_t GetNumberOfStackMaps() const {
return stack_maps_.NumRows();
}
@@ -347,14 +351,18 @@
return DexRegisterMap(0, DexRegisterLocation::None());
}
- ALWAYS_INLINE DexRegisterMap GetDexRegisterMapAtDepth(uint8_t depth, StackMap stack_map) const {
+ ALWAYS_INLINE DexRegisterMap GetInlineDexRegisterMapOf(StackMap stack_map,
+ InlineInfo inline_info) const {
if (stack_map.HasDexRegisterMap()) {
+ DCHECK(stack_map.HasInlineInfoIndex());
+ uint32_t depth = inline_info.Row() - stack_map.GetInlineInfoIndex();
// The register counts are commutative and include all outer levels.
// This allows us to determine the range [first, last) in just two lookups.
// If we are at depth 0 (the first inlinee), the count from the main method is used.
- uint32_t first = (depth == 0) ? number_of_dex_registers_
- : GetInlineInfoAtDepth(stack_map, depth - 1).GetNumberOfDexRegisters();
- uint32_t last = GetInlineInfoAtDepth(stack_map, depth).GetNumberOfDexRegisters();
+ uint32_t first = (depth == 0)
+ ? number_of_dex_registers_
+ : inline_infos_.GetRow(inline_info.Row() - 1).GetNumberOfDexRegisters();
+ uint32_t last = inline_info.GetNumberOfDexRegisters();
DexRegisterMap map(last - first, DexRegisterLocation::Invalid());
DecodeDexRegisterMap(stack_map.Row(), first, &map);
return map;
@@ -362,28 +370,20 @@
return DexRegisterMap(0, DexRegisterLocation::None());
}
- InlineInfo GetInlineInfo(size_t index) const {
- return inline_infos_.GetRow(index);
- }
-
- uint32_t GetInlineDepthOf(StackMap stack_map) const {
- uint32_t depth = 0;
+ BitTableRange<InlineInfo> GetInlineInfosOf(StackMap stack_map) const {
uint32_t index = stack_map.GetInlineInfoIndex();
if (index != StackMap::kNoValue) {
- while (GetInlineInfo(index + depth++).GetIsLast() == InlineInfo::kMore) { }
+ auto begin = inline_infos_.begin() + index;
+ auto end = begin;
+ while ((*end++).GetIsLast() == InlineInfo::kMore) { }
+ return BitTableRange<InlineInfo>(begin, end);
+ } else {
+ return BitTableRange<InlineInfo>();
}
- return depth;
- }
-
- InlineInfo GetInlineInfoAtDepth(StackMap stack_map, uint32_t depth) const {
- DCHECK(stack_map.HasInlineInfo());
- DCHECK_LT(depth, GetInlineDepthOf(stack_map));
- return GetInlineInfo(stack_map.GetInlineInfoIndex() + depth);
}
StackMap GetStackMapForDexPc(uint32_t dex_pc) const {
- for (size_t i = 0, e = GetNumberOfStackMaps(); i < e; ++i) {
- StackMap stack_map = GetStackMapAt(i);
+ for (StackMap stack_map : stack_maps_) {
if (stack_map.GetDexPc() == dex_pc && stack_map.GetKind() != StackMap::Kind::Debug) {
return stack_map;
}
@@ -403,8 +403,7 @@
}
StackMap GetOsrStackMapForDexPc(uint32_t dex_pc) const {
- for (size_t i = 0, e = GetNumberOfStackMaps(); i < e; ++i) {
- StackMap stack_map = GetStackMapAt(i);
+ for (StackMap stack_map : stack_maps_) {
if (stack_map.GetDexPc() == dex_pc && stack_map.GetKind() == StackMap::Kind::OSR) {
return stack_map;
}
@@ -415,8 +414,7 @@
StackMap GetStackMapForNativePcOffset(uint32_t pc, InstructionSet isa = kRuntimeISA) const;
InvokeInfo GetInvokeInfoForNativePcOffset(uint32_t native_pc_offset) {
- for (size_t index = 0; index < invoke_infos_.NumRows(); index++) {
- InvokeInfo item = GetInvokeInfo(index);
+ for (InvokeInfo item : invoke_infos_) {
if (item.GetNativePcOffset(kRuntimeISA) == native_pc_offset) {
return item;
}