| Index: runtime/vm/block_scheduler.cc
|
| diff --git a/runtime/vm/block_scheduler.cc b/runtime/vm/block_scheduler.cc
|
| index 7d6cfc567c74fb7825e3a6886cce8e358f8ffaa4..a84a5d96300b070fb4959b719a97e53a7455fe1e 100644
|
| --- a/runtime/vm/block_scheduler.cc
|
| +++ b/runtime/vm/block_scheduler.cc
|
| @@ -12,63 +12,37 @@ namespace dart {
|
|
|
| DEFINE_FLAG(bool, emit_edge_counters, true, "Emit edge counters at targets.");
|
|
|
| -// Compute the edge count at the deopt id of a TargetEntry or Goto.
|
| -static intptr_t ComputeEdgeCount(
|
| - const Code& unoptimized_code,
|
| - const ZoneGrowableArray<uword>& deopt_id_pc_pairs,
|
| - intptr_t deopt_id) {
|
| - ASSERT(deopt_id != Isolate::kNoDeoptId);
|
| -
|
| +static intptr_t GetEdgeCount(const Array& edge_counters, intptr_t edge_id) {
|
| if (!FLAG_emit_edge_counters) {
|
| // Assume everything was visited once.
|
| return 1;
|
| }
|
| -
|
| - for (intptr_t i = 0; i < deopt_id_pc_pairs.length(); i += 2) {
|
| - intptr_t deopt_id_entry = static_cast<intptr_t>(deopt_id_pc_pairs[i]);
|
| - uword pc = deopt_id_pc_pairs[i + 1];
|
| - if (deopt_id_entry == deopt_id) {
|
| - Array& array = Array::Handle();
|
| - array ^= CodePatcher::GetEdgeCounterAt(pc, unoptimized_code);
|
| - ASSERT(!array.IsNull());
|
| - return Smi::Value(Smi::RawCast(array.At(0)));
|
| - }
|
| - }
|
| -
|
| - UNREACHABLE();
|
| - return 1;
|
| + return Smi::Value(Smi::RawCast(edge_counters.At(edge_id)));
|
| }
|
|
|
|
|
| // There is an edge from instruction->successor. Set its weight (edge count
|
| // per function entry).
|
| -static void SetEdgeWeight(Instruction* instruction,
|
| +static void SetEdgeWeight(BlockEntryInstr* block,
|
| BlockEntryInstr* successor,
|
| - const Code& unoptimized_code,
|
| - const ZoneGrowableArray<uword>& deopt_id_pc_pairs,
|
| + const Array& edge_counters,
|
| intptr_t entry_count) {
|
| TargetEntryInstr* target = successor->AsTargetEntry();
|
| if (target != NULL) {
|
| // If this block ends in a goto, the edge count of this edge is the same
|
| // as the count on the single outgoing edge. This is true as long as the
|
| // block does not throw an exception.
|
| - GotoInstr* jump = target->last_instruction()->AsGoto();
|
| - const intptr_t deopt_id =
|
| - (jump != NULL) ? jump->deopt_id() : target->deopt_id();
|
| - intptr_t count = ComputeEdgeCount(unoptimized_code,
|
| - deopt_id_pc_pairs,
|
| - deopt_id);
|
| + intptr_t count = GetEdgeCount(edge_counters, target->preorder_number());
|
| if ((count >= 0) && (entry_count != 0)) {
|
| double weight =
|
| static_cast<double>(count) / static_cast<double>(entry_count);
|
| target->set_edge_weight(weight);
|
| }
|
| } else {
|
| - GotoInstr* jump = instruction->AsGoto();
|
| + GotoInstr* jump = block->last_instruction()->AsGoto();
|
| if (jump != NULL) {
|
| - intptr_t count = ComputeEdgeCount(unoptimized_code,
|
| - deopt_id_pc_pairs,
|
| - jump->deopt_id());
|
| + intptr_t count =
|
| + GetEdgeCount(edge_counters, block->preorder_number());
|
| if ((count >= 0) && (entry_count != 0)) {
|
| double weight =
|
| static_cast<double>(count) / static_cast<double>(entry_count);
|
| @@ -83,27 +57,15 @@ void BlockScheduler::AssignEdgeWeights() const {
|
| if (!FLAG_emit_edge_counters) {
|
| return;
|
| }
|
| - const Code& unoptimized_code = flow_graph()->parsed_function().code();
|
| - ASSERT(!unoptimized_code.IsNull());
|
| -
|
| - ZoneGrowableArray<uword>* deopt_id_pc_pairs = new ZoneGrowableArray<uword>();
|
| - const PcDescriptors& descriptors =
|
| - PcDescriptors::Handle(unoptimized_code.pc_descriptors());
|
| - PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kDeopt);
|
| - uword entry =
|
| - Instructions::Handle(unoptimized_code.instructions()).EntryPoint();
|
| - while (iter.MoveNext()) {
|
| - intptr_t deopt_id = iter.DeoptId();
|
| - ASSERT(deopt_id != Isolate::kNoDeoptId);
|
| - uint32_t pc_offset = iter.PcOffset();
|
| - deopt_id_pc_pairs->Add(static_cast<uword>(deopt_id));
|
| - deopt_id_pc_pairs->Add(entry + pc_offset);
|
| - }
|
|
|
| - intptr_t entry_count =
|
| - ComputeEdgeCount(unoptimized_code,
|
| - *deopt_id_pc_pairs,
|
| - flow_graph()->graph_entry()->normal_entry()->deopt_id());
|
| + const Array& ic_data_array = Array::Handle(flow_graph()->zone(),
|
| + flow_graph()->parsed_function().function().ic_data_array());
|
| + Array& edge_counters = Array::Handle();
|
| + edge_counters ^= ic_data_array.At(0);
|
| +
|
| + intptr_t entry_count = GetEdgeCount(
|
| + edge_counters,
|
| + flow_graph()->graph_entry()->normal_entry()->preorder_number());
|
| flow_graph()->graph_entry()->set_entry_count(entry_count);
|
|
|
| for (BlockIterator it = flow_graph()->reverse_postorder_iterator();
|
| @@ -113,8 +75,7 @@ void BlockScheduler::AssignEdgeWeights() const {
|
| Instruction* last = block->last_instruction();
|
| for (intptr_t i = 0; i < last->SuccessorCount(); ++i) {
|
| BlockEntryInstr* succ = last->SuccessorAt(i);
|
| - SetEdgeWeight(last, succ,
|
| - unoptimized_code, *deopt_id_pc_pairs, entry_count);
|
| + SetEdgeWeight(block, succ, edge_counters, entry_count);
|
| }
|
| }
|
| }
|
|
|