caller_instruction_counter);
callee_graph->SetArtMethod(resolved_method);
- // When they are needed, allocate `inline_stats` on the heap instead
+ // When they are needed, allocate `inline_stats_` on the Arena instead
// of on the stack, as Clang might produce a stack frame too large
// for this function, that would not fit the requirements of the
// `-Wframe-larger-than` option.
- std::unique_ptr<OptimizingCompilerStats> inline_stats =
- (stats_ == nullptr) ? nullptr : MakeUnique<OptimizingCompilerStats>();
+ if (stats_ != nullptr) {
+ // Reuse one object for all inline attempts from this caller to keep Arena memory usage low.
+ if (inline_stats_ == nullptr) {
+ void* storage = graph_->GetArena()->Alloc<OptimizingCompilerStats>(kArenaAllocMisc);
+ inline_stats_ = new (storage) OptimizingCompilerStats;
+ } else {
+ inline_stats_->Reset();
+ }
+ }
HGraphBuilder builder(callee_graph,
&dex_compilation_unit,
&outer_compilation_unit_,
*code_item,
compiler_driver_,
codegen_,
- inline_stats.get(),
+ inline_stats_,
resolved_method->GetQuickenedInfo(class_linker->GetImagePointerSize()),
dex_cache,
handles_);
DCHECK_EQ(callee_instruction_counter, callee_graph->GetCurrentInstructionId())
<< "No instructions can be added to the inner graph during inlining into the outer graph";
+ if (stats_ != nullptr) {
+ DCHECK(inline_stats_ != nullptr);
+ inline_stats_->AddTo(stats_);
+ }
+
return true;
}
const DexCompilationUnit& dex_compilation_unit) {
// Note: if the outermost_graph_ is being compiled OSR, we should not run any
// optimization that could lead to a HDeoptimize. The following optimizations do not.
- HDeadCodeElimination dce(callee_graph, stats_, "dead_code_elimination$inliner");
+ HDeadCodeElimination dce(callee_graph, inline_stats_, "dead_code_elimination$inliner");
HConstantFolding fold(callee_graph, "constant_folding$inliner");
HSharpening sharpening(callee_graph, codegen_, dex_compilation_unit, compiler_driver_, handles_);
- InstructionSimplifier simplify(callee_graph, stats_);
- IntrinsicsRecognizer intrinsics(callee_graph, stats_);
+ InstructionSimplifier simplify(callee_graph, inline_stats_);
+ IntrinsicsRecognizer intrinsics(callee_graph, inline_stats_);
HOptimization* optimizations[] = {
&intrinsics,
dex_compilation_unit,
compiler_driver_,
handles_,
- stats_,
+ inline_stats_,
total_number_of_dex_registers_ + code_item->registers_size_,
depth_ + 1);
inliner.Run();
total_number_of_dex_registers_(total_number_of_dex_registers),
depth_(depth),
number_of_inlined_instructions_(0),
- handles_(handles) {}
+ handles_(handles),
+ inline_stats_(nullptr) {}
void Run() OVERRIDE;
size_t number_of_inlined_instructions_;
VariableSizedHandleScope* const handles_;
+ // Used to record stats about optimizations on the inlined graph.
+ // If the inlining is successful, these stats are merged to the caller graph's stats.
+ OptimizingCompilerStats* inline_stats_;
+
DISALLOW_COPY_AND_ASSIGN(HInliner);
};
#ifndef ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_
#define ART_COMPILER_OPTIMIZING_OPTIMIZING_COMPILER_STATS_H_
+#include <atomic>
#include <iomanip>
#include <string>
#include <type_traits>
public:
OptimizingCompilerStats() {}
- void RecordStat(MethodCompilationStat stat, size_t count = 1) {
+ void RecordStat(MethodCompilationStat stat, uint32_t count = 1) {
compile_stats_[stat] += count;
}
<< " methods: " << std::fixed << std::setprecision(2)
<< compiled_percent << "% (" << compile_stats_[kCompiled] << ") compiled.";
- for (int i = 0; i < kLastStat; i++) {
+ for (size_t i = 0; i < kLastStat; i++) {
if (compile_stats_[i] != 0) {
LOG(INFO) << PrintMethodCompilationStat(static_cast<MethodCompilationStat>(i)) << ": "
<< compile_stats_[i];
}
}
+ void AddTo(OptimizingCompilerStats* other_stats) {
+ for (size_t i = 0; i != kLastStat; ++i) {
+ uint32_t count = compile_stats_[i];
+ if (count != 0) {
+ other_stats->RecordStat(static_cast<MethodCompilationStat>(i), count);
+ }
+ }
+ }
+
+ void Reset() {
+ for (size_t i = 0; i != kLastStat; ++i) {
+ compile_stats_[i] = 0u;
+ }
+ }
+
private:
std::string PrintMethodCompilationStat(MethodCompilationStat stat) const {
std::string name;
return "OptStat#" + name;
}
- AtomicInteger compile_stats_[kLastStat];
+ std::atomic<uint32_t> compile_stats_[kLastStat];
DISALLOW_COPY_AND_ASSIGN(OptimizingCompilerStats);
};