V8 Project
basic-block-instrumentor.cc
Go to the documentation of this file.
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
7 #include "src/compiler/graph.h"
10 #include "src/compiler/schedule.h"
11 
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15 
16 // Find the first place to insert new nodes in a block that's already been
17 // scheduled that won't upset the register allocator.
18 static NodeVector::iterator FindInsertionPoint(NodeVector* nodes) {
19  NodeVector::iterator i = nodes->begin();
20  for (; i != nodes->end(); ++i) {
21  const Operator* op = (*i)->op();
22  if (OperatorProperties::IsBasicBlockBegin(op)) continue;
23  switch (op->opcode()) {
24  case IrOpcode::kParameter:
25  case IrOpcode::kPhi:
26  case IrOpcode::kEffectPhi:
27  continue;
28  }
29  break;
30  }
31  return i;
32 }
33 
34 
35 // TODO(dcarney): need to mark code as non-serializable.
36 static const Operator* PointerConstant(CommonOperatorBuilder* common,
37  void* ptr) {
38  return kPointerSize == 8
39  ? common->Int64Constant(reinterpret_cast<intptr_t>(ptr))
40  : common->Int32Constant(
41  static_cast<int32_t>(reinterpret_cast<intptr_t>(ptr)));
42 }
43 
44 
46  CompilationInfo* info, Graph* graph, Schedule* schedule) {
47  // Skip the exit block in profiles, since the register allocator can't handle
48  // it and entry into it means falling off the end of the function anyway.
49  size_t n_blocks = static_cast<size_t>(schedule->RpoBlockCount()) - 1;
51  info->isolate()->GetOrCreateBasicBlockProfiler()->NewData(n_blocks);
52  // Set the function name.
53  if (!info->shared_info().is_null() &&
54  info->shared_info()->name()->IsString()) {
55  OStringStream os;
56  String::cast(info->shared_info()->name())->PrintUC16(os);
57  data->SetFunctionName(&os);
58  }
59  // Capture the schedule string before instrumentation.
60  {
61  OStringStream os;
62  os << *schedule;
63  data->SetSchedule(&os);
64  }
65  // Add the increment instructions to the start of every block.
66  CommonOperatorBuilder common(graph->zone());
67  Node* zero = graph->NewNode(common.Int32Constant(0));
68  Node* one = graph->NewNode(common.Int32Constant(1));
69  MachineOperatorBuilder machine;
70  BasicBlockVector* blocks = schedule->rpo_order();
71  size_t block_number = 0;
72  for (BasicBlockVector::iterator it = blocks->begin(); block_number < n_blocks;
73  ++it, ++block_number) {
74  BasicBlock* block = (*it);
75  data->SetBlockId(block_number, block->id());
76  // TODO(dcarney): wire effect and control deps for load and store.
77  // Construct increment operation.
78  Node* base = graph->NewNode(
79  PointerConstant(&common, data->GetCounterAddress(block_number)));
80  Node* load = graph->NewNode(machine.Load(kMachUint32), base, zero);
81  Node* inc = graph->NewNode(machine.Int32Add(), load, one);
82  Node* store = graph->NewNode(
83  machine.Store(StoreRepresentation(kMachUint32, kNoWriteBarrier)), base,
84  zero, inc);
85  // Insert the new nodes.
86  static const int kArraySize = 6;
87  Node* to_insert[kArraySize] = {zero, one, base, load, inc, store};
88  int insertion_start = block_number == 0 ? 0 : 2;
89  NodeVector* nodes = &block->nodes_;
90  NodeVector::iterator insertion_point = FindInsertionPoint(nodes);
91  nodes->insert(insertion_point, &to_insert[insertion_start],
92  &to_insert[kArraySize]);
93  // Tell the scheduler about the new nodes.
94  for (int i = insertion_start; i < kArraySize; ++i) {
95  schedule->SetBlockForNode(block, to_insert[i]);
96  }
97  }
98  return data;
99 }
100 
101 } // namespace compiler
102 } // namespace internal
103 } // namespace v8
void SetBlockId(size_t offset, int block_id)
Isolate * isolate() const
Definition: compiler.h:96
Handle< SharedFunctionInfo > shared_info() const
Definition: compiler.h:112
BasicBlockProfiler * GetOrCreateBasicBlockProfiler()
Definition: isolate.cc:2365
static BasicBlockProfiler::Data * Instrument(CompilationInfo *info, Graph *graph, Schedule *schedule)
Node * NewNode(const Operator *op, int input_count, Node **inputs)
Definition: graph.cc:24
static bool IsBasicBlockBegin(const Operator *op)
void SetBlockForNode(BasicBlock *block, Node *node)
Definition: schedule.h:290
BasicBlockVector * rpo_order()
Definition: schedule.h:279
int int32_t
Definition: unicode.cc:24
static const Operator * PointerConstant(CommonOperatorBuilder *common, void *ptr)
static NodeVector::iterator FindInsertionPoint(NodeVector *nodes)
const int kPointerSize
Definition: globals.h:129
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20