V8 Project
v8::internal::compiler::Verifier::Visitor Class Reference
+ Inheritance diagram for v8::internal::compiler::Verifier::Visitor:
+ Collaboration diagram for v8::internal::compiler::Verifier::Visitor:

Public Member Functions

 Visitor (Zone *zone)
 
GenericGraphVisit::Control Pre (Node *node)
 
- Public Member Functions inherited from v8::internal::compiler::GenericGraphVisit::NullNodeVisitor< B, S >
Control Pre (GenericNode< B, S > *node)
 
Control Post (GenericNode< B, S > *node)
 
void PreEdge (GenericNode< B, S > *from, int index, GenericNode< B, S > *to)
 
void PostEdge (GenericNode< B, S > *from, int index, GenericNode< B, S > *to)
 

Public Attributes

bool from_start
 
NodeSet reached_from_start
 
NodeSet reached_from_end
 

Detailed Description

Definition at line 46 of file verifier.cc.

Constructor & Destructor Documentation

◆ Visitor()

v8::internal::compiler::Verifier::Visitor::Visitor ( Zone zone)
inlineexplicit

Definition at line 48 of file verifier.cc.

49  : reached_from_start(NodeSet::key_compare(),
50  NodeSet::allocator_type(zone)),
51  reached_from_end(NodeSet::key_compare(),
52  NodeSet::allocator_type(zone)) {}

Member Function Documentation

◆ Pre()

GenericGraphVisit::Control v8::internal::compiler::Verifier::Visitor::Pre ( Node *  node)

Definition at line 63 of file verifier.cc.

63  {
64  int value_count = OperatorProperties::GetValueInputCount(node->op());
65  int context_count = OperatorProperties::GetContextInputCount(node->op());
66  int frame_state_count =
68  int effect_count = OperatorProperties::GetEffectInputCount(node->op());
69  int control_count = OperatorProperties::GetControlInputCount(node->op());
70 
71  // Verify number of inputs matches up.
72  int input_count = value_count + context_count + frame_state_count +
73  effect_count + control_count;
74  CHECK_EQ(input_count, node->InputCount());
75 
76  // Verify that frame state has been inserted for the nodes that need it.
78  Node* frame_state = NodeProperties::GetFrameStateInput(node);
79  CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
80  // kFrameState uses undefined as a sentinel.
81  (node->opcode() == IrOpcode::kFrameState &&
82  frame_state->opcode() == IrOpcode::kHeapConstant));
83  CHECK(IsDefUseChainLinkPresent(frame_state, node));
84  CHECK(IsUseDefChainLinkPresent(frame_state, node));
85  }
86 
87  // Verify all value inputs actually produce a value.
88  for (int i = 0; i < value_count; ++i) {
89  Node* value = NodeProperties::GetValueInput(node, i);
91  CHECK(IsDefUseChainLinkPresent(value, node));
92  CHECK(IsUseDefChainLinkPresent(value, node));
93  }
94 
95  // Verify all context inputs are value nodes.
96  for (int i = 0; i < context_count; ++i) {
97  Node* context = NodeProperties::GetContextInput(node);
99  CHECK(IsDefUseChainLinkPresent(context, node));
100  CHECK(IsUseDefChainLinkPresent(context, node));
101  }
102 
103  // Verify all effect inputs actually have an effect.
104  for (int i = 0; i < effect_count; ++i) {
105  Node* effect = NodeProperties::GetEffectInput(node);
107  CHECK(IsDefUseChainLinkPresent(effect, node));
108  CHECK(IsUseDefChainLinkPresent(effect, node));
109  }
110 
111  // Verify all control inputs are control nodes.
112  for (int i = 0; i < control_count; ++i) {
113  Node* control = NodeProperties::GetControlInput(node, i);
115  CHECK(IsDefUseChainLinkPresent(control, node));
116  CHECK(IsUseDefChainLinkPresent(control, node));
117  }
118 
119  // Verify all successors are projections if multiple value outputs exist.
120  if (OperatorProperties::GetValueOutputCount(node->op()) > 1) {
121  Node::Uses uses = node->uses();
122  for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
123  CHECK(!NodeProperties::IsValueEdge(it.edge()) ||
124  (*it)->opcode() == IrOpcode::kProjection ||
125  (*it)->opcode() == IrOpcode::kParameter);
126  }
127  }
128 
129  switch (node->opcode()) {
130  case IrOpcode::kStart:
131  // Start has no inputs.
132  CHECK_EQ(0, input_count);
133  break;
134  case IrOpcode::kEnd:
135  // End has no outputs.
139  break;
140  case IrOpcode::kDead:
141  // Dead is never connected to the graph.
142  UNREACHABLE();
143  case IrOpcode::kBranch: {
144  // Branch uses are IfTrue and IfFalse.
145  Node::Uses uses = node->uses();
146  bool got_true = false, got_false = false;
147  for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
148  CHECK(((*it)->opcode() == IrOpcode::kIfTrue && !got_true) ||
149  ((*it)->opcode() == IrOpcode::kIfFalse && !got_false));
150  if ((*it)->opcode() == IrOpcode::kIfTrue) got_true = true;
151  if ((*it)->opcode() == IrOpcode::kIfFalse) got_false = true;
152  }
153  // TODO(rossberg): Currently fails for various tests.
154  // CHECK(got_true && got_false);
155  break;
156  }
157  case IrOpcode::kIfTrue:
158  case IrOpcode::kIfFalse:
159  CHECK_EQ(IrOpcode::kBranch,
160  NodeProperties::GetControlInput(node, 0)->opcode());
161  break;
162  case IrOpcode::kLoop:
163  case IrOpcode::kMerge:
164  break;
165  case IrOpcode::kReturn:
166  // TODO(rossberg): check successor is End
167  break;
168  case IrOpcode::kThrow:
169  // TODO(rossberg): what are the constraints on these?
170  break;
171  case IrOpcode::kParameter: {
172  // Parameters have the start node as inputs.
173  CHECK_EQ(1, input_count);
174  CHECK_EQ(IrOpcode::kStart,
175  NodeProperties::GetValueInput(node, 0)->opcode());
176  // Parameter has an input that produces enough values.
177  int index = OpParameter<int>(node);
178  Node* input = NodeProperties::GetValueInput(node, 0);
179  // Currently, parameter indices start at -1 instead of 0.
180  CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index + 1);
181  break;
182  }
183  case IrOpcode::kInt32Constant:
184  case IrOpcode::kInt64Constant:
185  case IrOpcode::kFloat64Constant:
186  case IrOpcode::kExternalConstant:
187  case IrOpcode::kNumberConstant:
188  case IrOpcode::kHeapConstant:
189  // Constants have no inputs.
190  CHECK_EQ(0, input_count);
191  break;
192  case IrOpcode::kPhi: {
193  // Phi input count matches parent control node.
194  CHECK_EQ(1, control_count);
195  Node* control = NodeProperties::GetControlInput(node, 0);
196  CHECK_EQ(value_count,
198  break;
199  }
200  case IrOpcode::kEffectPhi: {
201  // EffectPhi input count matches parent control node.
202  CHECK_EQ(1, control_count);
203  Node* control = NodeProperties::GetControlInput(node, 0);
204  CHECK_EQ(effect_count,
206  break;
207  }
208  case IrOpcode::kFrameState:
209  // TODO(jarin): what are the constraints on these?
210  break;
211  case IrOpcode::kCall:
212  // TODO(rossberg): what are the constraints on these?
213  break;
214  case IrOpcode::kProjection: {
215  // Projection has an input that produces enough values.
216  size_t index = OpParameter<size_t>(node);
217  Node* input = NodeProperties::GetValueInput(node, 0);
219  static_cast<int>(index));
220  break;
221  }
222  default:
223  // TODO(rossberg): Check other node kinds.
224  break;
225  }
226 
227  if (from_start) {
228  reached_from_start.insert(node);
229  } else {
230  reached_from_end.insert(node);
231  }
232 
234 }
static Node * GetContextInput(Node *node)
static Node * GetValueInput(Node *node, int index)
static Node * GetFrameStateInput(Node *node)
static bool IsValueEdge(Node::Edge edge)
static Node * GetEffectInput(Node *node, int index=0)
static Node * GetControlInput(Node *node, int index=0)
static int GetEffectInputCount(const Operator *op)
static int GetFrameStateInputCount(const Operator *op)
static int GetContextInputCount(const Operator *op)
static bool HasValueOutput(const Operator *op)
static int GetValueInputCount(const Operator *op)
static bool HasFrameStateInput(const Operator *op)
static bool HasEffectOutput(const Operator *op)
static int GetValueOutputCount(const Operator *op)
static int GetControlInputCount(const Operator *op)
static bool HasControlOutput(const Operator *op)
#define UNREACHABLE()
Definition: logging.h:30
#define CHECK_EQ(expected, value)
Definition: logging.h:169
#define CHECK(condition)
Definition: logging.h:36
#define CHECK_GT(a, b)
Definition: logging.h:177
static bool IsUseDefChainLinkPresent(Node *def, Node *use)
Definition: verifier.cc:37
static bool IsDefUseChainLinkPresent(Node *def, Node *use)
Definition: verifier.cc:28

