Move some helper methods to DexRegisterLocation.
Test: test-art-host-gtest-stack_map_test
Change-Id: I0abab008159db023d531df69214cd3bb8c0639bd
diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h
index 4009acb..b663291 100644
--- a/compiler/debug/elf_debug_loc_writer.h
+++ b/compiler/debug/elf_debug_loc_writer.h
@@ -149,9 +149,9 @@
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 b3feb78..eea146e 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -1294,50 +1294,45 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 094b75d..2bfa430 100644
--- a/compiler/optimizing/stack_map_stream.cc
+++ b/compiler/optimizing/stack_map_stream.cc
@@ -114,10 +114,6 @@
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 02fb6cb..e3ae8a2 100644
--- a/compiler/optimizing/stack_map_stream.h
+++ b/compiler/optimizing/stack_map_stream.h
@@ -69,7 +69,9 @@
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 9adc4c5..56717b5 100644
--- a/compiler/optimizing/stack_map_test.cc
+++ b/compiler/optimizing/stack_map_test.cc
@@ -83,14 +83,14 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 777a1fc..1168798 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -47,6 +47,7 @@
"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 8a2a70e..8f9f45c 100644
--- a/runtime/check_reference_map_visitor.h
+++ b/runtime/check_reference_map_visitor.h
@@ -75,7 +75,7 @@
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 @@
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 0000000..f3b0973
--- /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 a20dccb..98b4d41 100644
--- a/runtime/dex_register_location.h
+++ b/runtime/dex_register_location.h
@@ -48,9 +48,6 @@
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 @@
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 @@
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 0a8e0cd..5e73603 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -515,7 +515,7 @@
} 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 @@
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 cf1cbe7..8b99b9f 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -245,7 +245,7 @@
// 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 @@
// 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 @@
<< "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 @@
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 @@
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 @@
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 @@
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 56e47b9..2188cdc 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -242,10 +242,10 @@
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 @@
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 23cc1d6..43609e8 100644
--- a/runtime/stack_map.cc
+++ b/runtime/stack_map.cc
@@ -89,31 +89,6 @@
}
}
-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 @@
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 @@
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 @@
<< ", 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 ea358c6..aa19f09 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -54,9 +54,11 @@
// 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 @@
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];
+ return data()[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();
- }
-
- 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 4a53425..7a7a80e 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -3658,7 +3658,7 @@
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;