diff options
author | 2018-06-13 18:20:45 +0100 | |
---|---|---|
committer | 2018-06-14 12:31:44 +0100 | |
commit | e1402125e8363b49e176c6072893d1c110a05d2f (patch) | |
tree | 44ec055be78cdcb8086a598cbf791f8c4627e157 | |
parent | 86decb6a3e3ebba8c3c67bfd25c12d9a85794f65 (diff) |
Move some helper methods to DexRegisterLocation.
Test: test-art-host-gtest-stack_map_test
Change-Id: I0abab008159db023d531df69214cd3bb8c0639bd
-rw-r--r-- | compiler/debug/elf_debug_loc_writer.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.cc | 64 | ||||
-rw-r--r-- | compiler/optimizing/stack_map_stream.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/stack_map_stream.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/stack_map_test.cc | 132 | ||||
-rw-r--r-- | runtime/Android.bp | 1 | ||||
-rw-r--r-- | runtime/check_reference_map_visitor.h | 4 | ||||
-rw-r--r-- | runtime/dex_register_location.cc | 50 | ||||
-rw-r--r-- | runtime/dex_register_location.h | 26 | ||||
-rw-r--r-- | runtime/jit/jit.cc | 4 | ||||
-rw-r--r-- | runtime/quick_exception_handler.cc | 18 | ||||
-rw-r--r-- | runtime/stack.cc | 12 | ||||
-rw-r--r-- | runtime/stack_map.cc | 41 | ||||
-rw-r--r-- | runtime/stack_map.h | 70 | ||||
-rw-r--r-- | runtime/thread.cc | 2 |
15 files changed, 212 insertions, 224 deletions
diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h index 4009acb992..b663291b4d 100644 --- a/compiler/debug/elf_debug_loc_writer.h +++ b/compiler/debug/elf_debug_loc_writer.h @@ -149,9 +149,9 @@ static std::vector<VariableLocation> GetVariableLocations( DexRegisterMap dex_register_map = dex_register_maps[stack_map_index]; DCHECK(!dex_register_map.empty()); CodeItemDataAccessor accessor(*method_info->dex_file, method_info->code_item); - reg_lo = dex_register_map.GetDexRegisterLocation(vreg); + reg_lo = dex_register_map[vreg]; if (is64bitValue) { - reg_hi = dex_register_map.GetDexRegisterLocation(vreg + 1); + reg_hi = dex_register_map[vreg + 1]; } // Add location entry for this address range. diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index b3feb787a9..eea146e9f9 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -1294,50 +1294,45 @@ void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slo continue; } + using Kind = DexRegisterLocation::Kind; Location location = environment->GetLocationAt(i); switch (location.GetKind()) { case Location::kConstant: { DCHECK_EQ(current, location.GetConstant()); if (current->IsLongConstant()) { int64_t value = current->AsLongConstant()->GetValue(); - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kConstant, Low32Bits(value)); - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kConstant, High32Bits(value)); + stack_map_stream->AddDexRegisterEntry(Kind::kConstant, Low32Bits(value)); + stack_map_stream->AddDexRegisterEntry(Kind::kConstant, High32Bits(value)); ++i; DCHECK_LT(i, environment_size); } else if (current->IsDoubleConstant()) { int64_t value = bit_cast<int64_t, double>(current->AsDoubleConstant()->GetValue()); - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kConstant, Low32Bits(value)); - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kConstant, High32Bits(value)); + stack_map_stream->AddDexRegisterEntry(Kind::kConstant, Low32Bits(value)); + stack_map_stream->AddDexRegisterEntry(Kind::kConstant, High32Bits(value)); ++i; DCHECK_LT(i, environment_size); } else if (current->IsIntConstant()) { int32_t value = current->AsIntConstant()->GetValue(); - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, value); + stack_map_stream->AddDexRegisterEntry(Kind::kConstant, value); } else if (current->IsNullConstant()) { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, 0); + stack_map_stream->AddDexRegisterEntry(Kind::kConstant, 0); } else { DCHECK(current->IsFloatConstant()) << current->DebugName(); int32_t value = bit_cast<int32_t, float>(current->AsFloatConstant()->GetValue()); - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kConstant, value); + stack_map_stream->AddDexRegisterEntry(Kind::kConstant, value); } break; } case Location::kStackSlot: { - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kInStack, location.GetStackIndex()); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, location.GetStackIndex()); break; } case Location::kDoubleStackSlot: { + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, location.GetStackIndex()); stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kInStack, location.GetStackIndex()); - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kInStack, location.GetHighStackIndex(kVRegSize)); + Kind::kInStack, location.GetHighStackIndex(kVRegSize)); ++i; DCHECK_LT(i, environment_size); break; @@ -1347,17 +1342,16 @@ void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slo int id = location.reg(); if (slow_path != nullptr && slow_path->IsCoreRegisterSaved(id)) { uint32_t offset = slow_path->GetStackOffsetOfCoreRegister(id); - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, offset); if (current->GetType() == DataType::Type::kInt64) { - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kInStack, offset + kVRegSize); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, offset + kVRegSize); ++i; DCHECK_LT(i, environment_size); } } else { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, id); + stack_map_stream->AddDexRegisterEntry(Kind::kInRegister, id); if (current->GetType() == DataType::Type::kInt64) { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegisterHigh, id); + stack_map_stream->AddDexRegisterEntry(Kind::kInRegisterHigh, id); ++i; DCHECK_LT(i, environment_size); } @@ -1369,18 +1363,16 @@ void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slo int id = location.reg(); if (slow_path != nullptr && slow_path->IsFpuRegisterSaved(id)) { uint32_t offset = slow_path->GetStackOffsetOfFpuRegister(id); - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, offset); if (current->GetType() == DataType::Type::kFloat64) { - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kInStack, offset + kVRegSize); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, offset + kVRegSize); ++i; DCHECK_LT(i, environment_size); } } else { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, id); + stack_map_stream->AddDexRegisterEntry(Kind::kInFpuRegister, id); if (current->GetType() == DataType::Type::kFloat64) { - stack_map_stream->AddDexRegisterEntry( - DexRegisterLocation::Kind::kInFpuRegisterHigh, id); + stack_map_stream->AddDexRegisterEntry(Kind::kInFpuRegisterHigh, id); ++i; DCHECK_LT(i, environment_size); } @@ -1393,16 +1385,16 @@ void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slo int high = location.high(); if (slow_path != nullptr && slow_path->IsFpuRegisterSaved(low)) { uint32_t offset = slow_path->GetStackOffsetOfFpuRegister(low); - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, offset); } else { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, low); + stack_map_stream->AddDexRegisterEntry(Kind::kInFpuRegister, low); } if (slow_path != nullptr && slow_path->IsFpuRegisterSaved(high)) { uint32_t offset = slow_path->GetStackOffsetOfFpuRegister(high); - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, offset); ++i; } else { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInFpuRegister, high); + stack_map_stream->AddDexRegisterEntry(Kind::kInFpuRegister, high); ++i; } DCHECK_LT(i, environment_size); @@ -1414,15 +1406,15 @@ void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slo int high = location.high(); if (slow_path != nullptr && slow_path->IsCoreRegisterSaved(low)) { uint32_t offset = slow_path->GetStackOffsetOfCoreRegister(low); - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, offset); } else { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, low); + stack_map_stream->AddDexRegisterEntry(Kind::kInRegister, low); } if (slow_path != nullptr && slow_path->IsCoreRegisterSaved(high)) { uint32_t offset = slow_path->GetStackOffsetOfCoreRegister(high); - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInStack, offset); + stack_map_stream->AddDexRegisterEntry(Kind::kInStack, offset); } else { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kInRegister, high); + stack_map_stream->AddDexRegisterEntry(Kind::kInRegister, high); } ++i; DCHECK_LT(i, environment_size); @@ -1430,7 +1422,7 @@ void CodeGenerator::EmitEnvironment(HEnvironment* environment, SlowPathCode* slo } case Location::kInvalid: { - stack_map_stream->AddDexRegisterEntry(DexRegisterLocation::Kind::kNone, 0); + stack_map_stream->AddDexRegisterEntry(Kind::kNone, 0); break; } diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc index 094b75de69..2bfa430196 100644 --- a/compiler/optimizing/stack_map_stream.cc +++ b/compiler/optimizing/stack_map_stream.cc @@ -114,10 +114,6 @@ void StackMapStream::EndStackMapEntry() { stack_maps_.Add(current_stack_map_); } -void StackMapStream::AddDexRegisterEntry(DexRegisterLocation::Kind kind, int32_t value) { - current_dex_registers_.push_back(DexRegisterLocation(kind, value)); -} - void StackMapStream::AddInvoke(InvokeType invoke_type, uint32_t dex_method_index) { uint32_t packed_native_pc = current_stack_map_.packed_native_pc; size_t invoke_info_index = invoke_infos_.size(); diff --git a/compiler/optimizing/stack_map_stream.h b/compiler/optimizing/stack_map_stream.h index 02fb6cb434..e3ae8a2178 100644 --- a/compiler/optimizing/stack_map_stream.h +++ b/compiler/optimizing/stack_map_stream.h @@ -69,7 +69,9 @@ class StackMapStream : public ValueObject { uint8_t inlining_depth); void EndStackMapEntry(); - void AddDexRegisterEntry(DexRegisterLocation::Kind kind, int32_t value); + void AddDexRegisterEntry(DexRegisterLocation::Kind kind, int32_t value) { + current_dex_registers_.push_back(DexRegisterLocation(kind, value)); + } void AddInvoke(InvokeType type, uint32_t dex_method_index); diff --git a/compiler/optimizing/stack_map_test.cc b/compiler/optimizing/stack_map_test.cc index 9adc4c5ba6..56717b52cd 100644 --- a/compiler/optimizing/stack_map_test.cc +++ b/compiler/optimizing/stack_map_test.cc @@ -83,14 +83,14 @@ TEST(StackMapTest, Test1) { ASSERT_TRUE(stack_map.HasDexRegisterMap()); DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map); ASSERT_EQ(number_of_dex_registers, dex_register_map.size()); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); + ASSERT_TRUE(dex_register_map[0].IsLive()); + ASSERT_TRUE(dex_register_map[1].IsLive()); ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters()); - ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(0)); - ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(1)); - ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(0)); - ASSERT_EQ(-2, dex_register_map.GetConstant(1)); + ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind()); + ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind()); + ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes()); + ASSERT_EQ(-2, dex_register_map[1].GetConstant()); DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0); DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1); @@ -172,14 +172,14 @@ TEST(StackMapTest, Test2) { ASSERT_TRUE(stack_map.HasDexRegisterMap()); DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map); ASSERT_EQ(number_of_dex_registers, dex_register_map.size()); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); + ASSERT_TRUE(dex_register_map[0].IsLive()); + ASSERT_TRUE(dex_register_map[1].IsLive()); ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters()); - ASSERT_EQ(Kind::kInStack, dex_register_map.GetLocationKind(0)); - ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(1)); - ASSERT_EQ(0, dex_register_map.GetStackOffsetInBytes(0)); - ASSERT_EQ(-2, dex_register_map.GetConstant(1)); + ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind()); + ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind()); + ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes()); + ASSERT_EQ(-2, dex_register_map[1].GetConstant()); DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0); DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1); @@ -212,14 +212,14 @@ TEST(StackMapTest, Test2) { ASSERT_TRUE(stack_map.HasDexRegisterMap()); DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map); ASSERT_EQ(number_of_dex_registers, dex_register_map.size()); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); + ASSERT_TRUE(dex_register_map[0].IsLive()); + ASSERT_TRUE(dex_register_map[1].IsLive()); ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters()); - ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(0)); - ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(1)); - ASSERT_EQ(18, dex_register_map.GetMachineRegister(0)); - ASSERT_EQ(3, dex_register_map.GetMachineRegister(1)); + ASSERT_EQ(Kind::kInRegister, dex_register_map[0].GetKind()); + ASSERT_EQ(Kind::kInFpuRegister, dex_register_map[1].GetKind()); + ASSERT_EQ(18, dex_register_map[0].GetMachineRegister()); + ASSERT_EQ(3, dex_register_map[1].GetMachineRegister()); DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(2); DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(3); @@ -245,14 +245,14 @@ TEST(StackMapTest, Test2) { ASSERT_TRUE(stack_map.HasDexRegisterMap()); DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map); ASSERT_EQ(number_of_dex_registers, dex_register_map.size()); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); + ASSERT_TRUE(dex_register_map[0].IsLive()); + ASSERT_TRUE(dex_register_map[1].IsLive()); ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters()); - ASSERT_EQ(Kind::kInRegister, dex_register_map.GetLocationKind(0)); - ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map.GetLocationKind(1)); - ASSERT_EQ(6, dex_register_map.GetMachineRegister(0)); - ASSERT_EQ(8, dex_register_map.GetMachineRegister(1)); + ASSERT_EQ(Kind::kInRegister, dex_register_map[0].GetKind()); + ASSERT_EQ(Kind::kInRegisterHigh, dex_register_map[1].GetKind()); + ASSERT_EQ(6, dex_register_map[0].GetMachineRegister()); + ASSERT_EQ(8, dex_register_map[1].GetMachineRegister()); DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(4); DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(5); @@ -278,14 +278,14 @@ TEST(StackMapTest, Test2) { ASSERT_TRUE(stack_map.HasDexRegisterMap()); DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map); ASSERT_EQ(number_of_dex_registers, dex_register_map.size()); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(0)); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); + ASSERT_TRUE(dex_register_map[0].IsLive()); + ASSERT_TRUE(dex_register_map[1].IsLive()); ASSERT_EQ(2u, dex_register_map.GetNumberOfLiveDexRegisters()); - ASSERT_EQ(Kind::kInFpuRegister, dex_register_map.GetLocationKind(0)); - ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map.GetLocationKind(1)); - ASSERT_EQ(3, dex_register_map.GetMachineRegister(0)); - ASSERT_EQ(1, dex_register_map.GetMachineRegister(1)); + ASSERT_EQ(Kind::kInFpuRegister, dex_register_map[0].GetKind()); + ASSERT_EQ(Kind::kInFpuRegisterHigh, dex_register_map[1].GetKind()); + ASSERT_EQ(3, dex_register_map[0].GetMachineRegister()); + ASSERT_EQ(1, dex_register_map[1].GetMachineRegister()); DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(3); DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(6); @@ -344,14 +344,14 @@ TEST(StackMapTest, TestDeduplicateInlineInfoDexRegisterMap) { ASSERT_TRUE(stack_map.HasDexRegisterMap()); DexRegisterMap map(code_info.GetDexRegisterMapOf(stack_map)); ASSERT_EQ(number_of_dex_registers, map.size()); - ASSERT_TRUE(map.IsDexRegisterLive(0)); - ASSERT_TRUE(map.IsDexRegisterLive(1)); + ASSERT_TRUE(map[0].IsLive()); + ASSERT_TRUE(map[1].IsLive()); ASSERT_EQ(2u, map.GetNumberOfLiveDexRegisters()); - ASSERT_EQ(Kind::kInStack, map.GetLocationKind(0)); - ASSERT_EQ(Kind::kConstant, map.GetLocationKind(1)); - ASSERT_EQ(0, map.GetStackOffsetInBytes(0)); - ASSERT_EQ(-2, map.GetConstant(1)); + ASSERT_EQ(Kind::kInStack, map[0].GetKind()); + ASSERT_EQ(Kind::kConstant, map[1].GetKind()); + ASSERT_EQ(0, map[0].GetStackOffsetInBytes()); + ASSERT_EQ(-2, map[1].GetConstant()); DexRegisterLocation location0 = code_info.GetDexRegisterCatalogEntry(0); DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(1); @@ -396,13 +396,13 @@ TEST(StackMapTest, TestNonLiveDexRegisters) { ASSERT_TRUE(stack_map.HasDexRegisterMap()); DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map); ASSERT_EQ(number_of_dex_registers, dex_register_map.size()); - ASSERT_FALSE(dex_register_map.IsDexRegisterLive(0)); - ASSERT_TRUE(dex_register_map.IsDexRegisterLive(1)); + ASSERT_FALSE(dex_register_map[0].IsLive()); + ASSERT_TRUE(dex_register_map[1].IsLive()); ASSERT_EQ(1u, dex_register_map.GetNumberOfLiveDexRegisters()); - ASSERT_EQ(Kind::kNone, dex_register_map.GetLocationKind(0)); - ASSERT_EQ(Kind::kConstant, dex_register_map.GetLocationKind(1)); - ASSERT_EQ(-2, dex_register_map.GetConstant(1)); + ASSERT_EQ(Kind::kNone, dex_register_map[0].GetKind()); + ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind()); + ASSERT_EQ(-2, dex_register_map[1].GetConstant()); DexRegisterLocation location1 = code_info.GetDexRegisterCatalogEntry(0); ASSERT_EQ(Kind::kConstant, location1.GetKind()); @@ -446,22 +446,22 @@ TEST(StackMapTest, TestShareDexRegisterMap) { StackMap sm0 = ci.GetStackMapAt(0); DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0); ASSERT_EQ(number_of_dex_registers, dex_registers0.size()); - ASSERT_EQ(0, dex_registers0.GetMachineRegister(0)); - ASSERT_EQ(-2, dex_registers0.GetConstant(1)); + ASSERT_EQ(0, dex_registers0[0].GetMachineRegister()); + ASSERT_EQ(-2, dex_registers0[1].GetConstant()); // Verify second stack map. StackMap sm1 = ci.GetStackMapAt(1); DexRegisterMap dex_registers1 = ci.GetDexRegisterMapOf(sm1); ASSERT_EQ(number_of_dex_registers, dex_registers1.size()); - ASSERT_EQ(0, dex_registers1.GetMachineRegister(0)); - ASSERT_EQ(-2, dex_registers1.GetConstant(1)); + ASSERT_EQ(0, dex_registers1[0].GetMachineRegister()); + ASSERT_EQ(-2, dex_registers1[1].GetConstant()); // Verify third stack map. StackMap sm2 = ci.GetStackMapAt(2); DexRegisterMap dex_registers2 = ci.GetDexRegisterMapOf(sm2); ASSERT_EQ(number_of_dex_registers, dex_registers2.size()); - ASSERT_EQ(2, dex_registers2.GetMachineRegister(0)); - ASSERT_EQ(-2, dex_registers2.GetConstant(1)); + ASSERT_EQ(2, dex_registers2[0].GetMachineRegister()); + ASSERT_EQ(-2, dex_registers2[1].GetConstant()); // Verify dex register mask offsets. ASSERT_FALSE(sm1.HasDexRegisterMaskIndex()); // No delta. @@ -597,8 +597,8 @@ TEST(StackMapTest, InlineTest) { DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm0); ASSERT_EQ(2u, dex_registers0.size()); - ASSERT_EQ(0, dex_registers0.GetStackOffsetInBytes(0)); - ASSERT_EQ(4, dex_registers0.GetConstant(1)); + 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); @@ -610,13 +610,13 @@ TEST(StackMapTest, InlineTest) { DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, sm0); ASSERT_EQ(1u, dex_registers1.size()); - ASSERT_EQ(8, dex_registers1.GetStackOffsetInBytes(0)); + ASSERT_EQ(8, dex_registers1[0].GetStackOffsetInBytes()); DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, sm0); ASSERT_EQ(3u, dex_registers2.size()); - ASSERT_EQ(16, dex_registers2.GetStackOffsetInBytes(0)); - ASSERT_EQ(20, dex_registers2.GetConstant(1)); - ASSERT_EQ(15, dex_registers2.GetMachineRegister(2)); + ASSERT_EQ(16, dex_registers2[0].GetStackOffsetInBytes()); + ASSERT_EQ(20, dex_registers2[1].GetConstant()); + ASSERT_EQ(15, dex_registers2[2].GetMachineRegister()); } { @@ -625,8 +625,8 @@ TEST(StackMapTest, InlineTest) { DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm1); ASSERT_EQ(2u, dex_registers0.size()); - ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0)); - ASSERT_EQ(0, dex_registers0.GetConstant(1)); + 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); @@ -641,13 +641,13 @@ TEST(StackMapTest, InlineTest) { DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(0, sm1); ASSERT_EQ(1u, dex_registers1.size()); - ASSERT_EQ(12, dex_registers1.GetStackOffsetInBytes(0)); + ASSERT_EQ(12, dex_registers1[0].GetStackOffsetInBytes()); DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(1, sm1); ASSERT_EQ(3u, dex_registers2.size()); - ASSERT_EQ(80, dex_registers2.GetStackOffsetInBytes(0)); - ASSERT_EQ(10, dex_registers2.GetConstant(1)); - ASSERT_EQ(5, dex_registers2.GetMachineRegister(2)); + ASSERT_EQ(80, dex_registers2[0].GetStackOffsetInBytes()); + ASSERT_EQ(10, dex_registers2[1].GetConstant()); + ASSERT_EQ(5, dex_registers2[2].GetMachineRegister()); } { @@ -656,8 +656,8 @@ TEST(StackMapTest, InlineTest) { DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm2); ASSERT_EQ(2u, dex_registers0.size()); - ASSERT_FALSE(dex_registers0.IsDexRegisterLive(0)); - ASSERT_EQ(4, dex_registers0.GetConstant(1)); + ASSERT_FALSE(dex_registers0[0].IsLive()); + ASSERT_EQ(4, dex_registers0[1].GetConstant()); ASSERT_FALSE(sm2.HasInlineInfo()); } @@ -667,8 +667,8 @@ TEST(StackMapTest, InlineTest) { DexRegisterMap dex_registers0 = ci.GetDexRegisterMapOf(sm3); ASSERT_EQ(2u, dex_registers0.size()); - ASSERT_EQ(56, dex_registers0.GetStackOffsetInBytes(0)); - ASSERT_EQ(0, dex_registers0.GetConstant(1)); + 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); @@ -683,12 +683,12 @@ TEST(StackMapTest, InlineTest) { DexRegisterMap dex_registers1 = ci.GetDexRegisterMapAtDepth(1, sm3); ASSERT_EQ(1u, dex_registers1.size()); - ASSERT_EQ(2, dex_registers1.GetMachineRegister(0)); + ASSERT_EQ(2, dex_registers1[0].GetMachineRegister()); DexRegisterMap dex_registers2 = ci.GetDexRegisterMapAtDepth(2, sm3); ASSERT_EQ(2u, dex_registers2.size()); - ASSERT_FALSE(dex_registers2.IsDexRegisterLive(0)); - ASSERT_EQ(3, dex_registers2.GetMachineRegister(1)); + ASSERT_FALSE(dex_registers2[0].IsLive()); + ASSERT_EQ(3, dex_registers2[1].GetMachineRegister()); } } diff --git a/runtime/Android.bp b/runtime/Android.bp index 777a1fc5ee..1168798f38 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -47,6 +47,7 @@ libart_cc_defaults { "debug_print.cc", "debugger.cc", "dex/dex_file_annotations.cc", + "dex_register_location.cc", "dex_to_dex_decompiler.cc", "elf_file.cc", "exec_utils.cc", diff --git a/runtime/check_reference_map_visitor.h b/runtime/check_reference_map_visitor.h index 8a2a70e7ab..8f9f45c30b 100644 --- a/runtime/check_reference_map_visitor.h +++ b/runtime/check_reference_map_visitor.h @@ -75,7 +75,7 @@ class CheckReferenceMapVisitor : public StackVisitor { for (int i = 0; i < number_of_references; ++i) { int reg = registers[i]; CHECK_LT(reg, accessor.RegistersSize()); - DexRegisterLocation location = dex_register_map.GetDexRegisterLocation(reg); + DexRegisterLocation location = dex_register_map[reg]; switch (location.GetKind()) { case DexRegisterLocation::Kind::kNone: // Not set, should not be a reference. @@ -98,7 +98,7 @@ class CheckReferenceMapVisitor : public StackVisitor { CHECK_EQ(location.GetValue(), 0); break; default: - LOG(FATAL) << "Unexpected location kind " << location.GetInternalKind(); + LOG(FATAL) << "Unexpected location kind " << location.GetKind(); } } } diff --git a/runtime/dex_register_location.cc b/runtime/dex_register_location.cc new file mode 100644 index 0000000000..f3b09733b9 --- /dev/null +++ b/runtime/dex_register_location.cc @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2018 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. + */ + +#include "dex_register_location.h" + +namespace art { + +std::ostream& operator<<(std::ostream& stream, DexRegisterLocation::Kind kind) { + return stream << "Kind<" << static_cast<int32_t>(kind) << ">"; +} + +std::ostream& operator<<(std::ostream& stream, const DexRegisterLocation& reg) { + using Kind = DexRegisterLocation::Kind; + switch (reg.GetKind()) { + case Kind::kInvalid: + return stream << "Invalid"; + case Kind::kNone: + return stream << "None"; + case Kind::kInStack: + return stream << "sp+" << reg.GetValue(); + case Kind::kInRegister: + return stream << "r" << reg.GetValue(); + case Kind::kInRegisterHigh: + return stream << "r" << reg.GetValue() << "/hi"; + case Kind::kInFpuRegister: + return stream << "f" << reg.GetValue(); + case Kind::kInFpuRegisterHigh: + return stream << "f" << reg.GetValue() << "/hi"; + case Kind::kConstant: + return stream << "#" << reg.GetValue(); + default: + return stream << "DexRegisterLocation(" << static_cast<uint32_t>(reg.GetKind()) + << "," << reg.GetValue() << ")"; + } +} + +} // namespace art diff --git a/runtime/dex_register_location.h b/runtime/dex_register_location.h index a20dccbc12..98b4d41e2d 100644 --- a/runtime/dex_register_location.h +++ b/runtime/dex_register_location.h @@ -48,9 +48,6 @@ class DexRegisterLocation { Kind GetKind() const { return kind_; } - // TODO: Remove. - Kind GetInternalKind() const { return kind_; } - int32_t GetValue() const { return value_; } bool operator==(DexRegisterLocation other) const { @@ -61,6 +58,24 @@ class DexRegisterLocation { return !(*this == other); } + int32_t GetStackOffsetInBytes() const { + DCHECK(kind_ == Kind::kInStack); + return value_; + } + + int32_t GetConstant() const { + DCHECK(kind_ == Kind::kConstant); + return value_; + } + + int32_t GetMachineRegister() const { + DCHECK(kind_ == Kind::kInRegister || + kind_ == Kind::kInRegisterHigh || + kind_ == Kind::kInFpuRegister || + kind_ == Kind::kInFpuRegisterHigh); + return value_; + } + private: DexRegisterLocation() {} @@ -70,9 +85,8 @@ class DexRegisterLocation { friend class DexRegisterMap; // Allow creation of uninitialized array of locations. }; -static inline std::ostream& operator<<(std::ostream& stream, DexRegisterLocation::Kind kind) { - return stream << "Kind<" << static_cast<int32_t>(kind) << ">"; -} +std::ostream& operator<<(std::ostream& stream, DexRegisterLocation::Kind kind); +std::ostream& operator<<(std::ostream& stream, const DexRegisterLocation& reg); } // namespace art diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc index 0a8e0cd64f..5e736035f8 100644 --- a/runtime/jit/jit.cc +++ b/runtime/jit/jit.cc @@ -515,7 +515,7 @@ bool Jit::MaybeDoOnStackReplacement(Thread* thread, } else { DCHECK_EQ(vreg_map.size(), number_of_vregs); for (uint16_t vreg = 0; vreg < number_of_vregs; ++vreg) { - DexRegisterLocation::Kind location = vreg_map.GetLocationKind(vreg); + DexRegisterLocation::Kind location = vreg_map[vreg].GetKind(); if (location == DexRegisterLocation::Kind::kNone) { // Dex register is dead or uninitialized. continue; @@ -529,7 +529,7 @@ bool Jit::MaybeDoOnStackReplacement(Thread* thread, DCHECK_EQ(location, DexRegisterLocation::Kind::kInStack); int32_t vreg_value = shadow_frame->GetVReg(vreg); - int32_t slot_offset = vreg_map.GetStackOffsetInBytes(vreg); + int32_t slot_offset = vreg_map[vreg].GetStackOffsetInBytes(); DCHECK_LT(slot_offset, static_cast<int32_t>(frame_size)); DCHECK_GT(slot_offset, 0); (reinterpret_cast<int32_t*>(memory))[slot_offset / sizeof(int32_t)] = vreg_value; diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index cf1cbe7f7b..8b99b9f9c8 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -245,7 +245,7 @@ void QuickExceptionHandler::SetCatchEnvironmentForOptimizedHandler(StackVisitor* // Copy values between them. for (uint16_t vreg = 0; vreg < number_of_vregs; ++vreg) { - DexRegisterLocation::Kind catch_location = catch_vreg_map.GetLocationKind(vreg); + DexRegisterLocation::Kind catch_location = catch_vreg_map[vreg].GetKind(); if (catch_location == DexRegisterLocation::Kind::kNone) { continue; } @@ -253,7 +253,7 @@ void QuickExceptionHandler::SetCatchEnvironmentForOptimizedHandler(StackVisitor* // Get vreg value from its current location. uint32_t vreg_value; - VRegKind vreg_kind = ToVRegKind(throw_vreg_map.GetLocationKind(vreg)); + VRegKind vreg_kind = ToVRegKind(throw_vreg_map[vreg].GetKind()); bool get_vreg_success = stack_visitor->GetVReg(stack_visitor->GetMethod(), vreg, vreg_kind, @@ -264,7 +264,7 @@ void QuickExceptionHandler::SetCatchEnvironmentForOptimizedHandler(StackVisitor* << "native_pc_offset=" << stack_visitor->GetNativePcOffset() << ")"; // Copy value to the catch phi's stack slot. - int32_t slot_offset = catch_vreg_map.GetStackOffsetInBytes(vreg); + int32_t slot_offset = catch_vreg_map[vreg].GetStackOffsetInBytes(); ArtMethod** frame_top = stack_visitor->GetCurrentQuickFrame(); uint8_t* slot_address = reinterpret_cast<uint8_t*>(frame_top) + slot_offset; uint32_t* slot_ptr = reinterpret_cast<uint32_t*>(slot_address); @@ -417,14 +417,14 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor { continue; } - DexRegisterLocation::Kind location = vreg_map.GetLocationKind(vreg); + DexRegisterLocation::Kind location = vreg_map[vreg].GetKind(); static constexpr uint32_t kDeadValue = 0xEBADDE09; uint32_t value = kDeadValue; bool is_reference = false; switch (location) { case DexRegisterLocation::Kind::kInStack: { - const int32_t offset = vreg_map.GetStackOffsetInBytes(vreg); + const int32_t offset = vreg_map[vreg].GetStackOffsetInBytes(); const uint8_t* addr = reinterpret_cast<const uint8_t*>(GetCurrentQuickFrame()) + offset; value = *reinterpret_cast<const uint32_t*>(addr); uint32_t bit = (offset >> 2); @@ -437,7 +437,7 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor { case DexRegisterLocation::Kind::kInRegisterHigh: case DexRegisterLocation::Kind::kInFpuRegister: case DexRegisterLocation::Kind::kInFpuRegisterHigh: { - uint32_t reg = vreg_map.GetMachineRegister(vreg); + uint32_t reg = vreg_map[vreg].GetMachineRegister(); bool result = GetRegisterIfAccessible(reg, ToVRegKind(location), &value); CHECK(result); if (location == DexRegisterLocation::Kind::kInRegister) { @@ -448,7 +448,7 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor { break; } case DexRegisterLocation::Kind::kConstant: { - value = vreg_map.GetConstant(vreg); + value = vreg_map[vreg].GetConstant(); if (value == 0) { // Make it a reference for extra safety. is_reference = true; @@ -459,9 +459,7 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor { break; } default: { - LOG(FATAL) - << "Unexpected location kind " - << vreg_map.GetLocationInternalKind(vreg); + LOG(FATAL) << "Unexpected location kind " << vreg_map[vreg].GetKind(); UNREACHABLE(); } } diff --git a/runtime/stack.cc b/runtime/stack.cc index 56e47b9c77..2188cdc301 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -242,10 +242,10 @@ bool StackVisitor::GetVRegFromOptimizedCode(ArtMethod* m, uint16_t vreg, VRegKin return false; } DCHECK_EQ(dex_register_map.size(), number_of_dex_registers); - DexRegisterLocation::Kind location_kind = dex_register_map.GetLocationKind(vreg); + DexRegisterLocation::Kind location_kind = dex_register_map[vreg].GetKind(); switch (location_kind) { case DexRegisterLocation::Kind::kInStack: { - const int32_t offset = dex_register_map.GetStackOffsetInBytes(vreg); + const int32_t offset = dex_register_map[vreg].GetStackOffsetInBytes(); const uint8_t* addr = reinterpret_cast<const uint8_t*>(cur_quick_frame_) + offset; *val = *reinterpret_cast<const uint32_t*>(addr); return true; @@ -254,18 +254,16 @@ bool StackVisitor::GetVRegFromOptimizedCode(ArtMethod* m, uint16_t vreg, VRegKin case DexRegisterLocation::Kind::kInRegisterHigh: case DexRegisterLocation::Kind::kInFpuRegister: case DexRegisterLocation::Kind::kInFpuRegisterHigh: { - uint32_t reg = dex_register_map.GetMachineRegister(vreg); + uint32_t reg = dex_register_map[vreg].GetMachineRegister(); return GetRegisterIfAccessible(reg, kind, val); } case DexRegisterLocation::Kind::kConstant: - *val = dex_register_map.GetConstant(vreg); + *val = dex_register_map[vreg].GetConstant(); return true; case DexRegisterLocation::Kind::kNone: return false; default: - LOG(FATAL) - << "Unexpected location kind " - << dex_register_map.GetLocationInternalKind(vreg); + LOG(FATAL) << "Unexpected location kind " << dex_register_map[vreg].GetKind(); UNREACHABLE(); } } diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc index 23cc1d6358..43609e80bd 100644 --- a/runtime/stack_map.cc +++ b/runtime/stack_map.cc @@ -89,31 +89,6 @@ void CodeInfo::DecodeDexRegisterMap(uint32_t stack_map_index, } } -std::ostream& operator<<(std::ostream& stream, const DexRegisterLocation& reg) { - using Kind = DexRegisterLocation::Kind; - switch (reg.GetKind()) { - case Kind::kNone: - return stream << "None"; - case Kind::kInStack: - return stream << "sp+" << reg.GetValue(); - case Kind::kInRegister: - return stream << "r" << reg.GetValue(); - case Kind::kInRegisterHigh: - return stream << "r" << reg.GetValue() << "/hi"; - case Kind::kInFpuRegister: - return stream << "f" << reg.GetValue(); - case Kind::kInFpuRegisterHigh: - return stream << "f" << reg.GetValue() << "/hi"; - case Kind::kConstant: - return stream << "#" << reg.GetValue(); - case Kind::kInvalid: - return stream << "Invalid"; - default: - return stream << "DexRegisterLocation(" << static_cast<uint32_t>(reg.GetKind()) - << "," << reg.GetValue() << ")"; - } -} - template<typename Accessor> static void AddTableSizeStats(const char* table_name, const BitTable<Accessor::kCount>& table, @@ -144,13 +119,13 @@ void CodeInfo::AddSizeStats(/*out*/ Stats* parent) const { AddTableSizeStats<DexRegisterInfo>("DexRegisterCatalog", dex_register_catalog_, stats); } -static void DumpDexRegisterMap(VariableIndentationOutputStream* vios, - const DexRegisterMap& map) { - if (map.HasAnyLiveDexRegisters()) { +void DexRegisterMap::Dump(VariableIndentationOutputStream* vios) const { + if (HasAnyLiveDexRegisters()) { ScopedIndentation indent1(vios); - for (size_t i = 0; i < map.size(); ++i) { - if (map.IsDexRegisterLive(i)) { - vios->Stream() << "v" << i << ":" << map.Get(i) << " "; + for (size_t i = 0; i < size(); ++i) { + DexRegisterLocation reg = (*this)[i]; + if (reg.IsLive()) { + vios->Stream() << "v" << i << ":" << reg << " "; } } vios->Stream() << "\n"; @@ -240,7 +215,7 @@ void StackMap::Dump(VariableIndentationOutputStream* vios, vios->Stream() << stack_mask.LoadBit(e - i - 1); } vios->Stream() << ")\n"; - DumpDexRegisterMap(vios, code_info.GetDexRegisterMapOf(*this)); + 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); @@ -267,7 +242,7 @@ void InlineInfo::Dump(VariableIndentationOutputStream* vios, << ", method_index=" << GetMethodIndex(method_info); } vios->Stream() << ")\n"; - DumpDexRegisterMap(vios, code_info.GetDexRegisterMapAtDepth(depth, stack_map)); + code_info.GetDexRegisterMapAtDepth(depth, stack_map).Dump(vios); } } // namespace art diff --git a/runtime/stack_map.h b/runtime/stack_map.h index ea358c630d..aa19f0941a 100644 --- a/runtime/stack_map.h +++ b/runtime/stack_map.h @@ -54,9 +54,11 @@ std::ostream& operator<<(std::ostream& stream, const DexRegisterLocation& reg); // Information on Dex register locations for a specific PC. // Effectively just a convenience wrapper for DexRegisterLocation vector. // If the size is small enough, it keeps the data on the stack. +// TODO: Replace this with generic purpose "small-vector" implementation. class DexRegisterMap { public: using iterator = DexRegisterLocation*; + using const_iterator = const DexRegisterLocation*; // Create map for given number of registers and initialize them to the given value. DexRegisterMap(size_t count, DexRegisterLocation value) : count_(count), regs_small_{} { @@ -70,76 +72,36 @@ class DexRegisterMap { DexRegisterLocation* data() { return count_ <= kSmallCount ? regs_small_.data() : regs_large_.data(); } + const DexRegisterLocation* data() const { + return count_ <= kSmallCount ? regs_small_.data() : regs_large_.data(); + } iterator begin() { return data(); } iterator end() { return data() + count_; } - + const_iterator begin() const { return data(); } + const_iterator end() const { return data() + count_; } size_t size() const { return count_; } - bool empty() const { return count_ == 0; } - DexRegisterLocation Get(size_t index) const { + DexRegisterLocation& operator[](size_t index) { DCHECK_LT(index, count_); - return count_ <= kSmallCount ? regs_small_[index] : regs_large_[index]; - } - - DexRegisterLocation::Kind GetLocationKind(uint16_t dex_register_number) const { - return Get(dex_register_number).GetKind(); - } - - // TODO: Remove. - DexRegisterLocation::Kind GetLocationInternalKind(uint16_t dex_register_number) const { - return Get(dex_register_number).GetKind(); - } - - DexRegisterLocation GetDexRegisterLocation(uint16_t dex_register_number) const { - return Get(dex_register_number); - } - - int32_t GetStackOffsetInBytes(uint16_t dex_register_number) const { - DexRegisterLocation location = Get(dex_register_number); - DCHECK(location.GetKind() == DexRegisterLocation::Kind::kInStack); - return location.GetValue(); + return data()[index]; } - - int32_t GetConstant(uint16_t dex_register_number) const { - DexRegisterLocation location = Get(dex_register_number); - DCHECK(location.GetKind() == DexRegisterLocation::Kind::kConstant); - return location.GetValue(); - } - - int32_t GetMachineRegister(uint16_t dex_register_number) const { - DexRegisterLocation location = Get(dex_register_number); - DCHECK(location.GetKind() == DexRegisterLocation::Kind::kInRegister || - location.GetKind() == DexRegisterLocation::Kind::kInRegisterHigh || - location.GetKind() == DexRegisterLocation::Kind::kInFpuRegister || - location.GetKind() == DexRegisterLocation::Kind::kInFpuRegisterHigh); - return location.GetValue(); - } - - ALWAYS_INLINE bool IsDexRegisterLive(uint16_t dex_register_number) const { - return Get(dex_register_number).IsLive(); + const DexRegisterLocation& operator[](size_t index) const { + DCHECK_LT(index, count_); + return data()[index]; } size_t GetNumberOfLiveDexRegisters() const { - size_t number_of_live_dex_registers = 0; - for (size_t i = 0; i < count_; ++i) { - if (IsDexRegisterLive(i)) { - ++number_of_live_dex_registers; - } - } - return number_of_live_dex_registers; + return std::count_if(begin(), end(), [](auto& loc) { return loc.IsLive(); }); } bool HasAnyLiveDexRegisters() const { - for (size_t i = 0; i < count_; ++i) { - if (IsDexRegisterLive(i)) { - return true; - } - } - return false; + return std::any_of(begin(), end(), [](auto& loc) { return loc.IsLive(); }); } + void Dump(VariableIndentationOutputStream* vios) const; + private: // Store the data inline if the number of registers is small to avoid memory allocations. // If count_ <= kSmallCount, we use the regs_small_ array, and regs_large_ otherwise. diff --git a/runtime/thread.cc b/runtime/thread.cc index 4a53425477..7a7a80e4b6 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -3658,7 +3658,7 @@ class ReferenceMapVisitor : public StackVisitor { REQUIRES_SHARED(Locks::mutator_lock_) { bool found = false; for (size_t dex_reg = 0; dex_reg != number_of_dex_registers; ++dex_reg) { - DexRegisterLocation location = dex_register_map.GetDexRegisterLocation(dex_reg); + DexRegisterLocation location = dex_register_map[dex_reg]; if (location.GetKind() == kind && static_cast<size_t>(location.GetValue()) == index) { visitor(ref, dex_reg, stack_visitor); found = true; |