v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
js-context-specialization.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
6
7#include "src/base/logging.h"
22
23namespace v8 {
24namespace internal {
25namespace compiler {
26
28 switch (node->opcode()) {
29 case IrOpcode::kParameter:
30 return ReduceParameter(node);
31 case IrOpcode::kJSLoadContext:
32 return ReduceJSLoadContext(node);
33 case IrOpcode::kJSLoadScriptContext:
34 return ReduceJSLoadScriptContext(node);
35 case IrOpcode::kJSStoreContext:
36 return ReduceJSStoreContext(node);
37 case IrOpcode::kJSStoreScriptContext:
38 return ReduceJSStoreScriptContext(node);
39 case IrOpcode::kJSGetImportMeta:
40 return ReduceJSGetImportMeta(node);
41 default:
42 break;
43 }
44 return NoChange();
45}
46
48 DCHECK_EQ(IrOpcode::kParameter, node->opcode());
49 int const index = ParameterIndexOf(node->op());
51 // Constant-fold the function parameter {node}.
52 Handle<JSFunction> function;
53 if (closure().ToHandle(&function)) {
54 Node* value =
56 return Replace(value);
57 }
58 }
59 return NoChange();
60}
61
63 Node* new_context,
64 size_t new_depth) {
65 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
66 const ContextAccess& access = ContextAccessOf(node->op());
67 DCHECK_LE(new_depth, access.depth());
68
69 if (new_depth == access.depth() &&
70 new_context == NodeProperties::GetContextInput(node)) {
71 return NoChange();
72 }
73
75 new_depth, access.index(), access.immutable());
76 NodeProperties::ReplaceContextInput(node, new_context);
78 return Changed(node);
79}
80
82 Node* node, Node* new_context, size_t new_depth) {
83 DCHECK_EQ(IrOpcode::kJSLoadScriptContext, node->opcode());
84 const ContextAccess& access = ContextAccessOf(node->op());
85 DCHECK_LE(new_depth, access.depth());
86
87 if (new_depth == access.depth() &&
88 new_context == NodeProperties::GetContextInput(node)) {
89 return NoChange();
90 }
91
92 const Operator* op =
93 jsgraph_->javascript()->LoadScriptContext(new_depth, access.index());
94 NodeProperties::ReplaceContextInput(node, new_context);
96 return Changed(node);
97}
98
100 Node* new_context,
101 size_t new_depth) {
102 DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
103 const ContextAccess& access = ContextAccessOf(node->op());
104 DCHECK_LE(new_depth, access.depth());
105
106 if (new_depth == access.depth() &&
107 new_context == NodeProperties::GetContextInput(node)) {
108 return NoChange();
109 }
110
111 const Operator* op =
112 jsgraph_->javascript()->StoreContext(new_depth, access.index());
113 NodeProperties::ReplaceContextInput(node, new_context);
114 NodeProperties::ChangeOp(node, op);
115 return Changed(node);
116}
117
119 Node* node, Node* new_context, size_t new_depth) {
120 DCHECK_EQ(IrOpcode::kJSStoreScriptContext, node->opcode());
121 const ContextAccess& access = ContextAccessOf(node->op());
122 DCHECK_LE(new_depth, access.depth());
123
124 if (new_depth == access.depth() &&
125 new_context == NodeProperties::GetContextInput(node)) {
126 return NoChange();
127 }
128
129 const Operator* op =
130 jsgraph_->javascript()->StoreScriptContext(new_depth, access.index());
131 NodeProperties::ReplaceContextInput(node, new_context);
132 NodeProperties::ChangeOp(node, op);
133 return Changed(node);
134}
135
136namespace {
137
138bool IsContextParameter(Node* node) {
139 DCHECK_EQ(IrOpcode::kParameter, node->opcode());
140 return ParameterIndexOf(node->op()) ==
143}
144
145// Given a context {node} and the {distance} from that context to the target
146// context (which we want to read from or store to), try to return a
147// specialization context. If successful, update {distance} to whatever
148// distance remains from the specialization context.
149OptionalContextRef GetSpecializationContext(JSHeapBroker* broker, Node* node,
150 size_t* distance,
151 Maybe<OuterContext> maybe_outer) {
152 switch (node->opcode()) {
153 case IrOpcode::kHeapConstant: {
154 // TODO(jgruber,chromium:1209798): Using kAssumeMemoryFence works around
155 // the fact that the graph stores handles (and not refs). The assumption
156 // is that any handle inserted into the graph is safe to read; but we
157 // don't preserve the reason why it is safe to read. Thus we must
158 // over-approximate here and assume the existence of a memory fence. In
159 // the future, we should consider having the graph store ObjectRefs or
160 // ObjectData pointer instead, which would make new ref construction here
161 // unnecessary.
162 HeapObjectRef object =
164 if (object.IsContext()) return object.AsContext();
165 break;
166 }
167 case IrOpcode::kParameter: {
168 OuterContext outer;
169 if (maybe_outer.To(&outer) && IsContextParameter(node) &&
170 *distance >= outer.distance) {
171 *distance -= outer.distance;
172 return MakeRef(broker, outer.context);
173 }
174 break;
175 }
176 default:
177 break;
178 }
179 return OptionalContextRef();
180}
181
182} // anonymous namespace
183
185 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
186
187 const ContextAccess& access = ContextAccessOf(node->op());
188 size_t depth = access.depth();
189
190 // First walk up the context chain in the graph as far as possible.
191 Node* context = NodeProperties::GetOuterContext(node, &depth);
192
193 OptionalContextRef maybe_concrete =
194 GetSpecializationContext(broker(), context, &depth, outer());
195 if (!maybe_concrete.has_value()) {
196 // We do not have a concrete context object, so we can only partially reduce
197 // the load by folding-in the outer context node.
198 return SimplifyJSLoadContext(node, context, depth);
199 }
200
201 // Now walk up the concrete context chain for the remaining depth.
202 ContextRef concrete = maybe_concrete.value();
203 concrete = concrete.previous(broker(), &depth);
204 if (depth > 0) {
205 TRACE_BROKER_MISSING(broker(), "previous value for context " << concrete);
207 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
208 }
209
210 if (!access.immutable() &&
211 !broker()->dependencies()->DependOnScriptContextSlotProperty(
212 concrete, access.index(), ContextSidePropertyCell::kConst,
213 broker())) {
214 // We found the requested context object but since the context slot is
215 // mutable we can only partially reduce the load.
217 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
218 }
219
220 // This will hold the final value, if we can figure it out.
221 OptionalObjectRef maybe_value;
222 maybe_value = concrete.get(broker(), static_cast<int>(access.index()));
223
224 if (!maybe_value.has_value()) {
225 TRACE_BROKER_MISSING(broker(), "slot value " << access.index()
226 << " for context "
227 << concrete);
229 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
230 }
231
232 // Even though the context slot is immutable, the context might have escaped
233 // before the function to which it belongs has initialized the slot.
234 // We must be conservative and check if the value in the slot is currently
235 // the hole or undefined. Only if it is neither of these, can we be sure
236 // that it won't change anymore.
237 if (maybe_value->IsUndefined() || maybe_value->IsTheHole()) {
239 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
240 }
241
242 // Success. The context load can be replaced with the constant.
243 Node* constant = jsgraph_->ConstantNoHole(*maybe_value, broker());
244 ReplaceWithValue(node, constant);
245 return Replace(constant);
246}
247
249 DCHECK_EQ(IrOpcode::kJSLoadScriptContext, node->opcode());
250
251 const ContextAccess& access = ContextAccessOf(node->op());
252 DCHECK(!access.immutable());
253 size_t depth = access.depth();
254
255 // First walk up the context chain in the graph as far as possible.
256 Node* effect = NodeProperties::GetEffectInput(node);
257 Node* control = NodeProperties::GetControlInput(node);
258 Node* context = NodeProperties::GetOuterContext(node, &depth);
259
260 OptionalContextRef maybe_concrete =
261 GetSpecializationContext(broker(), context, &depth, outer());
262 if (!maybe_concrete.has_value()) {
263 // We do not have a concrete context object, so we can only partially reduce
264 // the load by folding-in the outer context node.
265 return SimplifyJSLoadScriptContext(node, context, depth);
266 }
267
268 // Now walk up the concrete context chain for the remaining depth.
269 ContextRef concrete = maybe_concrete.value();
270 concrete = concrete.previous(broker(), &depth);
271 if (depth > 0) {
272 TRACE_BROKER_MISSING(broker(), "previous value for context " << concrete);
274 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
275 }
276
277 DCHECK(concrete.object()->IsScriptContext());
278 auto maybe_property =
279 concrete.object()->GetScriptContextSideProperty(access.index());
280 if (!maybe_property) {
282 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
283 }
284 auto property = maybe_property.value();
285 switch (property) {
287 OptionalObjectRef maybe_value =
288 concrete.get(broker(), static_cast<int>(access.index()));
289 if (!maybe_value.has_value()) {
290 TRACE_BROKER_MISSING(broker(), "slot value " << access.index()
291 << " for context "
292 << concrete);
294 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
295 }
297 concrete, access.index(), property, broker());
298 Node* constant = jsgraph_->ConstantNoHole(*maybe_value, broker());
299 ReplaceWithValue(node, constant, effect, control);
300 return Changed(node);
301 }
304 concrete, access.index(), property, broker());
305 Node* load = effect = jsgraph_->graph()->NewNode(
307 AccessBuilder::ForContextSlotSmi(access.index())),
308 jsgraph_->ConstantNoHole(concrete, broker()), effect, control);
309 ReplaceWithValue(node, load, effect, control);
310 return Changed(node);
311 }
313 Node* mutable_heap_number;
314 if (auto concrete_heap_number =
315 concrete.get(broker(), static_cast<int>(access.index()))) {
316 if (!concrete_heap_number->IsHeapNumber()) {
317 // TODO(victorgomes): In case the tag is out of date by now we could
318 // retry this reduction.
319 return NoChange();
320 }
321 mutable_heap_number = jsgraph_->ConstantMutableHeapNumber(
322 concrete_heap_number->AsHeapNumber(), broker());
323 } else {
324 mutable_heap_number = effect = jsgraph_->graph()->NewNode(
326 AccessBuilder::ForContextSlot(access.index())),
327 jsgraph_->ConstantNoHole(concrete, broker()), effect, control);
328 }
330 concrete, access.index(), property, broker());
331 Node* int32_load = effect = jsgraph_->graph()->NewNode(
333 mutable_heap_number, effect, control);
334 ReplaceWithValue(node, int32_load, effect, control);
335 return Changed(node);
336 }
338 Node* mutable_heap_number;
339 if (auto concrete_heap_number =
340 concrete.get(broker(), static_cast<int>(access.index()))) {
341 if (!concrete_heap_number->IsHeapNumber()) {
342 // TODO(victorgomes): In case the tag is out of date by now we could
343 // retry this reduction.
344 return NoChange();
345 }
346 mutable_heap_number = jsgraph_->ConstantMutableHeapNumber(
347 concrete_heap_number->AsHeapNumber(), broker());
348 } else {
349 mutable_heap_number = effect = jsgraph_->graph()->NewNode(
351 AccessBuilder::ForContextSlot(access.index())),
352 jsgraph_->ConstantNoHole(concrete, broker()), effect, control);
353 }
355 concrete, access.index(), property, broker());
356 Node* double_load = effect =
359 mutable_heap_number, effect, control);
360 ReplaceWithValue(node, double_load, effect, control);
361 return Changed(node);
362 }
364 // Do a normal context load.
365 Node* load = effect = jsgraph_->graph()->NewNode(
367 AccessBuilder::ForContextSlot(access.index())),
368 jsgraph_->ConstantNoHole(concrete, broker()), effect, control);
369 ReplaceWithValue(node, load, effect, control);
370 return Changed(node);
371 }
372 default:
373 UNREACHABLE();
374 }
375}
376
378 DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
379
380 const ContextAccess& access = ContextAccessOf(node->op());
381 size_t depth = access.depth();
382
383 // First walk up the context chain in the graph until we reduce the depth to 0
384 // or hit a node that does not have a CreateXYZContext operator.
385 Node* context = NodeProperties::GetOuterContext(node, &depth);
386
387 OptionalContextRef maybe_concrete =
388 GetSpecializationContext(broker(), context, &depth, outer());
389 if (!maybe_concrete.has_value()) {
390 // We do not have a concrete context object, so we can only partially reduce
391 // the load by folding-in the outer context node.
392 return SimplifyJSStoreContext(node, context, depth);
393 }
394
395 // Now walk up the concrete context chain for the remaining depth.
396 ContextRef concrete = maybe_concrete.value();
397 concrete = concrete.previous(broker(), &depth);
398 if (depth > 0) {
399 TRACE_BROKER_MISSING(broker(), "previous value for context " << concrete);
401 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
402 }
403
405 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
406}
407
409 DCHECK(v8_flags.script_context_mutable_heap_number ||
410 v8_flags.const_tracking_let);
411 DCHECK_EQ(IrOpcode::kJSStoreScriptContext, node->opcode());
412
413 const ContextAccess& access = ContextAccessOf(node->op());
414 size_t depth = access.depth();
415
416 // First walk up the context chain in the graph until we reduce the depth to 0
417 // or hit a node that does not have a CreateXYZContext operator.
418 Node* context = NodeProperties::GetOuterContext(node, &depth);
419 Node* value = NodeProperties::GetValueInput(node, 0);
422
423 OptionalContextRef maybe_concrete =
424 GetSpecializationContext(broker(), context, &depth, outer());
425 if (!maybe_concrete.has_value()) {
426 // We do not have a concrete context object, so we can only partially reduce
427 // the load by folding-in the outer context node.
428 return SimplifyJSStoreScriptContext(node, context, depth);
429 }
430
431 // Now walk up the concrete context chain for the remaining depth.
432 ContextRef concrete = maybe_concrete.value();
433 concrete = concrete.previous(broker(), &depth);
434 if (depth > 0) {
435 TRACE_BROKER_MISSING(broker(), "previous value for context " << concrete);
437 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
438 }
439 DCHECK(concrete.object()->IsScriptContext());
440 auto maybe_property =
441 concrete.object()->GetScriptContextSideProperty(access.index());
442 if (!maybe_property) {
444 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
445 }
446 auto property = maybe_property.value();
447 PropertyAccessBuilder access_builder(jsgraph(), broker());
448 if (property == ContextSidePropertyCell::kConst) {
449 compiler::OptionalObjectRef constant =
450 concrete.get(broker(), static_cast<int>(access.index()));
451 if (!constant.has_value() ||
452 (constant->IsString() && !constant->IsInternalizedString())) {
454 node, jsgraph()->ConstantNoHole(concrete, broker()), depth);
455 }
457 concrete, access.index(), property, broker());
458 access_builder.BuildCheckValue(value, &effect, control, *constant);
459 ReplaceWithValue(node, effect, effect, control);
460 return Changed(node);
461 }
462
463 if (!v8_flags.script_context_mutable_heap_number) {
464 // Do a normal context store.
465 Node* store = jsgraph()->graph()->NewNode(
466 jsgraph()->simplified()->StoreField(
467 AccessBuilder::ForContextSlot(access.index())),
468 jsgraph()->ConstantNoHole(concrete, broker()), value, effect, control);
469 ReplaceWithValue(node, store, store, control);
470 return Changed(node);
471 }
472
473 switch (property) {
475 UNREACHABLE();
478 concrete, access.index(), property, broker());
479 Node* smi_value = access_builder.BuildCheckSmi(value, &effect, control);
480 Node* smi_store = jsgraph()->graph()->NewNode(
481 jsgraph()->simplified()->StoreField(
482 AccessBuilder::ForContextSlotSmi(access.index())),
483 jsgraph()->ConstantNoHole(concrete, broker()), smi_value, effect,
484 control);
485 ReplaceWithValue(node, smi_store, smi_store, control);
486 return Changed(node);
487 }
489 Node* mutable_heap_number;
490 if (auto concrete_heap_number =
491 concrete.get(broker(), static_cast<int>(access.index()))) {
492 if (!concrete_heap_number->IsHeapNumber()) {
493 // TODO(victorgomes): In case the tag is out of date by now we could
494 // retry this reduction.
495 return NoChange();
496 }
497 mutable_heap_number = jsgraph_->ConstantMutableHeapNumber(
498 concrete_heap_number->AsHeapNumber(), broker());
499 } else {
500 mutable_heap_number = effect = jsgraph_->graph()->NewNode(
502 AccessBuilder::ForContextSlot(access.index())),
503 jsgraph_->ConstantNoHole(concrete, broker()), effect, control);
504 }
506 concrete, access.index(), property, broker());
507 Node* input_number =
508 access_builder.BuildCheckNumberFitsInt32(value, &effect, control);
509 Node* double_store = jsgraph()->graph()->NewNode(
510 jsgraph()->simplified()->StoreField(
512 mutable_heap_number, input_number, effect, control);
513 ReplaceWithValue(node, double_store, double_store, control);
514 return Changed(node);
515 }
517 Node* mutable_heap_number;
518 if (auto concrete_heap_number =
519 concrete.get(broker(), static_cast<int>(access.index()))) {
520 if (!concrete_heap_number->IsHeapNumber()) {
521 // TODO(victorgomes): In case the tag is out of date by now we could
522 // retry this reduction.
523 return NoChange();
524 }
525 mutable_heap_number = jsgraph_->ConstantMutableHeapNumber(
526 concrete_heap_number->AsHeapNumber(), broker());
527 } else {
528 mutable_heap_number = effect = jsgraph_->graph()->NewNode(
530 AccessBuilder::ForContextSlot(access.index())),
531 jsgraph_->ConstantNoHole(concrete, broker()), effect, control);
532 }
534 concrete, access.index(), property, broker());
535 Node* input_number =
536 access_builder.BuildCheckNumber(value, &effect, control);
537 Node* double_store = jsgraph()->graph()->NewNode(
538 jsgraph()->simplified()->StoreField(
540 mutable_heap_number, input_number, effect, control);
541 ReplaceWithValue(node, double_store, double_store, control);
542 return Changed(node);
543 }
545 // Do a normal context store.
546 Node* store = jsgraph()->graph()->NewNode(
547 jsgraph()->simplified()->StoreField(
548 AccessBuilder::ForContextSlot(access.index())),
549 jsgraph()->ConstantNoHole(concrete, broker()), value, effect,
550 control);
551 ReplaceWithValue(node, store, store, control);
552 return Changed(node);
553 }
554 default:
555 UNREACHABLE();
556 }
557}
558
559OptionalContextRef GetModuleContext(JSHeapBroker* broker, Node* node,
560 Maybe<OuterContext> maybe_context) {
561 size_t depth = std::numeric_limits<size_t>::max();
562 Node* context = NodeProperties::GetOuterContext(node, &depth);
563
564 auto find_context = [broker](ContextRef c) {
565 while (c.map(broker).instance_type() != MODULE_CONTEXT_TYPE) {
566 size_t depth = 1;
567 c = c.previous(broker, &depth);
568 CHECK_EQ(depth, 0);
569 }
570 return c;
571 };
572
573 switch (context->opcode()) {
574 case IrOpcode::kHeapConstant: {
575 // TODO(jgruber,chromium:1209798): Using kAssumeMemoryFence works around
576 // the fact that the graph stores handles (and not refs). The assumption
577 // is that any handle inserted into the graph is safe to read; but we
578 // don't preserve the reason why it is safe to read. Thus we must
579 // over-approximate here and assume the existence of a memory fence. In
580 // the future, we should consider having the graph store ObjectRefs or
581 // ObjectData pointer instead, which would make new ref construction here
582 // unnecessary.
583 HeapObjectRef object =
585 if (object.IsContext()) {
586 return find_context(object.AsContext());
587 }
588 break;
589 }
590 case IrOpcode::kParameter: {
591 OuterContext outer;
592 if (maybe_context.To(&outer) && IsContextParameter(context)) {
593 return find_context(MakeRef(broker, outer.context));
594 }
595 break;
596 }
597 default:
598 break;
599 }
600
601 return OptionalContextRef();
602}
603
605 OptionalContextRef maybe_context = GetModuleContext(broker(), node, outer());
606 if (!maybe_context.has_value()) return NoChange();
607
608 ContextRef context = maybe_context.value();
609 OptionalObjectRef module = context.get(broker(), Context::EXTENSION_INDEX);
610 if (!module.has_value()) return NoChange();
611 OptionalObjectRef import_meta =
612 module->AsSourceTextModule().import_meta(broker());
613 if (!import_meta.has_value()) return NoChange();
614 if (!import_meta->IsJSObject()) {
615 DCHECK(import_meta->IsTheHole());
616 // The import.meta object has not yet been created. Let JSGenericLowering
617 // replace the operator with a runtime call.
618 return NoChange();
619 }
620
621 Node* import_meta_const = jsgraph()->ConstantNoHole(*import_meta, broker());
622 ReplaceWithValue(node, import_meta_const);
623 return Changed(import_meta_const);
624}
625
629
630} // namespace compiler
631} // namespace internal
632} // namespace v8
SimplifiedOperatorBuilder * simplified
V8_WARN_UNUSED_RESULT V8_INLINE bool To(T *out) const
Definition v8-maybe.h:55
static FieldAccess ForContextSlotSmi(size_t index)
static FieldAccess ForContextSlot(size_t index)
void ReplaceWithValue(Node *node, Node *value, Node *effect=nullptr, Node *control=nullptr)
static Reduction Replace(Node *node)
bool DependOnScriptContextSlotProperty(ContextRef script_context, size_t index, ContextSidePropertyCell::Property property, JSHeapBroker *broker)
ContextRef previous(JSHeapBroker *broker, size_t *depth) const
Definition heap-refs.cc:986
OptionalObjectRef get(JSHeapBroker *broker, int index) const
IndirectHandle< Context > object() const
Reduction SimplifyJSStoreScriptContext(Node *node, Node *new_context, size_t new_depth)
Reduction SimplifyJSLoadContext(Node *node, Node *new_context, size_t new_depth)
Reduction SimplifyJSLoadScriptContext(Node *node, Node *new_context, size_t new_depth)
Reduction SimplifyJSStoreContext(Node *node, Node *new_context, size_t new_depth)
JSOperatorBuilder * javascript() const
Definition js-graph.h:104
SimplifiedOperatorBuilder * simplified() const
Definition js-graph.h:105
Isolate * isolate() const
Definition js-graph.h:106
Node * ConstantMutableHeapNumber(HeapNumberRef ref, JSHeapBroker *broker)
Definition js-graph.cc:120
Node * ConstantNoHole(ObjectRef ref, JSHeapBroker *broker)
Definition js-graph.cc:51
CompilationDependencies * dependencies() const
const Operator * LoadScriptContext(size_t depth, size_t index)
const Operator * StoreContext(size_t depth, size_t index)
const Operator * StoreScriptContext(size_t depth, size_t index)
const Operator * LoadContext(size_t depth, size_t index, bool immutable)
static constexpr int kJSCallClosureParamIndex
Definition linkage.h:504
static void ChangeOp(Node *node, const Operator *new_op)
static Node * GetEffectInput(Node *node, int index=0)
static Node * GetContextInput(Node *node)
static void ReplaceContextInput(Node *node, Node *context)
static Node * GetValueInput(Node *node, int index)
static Node * GetOuterContext(Node *node, size_t *depth)
static Node * GetControlInput(Node *node, int index=0)
Node * BuildCheckNumberFitsInt32(Node *value, Effect *effect, Control control, FeedbackSource feedback_source=FeedbackSource())
Node * BuildCheckValue(Node *receiver, Effect *effect, Control control, ObjectRef value)
Node * BuildCheckSmi(Node *value, Effect *effect, Control control, FeedbackSource feedback_source=FeedbackSource())
Node * BuildCheckNumber(Node *value, Effect *effect, Control control, FeedbackSource feedback_source=FeedbackSource())
static Reduction Changed(Node *node)
const Operator * LoadField(FieldAccess const &)
int ContextParameterIndex_MaybeNonStandardLayout() const
Node * NewNode(const Operator *op, int input_count, Node *const *inputs, bool incomplete=false)
JSHeapBroker * broker
#define TRACE_BROKER_MISSING(broker, x)
Handle< HeapObject > HeapConstantOf(const Operator *op)
int ParameterIndexOf(const Operator *const op)
ref_traits< T >::ref_type MakeRefAssumeMemoryFence(JSHeapBroker *broker, Tagged< T > object)
OptionalContextRef GetModuleContext(JSHeapBroker *broker, Node *node, Maybe< OuterContext > maybe_context)
ContextAccess const & ContextAccessOf(Operator const *op)
ref_traits< T >::ref_type MakeRef(JSHeapBroker *broker, Tagged< T > object)
V8_EXPORT_PRIVATE FlagValues v8_flags
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485