[turbofan] split compilation stats off from HStatistics and track high water marks
R=jarin@chromium.org BUG= Review URL: https://codereview.chromium.org/669053002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24830 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b6f66b5fc7
commit
5f83dabb60
4
BUILD.gn
4
BUILD.gn
@ -474,6 +474,8 @@ source_set("v8_base") {
|
||||
"src/codegen.h",
|
||||
"src/compilation-cache.cc",
|
||||
"src/compilation-cache.h",
|
||||
"src/compilation-statistics.cc",
|
||||
"src/compilation-statistics.h",
|
||||
"src/compiler/access-builder.cc",
|
||||
"src/compiler/access-builder.h",
|
||||
"src/compiler/ast-graph-builder.cc",
|
||||
@ -560,6 +562,8 @@ source_set("v8_base") {
|
||||
"src/compiler/phi-reducer.h",
|
||||
"src/compiler/pipeline.cc",
|
||||
"src/compiler/pipeline.h",
|
||||
"src/compiler/pipeline-statistics.cc",
|
||||
"src/compiler/pipeline-statistics.h",
|
||||
"src/compiler/raw-machine-assembler.cc",
|
||||
"src/compiler/raw-machine-assembler.h",
|
||||
"src/compiler/register-allocator.cc",
|
||||
|
140
src/compilation-statistics.cc
Normal file
140
src/compilation-statistics.cc
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <iostream> // NOLINT(readability/streams)
|
||||
#include <vector>
|
||||
|
||||
#include "src/base/platform/platform.h"
|
||||
#include "src/compilation-statistics.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void CompilationStatistics::RecordPhaseStats(const char* phase_kind_name,
|
||||
const char* phase_name,
|
||||
const BasicStats& stats) {
|
||||
std::string phase_name_str(phase_name);
|
||||
auto it = phase_map_.find(phase_name_str);
|
||||
if (it == phase_map_.end()) {
|
||||
PhaseStats phase_stats(phase_map_.size(), phase_kind_name);
|
||||
it = phase_map_.insert(std::make_pair(phase_name_str, phase_stats)).first;
|
||||
}
|
||||
it->second.Accumulate(stats);
|
||||
}
|
||||
|
||||
|
||||
void CompilationStatistics::RecordPhaseKindStats(const char* phase_kind_name,
|
||||
const BasicStats& stats) {
|
||||
std::string phase_kind_name_str(phase_kind_name);
|
||||
auto it = phase_kind_map_.find(phase_kind_name_str);
|
||||
if (it == phase_kind_map_.end()) {
|
||||
PhaseKindStats phase_kind_stats(phase_kind_map_.size());
|
||||
it = phase_kind_map_.insert(std::make_pair(phase_kind_name_str,
|
||||
phase_kind_stats)).first;
|
||||
}
|
||||
it->second.Accumulate(stats);
|
||||
}
|
||||
|
||||
|
||||
void CompilationStatistics::RecordTotalStats(size_t source_size,
|
||||
const BasicStats& stats) {
|
||||
source_size += source_size;
|
||||
total_stats_.Accumulate(stats);
|
||||
}
|
||||
|
||||
|
||||
void CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) {
|
||||
delta_ += stats.delta_;
|
||||
total_allocated_bytes_ += stats.total_allocated_bytes_;
|
||||
if (stats.max_allocated_bytes_ > max_allocated_bytes_) {
|
||||
max_allocated_bytes_ = stats.max_allocated_bytes_;
|
||||
function_name_ = stats.function_name_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void WriteLine(std::ostream& os, const char* name,
|
||||
const CompilationStatistics::BasicStats& stats,
|
||||
const CompilationStatistics::BasicStats& total_stats) {
|
||||
const size_t kBufferSize = 128;
|
||||
char buffer[kBufferSize];
|
||||
|
||||
double ms = stats.delta_.InMillisecondsF();
|
||||
double percent = stats.delta_.PercentOf(total_stats.delta_);
|
||||
double size_percent =
|
||||
static_cast<double>(stats.total_allocated_bytes_ * 100) /
|
||||
static_cast<double>(total_stats.total_allocated_bytes_);
|
||||
base::OS::SNPrintF(buffer, kBufferSize,
|
||||
"%28s %10.3f ms / %5.1f %% %10u total / %5.1f %% %10u max",
|
||||
name, ms, percent, stats.total_allocated_bytes_,
|
||||
size_percent, stats.max_allocated_bytes_);
|
||||
|
||||
os << buffer;
|
||||
if (stats.function_name_.size() > 0) {
|
||||
os << " : " << stats.function_name_.c_str();
|
||||
}
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
|
||||
static void WriteFullLine(std::ostream& os) {
|
||||
os << "-----------------------------------------------"
|
||||
"-----------------------------------------------\n";
|
||||
}
|
||||
|
||||
|
||||
static void WriteHeader(std::ostream& os) {
|
||||
WriteFullLine(os);
|
||||
os << " Turbofan timing results:\n";
|
||||
WriteFullLine(os);
|
||||
}
|
||||
|
||||
|
||||
static void WritePhaseKindBreak(std::ostream& os) {
|
||||
os << " ------------------"
|
||||
"-----------------------------------------------\n";
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CompilationStatistics& s) {
|
||||
// phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of
|
||||
// pointers into them.
|
||||
|
||||
typedef std::vector<CompilationStatistics::PhaseKindMap::const_iterator>
|
||||
SortedPhaseKinds;
|
||||
SortedPhaseKinds sorted_phase_kinds(s.phase_kind_map_.size());
|
||||
for (auto it = s.phase_kind_map_.begin(); it != s.phase_kind_map_.end();
|
||||
++it) {
|
||||
sorted_phase_kinds[it->second.insert_order_] = it;
|
||||
}
|
||||
|
||||
typedef std::vector<CompilationStatistics::PhaseMap::const_iterator>
|
||||
SortedPhases;
|
||||
SortedPhases sorted_phases(s.phase_map_.size());
|
||||
for (auto it = s.phase_map_.begin(); it != s.phase_map_.end(); ++it) {
|
||||
sorted_phases[it->second.insert_order_] = it;
|
||||
}
|
||||
|
||||
WriteHeader(os);
|
||||
for (auto phase_kind_it : sorted_phase_kinds) {
|
||||
const auto& phase_kind_name = phase_kind_it->first;
|
||||
for (auto phase_it : sorted_phases) {
|
||||
const auto& phase_stats = phase_it->second;
|
||||
if (phase_stats.phase_kind_name_ != phase_kind_name) continue;
|
||||
const auto& phase_name = phase_it->first;
|
||||
WriteLine(os, phase_name.c_str(), phase_stats, s.total_stats_);
|
||||
}
|
||||
WritePhaseKindBreak(os);
|
||||
const auto& phase_kind_stats = phase_kind_it->second;
|
||||
WriteLine(os, phase_kind_name.c_str(), phase_kind_stats, s.total_stats_);
|
||||
os << std::endl;
|
||||
}
|
||||
WriteFullLine(os);
|
||||
WriteLine(os, "totals", s.total_stats_, s.total_stats_);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
82
src/compilation-statistics.h
Normal file
82
src/compilation-statistics.h
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_COMPILATION_STATISTICS_H_
|
||||
#define V8_COMPILATION_STATISTICS_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "src/allocation.h"
|
||||
#include "src/base/platform/time.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
class CompilationInfo;
|
||||
|
||||
class CompilationStatistics FINAL : public Malloced {
|
||||
public:
|
||||
CompilationStatistics() {}
|
||||
|
||||
class BasicStats {
|
||||
public:
|
||||
BasicStats() : total_allocated_bytes_(0), max_allocated_bytes_(0) {}
|
||||
|
||||
void Accumulate(const BasicStats& stats);
|
||||
|
||||
base::TimeDelta delta_;
|
||||
size_t total_allocated_bytes_;
|
||||
size_t max_allocated_bytes_;
|
||||
std::string function_name_;
|
||||
};
|
||||
|
||||
void RecordPhaseStats(const char* phase_kind_name, const char* phase_name,
|
||||
const BasicStats& stats);
|
||||
|
||||
void RecordPhaseKindStats(const char* phase_kind_name,
|
||||
const BasicStats& stats);
|
||||
|
||||
void RecordTotalStats(size_t source_size, const BasicStats& stats);
|
||||
|
||||
private:
|
||||
class TotalStats : public BasicStats {
|
||||
public:
|
||||
TotalStats() : source_size_(0) {}
|
||||
uint64_t source_size_;
|
||||
};
|
||||
|
||||
class OrderedStats : public BasicStats {
|
||||
public:
|
||||
explicit OrderedStats(size_t insert_order) : insert_order_(insert_order) {}
|
||||
size_t insert_order_;
|
||||
};
|
||||
|
||||
class PhaseStats : public OrderedStats {
|
||||
public:
|
||||
PhaseStats(size_t insert_order, const char* phase_kind_name)
|
||||
: OrderedStats(insert_order), phase_kind_name_(phase_kind_name) {}
|
||||
std::string phase_kind_name_;
|
||||
};
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,
|
||||
const CompilationStatistics& s);
|
||||
|
||||
typedef OrderedStats PhaseKindStats;
|
||||
typedef std::map<std::string, PhaseKindStats> PhaseKindMap;
|
||||
typedef std::map<std::string, PhaseStats> PhaseMap;
|
||||
|
||||
TotalStats total_stats_;
|
||||
PhaseKindMap phase_kind_map_;
|
||||
PhaseMap phase_map_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CompilationStatistics);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CompilationStatistics& s);
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif
|
97
src/compiler/pipeline-statistics.cc
Normal file
97
src/compiler/pipeline-statistics.cc
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/compiler.h"
|
||||
#include "src/compiler/pipeline-statistics.h"
|
||||
#include "src/compiler/zone-pool.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
void PipelineStatistics::CommonStats::Begin(
|
||||
PipelineStatistics* pipeline_stats) {
|
||||
DCHECK(scope_.is_empty());
|
||||
scope_.Reset(new ZonePool::StatsScope(pipeline_stats->zone_pool_));
|
||||
timer_.Start();
|
||||
outer_zone_initial_size_ = pipeline_stats->OuterZoneSize();
|
||||
}
|
||||
|
||||
|
||||
void PipelineStatistics::CommonStats::End(
|
||||
PipelineStatistics* pipeline_stats,
|
||||
CompilationStatistics::BasicStats* diff) {
|
||||
DCHECK(!scope_.is_empty());
|
||||
diff->function_name_ = pipeline_stats->function_name_;
|
||||
diff->delta_ = timer_.Elapsed();
|
||||
size_t outer_zone_diff =
|
||||
pipeline_stats->OuterZoneSize() - outer_zone_initial_size_;
|
||||
diff->max_allocated_bytes_ = outer_zone_diff + scope_->GetMaxAllocatedBytes();
|
||||
diff->total_allocated_bytes_ =
|
||||
outer_zone_diff + scope_->GetTotalAllocatedBytes();
|
||||
scope_.Reset(NULL);
|
||||
timer_.Stop();
|
||||
}
|
||||
|
||||
|
||||
PipelineStatistics::PipelineStatistics(CompilationInfo* info,
|
||||
ZonePool* zone_pool)
|
||||
: isolate_(info->zone()->isolate()),
|
||||
outer_zone_(info->zone()),
|
||||
zone_pool_(zone_pool),
|
||||
compilation_stats_(isolate_->GetTurboStatistics()),
|
||||
source_size_(0),
|
||||
phase_kind_name_(NULL),
|
||||
phase_name_(NULL) {
|
||||
if (!info->shared_info().is_null()) {
|
||||
source_size_ = static_cast<size_t>(info->shared_info()->SourceSize());
|
||||
SmartArrayPointer<char> name =
|
||||
info->shared_info()->DebugName()->ToCString();
|
||||
function_name_ = name.get();
|
||||
}
|
||||
total_stats_.Begin(this);
|
||||
}
|
||||
|
||||
|
||||
PipelineStatistics::~PipelineStatistics() {
|
||||
if (InPhaseKind()) EndPhaseKind();
|
||||
CompilationStatistics::BasicStats diff;
|
||||
total_stats_.End(this, &diff);
|
||||
compilation_stats_->RecordTotalStats(source_size_, diff);
|
||||
}
|
||||
|
||||
|
||||
void PipelineStatistics::BeginPhaseKind(const char* phase_kind_name) {
|
||||
DCHECK(!InPhase());
|
||||
if (InPhaseKind()) EndPhaseKind();
|
||||
phase_kind_name_ = phase_kind_name;
|
||||
phase_kind_stats_.Begin(this);
|
||||
}
|
||||
|
||||
|
||||
void PipelineStatistics::EndPhaseKind() {
|
||||
DCHECK(!InPhase());
|
||||
CompilationStatistics::BasicStats diff;
|
||||
phase_kind_stats_.End(this, &diff);
|
||||
compilation_stats_->RecordPhaseKindStats(phase_kind_name_, diff);
|
||||
}
|
||||
|
||||
|
||||
void PipelineStatistics::BeginPhase(const char* name) {
|
||||
DCHECK(InPhaseKind());
|
||||
phase_name_ = name;
|
||||
phase_stats_.Begin(this);
|
||||
}
|
||||
|
||||
|
||||
void PipelineStatistics::EndPhase() {
|
||||
DCHECK(InPhaseKind());
|
||||
CompilationStatistics::BasicStats diff;
|
||||
phase_stats_.End(this, &diff);
|
||||
compilation_stats_->RecordPhaseStats(phase_kind_name_, phase_name_, diff);
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
94
src/compiler/pipeline-statistics.h
Normal file
94
src/compiler/pipeline-statistics.h
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_COMPILER_PIPELINE_STATISTICS_H_
|
||||
#define V8_COMPILER_PIPELINE_STATISTICS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/compilation-statistics.h"
|
||||
#include "src/compiler/zone-pool.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
class PhaseScope;
|
||||
|
||||
class PipelineStatistics : public Malloced {
|
||||
public:
|
||||
PipelineStatistics(CompilationInfo* info, ZonePool* zone_pool);
|
||||
~PipelineStatistics();
|
||||
|
||||
void BeginPhaseKind(const char* phase_kind_name);
|
||||
|
||||
private:
|
||||
size_t OuterZoneSize() {
|
||||
return static_cast<size_t>(outer_zone_->allocation_size());
|
||||
}
|
||||
|
||||
class CommonStats {
|
||||
public:
|
||||
CommonStats() : outer_zone_initial_size_(0) {}
|
||||
|
||||
void Begin(PipelineStatistics* pipeline_stats);
|
||||
void End(PipelineStatistics* pipeline_stats,
|
||||
CompilationStatistics::BasicStats* diff);
|
||||
|
||||
SmartPointer<ZonePool::StatsScope> scope_;
|
||||
base::ElapsedTimer timer_;
|
||||
size_t outer_zone_initial_size_;
|
||||
};
|
||||
|
||||
bool InPhaseKind() { return !phase_kind_stats_.scope_.is_empty(); }
|
||||
void EndPhaseKind();
|
||||
|
||||
friend class PhaseScope;
|
||||
bool InPhase() { return !phase_stats_.scope_.is_empty(); }
|
||||
void BeginPhase(const char* name);
|
||||
void EndPhase();
|
||||
|
||||
Isolate* isolate_;
|
||||
Zone* outer_zone_;
|
||||
ZonePool* zone_pool_;
|
||||
CompilationStatistics* compilation_stats_;
|
||||
std::string function_name_;
|
||||
|
||||
// Stats for the entire compilation.
|
||||
CommonStats total_stats_;
|
||||
size_t source_size_;
|
||||
|
||||
// Stats for phase kind.
|
||||
const char* phase_kind_name_;
|
||||
CommonStats phase_kind_stats_;
|
||||
|
||||
// Stats for phase.
|
||||
const char* phase_name_;
|
||||
CommonStats phase_stats_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PipelineStatistics);
|
||||
};
|
||||
|
||||
|
||||
class PhaseScope {
|
||||
public:
|
||||
PhaseScope(PipelineStatistics* pipeline_stats, const char* name)
|
||||
: pipeline_stats_(pipeline_stats) {
|
||||
if (pipeline_stats_ != NULL) pipeline_stats_->BeginPhase(name);
|
||||
}
|
||||
~PhaseScope() {
|
||||
if (pipeline_stats_ != NULL) pipeline_stats_->EndPhase();
|
||||
}
|
||||
|
||||
private:
|
||||
PipelineStatistics* const pipeline_stats_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(PhaseScope);
|
||||
};
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif
|
@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/compiler/pipeline.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "src/base/platform/elapsed-timer.h"
|
||||
@ -22,6 +20,8 @@
|
||||
#include "src/compiler/js-typed-lowering.h"
|
||||
#include "src/compiler/machine-operator-reducer.h"
|
||||
#include "src/compiler/phi-reducer.h"
|
||||
#include "src/compiler/pipeline.h"
|
||||
#include "src/compiler/pipeline-statistics.h"
|
||||
#include "src/compiler/register-allocator.h"
|
||||
#include "src/compiler/schedule.h"
|
||||
#include "src/compiler/scheduler.h"
|
||||
@ -31,7 +31,6 @@
|
||||
#include "src/compiler/value-numbering-reducer.h"
|
||||
#include "src/compiler/verifier.h"
|
||||
#include "src/compiler/zone-pool.h"
|
||||
#include "src/hydrogen.h"
|
||||
#include "src/ostreams.h"
|
||||
#include "src/utils.h"
|
||||
|
||||
@ -39,55 +38,6 @@ namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
class PhaseStats {
|
||||
public:
|
||||
enum PhaseKind { CREATE_GRAPH, OPTIMIZATION, CODEGEN };
|
||||
|
||||
PhaseStats(CompilationInfo* info, ZonePool* zone_pool, PhaseKind kind,
|
||||
const char* name)
|
||||
: info_(info),
|
||||
stats_scope_(zone_pool),
|
||||
kind_(kind),
|
||||
name_(name),
|
||||
size_(0) {
|
||||
if (FLAG_turbo_stats) {
|
||||
timer_.Start();
|
||||
size_ = info_->zone()->allocation_size();
|
||||
}
|
||||
}
|
||||
|
||||
~PhaseStats() {
|
||||
if (FLAG_turbo_stats) {
|
||||
base::TimeDelta delta = timer_.Elapsed();
|
||||
size_t bytes = info_->zone()->allocation_size() +
|
||||
stats_scope_.GetMaxAllocatedBytes() - size_;
|
||||
HStatistics* stats = info_->isolate()->GetTStatistics();
|
||||
stats->SaveTiming(name_, delta, static_cast<int>(bytes));
|
||||
|
||||
switch (kind_) {
|
||||
case CREATE_GRAPH:
|
||||
stats->IncrementCreateGraph(delta);
|
||||
break;
|
||||
case OPTIMIZATION:
|
||||
stats->IncrementOptimizeGraph(delta);
|
||||
break;
|
||||
case CODEGEN:
|
||||
stats->IncrementGenerateCode(delta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CompilationInfo* info_;
|
||||
ZonePool::StatsScope stats_scope_;
|
||||
PhaseKind kind_;
|
||||
const char* name_;
|
||||
size_t size_;
|
||||
base::ElapsedTimer timer_;
|
||||
};
|
||||
|
||||
|
||||
static inline bool VerifyGraphs() {
|
||||
#ifdef DEBUG
|
||||
return true;
|
||||
@ -226,7 +176,13 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
return Handle<Code>::null();
|
||||
}
|
||||
|
||||
if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_);
|
||||
ZonePool zone_pool(isolate());
|
||||
|
||||
SmartPointer<PipelineStatistics> pipeline_statistics;
|
||||
if (FLAG_turbo_stats) {
|
||||
pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
|
||||
pipeline_statistics->BeginPhaseKind("create graph");
|
||||
}
|
||||
|
||||
if (FLAG_trace_turbo) {
|
||||
OFStream os(stdout);
|
||||
@ -237,8 +193,6 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
PrintCompilationStart();
|
||||
}
|
||||
|
||||
ZonePool zone_pool(isolate());
|
||||
|
||||
// Build the graph.
|
||||
Graph graph(zone());
|
||||
SourcePositionTable source_positions(&graph);
|
||||
@ -253,8 +207,7 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
JSGraph jsgraph(&graph, &common, &javascript, &machine);
|
||||
Node* context_node;
|
||||
{
|
||||
PhaseStats graph_builder_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH,
|
||||
"graph builder");
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "graph builder");
|
||||
ZonePool::Scope zone_scope(&zone_pool);
|
||||
AstGraphBuilderWithPositions graph_builder(zone_scope.zone(), info(),
|
||||
&jsgraph, &source_positions);
|
||||
@ -262,8 +215,7 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
context_node = graph_builder.GetFunctionContext();
|
||||
}
|
||||
{
|
||||
PhaseStats phi_reducer_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH,
|
||||
"phi reduction");
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "phi reduction");
|
||||
PhiReducer phi_reducer;
|
||||
GraphReducer graph_reducer(&graph);
|
||||
graph_reducer.AddReducer(&phi_reducer);
|
||||
@ -285,6 +237,7 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
}
|
||||
|
||||
if (info()->is_inlining_enabled()) {
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "inlining");
|
||||
SourcePositionTable::Scope pos(&source_positions,
|
||||
SourcePosition::Unknown());
|
||||
ZonePool::Scope zone_scope(&zone_pool);
|
||||
@ -304,15 +257,20 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
if (info()->is_typing_enabled()) {
|
||||
{
|
||||
// Type the graph.
|
||||
PhaseStats typer_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH,
|
||||
"typer");
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "typer");
|
||||
typer.Run();
|
||||
VerifyAndPrintGraph(&graph, "Typed");
|
||||
}
|
||||
}
|
||||
|
||||
if (!pipeline_statistics.is_empty()) {
|
||||
pipeline_statistics->BeginPhaseKind("lowering");
|
||||
}
|
||||
|
||||
if (info()->is_typing_enabled()) {
|
||||
{
|
||||
// Lower JSOperators where we can determine types.
|
||||
PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH,
|
||||
"typed lowering");
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "typed lowering");
|
||||
SourcePositionTable::Scope pos(&source_positions,
|
||||
SourcePosition::Unknown());
|
||||
ValueNumberingReducer vn_reducer(zone());
|
||||
@ -328,8 +286,7 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
}
|
||||
{
|
||||
// Lower simplified operators and insert changes.
|
||||
PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH,
|
||||
"simplified lowering");
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "simplified lowering");
|
||||
SourcePositionTable::Scope pos(&source_positions,
|
||||
SourcePosition::Unknown());
|
||||
SimplifiedLowering lowering(&jsgraph);
|
||||
@ -345,8 +302,7 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
}
|
||||
{
|
||||
// Lower changes that have been inserted before.
|
||||
PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::OPTIMIZATION,
|
||||
"change lowering");
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "change lowering");
|
||||
SourcePositionTable::Scope pos(&source_positions,
|
||||
SourcePosition::Unknown());
|
||||
Linkage linkage(info());
|
||||
@ -367,10 +323,9 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
}
|
||||
|
||||
{
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "control reduction");
|
||||
SourcePositionTable::Scope pos(&source_positions,
|
||||
SourcePosition::Unknown());
|
||||
PhaseStats control_reducer_stats(
|
||||
info(), &zone_pool, PhaseStats::CREATE_GRAPH, "control reduction");
|
||||
ZonePool::Scope zone_scope(&zone_pool);
|
||||
ControlReducer::ReduceGraph(zone_scope.zone(), &jsgraph, &common);
|
||||
|
||||
@ -380,8 +335,7 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
|
||||
{
|
||||
// Lower any remaining generic JSOperators.
|
||||
PhaseStats lowering_stats(info(), &zone_pool, PhaseStats::CREATE_GRAPH,
|
||||
"generic lowering");
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "generic lowering");
|
||||
SourcePositionTable::Scope pos(&source_positions,
|
||||
SourcePosition::Unknown());
|
||||
JSGenericLowering lowering(info(), &jsgraph);
|
||||
@ -393,18 +347,25 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
VerifyAndPrintGraph(&graph, "Lowered generic", true);
|
||||
}
|
||||
|
||||
if (!pipeline_statistics.is_empty()) {
|
||||
pipeline_statistics->BeginPhaseKind("code generation");
|
||||
}
|
||||
|
||||
source_positions.RemoveDecorator();
|
||||
|
||||
Schedule* schedule;
|
||||
{
|
||||
PhaseScope phase_scope(pipeline_statistics.get(), "scheduling");
|
||||
// Compute a schedule.
|
||||
schedule = ComputeSchedule(&zone_pool, &graph);
|
||||
}
|
||||
|
||||
Handle<Code> code = Handle<Code>::null();
|
||||
{
|
||||
// Compute a schedule.
|
||||
Schedule* schedule = ComputeSchedule(&zone_pool, &graph);
|
||||
// Generate optimized code.
|
||||
PhaseStats codegen_stats(info(), &zone_pool, PhaseStats::CODEGEN,
|
||||
"codegen");
|
||||
Linkage linkage(info());
|
||||
code =
|
||||
GenerateCode(&zone_pool, &linkage, &graph, schedule, &source_positions);
|
||||
code = GenerateCode(pipeline_statistics.get(), &zone_pool, &linkage, &graph,
|
||||
schedule, &source_positions);
|
||||
info()->SetCode(code);
|
||||
}
|
||||
|
||||
@ -424,8 +385,6 @@ Handle<Code> Pipeline::GenerateCode() {
|
||||
|
||||
|
||||
Schedule* Pipeline::ComputeSchedule(ZonePool* zone_pool, Graph* graph) {
|
||||
PhaseStats schedule_stats(info(), zone_pool, PhaseStats::CODEGEN,
|
||||
"scheduling");
|
||||
Schedule* schedule = Scheduler::ComputeSchedule(zone_pool, graph);
|
||||
TraceSchedule(schedule);
|
||||
if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
|
||||
@ -446,8 +405,8 @@ Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
|
||||
TraceSchedule(schedule);
|
||||
|
||||
SourcePositionTable source_positions(graph);
|
||||
Handle<Code> code =
|
||||
GenerateCode(&zone_pool, linkage, graph, schedule, &source_positions);
|
||||
Handle<Code> code = GenerateCode(NULL, &zone_pool, linkage, graph, schedule,
|
||||
&source_positions);
|
||||
#if ENABLE_DISASSEMBLER
|
||||
if (!code.is_null() && FLAG_print_opt_code) {
|
||||
CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
|
||||
@ -459,7 +418,8 @@ Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
|
||||
}
|
||||
|
||||
|
||||
Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage,
|
||||
Handle<Code> Pipeline::GenerateCode(PipelineStatistics* pipeline_statistics,
|
||||
ZonePool* zone_pool, Linkage* linkage,
|
||||
Graph* graph, Schedule* schedule,
|
||||
SourcePositionTable* source_positions) {
|
||||
DCHECK_NOT_NULL(graph);
|
||||
@ -477,6 +437,7 @@ Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage,
|
||||
|
||||
// Select and schedule instructions covering the scheduled graph.
|
||||
{
|
||||
PhaseScope phase_scope(pipeline_statistics, "select instructions");
|
||||
ZonePool::Scope zone_scope(zone_pool);
|
||||
InstructionSelector selector(zone_scope.zone(), linkage, &sequence,
|
||||
schedule, source_positions);
|
||||
@ -502,7 +463,7 @@ Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage,
|
||||
ZonePool::Scope zone_scope(zone_pool);
|
||||
RegisterAllocator allocator(zone_scope.zone(), &frame, linkage->info(),
|
||||
&sequence);
|
||||
if (!allocator.Allocate(zone_pool)) {
|
||||
if (!allocator.Allocate(pipeline_statistics)) {
|
||||
linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
|
||||
return Handle<Code>::null();
|
||||
}
|
||||
@ -518,8 +479,12 @@ Handle<Code> Pipeline::GenerateCode(ZonePool* zone_pool, Linkage* linkage,
|
||||
}
|
||||
|
||||
// Generate native sequence.
|
||||
CodeGenerator generator(&frame, linkage, &sequence);
|
||||
Handle<Code> code = generator.GenerateCode();
|
||||
Handle<Code> code;
|
||||
{
|
||||
PhaseScope phase_scope(pipeline_statistics, "generate code");
|
||||
CodeGenerator generator(&frame, linkage, &sequence);
|
||||
code = generator.GenerateCode();
|
||||
}
|
||||
if (profiler_data != NULL) {
|
||||
#if ENABLE_DISASSEMBLER
|
||||
std::ostringstream os;
|
||||
|
@ -22,6 +22,7 @@ namespace compiler {
|
||||
class Graph;
|
||||
class InstructionSequence;
|
||||
class Linkage;
|
||||
class PipelineStatistics;
|
||||
class RegisterAllocator;
|
||||
class Schedule;
|
||||
class SourcePositionTable;
|
||||
@ -61,7 +62,8 @@ class Pipeline {
|
||||
void PrintAllocator(const char* phase, const RegisterAllocator* allocator);
|
||||
void VerifyAndPrintGraph(Graph* graph, const char* phase,
|
||||
bool untyped = false);
|
||||
Handle<Code> GenerateCode(ZonePool* zone_pool, Linkage* linkage, Graph* graph,
|
||||
Handle<Code> GenerateCode(PipelineStatistics* pipeline_statistics,
|
||||
ZonePool* zone_pool, Linkage* linkage, Graph* graph,
|
||||
Schedule* schedule,
|
||||
SourcePositionTable* source_positions);
|
||||
};
|
||||
|
@ -2,10 +2,9 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "src/compiler/register-allocator.h"
|
||||
|
||||
#include "src/compiler/linkage.h"
|
||||
#include "src/hydrogen.h"
|
||||
#include "src/compiler/pipeline-statistics.h"
|
||||
#include "src/compiler/register-allocator.h"
|
||||
#include "src/string-stream.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -503,7 +502,6 @@ RegisterAllocator::RegisterAllocator(Zone* local_zone, Frame* frame,
|
||||
CompilationInfo* info,
|
||||
InstructionSequence* code)
|
||||
: zone_(local_zone),
|
||||
zone_pool_(NULL),
|
||||
frame_(frame),
|
||||
info_(info),
|
||||
code_(code),
|
||||
@ -1096,72 +1094,53 @@ void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
|
||||
}
|
||||
|
||||
|
||||
bool RegisterAllocator::Allocate(ZonePool* zone_pool) {
|
||||
DCHECK_EQ(NULL, zone_pool_);
|
||||
zone_pool_ = zone_pool;
|
||||
bool RegisterAllocator::Allocate(PipelineStatistics* stats) {
|
||||
assigned_registers_ = new (code_zone())
|
||||
BitVector(Register::NumAllocatableRegisters(), code_zone());
|
||||
assigned_double_registers_ = new (code_zone())
|
||||
BitVector(DoubleRegister::NumAllocatableAliasedRegisters(), code_zone());
|
||||
MeetRegisterConstraints();
|
||||
{
|
||||
PhaseScope phase_scope(stats, "meet register constraints");
|
||||
MeetRegisterConstraints();
|
||||
}
|
||||
if (!AllocationOk()) return false;
|
||||
ResolvePhis();
|
||||
BuildLiveRanges();
|
||||
AllocateGeneralRegisters();
|
||||
{
|
||||
PhaseScope phase_scope(stats, "resolve phis");
|
||||
ResolvePhis();
|
||||
}
|
||||
{
|
||||
PhaseScope phase_scope(stats, "build live ranges");
|
||||
BuildLiveRanges();
|
||||
}
|
||||
{
|
||||
PhaseScope phase_scope(stats, "allocate general registers");
|
||||
AllocateGeneralRegisters();
|
||||
}
|
||||
if (!AllocationOk()) return false;
|
||||
AllocateDoubleRegisters();
|
||||
{
|
||||
PhaseScope phase_scope(stats, "allocate double registers");
|
||||
AllocateDoubleRegisters();
|
||||
}
|
||||
if (!AllocationOk()) return false;
|
||||
PopulatePointerMaps();
|
||||
ConnectRanges();
|
||||
ResolveControlFlow();
|
||||
{
|
||||
PhaseScope phase_scope(stats, "populate pointer maps");
|
||||
PopulatePointerMaps();
|
||||
}
|
||||
{
|
||||
PhaseScope phase_scope(stats, "connect ranges");
|
||||
ConnectRanges();
|
||||
}
|
||||
{
|
||||
PhaseScope phase_scope(stats, "resolve control flow");
|
||||
ResolveControlFlow();
|
||||
}
|
||||
frame()->SetAllocatedRegisters(assigned_registers_);
|
||||
frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class RegisterAllocatorPhase : public CompilationPhase {
|
||||
public:
|
||||
RegisterAllocatorPhase(const char* name, RegisterAllocator* allocator)
|
||||
: CompilationPhase(name, allocator->info()),
|
||||
allocator_(allocator),
|
||||
allocator_zone_start_allocation_size_(0),
|
||||
stats_(NULL) {
|
||||
if (FLAG_turbo_stats) {
|
||||
allocator_zone_start_allocation_size_ =
|
||||
allocator->info()->zone()->allocation_size();
|
||||
if (allocator->zone_pool() != NULL) {
|
||||
stats_ = new ZonePool::StatsScope(allocator->zone_pool());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~RegisterAllocatorPhase() {
|
||||
if (FLAG_turbo_stats) {
|
||||
unsigned size = allocator_->info()->zone()->allocation_size() -
|
||||
allocator_zone_start_allocation_size_;
|
||||
if (stats_ != NULL) {
|
||||
size += static_cast<unsigned>(stats_->GetMaxAllocatedBytes());
|
||||
}
|
||||
isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size);
|
||||
}
|
||||
delete stats_;
|
||||
#ifdef DEBUG
|
||||
if (allocator_ != NULL) allocator_->Verify();
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
RegisterAllocator* allocator_;
|
||||
unsigned allocator_zone_start_allocation_size_;
|
||||
ZonePool::StatsScope* stats_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorPhase);
|
||||
};
|
||||
|
||||
|
||||
void RegisterAllocator::MeetRegisterConstraints() {
|
||||
RegisterAllocatorPhase phase("L_Register constraints", this);
|
||||
for (int i = 0; i < code()->InstructionBlockCount(); ++i) {
|
||||
MeetRegisterConstraints(
|
||||
code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(i)));
|
||||
@ -1171,8 +1150,6 @@ void RegisterAllocator::MeetRegisterConstraints() {
|
||||
|
||||
|
||||
void RegisterAllocator::ResolvePhis() {
|
||||
RegisterAllocatorPhase phase("L_Resolve phis", this);
|
||||
|
||||
// Process the blocks in reverse order.
|
||||
for (int i = code()->InstructionBlockCount() - 1; i >= 0; --i) {
|
||||
ResolvePhis(code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(i)));
|
||||
@ -1250,7 +1227,6 @@ const InstructionBlock* RegisterAllocator::GetInstructionBlock(
|
||||
|
||||
|
||||
void RegisterAllocator::ConnectRanges() {
|
||||
RegisterAllocatorPhase phase("L_Connect ranges", this);
|
||||
for (int i = 0; i < live_ranges()->length(); ++i) {
|
||||
LiveRange* first_range = live_ranges()->at(i);
|
||||
if (first_range == NULL || first_range->parent() != NULL) continue;
|
||||
@ -1294,7 +1270,6 @@ bool RegisterAllocator::CanEagerlyResolveControlFlow(
|
||||
|
||||
|
||||
void RegisterAllocator::ResolveControlFlow() {
|
||||
RegisterAllocatorPhase phase("L_Resolve control flow", this);
|
||||
for (int block_id = 1; block_id < code()->InstructionBlockCount();
|
||||
++block_id) {
|
||||
const InstructionBlock* block =
|
||||
@ -1316,7 +1291,6 @@ void RegisterAllocator::ResolveControlFlow() {
|
||||
|
||||
|
||||
void RegisterAllocator::BuildLiveRanges() {
|
||||
RegisterAllocatorPhase phase("L_Build live ranges", this);
|
||||
InitializeLivenessAnalysis();
|
||||
// Process the blocks in reverse order.
|
||||
for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
|
||||
@ -1457,8 +1431,6 @@ bool RegisterAllocator::SafePointsAreInOrder() const {
|
||||
|
||||
|
||||
void RegisterAllocator::PopulatePointerMaps() {
|
||||
RegisterAllocatorPhase phase("L_Populate pointer maps", this);
|
||||
|
||||
DCHECK(SafePointsAreInOrder());
|
||||
|
||||
// Iterate over all safe point positions and record a pointer
|
||||
@ -1541,7 +1513,6 @@ void RegisterAllocator::PopulatePointerMaps() {
|
||||
|
||||
|
||||
void RegisterAllocator::AllocateGeneralRegisters() {
|
||||
RegisterAllocatorPhase phase("L_Allocate general registers", this);
|
||||
num_registers_ = Register::NumAllocatableRegisters();
|
||||
mode_ = GENERAL_REGISTERS;
|
||||
AllocateRegisters();
|
||||
@ -1549,7 +1520,6 @@ void RegisterAllocator::AllocateGeneralRegisters() {
|
||||
|
||||
|
||||
void RegisterAllocator::AllocateDoubleRegisters() {
|
||||
RegisterAllocatorPhase phase("L_Allocate double registers", this);
|
||||
num_registers_ = DoubleRegister::NumAllocatableAliasedRegisters();
|
||||
mode_ = DOUBLE_REGISTERS;
|
||||
AllocateRegisters();
|
||||
|
@ -23,6 +23,8 @@ class PointerMap;
|
||||
|
||||
namespace compiler {
|
||||
|
||||
class PipelineStatistics;
|
||||
|
||||
enum RegisterKind {
|
||||
UNALLOCATED_REGISTERS,
|
||||
GENERAL_REGISTERS,
|
||||
@ -331,8 +333,7 @@ class RegisterAllocator BASE_EMBEDDED {
|
||||
// Returns the register kind required by the given virtual register.
|
||||
RegisterKind RequiredRegisterKind(int virtual_register) const;
|
||||
|
||||
// TODO(dcarney): fix compilation phase stats to not require this.
|
||||
bool Allocate(ZonePool* zone_pool = NULL);
|
||||
bool Allocate(PipelineStatistics* stats = NULL);
|
||||
|
||||
const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
|
||||
const Vector<LiveRange*>* fixed_live_ranges() const {
|
||||
@ -344,7 +345,6 @@ class RegisterAllocator BASE_EMBEDDED {
|
||||
|
||||
CompilationInfo* info() const { return info_; }
|
||||
inline InstructionSequence* code() const { return code_; }
|
||||
ZonePool* zone_pool() const { return zone_pool_; }
|
||||
|
||||
// This zone is for datastructures only needed during register allocation.
|
||||
inline Zone* zone() const { return zone_; }
|
||||
@ -501,8 +501,6 @@ class RegisterAllocator BASE_EMBEDDED {
|
||||
Frame* frame() const { return frame_; }
|
||||
|
||||
Zone* const zone_;
|
||||
// TODO(dcarney): remove this.
|
||||
ZonePool* zone_pool_;
|
||||
Frame* const frame_;
|
||||
CompilationInfo* const info_;
|
||||
InstructionSequence* const code_;
|
||||
|
@ -9,7 +9,9 @@ namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
ZonePool::StatsScope::StatsScope(ZonePool* zone_pool)
|
||||
: zone_pool_(zone_pool), max_allocated_bytes_(0) {
|
||||
: zone_pool_(zone_pool),
|
||||
total_allocated_bytes_at_start_(zone_pool->GetTotalAllocatedBytes()),
|
||||
max_allocated_bytes_(0) {
|
||||
zone_pool_->stats_.push_back(this);
|
||||
for (auto zone : zone_pool_->used_) {
|
||||
size_t size = static_cast<size_t>(zone->allocation_size());
|
||||
@ -46,6 +48,11 @@ size_t ZonePool::StatsScope::GetCurrentAllocatedBytes() {
|
||||
}
|
||||
|
||||
|
||||
size_t ZonePool::StatsScope::GetTotalAllocatedBytes() {
|
||||
return zone_pool_->GetTotalAllocatedBytes() - total_allocated_bytes_at_start_;
|
||||
}
|
||||
|
||||
|
||||
void ZonePool::StatsScope::ZoneReturned(Zone* zone) {
|
||||
size_t current_total = GetCurrentAllocatedBytes();
|
||||
// Update max.
|
||||
|
@ -44,6 +44,7 @@ class ZonePool FINAL {
|
||||
|
||||
size_t GetMaxAllocatedBytes();
|
||||
size_t GetCurrentAllocatedBytes();
|
||||
size_t GetTotalAllocatedBytes();
|
||||
|
||||
private:
|
||||
friend class ZonePool;
|
||||
@ -53,6 +54,7 @@ class ZonePool FINAL {
|
||||
|
||||
ZonePool* const zone_pool_;
|
||||
InitialValues initial_values_;
|
||||
size_t total_allocated_bytes_at_start_;
|
||||
size_t max_allocated_bytes_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(StatsScope);
|
||||
|
@ -12594,15 +12594,14 @@ void HStatistics::Initialize(CompilationInfo* info) {
|
||||
}
|
||||
|
||||
|
||||
void HStatistics::Print(const char* stats_name) {
|
||||
void HStatistics::Print() {
|
||||
PrintF(
|
||||
"\n"
|
||||
"----------------------------------------"
|
||||
"----------------------------------------\n"
|
||||
"--- %s timing results:\n"
|
||||
"--- Hydrogen timing results:\n"
|
||||
"----------------------------------------"
|
||||
"----------------------------------------\n",
|
||||
stats_name);
|
||||
"----------------------------------------\n");
|
||||
base::TimeDelta sum;
|
||||
for (int i = 0; i < times_.length(); ++i) {
|
||||
sum += times_[i];
|
||||
|
@ -2760,7 +2760,7 @@ class HStatistics FINAL: public Malloced {
|
||||
source_size_(0) { }
|
||||
|
||||
void Initialize(CompilationInfo* info);
|
||||
void Print(const char* stats_name);
|
||||
void Print();
|
||||
void SaveTiming(const char* name, base::TimeDelta time, unsigned size);
|
||||
|
||||
void IncrementFullCodeGen(base::TimeDelta full_code_gen) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fstream> // NOLINT(readability/streams)
|
||||
#include <iostream> // NOLINT(readability/streams)
|
||||
|
||||
#include "src/v8.h"
|
||||
|
||||
@ -16,6 +17,7 @@
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/codegen.h"
|
||||
#include "src/compilation-cache.h"
|
||||
#include "src/compilation-statistics.h"
|
||||
#include "src/cpu-profiler.h"
|
||||
#include "src/debug.h"
|
||||
#include "src/deoptimizer.h"
|
||||
@ -1606,8 +1608,10 @@ void Isolate::Deinit() {
|
||||
heap_.mark_compact_collector()->EnsureSweepingCompleted();
|
||||
}
|
||||
|
||||
if (FLAG_turbo_stats) GetTStatistics()->Print("TurboFan");
|
||||
if (FLAG_hydrogen_stats) GetHStatistics()->Print("Hydrogen");
|
||||
if (turbo_statistics() != NULL) {
|
||||
std::cout << *turbo_statistics() << std::endl;
|
||||
}
|
||||
if (FLAG_hydrogen_stats) GetHStatistics()->Print();
|
||||
|
||||
if (FLAG_print_deopt_stress) {
|
||||
PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
|
||||
@ -2119,9 +2123,10 @@ HStatistics* Isolate::GetHStatistics() {
|
||||
}
|
||||
|
||||
|
||||
HStatistics* Isolate::GetTStatistics() {
|
||||
if (tstatistics() == NULL) set_tstatistics(new HStatistics());
|
||||
return tstatistics();
|
||||
CompilationStatistics* Isolate::GetTurboStatistics() {
|
||||
if (turbo_statistics() == NULL)
|
||||
set_turbo_statistics(new CompilationStatistics());
|
||||
return turbo_statistics();
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,7 @@ class CodeRange;
|
||||
class CodeStubDescriptor;
|
||||
class CodeTracer;
|
||||
class CompilationCache;
|
||||
class CompilationStatistics;
|
||||
class ContextSlotCache;
|
||||
class Counters;
|
||||
class CpuFeatures;
|
||||
@ -383,7 +384,7 @@ typedef List<HeapObject*> DebugObjectCache;
|
||||
V(int, pending_microtask_count, 0) \
|
||||
V(bool, autorun_microtasks, true) \
|
||||
V(HStatistics*, hstatistics, NULL) \
|
||||
V(HStatistics*, tstatistics, NULL) \
|
||||
V(CompilationStatistics*, turbo_statistics, NULL) \
|
||||
V(HTracer*, htracer, NULL) \
|
||||
V(CodeTracer*, code_tracer, NULL) \
|
||||
V(bool, fp_stubs_generated, false) \
|
||||
@ -1052,7 +1053,7 @@ class Isolate {
|
||||
int id() const { return static_cast<int>(id_); }
|
||||
|
||||
HStatistics* GetHStatistics();
|
||||
HStatistics* GetTStatistics();
|
||||
CompilationStatistics* GetTurboStatistics();
|
||||
HTracer* GetHTracer();
|
||||
CodeTracer* GetCodeTracer();
|
||||
|
||||
|
@ -23,9 +23,11 @@ class ZonePoolTest : public TestWithIsolate {
|
||||
ASSERT_EQ(total, zone_pool()->GetTotalAllocatedBytes());
|
||||
}
|
||||
|
||||
void Expect(ZonePool::StatsScope* stats, size_t current, size_t max) {
|
||||
void Expect(ZonePool::StatsScope* stats, size_t current, size_t max,
|
||||
size_t total) {
|
||||
ASSERT_EQ(current, stats->GetCurrentAllocatedBytes());
|
||||
ASSERT_EQ(max, stats->GetMaxAllocatedBytes());
|
||||
ASSERT_EQ(total, stats->GetTotalAllocatedBytes());
|
||||
}
|
||||
|
||||
size_t Allocate(Zone* zone) {
|
||||
@ -45,7 +47,7 @@ TEST_F(ZonePoolTest, Empty) {
|
||||
ExpectForPool(0, 0, 0);
|
||||
{
|
||||
ZonePool::StatsScope stats(zone_pool());
|
||||
Expect(&stats, 0, 0);
|
||||
Expect(&stats, 0, 0, 0);
|
||||
}
|
||||
ExpectForPool(0, 0, 0);
|
||||
{
|
||||
@ -77,7 +79,7 @@ TEST_F(ZonePoolTest, MultipleZonesWithDeletion) {
|
||||
before_deletion += Allocate(scopes[i]->zone()); // Add some stuff.
|
||||
}
|
||||
|
||||
Expect(&stats, before_deletion, before_deletion);
|
||||
Expect(&stats, before_deletion, before_deletion, before_deletion);
|
||||
ExpectForPool(before_stats + before_deletion, before_stats + before_deletion,
|
||||
before_stats + before_deletion);
|
||||
|
||||
@ -87,7 +89,7 @@ TEST_F(ZonePoolTest, MultipleZonesWithDeletion) {
|
||||
scopes[i] = new ZonePool::Scope(zone_pool());
|
||||
}
|
||||
|
||||
Expect(&stats, 0, before_deletion);
|
||||
Expect(&stats, 0, before_deletion, before_deletion);
|
||||
ExpectForPool(0, before_stats + before_deletion,
|
||||
before_stats + before_deletion);
|
||||
|
||||
@ -96,7 +98,8 @@ TEST_F(ZonePoolTest, MultipleZonesWithDeletion) {
|
||||
after_deletion += Allocate(scopes[i]->zone()); // Add some stuff.
|
||||
}
|
||||
|
||||
Expect(&stats, after_deletion, std::max(after_deletion, before_deletion));
|
||||
Expect(&stats, after_deletion, std::max(after_deletion, before_deletion),
|
||||
before_deletion + after_deletion);
|
||||
ExpectForPool(after_deletion,
|
||||
std::max(after_deletion, before_stats + before_deletion),
|
||||
before_stats + before_deletion + after_deletion);
|
||||
@ -106,7 +109,8 @@ TEST_F(ZonePoolTest, MultipleZonesWithDeletion) {
|
||||
delete scopes[i];
|
||||
}
|
||||
|
||||
Expect(&stats, 0, std::max(after_deletion, before_deletion));
|
||||
Expect(&stats, 0, std::max(after_deletion, before_deletion),
|
||||
before_deletion + after_deletion);
|
||||
ExpectForPool(0, std::max(after_deletion, before_stats + before_deletion),
|
||||
before_stats + before_deletion + after_deletion);
|
||||
}
|
||||
@ -136,19 +140,20 @@ TEST_F(ZonePoolTest, SimpleAllocationLoop) {
|
||||
total_allocated += bytes;
|
||||
max_loop_allocation =
|
||||
std::max(max_loop_allocation, outer_allocated + allocated);
|
||||
Expect(&inner_stats, allocated, allocated);
|
||||
Expect(&outer_stats, outer_allocated + allocated,
|
||||
max_loop_allocation);
|
||||
Expect(&inner_stats, allocated, allocated, allocated);
|
||||
Expect(&outer_stats, outer_allocated + allocated, max_loop_allocation,
|
||||
total_allocated);
|
||||
ExpectForPool(outer_allocated + allocated, max_loop_allocation,
|
||||
total_allocated);
|
||||
}
|
||||
}
|
||||
Expect(&inner_stats, 0, allocated);
|
||||
Expect(&outer_stats, outer_allocated, max_loop_allocation);
|
||||
Expect(&inner_stats, 0, allocated, allocated);
|
||||
Expect(&outer_stats, outer_allocated, max_loop_allocation,
|
||||
total_allocated);
|
||||
ExpectForPool(outer_allocated, max_loop_allocation, total_allocated);
|
||||
}
|
||||
}
|
||||
Expect(&outer_stats, 0, max_loop_allocation);
|
||||
Expect(&outer_stats, 0, max_loop_allocation, total_allocated);
|
||||
ExpectForPool(0, max_loop_allocation, total_allocated);
|
||||
}
|
||||
|
||||
|
@ -387,6 +387,8 @@
|
||||
'../../src/codegen.h',
|
||||
'../../src/compilation-cache.cc',
|
||||
'../../src/compilation-cache.h',
|
||||
'../../src/compilation-statistics.cc',
|
||||
'../../src/compilation-statistics.h',
|
||||
'../../src/compiler/access-builder.cc',
|
||||
'../../src/compiler/access-builder.h',
|
||||
'../../src/compiler/ast-graph-builder.cc',
|
||||
@ -473,6 +475,8 @@
|
||||
'../../src/compiler/phi-reducer.h',
|
||||
'../../src/compiler/pipeline.cc',
|
||||
'../../src/compiler/pipeline.h',
|
||||
'../../src/compiler/pipeline-statistics.cc',
|
||||
'../../src/compiler/pipeline-statistics.h',
|
||||
'../../src/compiler/raw-machine-assembler.cc',
|
||||
'../../src/compiler/raw-machine-assembler.h',
|
||||
'../../src/compiler/register-allocator.cc',
|
||||
|
Loading…
Reference in New Issue
Block a user