diff options
author | 2016-03-21 12:01:50 +0000 | |
---|---|---|
committer | 2016-03-21 16:50:08 +0000 | |
commit | f6a35de9eeefb20f6446f1b4815b4dcb0161d09c (patch) | |
tree | cf484acbd6889b92a7fe3e8615611129088c3894 /compiler/optimizing | |
parent | 459898dc4470559ba1e1d578bc52a914d1f573f5 (diff) |
Optimizing: Fix register allocator validation memory usage.
Also attribute ArenaBitVector allocations to appropriate
passes. This was used to track down the source of the
excessive memory alloactions.
Bug: 27690481
Change-Id: Ib895984cb7c04e24cbc7abbd8322079bab8ab100
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/builder.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.cc | 3 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/graph_checker.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/graph_checker.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/gvn.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/licm.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/load_store_elimination.cc | 5 | ||||
-rw-r--r-- | compiler/optimizing/locations.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 14 | ||||
-rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.h | 6 | ||||
-rw-r--r-- | compiler/optimizing/stack_map_stream.cc | 6 |
14 files changed, 41 insertions, 22 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 57660c2623..124afbc73b 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -367,7 +367,8 @@ GraphAnalysisResult HGraphBuilder::BuildGraph(const DexFile::CodeItem& code_item ArenaBitVector* native_debug_info_locations; if (native_debuggable) { const uint32_t num_instructions = code_item.insns_size_in_code_units_; - native_debug_info_locations = new (arena_) ArenaBitVector (arena_, num_instructions, false); + native_debug_info_locations = + ArenaBitVector::Create(arena_, num_instructions, false, kArenaAllocGraphBuilder); FindNativeDebugInfoLocations(code_item, native_debug_info_locations); } diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index d64a786a9e..32869ec0b4 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -856,7 +856,8 @@ void CodeGenerator::RecordCatchBlockInfo() { uint32_t register_mask = 0; // Not used. // The stack mask is not used, so we leave it empty. - ArenaBitVector* stack_mask = new (arena) ArenaBitVector(arena, 0, /* expandable */ true); + ArenaBitVector* stack_mask = + ArenaBitVector::Create(arena, 0, /* expandable */ true, kArenaAllocCodeGenerator); stack_map_stream_.BeginStackMapEntry(dex_pc, native_pc, diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc index e170e37bdd..d7bf16e0cc 100644 --- a/compiler/optimizing/dead_code_elimination.cc +++ b/compiler/optimizing/dead_code_elimination.cc @@ -97,7 +97,7 @@ void HDeadCodeElimination::RemoveDeadBlocks() { } // Classify blocks as reachable/unreachable. ArenaAllocator* allocator = graph_->GetArena(); - ArenaBitVector live_blocks(allocator, graph_->GetBlocks().size(), false); + ArenaBitVector live_blocks(allocator, graph_->GetBlocks().size(), false, kArenaAllocDCE); MarkReachableBlocks(graph_, &live_blocks); bool removed_one_or_more_blocks = false; diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index 11e3689a82..9491ef6119 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -812,7 +812,10 @@ void GraphChecker::VisitPhi(HPhi* phi) { phi->GetRegNumber(), type_str.str().c_str())); } else { - ArenaBitVector visited(GetGraph()->GetArena(), 0, /* expandable */ true); + ArenaBitVector visited(GetGraph()->GetArena(), + 0, + /* expandable */ true, + kArenaAllocGraphChecker); if (!IsConstantEquivalent(phi, other_phi, &visited)) { AddError(StringPrintf("Two phis (%d and %d) found for VReg %d but they " "are not equivalents of constants.", diff --git a/compiler/optimizing/graph_checker.h b/compiler/optimizing/graph_checker.h index 52252cd3d4..8da8457859 100644 --- a/compiler/optimizing/graph_checker.h +++ b/compiler/optimizing/graph_checker.h @@ -30,7 +30,10 @@ class GraphChecker : public HGraphDelegateVisitor { : HGraphDelegateVisitor(graph), errors_(graph->GetArena()->Adapter(kArenaAllocGraphChecker)), dump_prefix_(dump_prefix), - seen_ids_(graph->GetArena(), graph->GetCurrentInstructionId(), false) {} + seen_ids_(graph->GetArena(), + graph->GetCurrentInstructionId(), + false, + kArenaAllocGraphChecker) {} // Check the whole graph (in reverse post-order). void Run() { diff --git a/compiler/optimizing/gvn.cc b/compiler/optimizing/gvn.cc index b4922789d4..f7eb2adc6c 100644 --- a/compiler/optimizing/gvn.cc +++ b/compiler/optimizing/gvn.cc @@ -40,7 +40,7 @@ class ValueSet : public ArenaObject<kArenaAllocGvn> { : allocator_(allocator), num_buckets_(kMinimumNumberOfBuckets), buckets_(allocator->AllocArray<Node*>(num_buckets_, kArenaAllocGvn)), - buckets_owned_(allocator, num_buckets_, false), + buckets_owned_(allocator, num_buckets_, false, kArenaAllocGvn), num_entries_(0) { // ArenaAllocator returns zeroed memory, so no need to set buckets to null. DCHECK(IsPowerOfTwo(num_buckets_)); @@ -53,7 +53,7 @@ class ValueSet : public ArenaObject<kArenaAllocGvn> { : allocator_(allocator), num_buckets_(to_copy.IdealBucketCount()), buckets_(allocator->AllocArray<Node*>(num_buckets_, kArenaAllocGvn)), - buckets_owned_(allocator, num_buckets_, false), + buckets_owned_(allocator, num_buckets_, false, kArenaAllocGvn), num_entries_(to_copy.num_entries_) { // ArenaAllocator returns zeroed memory, so entries of buckets_ and // buckets_owned_ are initialized to null and false, respectively. diff --git a/compiler/optimizing/licm.cc b/compiler/optimizing/licm.cc index 33bb2e8f30..7a1e06b951 100644 --- a/compiler/optimizing/licm.cc +++ b/compiler/optimizing/licm.cc @@ -80,7 +80,7 @@ static void UpdateLoopPhisIn(HEnvironment* environment, HLoopInformation* info) void LICM::Run() { DCHECK(side_effects_.HasRun()); // Only used during debug. - ArenaBitVector visited(graph_->GetArena(), graph_->GetBlocks().size(), false); + ArenaBitVector visited(graph_->GetArena(), graph_->GetBlocks().size(), false, kArenaAllocLICM); // Post order visit to visit inner loops before outer loops. for (HPostOrderIterator it(*graph_); !it.Done(); it.Advance()) { diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc index 9601b066e5..e1977b1798 100644 --- a/compiler/optimizing/load_store_elimination.cc +++ b/compiler/optimizing/load_store_elimination.cc @@ -186,7 +186,10 @@ class HeapLocationCollector : public HGraphVisitor { : HGraphVisitor(graph), ref_info_array_(graph->GetArena()->Adapter(kArenaAllocLSE)), heap_locations_(graph->GetArena()->Adapter(kArenaAllocLSE)), - aliasing_matrix_(graph->GetArena(), kInitialAliasingMatrixBitVectorSize, true), + aliasing_matrix_(graph->GetArena(), + kInitialAliasingMatrixBitVectorSize, + true, + kArenaAllocLSE), has_heap_stores_(false), has_volatile_(false), has_monitor_operations_(false), diff --git a/compiler/optimizing/locations.cc b/compiler/optimizing/locations.cc index 1ab206f69e..83596da41a 100644 --- a/compiler/optimizing/locations.cc +++ b/compiler/optimizing/locations.cc @@ -37,7 +37,7 @@ LocationSummary::LocationSummary(HInstruction* instruction, if (NeedsSafepoint()) { ArenaAllocator* arena = instruction->GetBlock()->GetGraph()->GetArena(); - stack_mask_ = new (arena) ArenaBitVector(arena, 0, true); + stack_mask_ = ArenaBitVector::Create(arena, 0, true, kArenaAllocLocationSummary); } } diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 98766a31a6..c83340b1f6 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -54,7 +54,7 @@ void HGraph::FindBackEdges(ArenaBitVector* visited) { DCHECK_EQ(visited->GetHighestBitSet(), -1); // Nodes that we're currently visiting, indexed by block id. - ArenaBitVector visiting(arena_, blocks_.size(), false); + ArenaBitVector visiting(arena_, blocks_.size(), false, kArenaAllocGraphBuilder); // Number of successors visited from a given node, indexed by block id. ArenaVector<size_t> successors_visited(blocks_.size(), 0u, arena_->Adapter()); // Stack of nodes that we're currently visiting (same as marked in "visiting" above). @@ -140,7 +140,7 @@ GraphAnalysisResult HGraph::BuildDominatorTree() { // collect both normal- and exceptional-flow values at the same time. SimplifyCatchBlocks(); - ArenaBitVector visited(arena_, blocks_.size(), false); + ArenaBitVector visited(arena_, blocks_.size(), false, kArenaAllocGraphBuilder); // (2) Find the back edges in the graph doing a DFS traversal. FindBackEdges(&visited); diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 46377ee503..673631958a 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -645,7 +645,7 @@ class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> { irreducible_(false), back_edges_(graph->GetArena()->Adapter(kArenaAllocLoopInfoBackEdges)), // Make bit vector growable, as the number of blocks may change. - blocks_(graph->GetArena(), graph->GetBlocks().size(), true) { + blocks_(graph->GetArena(), graph->GetBlocks().size(), true, kArenaAllocLoopInfoBackEdges) { back_edges_.reserve(kDefaultNumberOfBackEdges); } diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index b8d76b912e..34d9af1e74 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -445,7 +445,7 @@ class AllRangesIterator : public ValueObject { bool RegisterAllocator::ValidateInternal(bool log_fatal_on_failure) const { // To simplify unit testing, we eagerly create the array of intervals, and // call the helper method. - ArenaVector<LiveInterval*> intervals(allocator_->Adapter(kArenaAllocRegisterAllocator)); + ArenaVector<LiveInterval*> intervals(allocator_->Adapter(kArenaAllocRegisterAllocatorValidate)); for (size_t i = 0; i < liveness_.GetNumberOfSsaValues(); ++i) { HInstruction* instruction = liveness_.GetInstructionFromSsaIndex(i); if (ShouldProcess(processing_core_registers_, instruction->GetLiveInterval())) { @@ -483,13 +483,21 @@ bool RegisterAllocator::ValidateIntervals(const ArenaVector<LiveInterval*>& inte ? codegen.GetNumberOfCoreRegisters() : codegen.GetNumberOfFloatingPointRegisters(); ArenaVector<ArenaBitVector*> liveness_of_values( - allocator->Adapter(kArenaAllocRegisterAllocator)); + allocator->Adapter(kArenaAllocRegisterAllocatorValidate)); liveness_of_values.reserve(number_of_registers + number_of_spill_slots); + size_t max_end = 0u; + for (LiveInterval* start_interval : intervals) { + for (AllRangesIterator it(start_interval); !it.Done(); it.Advance()) { + max_end = std::max(max_end, it.CurrentRange()->GetEnd()); + } + } + // Allocate a bit vector per register. A live interval that has a register // allocated will populate the associated bit vector based on its live ranges. for (size_t i = 0; i < number_of_registers + number_of_spill_slots; ++i) { - liveness_of_values.push_back(new (allocator) ArenaBitVector(allocator, 0, true)); + liveness_of_values.push_back( + ArenaBitVector::Create(allocator, max_end, false, kArenaAllocRegisterAllocatorValidate)); } for (LiveInterval* start_interval : intervals) { diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h index a78aedcff5..97f2aeeb1e 100644 --- a/compiler/optimizing/ssa_liveness_analysis.h +++ b/compiler/optimizing/ssa_liveness_analysis.h @@ -31,9 +31,9 @@ class BlockInfo : public ArenaObject<kArenaAllocSsaLiveness> { public: BlockInfo(ArenaAllocator* allocator, const HBasicBlock& block, size_t number_of_ssa_values) : block_(block), - live_in_(allocator, number_of_ssa_values, false), - live_out_(allocator, number_of_ssa_values, false), - kill_(allocator, number_of_ssa_values, false) { + live_in_(allocator, number_of_ssa_values, false, kArenaAllocSsaLiveness), + live_out_(allocator, number_of_ssa_values, false, kArenaAllocSsaLiveness), + kill_(allocator, number_of_ssa_values, false, kArenaAllocSsaLiveness) { UNUSED(block_); live_in_.ClearAllBits(); live_out_.ClearAllBits(); diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc index 54cbdf8b66..3f41e3594e 100644 --- a/compiler/optimizing/stack_map_stream.cc +++ b/compiler/optimizing/stack_map_stream.cc @@ -37,7 +37,7 @@ void StackMapStream::BeginStackMapEntry(uint32_t dex_pc, current_entry_.same_dex_register_map_as_ = kNoSameDexMapFound; if (num_dex_registers != 0) { current_entry_.live_dex_registers_mask = - new (allocator_) ArenaBitVector(allocator_, num_dex_registers, true); + ArenaBitVector::Create(allocator_, num_dex_registers, true, kArenaAllocStackMapStream); } else { current_entry_.live_dex_registers_mask = nullptr; } @@ -111,7 +111,7 @@ void StackMapStream::BeginInlineInfoEntry(uint32_t method_index, current_inline_info_.dex_register_locations_start_index = dex_register_locations_.size(); if (num_dex_registers != 0) { current_inline_info_.live_dex_registers_mask = - new (allocator_) ArenaBitVector(allocator_, num_dex_registers, true); + ArenaBitVector::Create(allocator_, num_dex_registers, true, kArenaAllocStackMapStream); } else { current_inline_info_.live_dex_registers_mask = nullptr; } @@ -256,7 +256,7 @@ void StackMapStream::FillIn(MemoryRegion region) { // Ensure we reached the end of the Dex registers location_catalog. DCHECK_EQ(location_catalog_offset, dex_register_location_catalog_region.size()); - ArenaBitVector empty_bitmask(allocator_, 0, /* expandable */ false); + ArenaBitVector empty_bitmask(allocator_, 0, /* expandable */ false, kArenaAllocStackMapStream); uintptr_t next_dex_register_map_offset = 0; uintptr_t next_inline_info_offset = 0; for (size_t i = 0, e = stack_maps_.size(); i < e; ++i) { |