28 node->op()->ValueInputCount());
52 node->op()->EffectInputCount());
60 node->op()->ControlInputCount());
67 for (
Edge const edge : node->use_edges()) {
69 if (edge.from()->opcode() == IrOpcode::kIfException) {
70 if (out_exception !=
nullptr) *out_exception = edge.from();
79 CHECK_GT(node->op()->ControlOutputCount(), 0);
81 for (
Edge const edge : node->use_edges()) {
83 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
93 CHECK_LT(index, node->op()->ValueInputCount());
100 int value_input_count = node->op()->ValueInputCount();
102 node->ReplaceInput(0, value);
103 while (--value_input_count > 0) {
104 node->RemoveInput(value_input_count);
119 CHECK_LT(index, node->op()->ControlInputCount());
127 CHECK_LT(index, node->op()->EffectInputCount());
140 node->TrimInputCount(node->op()->ValueInputCount());
146 int value_input_count = node->op()->ValueInputCount();
147 while (--value_input_count >= 0) {
148 node->RemoveInput(value_input_count);
155 graph->end()->AppendInput(graph->zone(), node);
156 graph->end()->set_op(common->
End(graph->end()->InputCount()));
162 int index_to_remove = -1;
163 for (
int i = 0;
i < graph->end()->op()->ControlInputCount();
i++) {
165 if (graph->end()->InputAt(index) == node) {
166 index_to_remove =
index;
171 graph->end()->RemoveInput(index_to_remove);
172 graph->end()->set_op(common->
End(graph->end()->InputCount()));
179 for (
Edge edge : node->use_edges()) {
181 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
183 edge.UpdateTo(success);
184 }
else if (edge.from()->opcode() == IrOpcode::kIfException) {
186 edge.UpdateTo(exception);
189 edge.UpdateTo(success);
193 edge.UpdateTo(effect);
196 edge.UpdateTo(value);
204 node->set_op(new_op);
210 node->set_op(new_op);
215 Node* unreachable_sentinel) {
217 while (effect->opcode() != IrOpcode::kCheckpoint) {
218 if (effect->opcode() == IrOpcode::kDead ||
219 effect->opcode() == IrOpcode::kUnreachable) {
220 return unreachable_sentinel;
223 DCHECK_EQ(1, effect->op()->EffectInputCount());
232 for (
auto use : node->uses()) {
233 if (use->opcode() == IrOpcode::kProjection &&
244 size_t projection_count) {
246 for (
size_t index = 0; index < projection_count; ++
index) {
250 for (
Edge const edge : node->use_edges()) {
252 Node* use = edge.from();
253 DCHECK_EQ(IrOpcode::kProjection, use->opcode());
261 size_t projection_count) {
263 DCHECK_LE(
static_cast<int>(projection_count), node->UseCount());
264 std::memset(projections, 0,
sizeof(*projections) * projection_count);
266 size_t if_value_index = 0;
267 for (
Edge const edge : node->use_edges()) {
269 Node* use = edge.from();
271 switch (use->opcode()) {
272 case IrOpcode::kIfTrue:
273 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
276 case IrOpcode::kIfFalse:
277 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
280 case IrOpcode::kIfSuccess:
284 case IrOpcode::kIfException:
288 case IrOpcode::kIfValue:
289 DCHECK_EQ(IrOpcode::kSwitch, node->opcode());
290 index = if_value_index++;
292 case IrOpcode::kIfDefault:
293 DCHECK_EQ(IrOpcode::kSwitch, node->opcode());
294 index = projection_count - 1;
299 DCHECK_LT(if_value_index, projection_count);
305 for (
size_t index = 0; index < projection_count; ++
index) {
313 Node const* projection) {
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));
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));
331 case IrOpcode::kTryTruncateFloat64ToInt32:
332 case IrOpcode::kTryTruncateFloat64ToUint32:
333 CHECK_LE(index,
static_cast<size_t>(1));
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));
343 case IrOpcode::kCall: {
345 return call_descriptor->GetReturnType(index).representation();
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));
367 if (a->opcode() == IrOpcode::kCheckHeapObject ||
368 a->opcode() == IrOpcode::kTypeGuard) {
372 if (b->
opcode() == IrOpcode::kCheckHeapObject ||
373 b->
opcode() == IrOpcode::kTypeGuard) {
385 receiver->opcode() == IrOpcode::kJSCreateArray);
396 DCHECK(target.AsJSFunction().map(
broker).is_constructor());
410 if (
m.HasResolvedValue()) {
419 if (!ref.IsJSObject() ||
420 !
broker->IsArrayOrObjectPrototype(ref.AsJSObject())) {
431 switch (effect->opcode()) {
432 case IrOpcode::kTypeGuard: {
433 DCHECK_EQ(1, effect->op()->EffectInputCount());
438 case IrOpcode::kMapGuard: {
446 case IrOpcode::kCheckMaps: {
454 case IrOpcode::kTransitionElementsKindOrCheckMap: {
466 case IrOpcode::kJSCreate: {
479 case IrOpcode::kJSCreatePromise: {
488 case IrOpcode::kStoreField: {
508 case IrOpcode::kJSStoreMessage:
509 case IrOpcode::kJSStoreModule:
510 case IrOpcode::kStoreElement:
511 case IrOpcode::kStoreTypedElement: {
515 case IrOpcode::kFinishRegion: {
522 case IrOpcode::kEffectPhi: {
524 if (control->
opcode() != IrOpcode::kLoop) {
526 control->
opcode() == IrOpcode::kMerge);
537 DCHECK_EQ(1, effect->op()->EffectOutputCount());
538 if (effect->op()->EffectInputCount() != 1) {
556 DCHECK_EQ(1, effect->op()->EffectInputCount());
564 while (effect != dominator) {
565 if (effect->op()->EffectInputCount() == 1 &&
579#define CASE(Opcode) case IrOpcode::k##Opcode:
583 case IrOpcode::kCheckReceiver:
584 case IrOpcode::kConvertReceiver:
585 case IrOpcode::kJSGetSuperConstructor:
586 case IrOpcode::kJSToObject:
588 case IrOpcode::kHeapConstant: {
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:
619 case IrOpcode::kHeapConstant: {
649 int input_count = node->op()->ValueInputCount();
650 for (
int index = 0; index < input_count; ++
index) {
658 if (num == 0)
return false;
659 int const index = edge.
index();
660 return first <= index && index < first + num;
678 if (!a->op()->Equals(b->
op()))
return false;
679 if (a->InputCount() != b->
InputCount())
return false;
683 auto aIt = aInputs.
begin();
684 auto bIt = bInputs.
begin();
685 auto aEnd = aInputs.
end();
687 for (; aIt != aEnd; ++aIt, ++bIt) {
690 if ((*aIt)->id() != (*bIt)->id())
return false;
static constexpr int kMapOffset
ZoneRefSet< Map > const & maps() const
const Operator * End(size_t control_input_count)
V8_EXPORT_PRIVATE MapRef map(JSHeapBroker *broker) const
static bool IsContextChainExtendingOpcode(Value value)
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
bool is_constructor() const
bool has_prototype_slot() const
OddballType oddball_type(JSHeapBroker *broker) const
bool IsPrimitiveMap() const
static void RemoveControlFromEnd(TFGraph *graph, CommonOperatorBuilder *common, Node *node)
static int FirstEffectIndex(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 bool IsControlEdge(Edge edge)
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 int FirstContextIndex(Node *node)
static Node * GetContextInput(Node *node)
static bool IsValueEdge(Edge edge)
static void MergeControlToEnd(TFGraph *graph, CommonOperatorBuilder *common, Node *node)
static bool IsFrameStateEdge(Edge edge)
static void ReplaceContextInput(Node *node, Node *context)
static void RemoveValueInputs(Node *node)
static Node * GetFrameStateInput(Node *node)
static bool IsContextEdge(Edge edge)
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 size_t HashCode(Node *node)
static bool IsEffectEdge(Edge edge)
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 int FirstControlIndex(Node *node)
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)
constexpr IrOpcode::Value opcode() const
const Operator * op() const
Node * InputAt(int index) const
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)
ZoneVector< RpoNumber > & result
V8_INLINE size_t hash_combine(size_t seed, size_t hash)
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)
#define JS_CONSTRUCT_OP_LIST(V)
#define DCHECK_LE(v1, v2)
#define CHECK_GT(lhs, rhs)
#define CHECK_LT(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NOT_NULL(val)
#define CHECK_NE(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
HeapObjectRef Ref(JSHeapBroker *broker) const
bool HasResolvedValue() const