From bdb4a8d33dbd99e48bb54594f7e96eb0313a0643 Mon Sep 17 00:00:00 2001 From: Ross McIlroy Date: Mon, 27 Mar 2017 12:46:10 +0100 Subject: [PATCH] [TurboFan] Reserve space in scheduler node data for split nodes. When node splitting is enabled new nodes could be created during scheduling. The Scheduler::node_data_ and Schedule::nodeid_to_block_ zone vectors reserve enough space for the node count before splitting, however will have to reallocate space when node splitting occurs. The vectors double in space by default, meaning the peak zone usage is 3x the required amount for these vectors as soon as a single node is split. Avoid this in the common case by reserving 10% extra space for split nodes. The value 10% was choosen since it covers 98.7% of the optimized functions in Octane. BUG=chromium:700364 Change-Id: Ibabd8d04cffd1eb08cc3b8a12b76892208ef3288 Reviewed-on: https://chromium-review.googlesource.com/458425 Commit-Queue: Ross McIlroy Reviewed-by: Michael Starzinger Cr-Commit-Position: refs/heads/master@{#44153} --- src/compiler/scheduler.cc | 21 +++++++++++++++------ src/compiler/scheduler.h | 3 ++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc index 756d256f05..76889a69cb 100644 --- a/src/compiler/scheduler.cc +++ b/src/compiler/scheduler.cc @@ -25,7 +25,8 @@ namespace compiler { if (FLAG_trace_turbo_scheduler) PrintF(__VA_ARGS__); \ } while (false) -Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags) +Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags, + size_t node_count_hint) : zone_(zone), graph_(graph), schedule_(schedule), @@ -33,15 +34,23 @@ Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags) scheduled_nodes_(zone), schedule_root_nodes_(zone), schedule_queue_(zone), - node_data_(graph_->NodeCount(), DefaultSchedulerData(), zone) {} - + node_data_(zone) { + node_data_.reserve(node_count_hint); + node_data_.resize(graph->NodeCount(), DefaultSchedulerData()); +} Schedule* Scheduler::ComputeSchedule(Zone* zone, Graph* graph, Flags flags) { Zone* schedule_zone = (flags & Scheduler::kTempSchedule) ? zone : graph->zone(); - Schedule* schedule = new (schedule_zone) - Schedule(schedule_zone, static_cast(graph->NodeCount())); - Scheduler scheduler(zone, graph, schedule, flags); + + // Reserve 10% more space for nodes if node splitting is enabled to try to + // avoid resizing the vector since that would triple its zone memory usage. + float node_hint_multiplier = (flags & Scheduler::kSplitNodes) ? 1.1 : 1; + size_t node_count_hint = node_hint_multiplier * graph->NodeCount(); + + Schedule* schedule = + new (schedule_zone) Schedule(schedule_zone, node_count_hint); + Scheduler scheduler(zone, graph, schedule, flags, node_count_hint); scheduler.BuildCFG(); scheduler.ComputeSpecialRPONumbering(); diff --git a/src/compiler/scheduler.h b/src/compiler/scheduler.h index 37c195e664..4d297e1756 100644 --- a/src/compiler/scheduler.h +++ b/src/compiler/scheduler.h @@ -74,7 +74,8 @@ class V8_EXPORT_PRIVATE Scheduler { SpecialRPONumberer* special_rpo_; // Special RPO numbering of blocks. ControlEquivalence* equivalence_; // Control dependence equivalence. - Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags); + Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags, + size_t node_count_hint_); inline SchedulerData DefaultSchedulerData(); inline SchedulerData* GetData(Node* node);