summaryrefslogtreecommitdiffstats
path: root/oatdump
diff options
context:
space:
mode:
authorRoland Levillain <rpl@google.com>2015-02-18 16:54:21 +0000
committerRoland Levillain <rpl@google.com>2015-02-19 12:13:09 +0000
commit442b46a087c389a91a0b51547ac9205058432364 (patch)
tree4efa4b4da919dd7b9aa18996a5316febcf1c8989 /oatdump
parentaa9b7c48069699e2aabedc6c0f62cb131fee0c73 (diff)
downloadart-442b46a087c389a91a0b51547ac9205058432364.zip
art-442b46a087c389a91a0b51547ac9205058432364.tar.gz
art-442b46a087c389a91a0b51547ac9205058432364.tar.bz2
Display optimizing compiler's CodeInfo objects in oatdump.
A few elements are not displayed yet (stack mask, inline info) though. Change-Id: I5e51a801c580169abc5d1ef43ad581aadc110754
Diffstat (limited to 'oatdump')
-rw-r--r--oatdump/oatdump.cc104
1 files changed, 77 insertions, 27 deletions
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 931cca7..11ccafb 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -764,7 +764,7 @@ class OatDumper {
oat_method.GetVmapTableOffsetOffset());
success = false;
} else if (options_->dump_vmap_) {
- DumpVmap(*indent2_os, oat_method);
+ DumpVmapData(*indent2_os, oat_method, code_item);
}
}
{
@@ -869,37 +869,87 @@ class OatDumper {
os << ")";
}
- void DumpVmap(std::ostream& os, const OatFile::OatMethod& oat_method) {
- // If the native GC map is null, then this method has been compiled with the
- // optimizing compiler. The optimizing compiler currently outputs its stack map
- // in the vmap table, and the code below does not work with such a stack map.
+ // Display data stored at the the vmap offset of an oat method.
+ void DumpVmapData(std::ostream& os,
+ const OatFile::OatMethod& oat_method,
+ const DexFile::CodeItem* code_item) {
if (oat_method.GetGcMap() == nullptr) {
- return;
+ // If the native GC map is null, then this method has been
+ // compiled with the optimizing compiler. The optimizing
+ // compiler currently outputs its stack maps in the vmap table.
+ const void* raw_code_info = oat_method.GetVmapTable();
+ if (raw_code_info != nullptr) {
+ CodeInfo code_info(raw_code_info);
+ DCHECK(code_item != nullptr);
+ DumpCodeInfo(os, code_info, *code_item);
+ }
+ } else {
+ // Otherwise, display the vmap table.
+ const uint8_t* raw_table = oat_method.GetVmapTable();
+ if (raw_table != nullptr) {
+ VmapTable vmap_table(raw_table);
+ DumpVmapTable(os, oat_method, vmap_table);
+ }
}
- const uint8_t* raw_table = oat_method.GetVmapTable();
- if (raw_table != nullptr) {
- const VmapTable vmap_table(raw_table);
- bool first = true;
- bool processing_fp = false;
- uint32_t spill_mask = oat_method.GetCoreSpillMask();
- for (size_t i = 0; i < vmap_table.Size(); i++) {
- uint16_t dex_reg = vmap_table[i];
- uint32_t cpu_reg = vmap_table.ComputeRegister(spill_mask, i,
- processing_fp ? kFloatVReg : kIntVReg);
- os << (first ? "v" : ", v") << dex_reg;
- if (!processing_fp) {
- os << "/r" << cpu_reg;
- } else {
- os << "/fr" << cpu_reg;
- }
- first = false;
- if (!processing_fp && dex_reg == 0xFFFF) {
- processing_fp = true;
- spill_mask = oat_method.GetFpSpillMask();
+ }
+
+ // Display a CodeInfo object emitted by the optimizing compiler.
+ void DumpCodeInfo(std::ostream& os,
+ const CodeInfo& code_info,
+ const DexFile::CodeItem& code_item) {
+ uint16_t number_of_dex_registers = code_item.registers_size_;
+ uint32_t code_info_size = code_info.GetOverallSize();
+ size_t number_of_stack_maps = code_info.GetNumberOfStackMaps();
+ os << " Optimized CodeInfo (size=" << code_info_size
+ << ", number_of_dex_registers=" << number_of_dex_registers
+ << ", number_of_stack_maps=" << number_of_stack_maps << ")\n";
+ for (size_t i = 0; i < number_of_stack_maps; ++i) {
+ StackMap stack_map = code_info.GetStackMapAt(i);
+ // TODO: Display stack_mask value.
+ os << " StackMap " << i
+ << std::hex
+ << " (dex_pc=0x" << stack_map.GetDexPc()
+ << ", native_pc_offset=0x" << stack_map.GetNativePcOffset()
+ << ", register_mask=0x" << stack_map.GetRegisterMask()
+ << std::dec
+ << ")\n";
+ if (stack_map.HasDexRegisterMap()) {
+ DexRegisterMap dex_register_map =
+ code_info.GetDexRegisterMapOf(stack_map, number_of_dex_registers);
+ for (size_t j = 0; j < number_of_dex_registers; ++j) {
+ os << " v" << j << ": "
+ << DexRegisterMap::PrettyDescriptor(dex_register_map.GetLocationKind(j))
+ << " (" << dex_register_map.GetValue(j) << ")\n";
}
}
- os << "\n";
+ // TODO: Display more information from code_info.
+ }
+ }
+
+ // Display a vmap table.
+ void DumpVmapTable(std::ostream& os,
+ const OatFile::OatMethod& oat_method,
+ const VmapTable& vmap_table) {
+ bool first = true;
+ bool processing_fp = false;
+ uint32_t spill_mask = oat_method.GetCoreSpillMask();
+ for (size_t i = 0; i < vmap_table.Size(); i++) {
+ uint16_t dex_reg = vmap_table[i];
+ uint32_t cpu_reg = vmap_table.ComputeRegister(spill_mask, i,
+ processing_fp ? kFloatVReg : kIntVReg);
+ os << (first ? "v" : ", v") << dex_reg;
+ if (!processing_fp) {
+ os << "/r" << cpu_reg;
+ } else {
+ os << "/fr" << cpu_reg;
+ }
+ first = false;
+ if (!processing_fp && dex_reg == 0xFFFF) {
+ processing_fp = true;
+ spill_mask = oat_method.GetFpSpillMask();
+ }
}
+ os << "\n";
}
void DumpVregLocations(std::ostream& os, const OatFile::OatMethod& oat_method,