References CHECK, CHECK_EQ, CHECK_GT, v8::internal::compiler::GenericGraphVisit::CONTINUE, from_start, v8::internal::compiler::NodeProperties::GetContextInput(), v8::internal::compiler::OperatorProperties::GetContextInputCount(), v8::internal::compiler::NodeProperties::GetControlInput(), v8::internal::compiler::OperatorProperties::GetControlInputCount(), v8::internal::compiler::NodeProperties::GetEffectInput(), v8::internal::compiler::OperatorProperties::GetEffectInputCount(), v8::internal::compiler::NodeProperties::GetFrameStateInput(), v8::internal::compiler::OperatorProperties::GetFrameStateInputCount(), v8::internal::compiler::NodeProperties::GetValueInput(), v8::internal::compiler::OperatorProperties::GetValueInputCount(), v8::internal::compiler::OperatorProperties::GetValueOutputCount(), v8::internal::compiler::OperatorProperties::HasControlOutput(), v8::internal::compiler::OperatorProperties::HasEffectOutput(), v8::internal::compiler::OperatorProperties::HasFrameStateInput(), v8::internal::compiler::OperatorProperties::HasValueOutput(), v8::internal::compiler::IsDefUseChainLinkPresent(), v8::internal::compiler::IsUseDefChainLinkPresent(), v8::internal::compiler::NodeProperties::IsValueEdge(), reached_from_end, reached_from_start, and UNREACHABLE.

+ Here is the call graph for this function:

Member Data Documentation

◆ from_start

bool v8::internal::compiler::Verifier::Visitor::from_start

Definition at line 57 of file verifier.cc.

Referenced by Pre(), and v8::internal::compiler::Verifier::Run().

◆ reached_from_end

NodeSet v8::internal::compiler::Verifier::Visitor::reached_from_end

Definition at line 59 of file verifier.cc.

Referenced by Pre(), and v8::internal::compiler::Verifier::Run().

◆ reached_from_start

NodeSet v8::internal::compiler::Verifier::Visitor::reached_from_start

Definition at line 58 of file verifier.cc.

Referenced by Pre(), and v8::internal::compiler::Verifier::Run().


The documentation for this class was generated from the following file: