Clean up OatQuickMethodHeader after Quick removal.
This reduces the size of the pre-header by 8 bytes, reducing
oat file size and mmapped .text section size. The memory
needed to store a CompiledMethod by dex2oat is also reduced,
for 32-bit dex2oat by 8B and for 64-bit dex2oat by 16B. The
aosp_flounder-userdebug 32-bit and 64-bit boot.oat are each
about 1.1MiB smaller.
Disable the broken StubTest.IMT, b/27991555 .
Change-Id: I05fe45c28c8ffb7a0fa8b1117b969786748b1039
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 9a3bb02..b673eff 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -38,7 +38,6 @@
#include "dex_instruction.h"
#include "disassembler.h"
#include "elf_builder.h"
-#include "gc_map.h"
#include "gc/space/image_space.h"
#include "gc/space/large_object_space.h"
#include "gc/space/space-inl.h"
@@ -46,7 +45,6 @@
#include "indenter.h"
#include "linker/buffered_output_stream.h"
#include "linker/file_output_stream.h"
-#include "mapping_table.h"
#include "mirror/array-inl.h"
#include "mirror/class-inl.h"
#include "mirror/dex_cache-inl.h"
@@ -62,7 +60,6 @@
#include "ScopedLocalRef.h"
#include "thread_list.h"
#include "verifier/method_verifier.h"
-#include "vmap_table.h"
#include "well_known_classes.h"
#include <sys/stat.h>
@@ -282,9 +279,7 @@
class OatDumperOptions {
public:
- OatDumperOptions(bool dump_raw_mapping_table,
- bool dump_raw_gc_map,
- bool dump_vmap,
+ OatDumperOptions(bool dump_vmap,
bool dump_code_info_stack_maps,
bool disassemble_code,
bool absolute_addresses,
@@ -297,9 +292,7 @@
const char* app_image,
const char* app_oat,
uint32_t addr2instr)
- : dump_raw_mapping_table_(dump_raw_mapping_table),
- dump_raw_gc_map_(dump_raw_gc_map),
- dump_vmap_(dump_vmap),
+ : dump_vmap_(dump_vmap),
dump_code_info_stack_maps_(dump_code_info_stack_maps),
disassemble_code_(disassemble_code),
absolute_addresses_(absolute_addresses),
@@ -314,8 +307,6 @@
addr2instr_(addr2instr),
class_loader_(nullptr) {}
- const bool dump_raw_mapping_table_;
- const bool dump_raw_gc_map_;
const bool dump_vmap_;
const bool dump_code_info_stack_maps_;
const bool disassemble_code_;
@@ -572,9 +563,7 @@
code_offset &= ~0x1;
}
offsets_.insert(code_offset);
- offsets_.insert(oat_method.GetMappingTableOffset());
offsets_.insert(oat_method.GetVmapTableOffset());
- offsets_.insert(oat_method.GetGcMapOffset());
}
bool DumpOatDexFile(std::ostream& os, const OatFile::OatDexFile& oat_dex_file) {
@@ -843,22 +832,6 @@
success = false;
}
vios->Stream() << "\n";
-
- vios->Stream() << "gc_map: ";
- if (options_.absolute_addresses_) {
- vios->Stream() << StringPrintf("%p ", oat_method.GetGcMap());
- }
- uint32_t gc_map_offset = oat_method.GetGcMapOffset();
- vios->Stream() << StringPrintf("(offset=0x%08x)\n", gc_map_offset);
- if (gc_map_offset > oat_file_.Size()) {
- vios->Stream() << StringPrintf("WARNING: "
- "gc map table offset 0x%08x is past end of file 0x%08zx.\n",
- gc_map_offset, oat_file_.Size());
- success = false;
- } else if (options_.dump_raw_gc_map_) {
- ScopedIndentation indent3(vios);
- DumpGcMap(vios->Stream(), oat_method, code_item);
- }
}
{
vios->Stream() << "OatQuickMethodHeader ";
@@ -879,24 +852,6 @@
}
ScopedIndentation indent2(vios);
- vios->Stream() << "mapping_table: ";
- if (options_.absolute_addresses_) {
- vios->Stream() << StringPrintf("%p ", oat_method.GetMappingTable());
- }
- uint32_t mapping_table_offset = oat_method.GetMappingTableOffset();
- vios->Stream() << StringPrintf("(offset=0x%08x)\n", oat_method.GetMappingTableOffset());
- if (mapping_table_offset > oat_file_.Size()) {
- vios->Stream() << StringPrintf("WARNING: "
- "mapping table offset 0x%08x is past end of file 0x%08zx. "
- "mapping table offset was loaded from offset 0x%08x.\n",
- mapping_table_offset, oat_file_.Size(),
- oat_method.GetMappingTableOffsetOffset());
- success = false;
- } else if (options_.dump_raw_mapping_table_) {
- ScopedIndentation indent3(vios);
- DumpMappingTable(vios, oat_method);
- }
-
vios->Stream() << "vmap_table: ";
if (options_.absolute_addresses_) {
vios->Stream() << StringPrintf("%p ", oat_method.GetVmapTable());
@@ -973,7 +928,7 @@
success = false;
if (options_.disassemble_code_) {
if (code_size_offset + kPrologueBytes <= oat_file_.Size()) {
- DumpCode(vios, verifier.get(), oat_method, code_item, true, kPrologueBytes);
+ DumpCode(vios, oat_method, code_item, true, kPrologueBytes);
}
}
} else if (code_size > kMaxCodeSize) {
@@ -986,11 +941,11 @@
success = false;
if (options_.disassemble_code_) {
if (code_size_offset + kPrologueBytes <= oat_file_.Size()) {
- DumpCode(vios, verifier.get(), oat_method, code_item, true, kPrologueBytes);
+ DumpCode(vios, oat_method, code_item, true, kPrologueBytes);
}
}
} else if (options_.disassemble_code_) {
- DumpCode(vios, verifier.get(), oat_method, code_item, !success, 0);
+ DumpCode(vios, oat_method, code_item, !success, 0);
}
}
}
@@ -1040,12 +995,7 @@
ScopedIndentation indent(vios);
vios->Stream() << "quickened data\n";
} else {
- // Otherwise, display the vmap table.
- const uint8_t* raw_table = oat_method.GetVmapTable();
- if (raw_table != nullptr) {
- VmapTable vmap_table(raw_table);
- DumpVmapTable(vios->Stream(), oat_method, vmap_table);
- }
+ // Otherwise, there is nothing to display.
}
}
@@ -1060,32 +1010,6 @@
options_.dump_code_info_stack_maps_);
}
- // 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,
const DexFile::CodeItem* code_item) {
if (code_item != nullptr) {
@@ -1128,203 +1052,18 @@
}
}
- void DescribeVReg(std::ostream& os, const OatFile::OatMethod& oat_method,
- const DexFile::CodeItem* code_item, size_t reg, VRegKind kind) {
- const uint8_t* raw_table = oat_method.GetVmapTable();
- if (raw_table != nullptr) {
- const VmapTable vmap_table(raw_table);
- uint32_t vmap_offset;
- if (vmap_table.IsInContext(reg, kind, &vmap_offset)) {
- bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
- uint32_t spill_mask = is_float ? oat_method.GetFpSpillMask()
- : oat_method.GetCoreSpillMask();
- os << (is_float ? "fr" : "r") << vmap_table.ComputeRegister(spill_mask, vmap_offset, kind);
- } else {
- uint32_t offset = StackVisitor::GetVRegOffsetFromQuickCode(
- code_item,
- oat_method.GetCoreSpillMask(),
- oat_method.GetFpSpillMask(),
- oat_method.GetFrameSizeInBytes(),
- reg,
- GetInstructionSet());
- os << "[sp + #" << offset << "]";
- }
- }
- }
-
- void DumpGcMapRegisters(std::ostream& os, const OatFile::OatMethod& oat_method,
- const DexFile::CodeItem* code_item,
- size_t num_regs, const uint8_t* reg_bitmap) {
- bool first = true;
- for (size_t reg = 0; reg < num_regs; reg++) {
- if (((reg_bitmap[reg / 8] >> (reg % 8)) & 0x01) != 0) {
- if (first) {
- os << " v" << reg << " (";
- DescribeVReg(os, oat_method, code_item, reg, kReferenceVReg);
- os << ")";
- first = false;
- } else {
- os << ", v" << reg << " (";
- DescribeVReg(os, oat_method, code_item, reg, kReferenceVReg);
- os << ")";
- }
- }
- }
- if (first) {
- os << "No registers in GC map\n";
- } else {
- os << "\n";
- }
- }
- void DumpGcMap(std::ostream& os, const OatFile::OatMethod& oat_method,
- const DexFile::CodeItem* code_item) {
- const uint8_t* gc_map_raw = oat_method.GetGcMap();
- if (gc_map_raw == nullptr) {
- return; // No GC map.
- }
- const void* quick_code = oat_method.GetQuickCode();
- NativePcOffsetToReferenceMap map(gc_map_raw);
- for (size_t entry = 0; entry < map.NumEntries(); entry++) {
- const uint8_t* native_pc = reinterpret_cast<const uint8_t*>(quick_code) +
- map.GetNativePcOffset(entry);
- os << StringPrintf("%p", native_pc);
- DumpGcMapRegisters(os, oat_method, code_item, map.RegWidth() * 8, map.GetBitMap(entry));
- }
- }
-
- void DumpMappingTable(VariableIndentationOutputStream* vios,
- const OatFile::OatMethod& oat_method) {
- const void* quick_code = oat_method.GetQuickCode();
- if (quick_code == nullptr) {
+ void DumpInformationAtOffset(VariableIndentationOutputStream* vios,
+ const OatFile::OatMethod& oat_method,
+ const DexFile::CodeItem* code_item,
+ size_t offset,
+ bool suspend_point_mapping) {
+ if (!IsMethodGeneratedByOptimizingCompiler(oat_method, code_item)) {
+ // Native method.
return;
}
- MappingTable table(oat_method.GetMappingTable());
- if (table.TotalSize() != 0) {
- if (table.PcToDexSize() != 0) {
- typedef MappingTable::PcToDexIterator It;
- vios->Stream() << "suspend point mappings {\n";
- for (It cur = table.PcToDexBegin(), end = table.PcToDexEnd(); cur != end; ++cur) {
- ScopedIndentation indent1(vios);
- vios->Stream() << StringPrintf("0x%04x -> 0x%04x\n", cur.NativePcOffset(), cur.DexPc());
- }
- vios->Stream() << "}\n";
- }
- if (table.DexToPcSize() != 0) {
- typedef MappingTable::DexToPcIterator It;
- vios->Stream() << "catch entry mappings {\n";
- for (It cur = table.DexToPcBegin(), end = table.DexToPcEnd(); cur != end; ++cur) {
- ScopedIndentation indent1(vios);
- vios->Stream() << StringPrintf("0x%04x -> 0x%04x\n", cur.NativePcOffset(), cur.DexPc());
- }
- vios->Stream() << "}\n";
- }
- }
- }
-
- uint32_t DumpInformationAtOffset(VariableIndentationOutputStream* vios,
- const OatFile::OatMethod& oat_method,
- const DexFile::CodeItem* code_item,
- size_t offset,
- bool suspend_point_mapping) {
- if (IsMethodGeneratedByOptimizingCompiler(oat_method, code_item)) {
- if (suspend_point_mapping) {
- ScopedIndentation indent1(vios);
- DumpDexRegisterMapAtOffset(vios, oat_method, code_item, offset);
- }
- // The return value is not used in the case of a method compiled
- // with the optimizing compiler.
- return DexFile::kDexNoIndex;
- } else {
- return DumpMappingAtOffset(vios->Stream(), oat_method, offset, suspend_point_mapping);
- }
- }
-
- uint32_t DumpMappingAtOffset(std::ostream& os, const OatFile::OatMethod& oat_method,
- size_t offset, bool suspend_point_mapping) {
- MappingTable table(oat_method.GetMappingTable());
- if (suspend_point_mapping && table.PcToDexSize() > 0) {
- typedef MappingTable::PcToDexIterator It;
- for (It cur = table.PcToDexBegin(), end = table.PcToDexEnd(); cur != end; ++cur) {
- if (offset == cur.NativePcOffset()) {
- os << StringPrintf("suspend point dex PC: 0x%04x\n", cur.DexPc());
- return cur.DexPc();
- }
- }
- } else if (!suspend_point_mapping && table.DexToPcSize() > 0) {
- typedef MappingTable::DexToPcIterator It;
- for (It cur = table.DexToPcBegin(), end = table.DexToPcEnd(); cur != end; ++cur) {
- if (offset == cur.NativePcOffset()) {
- os << StringPrintf("catch entry dex PC: 0x%04x\n", cur.DexPc());
- return cur.DexPc();
- }
- }
- }
- return DexFile::kDexNoIndex;
- }
-
- void DumpGcMapAtNativePcOffset(std::ostream& os, const OatFile::OatMethod& oat_method,
- const DexFile::CodeItem* code_item, size_t native_pc_offset) {
- const uint8_t* gc_map_raw = oat_method.GetGcMap();
- if (gc_map_raw != nullptr) {
- NativePcOffsetToReferenceMap map(gc_map_raw);
- if (map.HasEntry(native_pc_offset)) {
- size_t num_regs = map.RegWidth() * 8;
- const uint8_t* reg_bitmap = map.FindBitMap(native_pc_offset);
- bool first = true;
- for (size_t reg = 0; reg < num_regs; reg++) {
- if (((reg_bitmap[reg / 8] >> (reg % 8)) & 0x01) != 0) {
- if (first) {
- os << "GC map objects: v" << reg << " (";
- DescribeVReg(os, oat_method, code_item, reg, kReferenceVReg);
- os << ")";
- first = false;
- } else {
- os << ", v" << reg << " (";
- DescribeVReg(os, oat_method, code_item, reg, kReferenceVReg);
- os << ")";
- }
- }
- }
- if (!first) {
- os << "\n";
- }
- }
- }
- }
-
- void DumpVRegsAtDexPc(std::ostream& os, verifier::MethodVerifier* verifier,
- const OatFile::OatMethod& oat_method,
- const DexFile::CodeItem* code_item, uint32_t dex_pc) {
- DCHECK(verifier != nullptr);
- std::vector<int32_t> kinds = verifier->DescribeVRegs(dex_pc);
- bool first = true;
- for (size_t reg = 0; reg < code_item->registers_size_; reg++) {
- VRegKind kind = static_cast<VRegKind>(kinds.at(reg * 2));
- if (kind != kUndefined) {
- if (first) {
- os << "VRegs: v";
- first = false;
- } else {
- os << ", v";
- }
- os << reg << " (";
- switch (kind) {
- case kImpreciseConstant:
- os << "Imprecise Constant: " << kinds.at((reg * 2) + 1) << ", ";
- DescribeVReg(os, oat_method, code_item, reg, kind);
- break;
- case kConstant:
- os << "Constant: " << kinds.at((reg * 2) + 1);
- break;
- default:
- DescribeVReg(os, oat_method, code_item, reg, kind);
- break;
- }
- os << ")";
- }
- }
- if (!first) {
- os << "\n";
+ if (suspend_point_mapping) {
+ ScopedIndentation indent1(vios);
+ DumpDexRegisterMapAtOffset(vios, oat_method, code_item, offset);
}
}
@@ -1349,7 +1088,7 @@
// null, then this method has been compiled with the optimizing
// compiler.
return oat_method.GetQuickCode() != nullptr &&
- oat_method.GetGcMap() == nullptr &&
+ oat_method.GetVmapTable() != nullptr &&
code_item != nullptr;
}
@@ -1409,7 +1148,6 @@
}
void DumpCode(VariableIndentationOutputStream* vios,
- verifier::MethodVerifier* verifier,
const OatFile::OatMethod& oat_method, const DexFile::CodeItem* code_item,
bool bad_input, size_t code_size) {
const void* quick_code = oat_method.GetQuickCode();
@@ -1429,14 +1167,7 @@
}
offset += disassembler_->Dump(vios->Stream(), quick_native_pc + offset);
if (!bad_input) {
- uint32_t dex_pc =
- DumpInformationAtOffset(vios, oat_method, code_item, offset, true);
- if (dex_pc != DexFile::kDexNoIndex) {
- DumpGcMapAtNativePcOffset(vios->Stream(), oat_method, code_item, offset);
- if (verifier != nullptr) {
- DumpVRegsAtDexPc(vios->Stream(), verifier, oat_method, code_item, dex_pc);
- }
- }
+ DumpInformationAtOffset(vios, oat_method, code_item, offset, true);
}
}
}
@@ -1986,10 +1717,6 @@
OatQuickMethodHeader* method_header = reinterpret_cast<OatQuickMethodHeader*>(
reinterpret_cast<uintptr_t>(quick_oat_code_begin) - sizeof(OatQuickMethodHeader));
if (method->IsNative()) {
- if (!Runtime::Current()->GetClassLinker()->IsQuickGenericJniStub(quick_oat_code_begin)) {
- DCHECK(method_header->GetNativeGcMap() == nullptr) << PrettyMethod(method);
- DCHECK(method_header->GetMappingTable() == nullptr) << PrettyMethod(method);
- }
bool first_occurrence;
uint32_t quick_oat_code_size = GetQuickOatCodeSize(method);
ComputeOatSize(quick_oat_code_begin, &first_occurrence);
@@ -2013,17 +1740,6 @@
stats_.dex_instruction_bytes += dex_instruction_bytes;
bool first_occurrence;
- size_t gc_map_bytes = ComputeOatSize(method_header->GetNativeGcMap(), &first_occurrence);
- if (first_occurrence) {
- stats_.gc_map_bytes += gc_map_bytes;
- }
-
- size_t pc_mapping_table_bytes = ComputeOatSize(
- method_header->GetMappingTable(), &first_occurrence);
- if (first_occurrence) {
- stats_.pc_mapping_table_bytes += pc_mapping_table_bytes;
- }
-
size_t vmap_table_bytes = 0u;
if (!method_header->IsOptimized()) {
// Method compiled with the optimizing compiler have no vmap table.
@@ -2052,11 +1768,12 @@
uint32_t method_access_flags = method->GetAccessFlags();
indent_os << StringPrintf("OAT CODE: %p-%p\n", quick_oat_code_begin, quick_oat_code_end);
- indent_os << StringPrintf("SIZE: Dex Instructions=%zd GC=%zd Mapping=%zd AccessFlags=0x%x\n",
- dex_instruction_bytes, gc_map_bytes, pc_mapping_table_bytes,
+ indent_os << StringPrintf("SIZE: Dex Instructions=%zd StackMaps=%zd AccessFlags=0x%x\n",
+ dex_instruction_bytes,
+ vmap_table_bytes,
method_access_flags);
- size_t total_size = dex_instruction_bytes + gc_map_bytes + pc_mapping_table_bytes +
+ size_t total_size = dex_instruction_bytes +
vmap_table_bytes + quick_oat_code_size + ArtMethod::Size(image_header_.GetPointerSize());
double expansion =
@@ -2101,8 +1818,6 @@
size_t large_initializer_code_bytes;
size_t large_method_code_bytes;
- size_t gc_map_bytes;
- size_t pc_mapping_table_bytes;
size_t vmap_table_bytes;
size_t dex_instruction_bytes;
@@ -2131,8 +1846,6 @@
class_initializer_code_bytes(0),
large_initializer_code_bytes(0),
large_method_code_bytes(0),
- gc_map_bytes(0),
- pc_mapping_table_bytes(0),
vmap_table_bytes(0),
dex_instruction_bytes(0) {}
@@ -2351,11 +2064,7 @@
PercentOfOatBytes(oat_dex_file_size.second));
}
- os << "\n" << StringPrintf("gc_map_bytes = %7zd (%2.0f%% of oat file bytes)\n"
- "pc_mapping_table_bytes = %7zd (%2.0f%% of oat file bytes)\n"
- "vmap_table_bytes = %7zd (%2.0f%% of oat file bytes)\n\n",
- gc_map_bytes, PercentOfOatBytes(gc_map_bytes),
- pc_mapping_table_bytes, PercentOfOatBytes(pc_mapping_table_bytes),
+ os << "\n" << StringPrintf("vmap_table_bytes = %7zd (%2.0f%% of oat file bytes)\n\n",
vmap_table_bytes, PercentOfOatBytes(vmap_table_bytes))
<< std::flush;
@@ -2590,10 +2299,6 @@
oat_filename_ = option.substr(strlen("--oat-file=")).data();
} else if (option.starts_with("--image=")) {
image_location_ = option.substr(strlen("--image=")).data();
- } else if (option =="--dump:raw_mapping_table") {
- dump_raw_mapping_table_ = true;
- } else if (option == "--dump:raw_gc_map") {
- dump_raw_gc_map_ = true;
} else if (option == "--no-dump:vmap") {
dump_vmap_ = false;
} else if (option =="--dump:code_info_stack_maps") {
@@ -2683,12 +2388,6 @@
usage += Base::GetUsage();
usage += // Optional.
- " --dump:raw_mapping_table enables dumping of the mapping table.\n"
- " Example: --dump:raw_mapping_table\n"
- "\n"
- " --dump:raw_gc_map enables dumping of the GC map.\n"
- " Example: --dump:raw_gc_map\n"
- "\n"
" --no-dump:vmap may be used to disable vmap dumping.\n"
" Example: --no-dump:vmap\n"
"\n"
@@ -2739,8 +2438,6 @@
const char* method_filter_ = "";
const char* image_location_ = nullptr;
std::string elf_filename_prefix_;
- bool dump_raw_mapping_table_ = false;
- bool dump_raw_gc_map_ = false;
bool dump_vmap_ = true;
bool dump_code_info_stack_maps_ = false;
bool disassemble_code_ = true;
@@ -2763,8 +2460,6 @@
bool absolute_addresses = (args_->oat_filename_ == nullptr);
oat_dumper_options_.reset(new OatDumperOptions(
- args_->dump_raw_mapping_table_,
- args_->dump_raw_gc_map_,
args_->dump_vmap_,
args_->dump_code_info_stack_maps_,
args_->disassemble_code_,