Reduce memory used by CompiledMethods.
Use LengthPrefixedArray<>s instead of SwapVector<>s to store
CompiledMethod data and get rid of the unnecessary members
of CompiledMethod to reduce dex2oat memory usage. Refactor
the deduplication from CompilerDriver to a new class.
Use HashSet<> instead of std::set<> for the DedupeSet<> to
further decrease the memory usage and improve performance.
This reduces the dex2oat memory usage when compiling boot
image on Nexus 5 (with Optimizing, -j1) by ~6.75MiB (5%).
This also reduces the compile time by ~2.2% (~1.6% dex2oat
time; with Optimizing, without -j).
Change-Id: I974f1f5e58350de2bf487a2bca3907fa05fb80ea
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 58a2f96..151437b 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -54,22 +54,22 @@
method->GetDexMethodIndex()));
}
if (compiled_method != nullptr) {
- const SwapVector<uint8_t>* code = compiled_method->GetQuickCode();
- uint32_t code_size = code->size();
+ ArrayRef<const uint8_t> code = compiled_method->GetQuickCode();
+ uint32_t code_size = code.size();
CHECK_NE(0u, code_size);
- const SwapVector<uint8_t>* vmap_table = compiled_method->GetVmapTable();
- uint32_t vmap_table_offset = vmap_table->empty() ? 0u
- : sizeof(OatQuickMethodHeader) + vmap_table->size();
- const SwapVector<uint8_t>* mapping_table = compiled_method->GetMappingTable();
- bool mapping_table_used = mapping_table != nullptr && !mapping_table->empty();
- size_t mapping_table_size = mapping_table_used ? mapping_table->size() : 0U;
+ ArrayRef<const uint8_t> vmap_table = compiled_method->GetVmapTable();
+ uint32_t vmap_table_offset = vmap_table.empty() ? 0u
+ : sizeof(OatQuickMethodHeader) + vmap_table.size();
+ ArrayRef<const uint8_t> mapping_table = compiled_method->GetMappingTable();
+ bool mapping_table_used = !mapping_table.empty();
+ size_t mapping_table_size = mapping_table.size();
uint32_t mapping_table_offset = !mapping_table_used ? 0u
- : sizeof(OatQuickMethodHeader) + vmap_table->size() + mapping_table_size;
- const SwapVector<uint8_t>* gc_map = compiled_method->GetGcMap();
- bool gc_map_used = gc_map != nullptr && !gc_map->empty();
- size_t gc_map_size = gc_map_used ? gc_map->size() : 0U;
+ : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table_size;
+ ArrayRef<const uint8_t> gc_map = compiled_method->GetGcMap();
+ bool gc_map_used = !gc_map.empty();
+ size_t gc_map_size = gc_map.size();
uint32_t gc_map_offset = !gc_map_used ? 0u
- : sizeof(OatQuickMethodHeader) + vmap_table->size() + mapping_table_size + gc_map_size;
+ : sizeof(OatQuickMethodHeader) + vmap_table.size() + mapping_table_size + gc_map_size;
OatQuickMethodHeader method_header(mapping_table_offset, vmap_table_offset, gc_map_offset,
compiled_method->GetFrameSizeInBytes(),
compiled_method->GetCoreSpillMask(),
@@ -77,25 +77,25 @@
header_code_and_maps_chunks_.push_back(std::vector<uint8_t>());
std::vector<uint8_t>* chunk = &header_code_and_maps_chunks_.back();
- size_t size = sizeof(method_header) + code_size + vmap_table->size() + mapping_table_size +
+ size_t size = sizeof(method_header) + code_size + vmap_table.size() + mapping_table_size +
gc_map_size;
size_t code_offset = compiled_method->AlignCode(size - code_size);
size_t padding = code_offset - (size - code_size);
chunk->reserve(padding + size);
chunk->resize(sizeof(method_header));
memcpy(&(*chunk)[0], &method_header, sizeof(method_header));
- chunk->insert(chunk->begin(), vmap_table->begin(), vmap_table->end());
+ chunk->insert(chunk->begin(), vmap_table.begin(), vmap_table.end());
if (mapping_table_used) {
- chunk->insert(chunk->begin(), mapping_table->begin(), mapping_table->end());
+ chunk->insert(chunk->begin(), mapping_table.begin(), mapping_table.end());
}
if (gc_map_used) {
- chunk->insert(chunk->begin(), gc_map->begin(), gc_map->end());
+ chunk->insert(chunk->begin(), gc_map.begin(), gc_map.end());
}
chunk->insert(chunk->begin(), padding, 0);
- chunk->insert(chunk->end(), code->begin(), code->end());
+ chunk->insert(chunk->end(), code.begin(), code.end());
CHECK_EQ(padding + size, chunk->size());
const void* code_ptr = &(*chunk)[code_offset];
- MakeExecutable(code_ptr, code->size());
+ MakeExecutable(code_ptr, code.size());
const void* method_code = CompiledMethod::CodePointer(code_ptr,
compiled_method->GetInstructionSet());
LOG(INFO) << "MakeExecutable " << PrettyMethod(method) << " code=" << method_code;