v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
node-properties.cc
Go to the documentation of this file.
1// Copyright 2015 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
6
7#include <optional>
8
17
18namespace v8 {
19namespace internal {
20namespace compiler {
21
22// static
23
24// static
26 Node* const node = edge.from();
27 return IsInputRange(edge, FirstValueIndex(node),
28 node->op()->ValueInputCount());
29}
30
31
32// static
34 Node* const node = edge.from();
35 return IsInputRange(edge, FirstContextIndex(node),
37}
38
39
40// static
42 Node* const node = edge.from();
43 return IsInputRange(edge, FirstFrameStateIndex(node),
45}
46
47
48// static
50 Node* const node = edge.from();
51 return IsInputRange(edge, FirstEffectIndex(node),
52 node->op()->EffectInputCount());
53}
54
55
56// static
58 Node* const node = edge.from();
59 return IsInputRange(edge, FirstControlIndex(node),
60 node->op()->ControlInputCount());
61}
62
63
64// static
65bool NodeProperties::IsExceptionalCall(Node* node, Node** out_exception) {
66 if (node->op()->HasProperty(Operator::kNoThrow)) return false;
67 for (Edge const edge : node->use_edges()) {
68 if (!NodeProperties::IsControlEdge(edge)) continue;
69 if (edge.from()->opcode() == IrOpcode::kIfException) {
70 if (out_exception != nullptr) *out_exception = edge.from();
71 return true;
72 }
73 }
74 return false;
75}
76
77// static
79 CHECK_GT(node->op()->ControlOutputCount(), 0);
80 if (node->op()->HasProperty(Operator::kNoThrow)) return node;
81 for (Edge const edge : node->use_edges()) {
82 if (!NodeProperties::IsControlEdge(edge)) continue;
83 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
84 return edge.from();
85 }
86 }
87 return node;
88}
89
90// static
91void NodeProperties::ReplaceValueInput(Node* node, Node* value, int index) {
92 CHECK_LE(0, index);
93 CHECK_LT(index, node->op()->ValueInputCount());
94 node->ReplaceInput(FirstValueIndex(node) + index, value);
95}
96
97
98// static
100 int value_input_count = node->op()->ValueInputCount();
101 CHECK_GT(value_input_count, 0);
102 node->ReplaceInput(0, value);
103 while (--value_input_count > 0) {
104 node->RemoveInput(value_input_count);
105 }
106}
107
108
109// static
112 node->ReplaceInput(FirstContextIndex(node), context);
113}
114
115
116// static
117void NodeProperties::ReplaceControlInput(Node* node, Node* control, int index) {
118 CHECK_LE(0, index);
119 CHECK_LT(index, node->op()->ControlInputCount());
120 node->ReplaceInput(FirstControlIndex(node) + index, control);
121}
122
123
124// static
125void NodeProperties::ReplaceEffectInput(Node* node, Node* effect, int index) {
126 CHECK_LE(0, index);
127 CHECK_LT(index, node->op()->EffectInputCount());
128 return node->ReplaceInput(FirstEffectIndex(node) + index, effect);
129}
130
131
132// static
135 node->ReplaceInput(FirstFrameStateIndex(node), frame_state);
136}
137
138// static
140 node->TrimInputCount(node->op()->ValueInputCount());
141}
142
143
144// static
146 int value_input_count = node->op()->ValueInputCount();
147 while (--value_input_count >= 0) {
148 node->RemoveInput(value_input_count);
149 }
150}
151
153 CommonOperatorBuilder* common,
154 Node* node) {
155 graph->end()->AppendInput(graph->zone(), node);
156 graph->end()->set_op(common->End(graph->end()->InputCount()));
157}
158
160 CommonOperatorBuilder* common,
161 Node* node) {
162 int index_to_remove = -1;
163 for (int i = 0; i < graph->end()->op()->ControlInputCount(); i++) {
164 int index = NodeProperties::FirstControlIndex(graph->end()) + i;
165 if (graph->end()->InputAt(index) == node) {
166 index_to_remove = index;
167 break;
168 }
169 }
170 CHECK_NE(-1, index_to_remove);
171 graph->end()->RemoveInput(index_to_remove);
172 graph->end()->set_op(common->End(graph->end()->InputCount()));
173}
174
175// static
176void NodeProperties::ReplaceUses(Node* node, Node* value, Node* effect,
177 Node* success, Node* exception) {
178 // Requires distinguishing between value, effect and control edges.
179 for (Edge edge : node->use_edges()) {
180 if (IsControlEdge(edge)) {
181 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
182 DCHECK_NOT_NULL(success);
183 edge.UpdateTo(success);
184 } else if (edge.from()->opcode() == IrOpcode::kIfException) {
185 DCHECK_NOT_NULL(exception);
186 edge.UpdateTo(exception);
187 } else {
188 DCHECK_NOT_NULL(success);
189 edge.UpdateTo(success);
190 }
191 } else if (IsEffectEdge(edge)) {
192 DCHECK_NOT_NULL(effect);
193 edge.UpdateTo(effect);
194 } else {
195 DCHECK_NOT_NULL(value);
196 edge.UpdateTo(value);
197 }
198 }
199}
200
201
202// static
203void NodeProperties::ChangeOp(Node* node, const Operator* new_op) {
204 node->set_op(new_op);
206}
207
208// static
210 node->set_op(new_op);
211}
212
213// static
215 Node* unreachable_sentinel) {
216 Node* effect = NodeProperties::GetEffectInput(node);
217 while (effect->opcode() != IrOpcode::kCheckpoint) {
218 if (effect->opcode() == IrOpcode::kDead ||
219 effect->opcode() == IrOpcode::kUnreachable) {
220 return unreachable_sentinel;
221 }
222 DCHECK(effect->op()->HasProperty(Operator::kNoWrite));
223 DCHECK_EQ(1, effect->op()->EffectInputCount());
224 effect = NodeProperties::GetEffectInput(effect);
225 }
226 Node* frame_state = GetFrameStateInput(effect);
227 return frame_state;
228}
229
230// static
231Node* NodeProperties::FindProjection(Node* node, size_t projection_index) {
232 for (auto use : node->uses()) {
233 if (use->opcode() == IrOpcode::kProjection &&
234 ProjectionIndexOf(use->op()) == projection_index) {
235 return use;
236 }
237 }
238 return nullptr;
239}
240
241
242// static
244 size_t projection_count) {
245#ifdef DEBUG
246 for (size_t index = 0; index < projection_count; ++index) {
247 DCHECK_NULL(projections[index]);
248 }
249#endif
250 for (Edge const edge : node->use_edges()) {
251 if (!IsValueEdge(edge)) continue;
252 Node* use = edge.from();
253 DCHECK_EQ(IrOpcode::kProjection, use->opcode());
254 projections[ProjectionIndexOf(use->op())] = use;
255 }
256}
257
258
259// static
261 size_t projection_count) {
262#ifdef DEBUG
263 DCHECK_LE(static_cast<int>(projection_count), node->UseCount());
264 std::memset(projections, 0, sizeof(*projections) * projection_count);
265#endif
266 size_t if_value_index = 0;
267 for (Edge const edge : node->use_edges()) {
268 if (!IsControlEdge(edge)) continue;
269 Node* use = edge.from();
270 size_t index;
271 switch (use->opcode()) {
272 case IrOpcode::kIfTrue:
273 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
274 index = 0;
275 break;
276 case IrOpcode::kIfFalse:
277 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
278 index = 1;
279 break;
280 case IrOpcode::kIfSuccess:
281 DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
282 index = 0;
283 break;
284 case IrOpcode::kIfException:
285 DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
286 index = 1;
287 break;
288 case IrOpcode::kIfValue:
289 DCHECK_EQ(IrOpcode::kSwitch, node->opcode());
290 index = if_value_index++;
291 break;
292 case IrOpcode::kIfDefault:
293 DCHECK_EQ(IrOpcode::kSwitch, node->opcode());
294 index = projection_count - 1;
295 break;
296 default:
297 continue;
298 }
299 DCHECK_LT(if_value_index, projection_count);
300 DCHECK_LT(index, projection_count);
301 DCHECK_NULL(projections[index]);
302 projections[index] = use;
303 }
304#ifdef DEBUG
305 for (size_t index = 0; index < projection_count; ++index) {
306 DCHECK_NOT_NULL(projections[index]);
307 }
308#endif
309}
310
311// static
313 Node const* projection) {
314 size_t index = ProjectionIndexOf(projection->op());
315 Node* input = projection->InputAt(0);
316 switch (input->opcode()) {
317 case IrOpcode::kInt32AddWithOverflow:
318 case IrOpcode::kInt32SubWithOverflow:
319 case IrOpcode::kInt32MulWithOverflow:
320 case IrOpcode::kInt32AbsWithOverflow:
321 CHECK_LE(index, static_cast<size_t>(1));
322 return index == 0 ? MachineRepresentation::kWord32
324 case IrOpcode::kInt64AddWithOverflow:
325 case IrOpcode::kInt64SubWithOverflow:
326 case IrOpcode::kInt64MulWithOverflow:
327 case IrOpcode::kInt64AbsWithOverflow:
328 CHECK_LE(index, static_cast<size_t>(1));
329 return index == 0 ? MachineRepresentation::kWord64
331 case IrOpcode::kTryTruncateFloat64ToInt32:
332 case IrOpcode::kTryTruncateFloat64ToUint32:
333 CHECK_LE(index, static_cast<size_t>(1));
334 return index == 0 ? MachineRepresentation::kWord32
336 case IrOpcode::kTryTruncateFloat32ToInt64:
337 case IrOpcode::kTryTruncateFloat64ToInt64:
338 case IrOpcode::kTryTruncateFloat64ToUint64:
339 case IrOpcode::kTryTruncateFloat32ToUint64:
340 CHECK_LE(index, static_cast<size_t>(1));
341 return index == 0 ? MachineRepresentation::kWord64
343 case IrOpcode::kCall: {
344 auto call_descriptor = CallDescriptorOf(input->op());
345 return call_descriptor->GetReturnType(index).representation();
346 }
347 case IrOpcode::kInt32PairAdd:
348 case IrOpcode::kInt32PairSub:
349 case IrOpcode::kWord32AtomicPairLoad:
350 case IrOpcode::kWord32AtomicPairAdd:
351 case IrOpcode::kWord32AtomicPairSub:
352 case IrOpcode::kWord32AtomicPairAnd:
353 case IrOpcode::kWord32AtomicPairOr:
354 case IrOpcode::kWord32AtomicPairXor:
355 case IrOpcode::kWord32AtomicPairExchange:
356 case IrOpcode::kWord32AtomicPairCompareExchange:
357 CHECK_LE(index, static_cast<size_t>(1));
359 default:
361 }
362}
363
364// static
366 for (;;) {
367 if (a->opcode() == IrOpcode::kCheckHeapObject ||
368 a->opcode() == IrOpcode::kTypeGuard) {
369 a = GetValueInput(a, 0);
370 continue;
371 }
372 if (b->opcode() == IrOpcode::kCheckHeapObject ||
373 b->opcode() == IrOpcode::kTypeGuard) {
374 b = GetValueInput(b, 0);
375 continue;
376 }
377 return a == b;
378 }
379}
380
381// static
383 Node* receiver) {
384 DCHECK(receiver->opcode() == IrOpcode::kJSCreate ||
385 receiver->opcode() == IrOpcode::kJSCreateArray);
388 if (mtarget.HasResolvedValue() && mnewtarget.HasResolvedValue() &&
389 mnewtarget.Ref(broker).IsJSFunction()) {
390 ObjectRef target = mtarget.Ref(broker);
391 JSFunctionRef newtarget = mnewtarget.Ref(broker).AsJSFunction();
392 if (newtarget.map(broker).has_prototype_slot() &&
393 newtarget.has_initial_map(broker)) {
395 if (initial_map.GetConstructor(broker).equals(target)) {
396 DCHECK(target.AsJSFunction().map(broker).is_constructor());
397 DCHECK(newtarget.map(broker).is_constructor());
398 return initial_map;
399 }
400 }
401 }
402 return std::nullopt;
403}
404
405// static
408 ZoneRefSet<Map>* maps_out) {
410 if (m.HasResolvedValue()) {
411 HeapObjectRef ref = m.Ref(broker);
412 // We don't use ICs for the Array.prototype and the Object.prototype
413 // because the runtime has to be able to intercept them properly, so
414 // we better make sure that TurboFan doesn't outsmart the system here
415 // by storing to elements of either prototype directly.
416 //
417 // TODO(bmeurer): This can be removed once the Array.prototype and
418 // Object.prototype have NO_ELEMENTS elements kind.
419 if (!ref.IsJSObject() ||
420 !broker->IsArrayOrObjectPrototype(ref.AsJSObject())) {
421 if (ref.map(broker).is_stable()) {
422 // The {receiver_map} is only reliable when we install a stability
423 // code dependency.
424 *maps_out = ZoneRefSet<Map>{ref.map(broker)};
425 return kUnreliableMaps;
426 }
427 }
428 }
430 while (true) {
431 switch (effect->opcode()) {
432 case IrOpcode::kTypeGuard: {
433 DCHECK_EQ(1, effect->op()->EffectInputCount());
434 effect = NodeProperties::GetEffectInput(effect);
435 continue;
436 }
437
438 case IrOpcode::kMapGuard: {
439 Node* const object = GetValueInput(effect, 0);
440 if (IsSame(receiver, object)) {
441 *maps_out = MapGuardMapsOf(effect->op());
442 return result;
443 }
444 break;
445 }
446 case IrOpcode::kCheckMaps: {
447 Node* const object = GetValueInput(effect, 0);
448 if (IsSame(receiver, object)) {
449 *maps_out = CheckMapsParametersOf(effect->op()).maps();
450 return result;
451 }
452 break;
453 }
454 case IrOpcode::kTransitionElementsKindOrCheckMap: {
455 Node* const object = GetValueInput(effect, 0);
456 if (IsSame(receiver, object)) {
457 *maps_out = ZoneRefSet<Map>{
459 return result;
460 }
461 // `receiver` and `object` might alias, so
462 // TransitionElementsKindOrCheckMaps might change receiver's map.
464 break;
465 }
466 case IrOpcode::kJSCreate: {
467 if (IsSame(receiver, effect)) {
468 OptionalMapRef initial_map = GetJSCreateMap(broker, receiver);
469 if (initial_map.has_value()) {
470 *maps_out = ZoneRefSet<Map>{initial_map.value()};
471 return result;
472 }
473 // We reached the allocation of the {receiver}.
474 return kNoMaps;
475 }
476 result = kUnreliableMaps; // JSCreate can have side-effect.
477 break;
478 }
479 case IrOpcode::kJSCreatePromise: {
480 if (IsSame(receiver, effect)) {
481 *maps_out = ZoneRefSet<Map>{broker->target_native_context()
482 .promise_function(broker)
483 .initial_map(broker)};
484 return result;
485 }
486 break;
487 }
488 case IrOpcode::kStoreField: {
489 // We only care about StoreField of maps.
490 Node* const object = GetValueInput(effect, 0);
491 FieldAccess const& access = FieldAccessOf(effect->op());
492 if (access.base_is_tagged == kTaggedBase &&
493 access.offset == HeapObject::kMapOffset) {
494 if (IsSame(receiver, object)) {
495 Node* const value = GetValueInput(effect, 1);
496 HeapObjectMatcher m2(value);
497 if (m2.HasResolvedValue()) {
498 *maps_out = ZoneRefSet<Map>{m2.Ref(broker).AsMap()};
499 return result;
500 }
501 }
502 // Without alias analysis we cannot tell whether this
503 // StoreField[map] affects {receiver} or not.
505 }
506 break;
507 }
508 case IrOpcode::kJSStoreMessage:
509 case IrOpcode::kJSStoreModule:
510 case IrOpcode::kStoreElement:
511 case IrOpcode::kStoreTypedElement: {
512 // These never change the map of objects.
513 break;
514 }
515 case IrOpcode::kFinishRegion: {
516 // FinishRegion renames the output of allocations, so we need
517 // to update the {receiver} that we are looking for, if the
518 // {receiver} matches the current {effect}.
519 if (IsSame(receiver, effect)) receiver = GetValueInput(effect, 0);
520 break;
521 }
522 case IrOpcode::kEffectPhi: {
523 Node* control = GetControlInput(effect);
524 if (control->opcode() != IrOpcode::kLoop) {
525 DCHECK(control->opcode() == IrOpcode::kDead ||
526 control->opcode() == IrOpcode::kMerge);
527 return kNoMaps;
528 }
529
530 // Continue search for receiver map outside the loop. Since operations
531 // inside the loop may change the map, the result is unreliable.
532 effect = GetEffectInput(effect, 0);
534 continue;
535 }
536 default: {
537 DCHECK_EQ(1, effect->op()->EffectOutputCount());
538 if (effect->op()->EffectInputCount() != 1) {
539 // Didn't find any appropriate CheckMaps node.
540 return kNoMaps;
541 }
542 if (!effect->op()->HasProperty(Operator::kNoWrite)) {
543 // Without alias/escape analysis we cannot tell whether this
544 // {effect} affects {receiver} or not.
546 }
547 break;
548 }
549 }
550
551 // Stop walking the effect chain once we hit the definition of
552 // the {receiver} along the {effect}s.
553 if (IsSame(receiver, effect)) return kNoMaps;
554
555 // Continue with the next {effect}.
556 DCHECK_EQ(1, effect->op()->EffectInputCount());
557 effect = NodeProperties::GetEffectInput(effect);
558 }
559}
560
561// static
563 Node* dominator) {
564 while (effect != dominator) {
565 if (effect->op()->EffectInputCount() == 1 &&
566 effect->op()->properties() & Operator::kNoWrite) {
567 effect = NodeProperties::GetEffectInput(effect);
568 } else {
569 return false;
570 }
571 }
572 return true;
573}
574
575// static
577 Effect effect) {
578 switch (receiver->opcode()) {
579#define CASE(Opcode) case IrOpcode::k##Opcode:
582#undef CASE
583 case IrOpcode::kCheckReceiver:
584 case IrOpcode::kConvertReceiver:
585 case IrOpcode::kJSGetSuperConstructor:
586 case IrOpcode::kJSToObject:
587 return false;
588 case IrOpcode::kHeapConstant: {
590 return value.map(broker).IsPrimitiveMap();
591 }
592 default: {
593 MapInference inference(broker, receiver, effect);
594 return !inference.HaveMaps() ||
596 }
597 }
598}
599
600// static
602 Effect effect) {
603 if (CanBePrimitive(broker, receiver, effect)) {
604 switch (receiver->opcode()) {
605 case IrOpcode::kCheckInternalizedString:
606 case IrOpcode::kCheckNumber:
607 case IrOpcode::kCheckNumberFitsInt32:
608 case IrOpcode::kCheckSmi:
609 case IrOpcode::kCheckString:
610 case IrOpcode::kCheckSymbol:
611 case IrOpcode::kJSToLength:
612 case IrOpcode::kJSToName:
613 case IrOpcode::kJSToNumber:
614 case IrOpcode::kJSToNumberConvertBigInt:
615 case IrOpcode::kJSToNumeric:
616 case IrOpcode::kJSToString:
617 case IrOpcode::kToBoolean:
618 return false;
619 case IrOpcode::kHeapConstant: {
622 return type == OddballType::kNull || type == OddballType::kUndefined;
623 }
624 default:
625 return true;
626 }
627 }
628 return false;
629}
630
631// static
633 Node* context = NodeProperties::GetContextInput(node);
634 while (*depth > 0 &&
635 IrOpcode::IsContextChainExtendingOpcode(context->opcode())) {
636 context = NodeProperties::GetContextInput(context);
637 (*depth)--;
638 }
639 return context;
640}
641
642// static
644 return IsTyped(node) ? node->type() : Type::Any();
645}
646
647// static
649 int input_count = node->op()->ValueInputCount();
650 for (int index = 0; index < input_count; ++index) {
651 if (!IsTyped(GetValueInput(node, index))) return false;
652 }
653 return true;
654}
655
656// static
657bool NodeProperties::IsInputRange(Edge edge, int first, int num) {
658 if (num == 0) return false;
659 int const index = edge.index();
660 return first <= index && index < first + num;
661}
662
663// static
665 size_t h = base::hash_combine(node->op()->HashCode(), node->InputCount());
666 for (Node* input : node->inputs()) {
667 h = base::hash_combine(h, input->id());
668 }
669 return h;
670}
671
672// static
676 DCHECK_NOT_NULL(a->op());
677 DCHECK_NOT_NULL(b->op());
678 if (!a->op()->Equals(b->op())) return false;
679 if (a->InputCount() != b->InputCount()) return false;
680 Node::Inputs aInputs = a->inputs();
681 Node::Inputs bInputs = b->inputs();
682
683 auto aIt = aInputs.begin();
684 auto bIt = bInputs.begin();
685 auto aEnd = aInputs.end();
686
687 for (; aIt != aEnd; ++aIt, ++bIt) {
688 DCHECK_NOT_NULL(*aIt);
689 DCHECK_NOT_NULL(*bIt);
690 if ((*aIt)->id() != (*bIt)->id()) return false;
691 }
692 return true;
693}
694
695} // namespace compiler
696} // namespace internal
697} // namespace v8
static constexpr int kMapOffset
const Operator * End(size_t control_input_count)
Node * from() const
Definition node.h:425
V8_EXPORT_PRIVATE MapRef map(JSHeapBroker *broker) const
static bool IsContextChainExtendingOpcode(Value value)
Definition opcodes.h:1441
bool has_initial_map(JSHeapBroker *broker) const
MapRef initial_map(JSHeapBroker *broker) const
V8_WARN_UNUSED_RESULT bool HaveMaps() const
V8_WARN_UNUSED_RESULT bool AllOfInstanceTypesAreJSReceiver() const
OddballType oddball_type(JSHeapBroker *broker) const
static void RemoveControlFromEnd(TFGraph *graph, CommonOperatorBuilder *common, Node *node)
static MachineRepresentation GetProjectionType(Node const *projection)
static void ChangeOp(Node *node, const Operator *new_op)
static void ReplaceEffectInput(Node *node, Node *effect, int index=0)
static bool IsInputRange(Edge edge, int first, int count)
static void RemoveNonValueInputs(Node *node)
static void ReplaceControlInput(Node *node, Node *control, int index=0)
static bool CanBeNullOrUndefined(JSHeapBroker *broker, Node *receiver, Effect effect)
static bool IsTyped(const Node *node)
static Type GetTypeOrAny(const Node *node)
static void ReplaceUses(Node *node, Node *value, Node *effect=nullptr, Node *success=nullptr, Node *exception=nullptr)
static OptionalMapRef GetJSCreateMap(JSHeapBroker *broker, Node *receiver)
static Node * GetEffectInput(Node *node, int index=0)
static int FirstFrameStateIndex(Node *node)
static Node * GetContextInput(Node *node)
static void MergeControlToEnd(TFGraph *graph, CommonOperatorBuilder *common, Node *node)
static void ReplaceContextInput(Node *node, Node *context)
static Node * GetFrameStateInput(Node *node)
static void CollectControlProjections(Node *node, Node **proj, size_t count)
static bool CanBePrimitive(JSHeapBroker *broker, Node *receiver, Effect effect)
static bool AllValueInputsAreTyped(Node *node)
static Node * GetValueInput(Node *node, int index)
static void ChangeOpUnchecked(Node *node, const Operator *new_op)
static bool Equals(Node *a, Node *b)
static void ReplaceValueInput(Node *node, Node *value, int index)
static Node * FindFrameStateBefore(Node *node, Node *unreachable_sentinel)
static Node * FindProjection(Node *node, size_t projection_index)
static void ReplaceValueInputs(Node *node, Node *value)
static void ReplaceFrameStateInput(Node *node, Node *frame_state)
static Node * GetOuterContext(Node *node, size_t *depth)
static int FirstValueIndex(const Node *node)
static bool NoObservableSideEffectBetween(Node *effect, Node *dominator)
static bool IsSame(Node *a, Node *b)
static bool IsExceptionalCall(Node *node, Node **out_exception=nullptr)
static InferMapsResult InferMapsUnsafe(JSHeapBroker *broker, Node *receiver, Effect effect, ZoneRefSet< Map > *maps_out)
static Node * GetControlInput(Node *node, int index=0)
static void CollectValueProjections(Node *node, Node **proj, size_t count)
static Node * FindSuccessfulControlProjection(Node *node)
const_iterator begin() const
Definition node.h:600
const_iterator end() const
Definition node.h:605
constexpr IrOpcode::Value opcode() const
Definition node.h:52
Inputs inputs() const
Definition node.h:478
const Operator * op() const
Definition node.h:50
int InputCount() const
Definition node.h:59
Node * InputAt(int index) const
Definition node.h:70
static int GetContextInputCount(const Operator *op)
static bool HasContextInput(const Operator *op)
static bool HasFrameStateInput(const Operator *op)
static int GetFrameStateInputCount(const Operator *op)
static void VerifyNode(Node *node)
Definition verifier.h:51
JSHeapBroker * broker
TNode< Context > context
TNode< Object > receiver
Node * node
ZoneVector< RpoNumber > & result
int m
Definition mul-fft.cc:294
V8_INLINE size_t hash_combine(size_t seed, size_t hash)
Definition hashing.h:77
size_t ProjectionIndexOf(const Operator *const op)
CheckMapsParameters const & CheckMapsParametersOf(Operator const *op)
CallDescriptor const * CallDescriptorOf(const Operator *const op)
ZoneRefSet< Map > const & MapGuardMapsOf(Operator const *op)
const FieldAccess & FieldAccessOf(const Operator *op)
ElementsTransitionWithMultipleSources const & ElementsTransitionWithMultipleSourcesOf(const Operator *op)
HeapObjectMatcherImpl< IrOpcode::kHeapConstant > HeapObjectMatcher
other heap size generate builtins concurrently on separate threads in mksnapshot track concurrent recompilation artificial compilation delay in ms max number of threads that concurrent Turbofan can use(0 for unbounded)") DEFINE_BOOL( stress_concurrent_inlining
#define JS_CREATE_OP_LIST(V)
Definition opcodes.h:157
#define JS_CONSTRUCT_OP_LIST(V)
Definition opcodes.h:219
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_NULL(val)
Definition logging.h:491
#define CHECK(condition)
Definition logging.h:124
#define CHECK_GT(lhs, rhs)
#define CHECK_LT(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define CHECK_NE(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
HeapObjectRef Ref(JSHeapBroker *broker) const