Index: src/compiler/escape-analysis.cc |
diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc |
index b57ae6d9b87424d028758e353aa74f39cbfe0836..2cddedae87f11fabe83ee75d1e259259bb1ea97d 100644 |
--- a/src/compiler/escape-analysis.cc |
+++ b/src/compiler/escape-analysis.cc |
@@ -40,6 +40,8 @@ const Alias EscapeStatusAnalysis::kNotReachable = |
const Alias EscapeStatusAnalysis::kUntrackable = |
std::numeric_limits<Alias>::max() - 1; |
+EscapeAnalysisStats EscapeAnalysis::stats; |
+ |
class VirtualObject : public ZoneObject { |
public: |
enum Status { |
@@ -56,7 +58,9 @@ class VirtualObject : public ZoneObject { |
fields_(zone), |
phi_(zone), |
object_state_(nullptr), |
- owner_(owner) {} |
+ owner_(owner) { |
+ EscapeAnalysis::stats.virtualObjectCount_++; |
+ } |
VirtualObject(VirtualState* owner, const VirtualObject& other) |
: id_(other.id_), |
@@ -64,7 +68,10 @@ class VirtualObject : public ZoneObject { |
fields_(other.fields_), |
phi_(other.phi_), |
object_state_(other.object_state_), |
- owner_(owner) {} |
+ owner_(owner) { |
+ EscapeAnalysis::stats.virtualObjectCount_++; |
+ EscapeAnalysis::stats.fieldCount_ += fields_.size(); |
+ } |
VirtualObject(NodeId id, VirtualState* owner, Zone* zone, size_t field_number, |
bool initialized) |
@@ -76,6 +83,8 @@ class VirtualObject : public ZoneObject { |
owner_(owner) { |
fields_.resize(field_number); |
phi_.resize(field_number, false); |
+ EscapeAnalysis::stats.virtualObjectCount_++; |
+ EscapeAnalysis::stats.fieldCount_ += fields_.size(); |
} |
Node* GetField(size_t offset) { return fields_[offset]; } |
@@ -95,6 +104,7 @@ class VirtualObject : public ZoneObject { |
size_t field_count() { return fields_.size(); } |
bool ResizeFields(size_t field_count) { |
if (field_count > fields_.size()) { |
+ EscapeAnalysis::stats.fieldCount_ += field_count - fields_.size(); |
fields_.resize(field_count); |
phi_.resize(field_count); |
return true; |
@@ -168,7 +178,9 @@ bool VirtualObject::UpdateFrom(const VirtualObject& other) { |
class VirtualState : public ZoneObject { |
public: |
VirtualState(Node* owner, Zone* zone, size_t size) |
- : info_(size, nullptr, zone), owner_(owner) {} |
+ : info_(size, nullptr, zone), owner_(owner) { |
+ EscapeAnalysis::stats.virtualStateCount_++; |
+ } |
VirtualState(Node* owner, const VirtualState& state) |
: info_(state.info_.size(), nullptr, state.info_.get_allocator().zone()), |
@@ -178,6 +190,7 @@ class VirtualState : public ZoneObject { |
info_[i] = state.info_[i]; |
} |
} |
+ EscapeAnalysis::stats.virtualStateCount_++; |
} |
VirtualObject* VirtualObjectFromAlias(size_t alias); |
@@ -763,7 +776,11 @@ EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, |
common_(common), |
virtual_states_(zone), |
replacements_(zone), |
- cache_(nullptr) {} |
+ cache_(nullptr), |
+ phi_map_(PhiObjectMap::key_compare(), |
+ PhiObjectMap::allocator_type(zone)) { |
+ stats = EscapeAnalysisStats(); |
+} |
EscapeAnalysis::~EscapeAnalysis() {} |
@@ -773,7 +790,7 @@ void EscapeAnalysis::Run() { |
PrintF("--trace-turbo-escape only supported in DEBUG builds\n."); |
} |
#endif |
- replacements_.resize(graph()->NodeCount()); |
+ EscapeAnalysis::stats.initialNodeCount_ = graph()->NodeCount(); |
status_analysis_.AssignAliases(); |
if (status_analysis_.AliasCount() > 0) { |
cache_ = new (zone()) MergeCache(zone()); |
@@ -781,6 +798,8 @@ void EscapeAnalysis::Run() { |
status_analysis_.ResizeStatusVector(); |
RunObjectAnalysis(); |
status_analysis_.RunStatusAnalysis(); |
+ } else { |
+ TRACE("No allocations discovered\n"); |
} |
} |
@@ -789,6 +808,7 @@ void EscapeStatusAnalysis::AssignAliases() { |
size_t min_size = 32; |
size_t stack_size = |
std::min(std::max(graph()->NodeCount() / 5, min_size), max_size); |
+ size_t max_stack = 0; |
stack_.reserve(stack_size); |
ResizeStatusVector(); |
stack_.push_back(graph()->end()); |
@@ -798,8 +818,12 @@ void EscapeStatusAnalysis::AssignAliases() { |
status_stack_.reserve(8); |
TRACE("Discovering trackable nodes"); |
while (!stack_.empty()) { |
+ max_stack = std::max(max_stack, stack_.size()); |
Node* node = stack_.back(); |
stack_.pop_back(); |
+ if (node->op()->EffectInputCount() > 0) { |
+ EscapeAnalysis::stats.effectNodeCount_++; |
+ } |
switch (node->opcode()) { |
case IrOpcode::kAllocate: |
if (aliases_[node->id()] >= kUntrackable) { |
@@ -841,6 +865,9 @@ void EscapeStatusAnalysis::AssignAliases() { |
} |
} |
TRACE("\n"); |
+ EscapeAnalysis::stats.discoverStackMaxSize_ = max_stack; |
+ EscapeAnalysis::stats.discoverStackCapacity_ = stack_.capacity(); |
+ EscapeAnalysis::stats.aliasCount_ = AliasCount(); |
} |
bool EscapeStatusAnalysis::IsNotReachable(Node* node) { |
@@ -1265,6 +1292,7 @@ int EscapeAnalysis::OffsetFromAccess(Node* node) { |
void EscapeAnalysis::ProcessLoadFromPhi(int offset, Node* from, Node* load, |
VirtualState* state) { |
+ EscapeAnalysis::stats.loadPhiCount_++; |
TRACE("Load #%d from phi #%d", load->id(), from->id()); |
cache_->fields().clear(); |
@@ -1447,6 +1475,7 @@ Node* EscapeAnalysis::GetOrCreateObjectState(Node* effect, Node* node) { |
if (Node* object_state = vobj->GetObjectState()) { |
return object_state; |
} else { |
+ stats.objectStatesCreated_++; |
cache_->fields().clear(); |
for (size_t i = 0; i < vobj->field_count(); ++i) { |
if (Node* field = vobj->GetField(i)) { |
@@ -1534,6 +1563,25 @@ bool EscapeAnalysis::ExistsVirtualAllocate() { |
return false; |
} |
+void EscapeAnalysisStats::Print() { |
+ PrintF("{\n"); |
+ PrintF(" \"InitialNodeCount\" : %zu,\n", initialNodeCount_); |
+ PrintF(" \"EffectNodeCount\" : %zu,\n", effectNodeCount_); |
+ PrintF(" \"DiscoverStackMaxSize\" : %zu,\n", discoverStackMaxSize_); |
+ PrintF(" \"DiscoverStackCapacity\" : %zu,\n", discoverStackCapacity_); |
+ PrintF(" \"AliasCount\" : %zu,\n", aliasCount_); |
+ PrintF(" \"VirtualObjects\" : %zu,\n", virtualObjectCount_); |
+ PrintF(" \"VirtualStates\" : %zu,\n", virtualStateCount_); |
+ PrintF(" \"FieldCount\" : %zu,\n", fieldCount_); |
+ PrintF(" \"MergePhiCount\" : %zu,\n", mergePhiCount_); |
+ PrintF(" \"LoadPhiCount\" : %zu,\n", loadPhiCount_); |
+ PrintF(" \"ObjectStatesCreated\" : %zu,\n", objectStatesCreated_); |
+ PrintF(" \"VirtualObjectSize\" : %zu,\n", sizeof(VirtualObject)); |
+ PrintF(" \"VirtualStateSize\" : %zu\n", |
+ sizeof(VirtualState) + aliasCount_ * kPointerSize); |
+ PrintF("},\n"); |
+} |
+ |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |