Line data Source code
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 :
5 : #include "src/compiler/typer.h"
6 :
7 : #include <iomanip>
8 :
9 : #include "src/base/flags.h"
10 : #include "src/bootstrapper.h"
11 : #include "src/compiler/common-operator.h"
12 : #include "src/compiler/graph-reducer.h"
13 : #include "src/compiler/js-operator.h"
14 : #include "src/compiler/linkage.h"
15 : #include "src/compiler/loop-variable-optimizer.h"
16 : #include "src/compiler/node-properties.h"
17 : #include "src/compiler/node.h"
18 : #include "src/compiler/operation-typer.h"
19 : #include "src/compiler/simplified-operator.h"
20 : #include "src/compiler/type-cache.h"
21 : #include "src/objects-inl.h"
22 : #include "src/objects/builtin-function-id.h"
23 :
24 : namespace v8 {
25 : namespace internal {
26 : namespace compiler {
27 :
28 0 : class Typer::Decorator final : public GraphDecorator {
29 : public:
30 456619 : explicit Decorator(Typer* typer) : typer_(typer) {}
31 : void Decorate(Node* node) final;
32 :
33 : private:
34 : Typer* const typer_;
35 : };
36 :
37 456617 : Typer::Typer(JSHeapBroker* broker, Flags flags, Graph* graph)
38 : : flags_(flags),
39 : graph_(graph),
40 : decorator_(nullptr),
41 456617 : cache_(TypeCache::Get()),
42 : broker_(broker),
43 1369851 : operation_typer_(broker, zone()) {
44 456619 : singleton_false_ = operation_typer_.singleton_false();
45 456619 : singleton_true_ = operation_typer_.singleton_true();
46 :
47 456619 : decorator_ = new (zone()) Decorator(this);
48 456619 : graph_->AddDecorator(decorator_);
49 456610 : }
50 :
51 :
52 456614 : Typer::~Typer() {
53 456614 : graph_->RemoveDecorator(decorator_);
54 456607 : }
55 :
56 :
57 5531115 : class Typer::Visitor : public Reducer {
58 : public:
59 5531191 : explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
60 : : typer_(typer),
61 : induction_vars_(induction_vars),
62 : weakened_nodes_(typer->zone()),
63 11062382 : remembered_types_(typer->zone()) {}
64 :
65 0 : const char* reducer_name() const override { return "Typer"; }
66 :
67 34743298 : Reduction Reduce(Node* node) override {
68 34734281 : if (node->op()->ValueOutputCount() == 0) return NoChange();
69 25756832 : switch (node->opcode()) {
70 : #define DECLARE_CASE(x) \
71 : case IrOpcode::k##x: \
72 : return UpdateType(node, TypeBinaryOp(node, x##Typer));
73 18193 : JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
74 : #undef DECLARE_CASE
75 :
76 : #define DECLARE_CASE(x) \
77 : case IrOpcode::k##x: \
78 : return UpdateType(node, Type##x(node));
79 456121 : DECLARE_CASE(Start)
80 177823 : DECLARE_CASE(IfException)
81 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
82 2054744 : COMMON_OP_LIST(DECLARE_CASE)
83 366545 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
84 598261 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
85 324742 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
86 75 : JS_OBJECT_OP_LIST(DECLARE_CASE)
87 312670 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
88 485741 : JS_OTHER_OP_LIST(DECLARE_CASE)
89 : #undef DECLARE_CASE
90 :
91 : #define DECLARE_CASE(x) \
92 : case IrOpcode::k##x: \
93 : return UpdateType(node, TypeBinaryOp(node, x));
94 17489 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
95 116422 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
96 : #undef DECLARE_CASE
97 :
98 : #define DECLARE_CASE(x) \
99 : case IrOpcode::k##x: \
100 : return UpdateType(node, TypeUnaryOp(node, x));
101 589 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
102 103587 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
103 : #undef DECLARE_CASE
104 :
105 : #define DECLARE_CASE(x) case IrOpcode::k##x:
106 : DECLARE_CASE(Loop)
107 : DECLARE_CASE(Branch)
108 : DECLARE_CASE(IfTrue)
109 : DECLARE_CASE(IfFalse)
110 : DECLARE_CASE(IfSuccess)
111 : DECLARE_CASE(Switch)
112 : DECLARE_CASE(IfValue)
113 : DECLARE_CASE(IfDefault)
114 : DECLARE_CASE(Merge)
115 : DECLARE_CASE(Deoptimize)
116 : DECLARE_CASE(DeoptimizeIf)
117 : DECLARE_CASE(DeoptimizeUnless)
118 : DECLARE_CASE(TrapIf)
119 : DECLARE_CASE(TrapUnless)
120 : DECLARE_CASE(Return)
121 : DECLARE_CASE(TailCall)
122 : DECLARE_CASE(Terminate)
123 : DECLARE_CASE(OsrNormalEntry)
124 : DECLARE_CASE(OsrLoopEntry)
125 : DECLARE_CASE(Throw)
126 : DECLARE_CASE(End)
127 : SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
128 : SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
129 : MACHINE_SIMD_OP_LIST(DECLARE_CASE)
130 : MACHINE_OP_LIST(DECLARE_CASE)
131 : #undef DECLARE_CASE
132 : break;
133 : }
134 : return NoChange();
135 : }
136 :
137 5119171 : Type TypeNode(Node* node) {
138 5074810 : switch (node->opcode()) {
139 : #define DECLARE_CASE(x) \
140 : case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
141 977 : JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
142 : #undef DECLARE_CASE
143 :
144 : #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
145 : DECLARE_CASE(Start)
146 : DECLARE_CASE(IfException)
147 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
148 1177357 : COMMON_OP_LIST(DECLARE_CASE)
149 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
150 31810 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
151 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
152 3 : JS_OBJECT_OP_LIST(DECLARE_CASE)
153 20 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
154 6948 : JS_OTHER_OP_LIST(DECLARE_CASE)
155 : #undef DECLARE_CASE
156 :
157 : #define DECLARE_CASE(x) \
158 : case IrOpcode::k##x: \
159 : return TypeBinaryOp(node, x);
160 118154 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
161 425 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
162 : #undef DECLARE_CASE
163 :
164 : #define DECLARE_CASE(x) \
165 : case IrOpcode::k##x: \
166 : return TypeUnaryOp(node, x);
167 8 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
168 644 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
169 : #undef DECLARE_CASE
170 :
171 : #define DECLARE_CASE(x) case IrOpcode::k##x:
172 : DECLARE_CASE(Loop)
173 : DECLARE_CASE(Branch)
174 : DECLARE_CASE(IfTrue)
175 : DECLARE_CASE(IfFalse)
176 : DECLARE_CASE(IfSuccess)
177 : DECLARE_CASE(Switch)
178 : DECLARE_CASE(IfValue)
179 : DECLARE_CASE(IfDefault)
180 : DECLARE_CASE(Merge)
181 : DECLARE_CASE(Deoptimize)
182 : DECLARE_CASE(DeoptimizeIf)
183 : DECLARE_CASE(DeoptimizeUnless)
184 : DECLARE_CASE(TrapIf)
185 : DECLARE_CASE(TrapUnless)
186 : DECLARE_CASE(Return)
187 : DECLARE_CASE(TailCall)
188 : DECLARE_CASE(Terminate)
189 : DECLARE_CASE(OsrNormalEntry)
190 : DECLARE_CASE(OsrLoopEntry)
191 : DECLARE_CASE(Throw)
192 : DECLARE_CASE(End)
193 : SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
194 : SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
195 : MACHINE_SIMD_OP_LIST(DECLARE_CASE)
196 : MACHINE_OP_LIST(DECLARE_CASE)
197 : #undef DECLARE_CASE
198 : break;
199 : }
200 0 : UNREACHABLE();
201 : }
202 :
203 : Type TypeConstant(Handle<Object> value);
204 :
205 : private:
206 : Typer* typer_;
207 : LoopVariableOptimizer* induction_vars_;
208 : ZoneSet<NodeId> weakened_nodes_;
209 : // TODO(tebbi): remove once chromium:906567 is resolved.
210 : ZoneUnorderedMap<std::pair<Node*, int>, Type> remembered_types_;
211 :
212 : #define DECLARE_METHOD(x) inline Type Type##x(Node* node);
213 : DECLARE_METHOD(Start)
214 : DECLARE_METHOD(IfException)
215 : COMMON_OP_LIST(DECLARE_METHOD)
216 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
217 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
218 : JS_OP_LIST(DECLARE_METHOD)
219 : #undef DECLARE_METHOD
220 :
221 : Type TypeOrNone(Node* node) {
222 : return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
223 8076147 : : Type::None();
224 : }
225 :
226 : Type Operand(Node* node, int i) {
227 8057408 : Node* operand_node = NodeProperties::GetValueInput(node, i);
228 : return TypeOrNone(operand_node);
229 : }
230 :
231 : Type Weaken(Node* node, Type current_type, Type previous_type);
232 :
233 : Zone* zone() { return typer_->zone(); }
234 : Graph* graph() { return typer_->graph(); }
235 :
236 : void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
237 : bool IsWeakened(NodeId node_id) {
238 : return weakened_nodes_.find(node_id) != weakened_nodes_.end();
239 : }
240 :
241 : typedef Type (*UnaryTyperFun)(Type, Typer* t);
242 : typedef Type (*BinaryTyperFun)(Type, Type, Typer* t);
243 :
244 : Type TypeUnaryOp(Node* node, UnaryTyperFun);
245 : Type TypeBinaryOp(Node* node, BinaryTyperFun);
246 :
247 : static Type BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
248 : BinaryTyperFun f);
249 :
250 : enum ComparisonOutcomeFlags {
251 : kComparisonTrue = 1,
252 : kComparisonFalse = 2,
253 : kComparisonUndefined = 4
254 : };
255 : typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;
256 :
257 : static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
258 : static Type FalsifyUndefined(ComparisonOutcome, Typer*);
259 :
260 : static Type BitwiseNot(Type, Typer*);
261 : static Type Decrement(Type, Typer*);
262 : static Type Increment(Type, Typer*);
263 : static Type Negate(Type, Typer*);
264 :
265 : static Type ToPrimitive(Type, Typer*);
266 : static Type ToBoolean(Type, Typer*);
267 : static Type ToInteger(Type, Typer*);
268 : static Type ToLength(Type, Typer*);
269 : static Type ToName(Type, Typer*);
270 : static Type ToNumber(Type, Typer*);
271 : static Type ToNumberConvertBigInt(Type, Typer*);
272 : static Type ToNumeric(Type, Typer*);
273 : static Type ToObject(Type, Typer*);
274 : static Type ToString(Type, Typer*);
275 : #define DECLARE_METHOD(Name) \
276 : static Type Name(Type type, Typer* t) { \
277 : return t->operation_typer_.Name(type); \
278 : }
279 73086 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
280 101689 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_METHOD)
281 : #undef DECLARE_METHOD
282 : #define DECLARE_METHOD(Name) \
283 : static Type Name(Type lhs, Type rhs, Typer* t) { \
284 : return t->operation_typer_.Name(lhs, rhs); \
285 : }
286 580769 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
287 476688 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
288 : #undef DECLARE_METHOD
289 :
290 : static Type ObjectIsArrayBufferView(Type, Typer*);
291 : static Type ObjectIsBigInt(Type, Typer*);
292 : static Type ObjectIsCallable(Type, Typer*);
293 : static Type ObjectIsConstructor(Type, Typer*);
294 : static Type ObjectIsDetectableCallable(Type, Typer*);
295 : static Type ObjectIsMinusZero(Type, Typer*);
296 : static Type NumberIsMinusZero(Type, Typer*);
297 : static Type ObjectIsNaN(Type, Typer*);
298 : static Type NumberIsNaN(Type, Typer*);
299 : static Type ObjectIsNonCallable(Type, Typer*);
300 : static Type ObjectIsNumber(Type, Typer*);
301 : static Type ObjectIsReceiver(Type, Typer*);
302 : static Type ObjectIsSmi(Type, Typer*);
303 : static Type ObjectIsString(Type, Typer*);
304 : static Type ObjectIsSymbol(Type, Typer*);
305 : static Type ObjectIsUndetectable(Type, Typer*);
306 :
307 : static ComparisonOutcome JSCompareTyper(Type, Type, Typer*);
308 : static ComparisonOutcome NumberCompareTyper(Type, Type, Typer*);
309 :
310 : #define DECLARE_METHOD(x) static Type x##Typer(Type, Type, Typer*);
311 : JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
312 : #undef DECLARE_METHOD
313 :
314 : static Type JSCallTyper(Type, Typer*);
315 :
316 : static Type NumberEqualTyper(Type, Type, Typer*);
317 : static Type NumberLessThanTyper(Type, Type, Typer*);
318 : static Type NumberLessThanOrEqualTyper(Type, Type, Typer*);
319 : static Type ReferenceEqualTyper(Type, Type, Typer*);
320 : static Type SameValueTyper(Type, Type, Typer*);
321 : static Type StringFromSingleCharCodeTyper(Type, Typer*);
322 : static Type StringFromSingleCodePointTyper(Type, Typer*);
323 :
324 25756540 : Reduction UpdateType(Node* node, Type current) {
325 57301227 : if (NodeProperties::IsTyped(node)) {
326 : // Widen the type of a previously typed node.
327 5788096 : Type previous = NodeProperties::GetType(node);
328 5788096 : if (node->opcode() == IrOpcode::kPhi ||
329 : node->opcode() == IrOpcode::kInductionVariablePhi) {
330 : // Speed up termination in the presence of range types:
331 546747 : current = Weaken(node, current, previous);
332 : }
333 :
334 5788147 : if (V8_UNLIKELY(!previous.Is(current))) {
335 : AllowHandleDereference allow;
336 0 : std::ostringstream ostream;
337 0 : node->Print(ostream);
338 :
339 0 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
340 0 : ostream << "Previous UpdateType run (inputs first):";
341 0 : for (int i = 0; i < 3; ++i) {
342 0 : ostream << " ";
343 0 : if (remembered_types_[{node, i}].IsInvalid()) {
344 0 : ostream << "untyped";
345 : } else {
346 0 : remembered_types_[{node, i}].PrintTo(ostream);
347 : }
348 : }
349 :
350 0 : ostream << "\nCurrent (output) type: ";
351 0 : previous.PrintTo(ostream);
352 :
353 0 : ostream << "\nThis UpdateType run (inputs first):";
354 0 : for (int i = 0; i < 2; ++i) {
355 0 : ostream << " ";
356 0 : Node* input = NodeProperties::GetValueInput(node, i);
357 0 : if (NodeProperties::IsTyped(input)) {
358 0 : NodeProperties::GetType(input).PrintTo(ostream);
359 : } else {
360 0 : ostream << "untyped";
361 : }
362 : }
363 0 : ostream << " ";
364 0 : current.PrintTo(ostream);
365 0 : ostream << "\n";
366 : }
367 :
368 0 : FATAL("UpdateType error for node %s", ostream.str().c_str());
369 : }
370 :
371 5788147 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
372 9972 : for (int i = 0; i < 2; ++i) {
373 9972 : Node* input = NodeProperties::GetValueInput(node, i);
374 9972 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
375 : ? NodeProperties::GetType(input)
376 9972 : : Type::Invalid();
377 : }
378 4986 : remembered_types_[{node, 2}] = current;
379 : }
380 :
381 : NodeProperties::SetType(node, current);
382 5788135 : if (!current.Is(previous)) {
383 : // If something changed, revisit all uses.
384 : return Changed(node);
385 : }
386 : return NoChange();
387 : } else {
388 19968444 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
389 25005 : for (int i = 0; i < 2; ++i) {
390 25005 : Node* input = NodeProperties::GetValueInput(node, i);
391 25005 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
392 : ? NodeProperties::GetType(input)
393 25005 : : Type::Invalid();
394 : }
395 12503 : remembered_types_[{node, 2}] = current;
396 : }
397 :
398 : // No previous type, simply update the type.
399 : NodeProperties::SetType(node, current);
400 : return Changed(node);
401 : }
402 : }
403 : };
404 :
405 496 : void Typer::Run() { Run(NodeVector(zone()), nullptr); }
406 :
407 456342 : void Typer::Run(const NodeVector& roots,
408 456351 : LoopVariableOptimizer* induction_vars) {
409 456342 : if (induction_vars != nullptr) {
410 456096 : induction_vars->ChangeToInductionVariablePhis();
411 : }
412 456342 : Visitor visitor(this, induction_vars);
413 912695 : GraphReducer graph_reducer(zone(), graph());
414 456364 : graph_reducer.AddReducer(&visitor);
415 7431066 : for (Node* const root : roots) graph_reducer.ReduceNode(root);
416 456365 : graph_reducer.ReduceGraph();
417 :
418 456359 : if (induction_vars != nullptr) {
419 456113 : induction_vars->ChangeToPhisAndInsertGuards();
420 : }
421 456362 : }
422 :
423 6783078 : void Typer::Decorator::Decorate(Node* node) {
424 13566156 : if (node->op()->ValueOutputCount() > 0) {
425 : // Only eagerly type-decorate nodes with known input types.
426 : // Other cases will generally require a proper fixpoint iteration with Run.
427 : bool is_typed = NodeProperties::IsTyped(node);
428 5131545 : if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
429 5074850 : Visitor typing(typer_, nullptr);
430 5074740 : Type type = typing.TypeNode(node);
431 5074762 : if (is_typed) {
432 : type = Type::Intersect(type, NodeProperties::GetType(node),
433 0 : typer_->zone());
434 : }
435 : NodeProperties::SetType(node, type);
436 : }
437 : }
438 6783089 : }
439 :
440 :
441 : // -----------------------------------------------------------------------------
442 :
443 : // Helper functions that lift a function f on types to a function on bounds,
444 : // and uses that to type the given node. Note that f is never called with None
445 : // as an argument.
446 :
447 1236795 : Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
448 : Type input = Operand(node, 0);
449 1236801 : return input.IsNone() ? Type::None() : f(input, typer_);
450 : }
451 :
452 1896306 : Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
453 : Type left = Operand(node, 0);
454 : Type right = Operand(node, 1);
455 1771623 : return left.IsNone() || right.IsNone() ? Type::None()
456 3660859 : : f(left, right, typer_);
457 : }
458 :
459 200735 : Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
460 : BinaryTyperFun f) {
461 200735 : lhs = ToNumeric(lhs, t);
462 200735 : rhs = ToNumeric(rhs, t);
463 : bool lhs_is_number = lhs.Is(Type::Number());
464 : bool rhs_is_number = rhs.Is(Type::Number());
465 200735 : if (lhs_is_number && rhs_is_number) {
466 160961 : return f(lhs, rhs, t);
467 : }
468 : // In order to maintain monotonicity, the following two conditions are
469 : // intentionally asymmetric.
470 39774 : if (lhs_is_number) {
471 : return Type::Number();
472 : }
473 29166 : if (lhs.Is(Type::BigInt())) {
474 : return Type::BigInt();
475 : }
476 : return Type::Numeric();
477 : }
478 :
479 0 : Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
480 : ComparisonOutcome outcome, Typer* t) {
481 : ComparisonOutcome result(0);
482 12978 : if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
483 12978 : if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
484 12978 : if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
485 0 : return result;
486 : }
487 :
488 356287 : Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
489 370495 : if ((outcome & kComparisonFalse) != 0 ||
490 : (outcome & kComparisonUndefined) != 0) {
491 : return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
492 343061 : : t->singleton_false_;
493 : }
494 : // Type should be non empty, so we know it should be true.
495 : DCHECK_NE(0, outcome & kComparisonTrue);
496 13226 : return t->singleton_true_;
497 : }
498 :
499 165 : Type Typer::Visitor::BitwiseNot(Type type, Typer* t) {
500 165 : type = ToNumeric(type, t);
501 165 : if (type.Is(Type::Number())) {
502 52 : return NumberBitwiseXor(type, t->cache_->kSingletonMinusOne, t);
503 : }
504 : return Type::Numeric();
505 : }
506 :
507 6278 : Type Typer::Visitor::Decrement(Type type, Typer* t) {
508 6278 : type = ToNumeric(type, t);
509 6278 : if (type.Is(Type::Number())) {
510 3972 : return NumberSubtract(type, t->cache_->kSingletonOne, t);
511 : }
512 : return Type::Numeric();
513 : }
514 :
515 250739 : Type Typer::Visitor::Increment(Type type, Typer* t) {
516 250740 : type = ToNumeric(type, t);
517 250740 : if (type.Is(Type::Number())) {
518 243417 : return NumberAdd(type, t->cache_->kSingletonOne, t);
519 : }
520 : return Type::Numeric();
521 : }
522 :
523 5397 : Type Typer::Visitor::Negate(Type type, Typer* t) {
524 5397 : type = ToNumeric(type, t);
525 5397 : if (type.Is(Type::Number())) {
526 2644 : return NumberMultiply(type, t->cache_->kSingletonMinusOne, t);
527 : }
528 : return Type::Numeric();
529 : }
530 :
531 : // Type conversion.
532 :
533 870962 : Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
534 870962 : if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
535 716075 : return type;
536 : }
537 : return Type::Primitive();
538 : }
539 :
540 137493 : Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
541 137493 : return t->operation_typer()->ToBoolean(type);
542 : }
543 :
544 :
545 : // static
546 115 : Type Typer::Visitor::ToInteger(Type type, Typer* t) {
547 : // ES6 section 7.1.4 ToInteger ( argument )
548 115 : type = ToNumber(type, t);
549 230 : if (type.Is(t->cache_->kIntegerOrMinusZero)) return type;
550 162 : if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
551 : return Type::Union(
552 : Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()),
553 3 : t->cache_->kSingletonZero, t->zone());
554 : }
555 78 : return t->cache_->kIntegerOrMinusZero;
556 : }
557 :
558 :
559 : // static
560 115 : Type Typer::Visitor::ToLength(Type type, Typer* t) {
561 : // ES6 section 7.1.15 ToLength ( argument )
562 115 : type = ToInteger(type, t);
563 115 : if (type.IsNone()) return type;
564 104 : double min = type.Min();
565 104 : double max = type.Max();
566 104 : if (max <= 0.0) {
567 7 : return Type::NewConstant(0, t->zone());
568 : }
569 97 : if (min >= kMaxSafeInteger) {
570 2 : return Type::NewConstant(kMaxSafeInteger, t->zone());
571 : }
572 95 : if (min <= 0.0) min = 0.0;
573 95 : if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
574 95 : return Type::Range(min, max, t->zone());
575 : }
576 :
577 :
578 : // static
579 1252 : Type Typer::Visitor::ToName(Type type, Typer* t) {
580 : // ES6 section 7.1.14 ToPropertyKey ( argument )
581 1252 : type = ToPrimitive(type, t);
582 1252 : if (type.Is(Type::Name())) return type;
583 1141 : if (type.Maybe(Type::Symbol())) return Type::Name();
584 100 : return ToString(type, t);
585 : }
586 :
587 :
588 : // static
589 11888 : Type Typer::Visitor::ToNumber(Type type, Typer* t) {
590 182824 : return t->operation_typer_.ToNumber(type);
591 : }
592 :
593 : // static
594 506 : Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
595 506 : return t->operation_typer_.ToNumberConvertBigInt(type);
596 : }
597 :
598 : // static
599 47857 : Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
600 1160904 : return t->operation_typer_.ToNumeric(type);
601 : }
602 :
603 : // static
604 2021 : Type Typer::Visitor::ToObject(Type type, Typer* t) {
605 : // ES6 section 7.1.13 ToObject ( argument )
606 2021 : if (type.Is(Type::Receiver())) return type;
607 1458 : if (type.Is(Type::Primitive())) return Type::OtherObject();
608 1325 : if (!type.Maybe(Type::OtherUndetectable())) {
609 : return Type::DetectableReceiver();
610 : }
611 : return Type::Receiver();
612 : }
613 :
614 :
615 : // static
616 2488 : Type Typer::Visitor::ToString(Type type, Typer* t) {
617 : // ES6 section 7.1.12 ToString ( argument )
618 2488 : type = ToPrimitive(type, t);
619 2488 : if (type.Is(Type::String())) return type;
620 : return Type::String();
621 : }
622 :
623 : // Type checks.
624 :
625 16 : Type Typer::Visitor::ObjectIsArrayBufferView(Type type, Typer* t) {
626 : // TODO(turbofan): Introduce a Type::ArrayBufferView?
627 16 : if (!type.Maybe(Type::OtherObject())) return t->singleton_false_;
628 : return Type::Boolean();
629 : }
630 :
631 27 : Type Typer::Visitor::ObjectIsBigInt(Type type, Typer* t) {
632 27 : if (type.Is(Type::BigInt())) return t->singleton_true_;
633 26 : if (!type.Maybe(Type::BigInt())) return t->singleton_false_;
634 : return Type::Boolean();
635 : }
636 :
637 2050 : Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
638 2050 : if (type.Is(Type::Callable())) return t->singleton_true_;
639 237 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
640 : return Type::Boolean();
641 : }
642 :
643 378 : Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
644 : // TODO(turbofan): Introduce a Type::Constructor?
645 378 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
646 : return Type::Boolean();
647 : }
648 :
649 16754 : Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
650 16755 : if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
651 16734 : if (!type.Maybe(Type::DetectableCallable())) return t->singleton_false_;
652 : return Type::Boolean();
653 : }
654 :
655 0 : Type Typer::Visitor::ObjectIsMinusZero(Type type, Typer* t) {
656 0 : if (type.Is(Type::MinusZero())) return t->singleton_true_;
657 0 : if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
658 : return Type::Boolean();
659 : }
660 :
661 0 : Type Typer::Visitor::NumberIsMinusZero(Type type, Typer* t) {
662 0 : if (type.Is(Type::MinusZero())) return t->singleton_true_;
663 0 : if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
664 : return Type::Boolean();
665 : }
666 :
667 4867 : Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
668 4867 : if (type.Is(Type::NaN())) return t->singleton_true_;
669 4860 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
670 : return Type::Boolean();
671 : }
672 :
673 13336 : Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
674 13336 : if (type.Is(Type::NaN())) return t->singleton_true_;
675 12574 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
676 : return Type::Boolean();
677 : }
678 :
679 8842 : Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
680 8842 : if (type.Is(Type::NonCallable())) return t->singleton_true_;
681 8516 : if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
682 : return Type::Boolean();
683 : }
684 :
685 10159 : Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
686 10159 : if (type.Is(Type::Number())) return t->singleton_true_;
687 8646 : if (!type.Maybe(Type::Number())) return t->singleton_false_;
688 : return Type::Boolean();
689 : }
690 :
691 26168 : Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
692 26169 : if (type.Is(Type::Receiver())) return t->singleton_true_;
693 22993 : if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
694 : return Type::Boolean();
695 : }
696 :
697 2172 : Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
698 2172 : if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
699 : return Type::Boolean();
700 : }
701 :
702 2104 : Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
703 2104 : if (type.Is(Type::String())) return t->singleton_true_;
704 2094 : if (!type.Maybe(Type::String())) return t->singleton_false_;
705 : return Type::Boolean();
706 : }
707 :
708 99 : Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
709 99 : if (type.Is(Type::Symbol())) return t->singleton_true_;
710 98 : if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
711 : return Type::Boolean();
712 : }
713 :
714 1865 : Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
715 1865 : if (type.Is(Type::Undetectable())) return t->singleton_true_;
716 1645 : if (!type.Maybe(Type::Undetectable())) return t->singleton_false_;
717 : return Type::Boolean();
718 : }
719 :
720 :
721 : // -----------------------------------------------------------------------------
722 :
723 :
724 : // Control operators.
725 :
726 : Type Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
727 :
728 : Type Typer::Visitor::TypeIfException(Node* node) { return Type::NonInternal(); }
729 :
730 : // Common operators.
731 :
732 3955250 : Type Typer::Visitor::TypeParameter(Node* node) {
733 1977625 : Node* const start = node->InputAt(0);
734 : DCHECK_EQ(IrOpcode::kStart, start->opcode());
735 3955250 : int const parameter_count = start->op()->ValueOutputCount() - 4;
736 : DCHECK_LE(1, parameter_count);
737 1977625 : int const index = ParameterIndexOf(node->op());
738 1977608 : if (index == Linkage::kJSCallClosureParamIndex) {
739 : return Type::Function();
740 1950320 : } else if (index == 0) {
741 902370 : if (typer_->flags() & Typer::kThisIsReceiver) {
742 : return Type::Receiver();
743 : } else {
744 : // Parameter[this] can be the_hole for derived class constructors.
745 89267 : return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
746 : }
747 1499135 : } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
748 36226 : if (typer_->flags() & Typer::kNewTargetIsReceiver) {
749 : return Type::Receiver();
750 : } else {
751 16769 : return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
752 : }
753 1481022 : } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
754 0 : return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone());
755 1481022 : } else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) {
756 : return Type::OtherInternal();
757 : }
758 : return Type::NonInternal();
759 : }
760 :
761 : Type Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }
762 :
763 0 : Type Typer::Visitor::TypeRetain(Node* node) { UNREACHABLE(); }
764 :
765 0 : Type Typer::Visitor::TypeInt32Constant(Node* node) { UNREACHABLE(); }
766 :
767 0 : Type Typer::Visitor::TypeInt64Constant(Node* node) { UNREACHABLE(); }
768 :
769 0 : Type Typer::Visitor::TypeRelocatableInt32Constant(Node* node) { UNREACHABLE(); }
770 :
771 0 : Type Typer::Visitor::TypeRelocatableInt64Constant(Node* node) { UNREACHABLE(); }
772 :
773 0 : Type Typer::Visitor::TypeFloat32Constant(Node* node) { UNREACHABLE(); }
774 :
775 0 : Type Typer::Visitor::TypeFloat64Constant(Node* node) { UNREACHABLE(); }
776 :
777 1976930 : Type Typer::Visitor::TypeNumberConstant(Node* node) {
778 1976930 : double number = OpParameter<double>(node->op());
779 1976930 : return Type::NewConstant(number, zone());
780 : }
781 :
782 6255976 : Type Typer::Visitor::TypeHeapConstant(Node* node) {
783 12511941 : return TypeConstant(HeapConstantOf(node->op()));
784 : }
785 :
786 : Type Typer::Visitor::TypeExternalConstant(Node* node) {
787 : return Type::ExternalPointer();
788 : }
789 :
790 : Type Typer::Visitor::TypePointerConstant(Node* node) {
791 : return Type::ExternalPointer();
792 : }
793 :
794 19550 : Type Typer::Visitor::TypeSelect(Node* node) {
795 19550 : return Type::Union(Operand(node, 1), Operand(node, 2), zone());
796 : }
797 :
798 2076243 : Type Typer::Visitor::TypePhi(Node* node) {
799 859971 : int arity = node->op()->ValueInputCount();
800 : Type type = Operand(node, 0);
801 2076233 : for (int i = 1; i < arity; ++i) {
802 1216264 : type = Type::Union(type, Operand(node, i), zone());
803 : }
804 859961 : return type;
805 : }
806 :
807 57802 : Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
808 25475 : int arity = NodeProperties::GetControlInput(node)->op()->ControlInputCount();
809 : DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(node)->opcode());
810 : DCHECK_EQ(2, NodeProperties::GetControlInput(node)->InputCount());
811 :
812 25475 : Type initial_type = Operand(node, 0);
813 25475 : Type increment_type = Operand(node, 2);
814 :
815 : // We only handle integer induction variables (otherwise ranges
816 : // do not apply and we cannot do anything).
817 69761 : if (!initial_type.Is(typer_->cache_->kInteger) ||
818 18811 : !increment_type.Is(typer_->cache_->kInteger)) {
819 : // Fallback to normal phi typing, but ensure monotonicity.
820 : // (Unfortunately, without baking in the previous type, monotonicity might
821 : // be violated because we might not yet have retyped the incrementing
822 : // operation even though the increment's type might been already reflected
823 : // in the induction variable phi.)
824 : Type type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
825 6891 : : Type::None();
826 13782 : for (int i = 0; i < arity; ++i) {
827 13782 : type = Type::Union(type, Operand(node, i), zone());
828 : }
829 6891 : return type;
830 : }
831 : // If we do not have enough type information for the initial value or
832 : // the increment, just return the initial value's type.
833 37146 : if (initial_type.IsNone() ||
834 18562 : increment_type.Is(typer_->cache_->kSingletonZero)) {
835 39 : return initial_type;
836 : }
837 :
838 : // Now process the bounds.
839 37090 : auto res = induction_vars_->induction_variables().find(node->id());
840 : DCHECK(res != induction_vars_->induction_variables().end());
841 18545 : InductionVariable* induction_var = res->second;
842 :
843 : InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
844 :
845 18545 : double min = -V8_INFINITY;
846 18545 : double max = V8_INFINITY;
847 :
848 : double increment_min;
849 : double increment_max;
850 18545 : if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
851 18259 : increment_min = increment_type.Min();
852 18259 : increment_max = increment_type.Max();
853 : } else {
854 : DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
855 286 : increment_min = -increment_type.Max();
856 286 : increment_max = -increment_type.Min();
857 : }
858 :
859 18545 : if (increment_min >= 0) {
860 : // increasing sequence
861 18275 : min = initial_type.Min();
862 54893 : for (auto bound : induction_var->upper_bounds()) {
863 18380 : Type bound_type = TypeOrNone(bound.bound);
864 : // If the type is not an integer, just skip the bound.
865 38824 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
866 : // If the type is not inhabited, then we can take the initial value.
867 16316 : if (bound_type.IsNone()) {
868 37 : max = initial_type.Max();
869 37 : break;
870 : }
871 16279 : double bound_max = bound_type.Max();
872 16279 : if (bound.kind == InductionVariable::kStrict) {
873 16114 : bound_max -= 1;
874 : }
875 32558 : max = std::min(max, bound_max + increment_max);
876 : }
877 : // The upper bound must be at least the initial value's upper bound.
878 36550 : max = std::max(max, initial_type.Max());
879 270 : } else if (increment_max <= 0) {
880 : // decreasing sequence
881 270 : max = initial_type.Max();
882 868 : for (auto bound : induction_var->lower_bounds()) {
883 328 : Type bound_type = TypeOrNone(bound.bound);
884 : // If the type is not an integer, just skip the bound.
885 656 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
886 : // If the type is not inhabited, then we can take the initial value.
887 328 : if (bound_type.IsNone()) {
888 0 : min = initial_type.Min();
889 0 : break;
890 : }
891 328 : double bound_min = bound_type.Min();
892 328 : if (bound.kind == InductionVariable::kStrict) {
893 150 : bound_min += 1;
894 : }
895 656 : min = std::max(min, bound_min + increment_min);
896 : }
897 : // The lower bound must be at most the initial value's lower bound.
898 540 : min = std::min(min, initial_type.Min());
899 : } else {
900 : // Shortcut: If the increment can be both positive and negative,
901 : // the variable can go arbitrarily far, so just return integer.
902 0 : return typer_->cache_->kInteger;
903 : }
904 18545 : if (FLAG_trace_turbo_loop) {
905 0 : StdoutStream{} << std::setprecision(10) << "Loop ("
906 0 : << NodeProperties::GetControlInput(node)->id()
907 0 : << ") variable bounds in "
908 : << (arithmetic_type ==
909 : InductionVariable::ArithmeticType::kAddition
910 : ? "addition"
911 0 : : "subtraction")
912 0 : << " for phi " << node->id() << ": (" << min << ", " << max
913 0 : << ")\n";
914 : }
915 37090 : return Type::Range(min, max, typer_->zone());
916 : }
917 :
918 0 : Type Typer::Visitor::TypeEffectPhi(Node* node) { UNREACHABLE(); }
919 :
920 0 : Type Typer::Visitor::TypeLoopExit(Node* node) { UNREACHABLE(); }
921 :
922 : Type Typer::Visitor::TypeLoopExitValue(Node* node) { return Operand(node, 0); }
923 :
924 0 : Type Typer::Visitor::TypeLoopExitEffect(Node* node) { UNREACHABLE(); }
925 :
926 : Type Typer::Visitor::TypeEnsureWritableFastElements(Node* node) {
927 : return Operand(node, 1);
928 : }
929 :
930 : Type Typer::Visitor::TypeMaybeGrowFastElements(Node* node) {
931 : return Operand(node, 1);
932 : }
933 :
934 0 : Type Typer::Visitor::TypeTransitionElementsKind(Node* node) { UNREACHABLE(); }
935 :
936 0 : Type Typer::Visitor::TypeCheckpoint(Node* node) { UNREACHABLE(); }
937 :
938 0 : Type Typer::Visitor::TypeBeginRegion(Node* node) { UNREACHABLE(); }
939 :
940 : Type Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); }
941 :
942 : Type Typer::Visitor::TypeFrameState(Node* node) {
943 : // TODO(rossberg): Ideally FrameState wouldn't have a value output.
944 : return Type::Internal();
945 : }
946 :
947 : Type Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }
948 :
949 : Type Typer::Visitor::TypeTypedStateValues(Node* node) {
950 : return Type::Internal();
951 : }
952 :
953 0 : Type Typer::Visitor::TypeObjectId(Node* node) { UNREACHABLE(); }
954 :
955 : Type Typer::Visitor::TypeArgumentsElementsState(Node* node) {
956 : return Type::Internal();
957 : }
958 :
959 : Type Typer::Visitor::TypeArgumentsLengthState(Node* node) {
960 : return Type::Internal();
961 : }
962 :
963 : Type Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
964 :
965 : Type Typer::Visitor::TypeTypedObjectState(Node* node) {
966 : return Type::Internal();
967 : }
968 :
969 : Type Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
970 :
971 0 : Type Typer::Visitor::TypeCallWithCallerSavedRegisters(Node* node) {
972 0 : UNREACHABLE();
973 : }
974 :
975 12090 : Type Typer::Visitor::TypeProjection(Node* node) {
976 6045 : Type const type = Operand(node, 0);
977 6045 : if (type.Is(Type::None())) return Type::None();
978 6045 : int const index = static_cast<int>(ProjectionIndexOf(node->op()));
979 10218 : if (type.IsTuple() && index < type.AsTuple()->Arity()) {
980 4173 : return type.AsTuple()->Element(index);
981 : }
982 : return Type::Any();
983 : }
984 :
985 0 : Type Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
986 :
987 48943 : Type Typer::Visitor::TypeTypeGuard(Node* node) {
988 24472 : Type const type = Operand(node, 0);
989 24472 : return typer_->operation_typer()->TypeTypeGuard(node->op(), type);
990 : }
991 :
992 : Type Typer::Visitor::TypeDead(Node* node) { return Type::None(); }
993 :
994 : Type Typer::Visitor::TypeDeadValue(Node* node) { return Type::None(); }
995 :
996 : Type Typer::Visitor::TypeUnreachable(Node* node) { return Type::None(); }
997 :
998 : // JS comparison operators.
999 :
1000 50045 : Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
1001 99864 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
1002 49780 : if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1003 0 : return t->singleton_true_;
1004 : }
1005 180457 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
1006 78131 : (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1007 2426 : return t->singleton_false_;
1008 : }
1009 48120 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1010 : // Types are equal and are inhabited only by a single semantic value,
1011 : // which is not nan due to the earlier check.
1012 163 : return t->singleton_true_;
1013 : }
1014 : return Type::Boolean();
1015 : }
1016 :
1017 181537 : Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
1018 181537 : return t->operation_typer()->StrictEqual(lhs, rhs);
1019 : }
1020 :
1021 : // The EcmaScript specification defines the four relational comparison operators
1022 : // (<, <=, >=, >) with the help of a single abstract one. It behaves like <
1023 : // but returns undefined when the inputs cannot be compared.
1024 : // We implement the typing analogously.
1025 227728 : Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
1026 : Type rhs,
1027 : Typer* t) {
1028 227728 : lhs = ToPrimitive(lhs, t);
1029 227728 : rhs = ToPrimitive(rhs, t);
1030 227728 : if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
1031 : return ComparisonOutcome(kComparisonTrue) |
1032 : ComparisonOutcome(kComparisonFalse);
1033 : }
1034 224499 : lhs = ToNumeric(lhs, t);
1035 224499 : rhs = ToNumeric(rhs, t);
1036 443649 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
1037 52073 : return NumberCompareTyper(lhs, rhs, t);
1038 : }
1039 : return ComparisonOutcome(kComparisonTrue) |
1040 : ComparisonOutcome(kComparisonFalse) |
1041 : ComparisonOutcome(kComparisonUndefined);
1042 : }
1043 :
1044 180633 : Typer::Visitor::ComparisonOutcome Typer::Visitor::NumberCompareTyper(Type lhs,
1045 : Type rhs,
1046 : Typer* t) {
1047 : DCHECK(lhs.Is(Type::Number()));
1048 : DCHECK(rhs.Is(Type::Number()));
1049 :
1050 : // Shortcut for NaNs.
1051 360798 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
1052 :
1053 : ComparisonOutcome result;
1054 179720 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1055 : // Types are equal and are inhabited only by a single semantic value.
1056 : result = kComparisonFalse;
1057 179720 : } else if (lhs.Min() >= rhs.Max()) {
1058 : result = kComparisonFalse;
1059 177108 : } else if (lhs.Max() < rhs.Min()) {
1060 : result = kComparisonTrue;
1061 : } else {
1062 : // We cannot figure out the result, return both true and false. (We do not
1063 : // have to return undefined because that cannot affect the result of
1064 : // FalsifyUndefined.)
1065 : return ComparisonOutcome(kComparisonTrue) |
1066 : ComparisonOutcome(kComparisonFalse);
1067 : }
1068 : // Add the undefined if we could see NaN.
1069 15487 : if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1070 : result |= kComparisonUndefined;
1071 : }
1072 15487 : return result;
1073 : }
1074 :
1075 116312 : Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1076 116312 : return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
1077 : }
1078 :
1079 98438 : Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1080 98438 : return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1081 : }
1082 :
1083 3815 : Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1084 7630 : return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1085 : }
1086 :
1087 4029 : Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1088 8058 : return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1089 : }
1090 :
1091 : // JS bitwise operators.
1092 :
1093 12574 : Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1094 12574 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1095 : }
1096 :
1097 10429 : Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1098 10429 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1099 : }
1100 :
1101 3140 : Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1102 3140 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1103 : }
1104 :
1105 4730 : Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1106 4730 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1107 : }
1108 :
1109 4918 : Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1110 4918 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1111 : }
1112 :
1113 4817 : Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1114 4817 : return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1115 : }
1116 :
1117 :
1118 : // JS arithmetic operators.
1119 :
1120 205883 : Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1121 205883 : lhs = ToPrimitive(lhs, t);
1122 205883 : rhs = ToPrimitive(rhs, t);
1123 205883 : if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
1124 126453 : if (lhs.Is(Type::String()) || rhs.Is(Type::String())) {
1125 : return Type::String();
1126 : } else {
1127 : return Type::NumericOrString();
1128 : }
1129 : }
1130 : // The addition must be numeric.
1131 122382 : return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1132 : }
1133 :
1134 9648 : Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1135 9648 : return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1136 : }
1137 :
1138 11001 : Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1139 11001 : return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1140 : }
1141 :
1142 16842 : Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1143 16842 : return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1144 : }
1145 :
1146 5070 : Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1147 5070 : return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
1148 : }
1149 :
1150 177 : Type Typer::Visitor::JSExponentiateTyper(Type lhs, Type rhs, Typer* t) {
1151 : // TODO(neis): Refine using BinaryNumberOpTyper?
1152 177 : return Type::Numeric();
1153 : }
1154 :
1155 : // JS unary operators.
1156 :
1157 : Type Typer::Visitor::TypeJSBitwiseNot(Node* node) {
1158 165 : return TypeUnaryOp(node, BitwiseNot);
1159 : }
1160 :
1161 : Type Typer::Visitor::TypeJSDecrement(Node* node) {
1162 6435 : return TypeUnaryOp(node, Decrement);
1163 : }
1164 :
1165 : Type Typer::Visitor::TypeJSIncrement(Node* node) {
1166 251799 : return TypeUnaryOp(node, Increment);
1167 : }
1168 :
1169 : Type Typer::Visitor::TypeJSNegate(Node* node) {
1170 5401 : return TypeUnaryOp(node, Negate);
1171 : }
1172 :
1173 : Type Typer::Visitor::TypeTypeOf(Node* node) {
1174 : return Type::InternalizedString();
1175 : }
1176 :
1177 :
1178 : // JS conversion operators.
1179 :
1180 : Type Typer::Visitor::TypeToBoolean(Node* node) {
1181 143496 : return TypeUnaryOp(node, ToBoolean);
1182 : }
1183 :
1184 : Type Typer::Visitor::TypeJSToLength(Node* node) {
1185 136 : return TypeUnaryOp(node, ToLength);
1186 : }
1187 :
1188 : Type Typer::Visitor::TypeJSToName(Node* node) {
1189 1273 : return TypeUnaryOp(node, ToName);
1190 : }
1191 :
1192 : Type Typer::Visitor::TypeJSToNumber(Node* node) {
1193 9616 : return TypeUnaryOp(node, ToNumber);
1194 : }
1195 :
1196 : Type Typer::Visitor::TypeJSToNumberConvertBigInt(Node* node) {
1197 506 : return TypeUnaryOp(node, ToNumberConvertBigInt);
1198 : }
1199 :
1200 : Type Typer::Visitor::TypeJSToNumeric(Node* node) {
1201 47926 : return TypeUnaryOp(node, ToNumeric);
1202 : }
1203 :
1204 : Type Typer::Visitor::TypeJSToObject(Node* node) {
1205 2043 : return TypeUnaryOp(node, ToObject);
1206 : }
1207 :
1208 : Type Typer::Visitor::TypeJSToString(Node* node) {
1209 2452 : return TypeUnaryOp(node, ToString);
1210 : }
1211 :
1212 : // JS object operators.
1213 :
1214 : Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1215 :
1216 19305 : Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1217 19305 : switch (CreateArgumentsTypeOf(node->op())) {
1218 : case CreateArgumentsType::kRestParameter:
1219 : return Type::Array();
1220 : case CreateArgumentsType::kMappedArguments:
1221 : case CreateArgumentsType::kUnmappedArguments:
1222 : return Type::OtherObject();
1223 : }
1224 0 : UNREACHABLE();
1225 : }
1226 :
1227 : Type Typer::Visitor::TypeJSCreateArray(Node* node) { return Type::Array(); }
1228 :
1229 : Type Typer::Visitor::TypeJSCreateArrayIterator(Node* node) {
1230 : return Type::OtherObject();
1231 : }
1232 :
1233 : Type Typer::Visitor::TypeJSCreateAsyncFunctionObject(Node* node) {
1234 : return Type::OtherObject();
1235 : }
1236 :
1237 : Type Typer::Visitor::TypeJSCreateCollectionIterator(Node* node) {
1238 : return Type::OtherObject();
1239 : }
1240 :
1241 : Type Typer::Visitor::TypeJSCreateBoundFunction(Node* node) {
1242 : return Type::BoundFunction();
1243 : }
1244 :
1245 : Type Typer::Visitor::TypeJSCreateGeneratorObject(Node* node) {
1246 : return Type::OtherObject();
1247 : }
1248 :
1249 : Type Typer::Visitor::TypeJSCreateClosure(Node* node) {
1250 : return Type::Function();
1251 : }
1252 :
1253 : Type Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
1254 : return Type::OtherObject();
1255 : }
1256 :
1257 : Type Typer::Visitor::TypeJSCreateStringIterator(Node* node) {
1258 : return Type::OtherObject();
1259 : }
1260 :
1261 : Type Typer::Visitor::TypeJSCreateKeyValueArray(Node* node) {
1262 : return Type::OtherObject();
1263 : }
1264 :
1265 : Type Typer::Visitor::TypeJSCreateObject(Node* node) {
1266 : return Type::OtherObject();
1267 : }
1268 :
1269 : Type Typer::Visitor::TypeJSCreatePromise(Node* node) {
1270 : return Type::OtherObject();
1271 : }
1272 :
1273 : Type Typer::Visitor::TypeJSCreateTypedArray(Node* node) {
1274 : return Type::OtherObject();
1275 : }
1276 :
1277 : Type Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
1278 : return Type::Array();
1279 : }
1280 :
1281 : Type Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) {
1282 : return Type::Array();
1283 : }
1284 :
1285 : Type Typer::Visitor::TypeJSCreateArrayFromIterable(Node* node) {
1286 : return Type::Array();
1287 : }
1288 :
1289 : Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
1290 : return Type::OtherObject();
1291 : }
1292 :
1293 : Type Typer::Visitor::TypeJSCreateEmptyLiteralObject(Node* node) {
1294 : return Type::OtherObject();
1295 : }
1296 :
1297 : Type Typer::Visitor::TypeJSCloneObject(Node* node) {
1298 : return Type::OtherObject();
1299 : }
1300 :
1301 : Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
1302 : return Type::OtherObject();
1303 : }
1304 :
1305 : Type Typer::Visitor::TypeJSLoadProperty(Node* node) {
1306 : return Type::NonInternal();
1307 : }
1308 :
1309 : Type Typer::Visitor::TypeJSLoadNamed(Node* node) { return Type::NonInternal(); }
1310 :
1311 : Type Typer::Visitor::TypeJSLoadGlobal(Node* node) {
1312 : return Type::NonInternal();
1313 : }
1314 :
1315 : Type Typer::Visitor::TypeJSParseInt(Node* node) { return Type::Number(); }
1316 :
1317 : Type Typer::Visitor::TypeJSRegExpTest(Node* node) { return Type::Boolean(); }
1318 :
1319 : // Returns a somewhat larger range if we previously assigned
1320 : // a (smaller) range to this node. This is used to speed up
1321 : // the fixpoint calculation in case there appears to be a loop
1322 : // in the graph. In the current implementation, we are
1323 : // increasing the limits to the closest power of two.
1324 2161394 : Type Typer::Visitor::Weaken(Node* node, Type current_type, Type previous_type) {
1325 : static const double kWeakenMinLimits[] = {
1326 : 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0,
1327 : -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0,
1328 : -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0,
1329 : -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0,
1330 : -70368744177664.0, -140737488355328.0, -281474976710656.0,
1331 : -562949953421312.0};
1332 : static const double kWeakenMaxLimits[] = {
1333 : 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
1334 : 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
1335 : 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
1336 : 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
1337 : 70368744177663.0, 140737488355327.0, 281474976710655.0,
1338 : 562949953421311.0};
1339 : STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
1340 :
1341 : // If the types have nothing to do with integers, return the types.
1342 546747 : Type const integer = typer_->cache_->kInteger;
1343 546747 : if (!previous_type.Maybe(integer)) {
1344 42352 : return current_type;
1345 : }
1346 : DCHECK(current_type.Maybe(integer));
1347 :
1348 504404 : Type current_integer = Type::Intersect(current_type, integer, zone());
1349 504404 : Type previous_integer = Type::Intersect(previous_type, integer, zone());
1350 :
1351 : // Once we start weakening a node, we should always weaken.
1352 504401 : if (!IsWeakened(node->id())) {
1353 : // Only weaken if there is range involved; we should converge quickly
1354 : // for all other types (the exception is a union of many constants,
1355 : // but we currently do not increase the number of constants in unions).
1356 101817 : Type previous = previous_integer.GetRange();
1357 101816 : Type current = current_integer.GetRange();
1358 203496 : if (current.IsInvalid() || previous.IsInvalid()) {
1359 382 : return current_type;
1360 : }
1361 : // Range is involved => we are weakening.
1362 : SetWeakened(node->id());
1363 : }
1364 :
1365 504018 : double current_min = current_integer.Min();
1366 : double new_min = current_min;
1367 : // Find the closest lower entry in the list of allowed
1368 : // minima (or negative infinity if there is no such entry).
1369 504017 : if (current_min != previous_integer.Min()) {
1370 : new_min = -V8_INFINITY;
1371 2077496 : for (double const min : kWeakenMinLimits) {
1372 1053865 : if (min <= current_min) {
1373 : new_min = min;
1374 : break;
1375 : }
1376 : }
1377 : }
1378 :
1379 504017 : double current_max = current_integer.Max();
1380 : double new_max = current_max;
1381 : // Find the closest greater entry in the list of allowed
1382 : // maxima (or infinity if there is no such entry).
1383 504017 : if (current_max != previous_integer.Max()) {
1384 : new_max = V8_INFINITY;
1385 8783163 : for (double const max : kWeakenMaxLimits) {
1386 4547599 : if (max >= current_max) {
1387 : new_max = max;
1388 : break;
1389 : }
1390 : }
1391 : }
1392 :
1393 : return Type::Union(current_type,
1394 : Type::Range(new_min, new_max, typer_->zone()),
1395 1008030 : typer_->zone());
1396 : }
1397 :
1398 0 : Type Typer::Visitor::TypeJSStoreProperty(Node* node) { UNREACHABLE(); }
1399 :
1400 0 : Type Typer::Visitor::TypeJSStoreNamed(Node* node) { UNREACHABLE(); }
1401 :
1402 0 : Type Typer::Visitor::TypeJSStoreGlobal(Node* node) { UNREACHABLE(); }
1403 :
1404 0 : Type Typer::Visitor::TypeJSStoreNamedOwn(Node* node) { UNREACHABLE(); }
1405 :
1406 0 : Type Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
1407 0 : UNREACHABLE();
1408 : }
1409 :
1410 0 : Type Typer::Visitor::TypeJSStoreInArrayLiteral(Node* node) { UNREACHABLE(); }
1411 :
1412 : Type Typer::Visitor::TypeJSDeleteProperty(Node* node) {
1413 : return Type::Boolean();
1414 : }
1415 :
1416 : Type Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
1417 :
1418 : // JS instanceof operator.
1419 :
1420 1375 : Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1421 1375 : return Type::Boolean();
1422 : }
1423 :
1424 1959 : Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1425 1959 : return Type::Boolean();
1426 : }
1427 :
1428 231 : Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1429 231 : return Type::Boolean();
1430 : }
1431 :
1432 : Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1433 : return Type::Callable();
1434 : }
1435 :
1436 : // JS context operators.
1437 :
1438 312690 : Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1439 312690 : ContextAccess const& access = ContextAccessOf(node->op());
1440 : switch (access.index()) {
1441 : case Context::PREVIOUS_INDEX:
1442 : case Context::NATIVE_CONTEXT_INDEX:
1443 : case Context::SCOPE_INFO_INDEX:
1444 : return Type::OtherInternal();
1445 : default:
1446 : return Type::Any();
1447 : }
1448 : }
1449 :
1450 0 : Type Typer::Visitor::TypeJSStoreContext(Node* node) { UNREACHABLE(); }
1451 :
1452 : Type Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
1453 : return Type::OtherInternal();
1454 : }
1455 :
1456 : Type Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
1457 : return Type::OtherInternal();
1458 : }
1459 :
1460 : Type Typer::Visitor::TypeJSCreateWithContext(Node* node) {
1461 : return Type::OtherInternal();
1462 : }
1463 :
1464 : Type Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
1465 : return Type::OtherInternal();
1466 : }
1467 :
1468 : // JS other operators.
1469 :
1470 : Type Typer::Visitor::TypeJSConstructForwardVarargs(Node* node) {
1471 : return Type::Receiver();
1472 : }
1473 :
1474 : Type Typer::Visitor::TypeJSConstruct(Node* node) { return Type::Receiver(); }
1475 :
1476 : Type Typer::Visitor::TypeJSConstructWithArrayLike(Node* node) {
1477 : return Type::Receiver();
1478 : }
1479 :
1480 : Type Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
1481 : return Type::Receiver();
1482 : }
1483 :
1484 : Type Typer::Visitor::TypeJSObjectIsArray(Node* node) { return Type::Boolean(); }
1485 :
1486 : Type Typer::Visitor::TypeDateNow(Node* node) { return Type::Number(); }
1487 :
1488 490197 : Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1489 490197 : if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
1490 : return Type::NonInternal();
1491 : }
1492 177508 : JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1493 177508 : if (!function.shared().HasBuiltinFunctionId()) {
1494 : return Type::NonInternal();
1495 : }
1496 9882 : switch (function.shared().builtin_function_id()) {
1497 : case BuiltinFunctionId::kMathRandom:
1498 : return Type::PlainNumber();
1499 : case BuiltinFunctionId::kMathFloor:
1500 : case BuiltinFunctionId::kMathCeil:
1501 : case BuiltinFunctionId::kMathRound:
1502 : case BuiltinFunctionId::kMathTrunc:
1503 12 : return t->cache_->kIntegerOrMinusZeroOrNaN;
1504 : // Unary math functions.
1505 : case BuiltinFunctionId::kMathAbs:
1506 : case BuiltinFunctionId::kMathExp:
1507 7 : return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1508 : case BuiltinFunctionId::kMathAcos:
1509 : case BuiltinFunctionId::kMathAcosh:
1510 : case BuiltinFunctionId::kMathAsin:
1511 : case BuiltinFunctionId::kMathAsinh:
1512 : case BuiltinFunctionId::kMathAtan:
1513 : case BuiltinFunctionId::kMathAtanh:
1514 : case BuiltinFunctionId::kMathCbrt:
1515 : case BuiltinFunctionId::kMathCos:
1516 : case BuiltinFunctionId::kMathExpm1:
1517 : case BuiltinFunctionId::kMathFround:
1518 : case BuiltinFunctionId::kMathLog:
1519 : case BuiltinFunctionId::kMathLog1p:
1520 : case BuiltinFunctionId::kMathLog10:
1521 : case BuiltinFunctionId::kMathLog2:
1522 : case BuiltinFunctionId::kMathSin:
1523 : case BuiltinFunctionId::kMathSqrt:
1524 : case BuiltinFunctionId::kMathTan:
1525 : return Type::Number();
1526 : case BuiltinFunctionId::kMathSign:
1527 1 : return t->cache_->kMinusOneToOneOrMinusZeroOrNaN;
1528 : // Binary math functions.
1529 : case BuiltinFunctionId::kMathAtan2:
1530 : case BuiltinFunctionId::kMathPow:
1531 : case BuiltinFunctionId::kMathMax:
1532 : case BuiltinFunctionId::kMathMin:
1533 : return Type::Number();
1534 : case BuiltinFunctionId::kMathImul:
1535 : return Type::Signed32();
1536 : case BuiltinFunctionId::kMathClz32:
1537 9 : return t->cache_->kZeroToThirtyTwo;
1538 : // Date functions.
1539 : case BuiltinFunctionId::kDateNow:
1540 0 : return t->cache_->kTimeValueType;
1541 : case BuiltinFunctionId::kDateGetDate:
1542 0 : return t->cache_->kJSDateDayType;
1543 : case BuiltinFunctionId::kDateGetDay:
1544 0 : return t->cache_->kJSDateWeekdayType;
1545 : case BuiltinFunctionId::kDateGetFullYear:
1546 0 : return t->cache_->kJSDateYearType;
1547 : case BuiltinFunctionId::kDateGetHours:
1548 0 : return t->cache_->kJSDateHourType;
1549 : case BuiltinFunctionId::kDateGetMilliseconds:
1550 : return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
1551 0 : t->zone());
1552 : case BuiltinFunctionId::kDateGetMinutes:
1553 0 : return t->cache_->kJSDateMinuteType;
1554 : case BuiltinFunctionId::kDateGetMonth:
1555 0 : return t->cache_->kJSDateMonthType;
1556 : case BuiltinFunctionId::kDateGetSeconds:
1557 0 : return t->cache_->kJSDateSecondType;
1558 : case BuiltinFunctionId::kDateGetTime:
1559 0 : return t->cache_->kJSDateValueType;
1560 :
1561 : // Symbol functions.
1562 : case BuiltinFunctionId::kSymbolConstructor:
1563 : return Type::Symbol();
1564 : case BuiltinFunctionId::kSymbolPrototypeToString:
1565 : return Type::String();
1566 : case BuiltinFunctionId::kSymbolPrototypeValueOf:
1567 : return Type::Symbol();
1568 :
1569 : // BigInt functions.
1570 : case BuiltinFunctionId::kBigIntConstructor:
1571 : return Type::BigInt();
1572 :
1573 : // Number functions.
1574 : case BuiltinFunctionId::kNumberConstructor:
1575 : return Type::Number();
1576 : case BuiltinFunctionId::kNumberIsFinite:
1577 : case BuiltinFunctionId::kNumberIsInteger:
1578 : case BuiltinFunctionId::kNumberIsNaN:
1579 : case BuiltinFunctionId::kNumberIsSafeInteger:
1580 : return Type::Boolean();
1581 : case BuiltinFunctionId::kNumberParseFloat:
1582 : return Type::Number();
1583 : case BuiltinFunctionId::kNumberParseInt:
1584 1 : return t->cache_->kIntegerOrMinusZeroOrNaN;
1585 : case BuiltinFunctionId::kNumberToString:
1586 : return Type::String();
1587 :
1588 : // String functions.
1589 : case BuiltinFunctionId::kStringConstructor:
1590 : return Type::String();
1591 : case BuiltinFunctionId::kStringCharCodeAt:
1592 : return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
1593 152 : t->zone());
1594 : case BuiltinFunctionId::kStringCharAt:
1595 : return Type::String();
1596 : case BuiltinFunctionId::kStringCodePointAt:
1597 : return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
1598 144 : Type::Undefined(), t->zone());
1599 : case BuiltinFunctionId::kStringConcat:
1600 : case BuiltinFunctionId::kStringFromCharCode:
1601 : case BuiltinFunctionId::kStringFromCodePoint:
1602 : return Type::String();
1603 : case BuiltinFunctionId::kStringIndexOf:
1604 : case BuiltinFunctionId::kStringLastIndexOf:
1605 36 : return Type::Range(-1.0, String::kMaxLength, t->zone());
1606 : case BuiltinFunctionId::kStringEndsWith:
1607 : case BuiltinFunctionId::kStringIncludes:
1608 : return Type::Boolean();
1609 : case BuiltinFunctionId::kStringRaw:
1610 : case BuiltinFunctionId::kStringRepeat:
1611 : case BuiltinFunctionId::kStringSlice:
1612 : return Type::String();
1613 : case BuiltinFunctionId::kStringStartsWith:
1614 : return Type::Boolean();
1615 : case BuiltinFunctionId::kStringSubstr:
1616 : case BuiltinFunctionId::kStringSubstring:
1617 : case BuiltinFunctionId::kStringToLowerCase:
1618 : case BuiltinFunctionId::kStringToString:
1619 : case BuiltinFunctionId::kStringToUpperCase:
1620 : case BuiltinFunctionId::kStringTrim:
1621 : case BuiltinFunctionId::kStringTrimEnd:
1622 : case BuiltinFunctionId::kStringTrimStart:
1623 : case BuiltinFunctionId::kStringValueOf:
1624 : return Type::String();
1625 :
1626 : case BuiltinFunctionId::kStringIterator:
1627 : case BuiltinFunctionId::kStringIteratorNext:
1628 : return Type::OtherObject();
1629 :
1630 : case BuiltinFunctionId::kArrayEntries:
1631 : case BuiltinFunctionId::kArrayKeys:
1632 : case BuiltinFunctionId::kArrayValues:
1633 : case BuiltinFunctionId::kTypedArrayEntries:
1634 : case BuiltinFunctionId::kTypedArrayKeys:
1635 : case BuiltinFunctionId::kTypedArrayValues:
1636 : case BuiltinFunctionId::kArrayIteratorNext:
1637 : case BuiltinFunctionId::kMapIteratorNext:
1638 : case BuiltinFunctionId::kSetIteratorNext:
1639 : return Type::OtherObject();
1640 : case BuiltinFunctionId::kTypedArrayToStringTag:
1641 : return Type::Union(Type::InternalizedString(), Type::Undefined(),
1642 2 : t->zone());
1643 :
1644 : // Array functions.
1645 : case BuiltinFunctionId::kArrayIsArray:
1646 : return Type::Boolean();
1647 : case BuiltinFunctionId::kArrayConcat:
1648 : return Type::Receiver();
1649 : case BuiltinFunctionId::kArrayEvery:
1650 : return Type::Boolean();
1651 : case BuiltinFunctionId::kArrayFill:
1652 : case BuiltinFunctionId::kArrayFilter:
1653 : return Type::Receiver();
1654 : case BuiltinFunctionId::kArrayFindIndex:
1655 3 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1656 : case BuiltinFunctionId::kArrayForEach:
1657 : return Type::Undefined();
1658 : case BuiltinFunctionId::kArrayIncludes:
1659 : return Type::Boolean();
1660 : case BuiltinFunctionId::kArrayIndexOf:
1661 37 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1662 : case BuiltinFunctionId::kArrayJoin:
1663 : return Type::String();
1664 : case BuiltinFunctionId::kArrayLastIndexOf:
1665 62 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1666 : case BuiltinFunctionId::kArrayMap:
1667 : return Type::Receiver();
1668 : case BuiltinFunctionId::kArrayPush:
1669 2549 : return t->cache_->kPositiveSafeInteger;
1670 : case BuiltinFunctionId::kArrayReverse:
1671 : case BuiltinFunctionId::kArraySlice:
1672 : return Type::Receiver();
1673 : case BuiltinFunctionId::kArraySome:
1674 : return Type::Boolean();
1675 : case BuiltinFunctionId::kArraySplice:
1676 : return Type::Receiver();
1677 : case BuiltinFunctionId::kArrayUnshift:
1678 38 : return t->cache_->kPositiveSafeInteger;
1679 :
1680 : // ArrayBuffer functions.
1681 : case BuiltinFunctionId::kArrayBufferIsView:
1682 : return Type::Boolean();
1683 :
1684 : // Object functions.
1685 : case BuiltinFunctionId::kObjectAssign:
1686 : return Type::Receiver();
1687 : case BuiltinFunctionId::kObjectCreate:
1688 : return Type::OtherObject();
1689 : case BuiltinFunctionId::kObjectIs:
1690 : case BuiltinFunctionId::kObjectHasOwnProperty:
1691 : case BuiltinFunctionId::kObjectIsPrototypeOf:
1692 : return Type::Boolean();
1693 : case BuiltinFunctionId::kObjectToString:
1694 : return Type::String();
1695 :
1696 : case BuiltinFunctionId::kPromiseAll:
1697 : return Type::Receiver();
1698 : case BuiltinFunctionId::kPromisePrototypeThen:
1699 : return Type::Receiver();
1700 : case BuiltinFunctionId::kPromiseRace:
1701 : return Type::Receiver();
1702 : case BuiltinFunctionId::kPromiseReject:
1703 : return Type::Receiver();
1704 : case BuiltinFunctionId::kPromiseResolve:
1705 : return Type::Receiver();
1706 :
1707 : // RegExp functions.
1708 : case BuiltinFunctionId::kRegExpCompile:
1709 : return Type::OtherObject();
1710 : case BuiltinFunctionId::kRegExpExec:
1711 137 : return Type::Union(Type::Array(), Type::Null(), t->zone());
1712 : case BuiltinFunctionId::kRegExpTest:
1713 : return Type::Boolean();
1714 : case BuiltinFunctionId::kRegExpToString:
1715 : return Type::String();
1716 :
1717 : // Function functions.
1718 : case BuiltinFunctionId::kFunctionBind:
1719 : return Type::BoundFunction();
1720 : case BuiltinFunctionId::kFunctionHasInstance:
1721 : return Type::Boolean();
1722 :
1723 : // Global functions.
1724 : case BuiltinFunctionId::kGlobalDecodeURI:
1725 : case BuiltinFunctionId::kGlobalDecodeURIComponent:
1726 : case BuiltinFunctionId::kGlobalEncodeURI:
1727 : case BuiltinFunctionId::kGlobalEncodeURIComponent:
1728 : case BuiltinFunctionId::kGlobalEscape:
1729 : case BuiltinFunctionId::kGlobalUnescape:
1730 : return Type::String();
1731 : case BuiltinFunctionId::kGlobalIsFinite:
1732 : case BuiltinFunctionId::kGlobalIsNaN:
1733 : return Type::Boolean();
1734 :
1735 : // Map functions.
1736 : case BuiltinFunctionId::kMapClear:
1737 : case BuiltinFunctionId::kMapForEach:
1738 : return Type::Undefined();
1739 : case BuiltinFunctionId::kMapDelete:
1740 : case BuiltinFunctionId::kMapHas:
1741 : return Type::Boolean();
1742 : case BuiltinFunctionId::kMapEntries:
1743 : case BuiltinFunctionId::kMapKeys:
1744 : case BuiltinFunctionId::kMapSet:
1745 : case BuiltinFunctionId::kMapValues:
1746 : return Type::OtherObject();
1747 :
1748 : // Set functions.
1749 : case BuiltinFunctionId::kSetAdd:
1750 : case BuiltinFunctionId::kSetEntries:
1751 : case BuiltinFunctionId::kSetValues:
1752 : return Type::OtherObject();
1753 : case BuiltinFunctionId::kSetClear:
1754 : case BuiltinFunctionId::kSetForEach:
1755 : return Type::Undefined();
1756 : case BuiltinFunctionId::kSetDelete:
1757 : case BuiltinFunctionId::kSetHas:
1758 : return Type::Boolean();
1759 :
1760 : // WeakMap functions.
1761 : case BuiltinFunctionId::kWeakMapDelete:
1762 : case BuiltinFunctionId::kWeakMapHas:
1763 : return Type::Boolean();
1764 : case BuiltinFunctionId::kWeakMapSet:
1765 : return Type::OtherObject();
1766 :
1767 : // WeakSet functions.
1768 : case BuiltinFunctionId::kWeakSetAdd:
1769 : return Type::OtherObject();
1770 : case BuiltinFunctionId::kWeakSetDelete:
1771 : case BuiltinFunctionId::kWeakSetHas:
1772 : return Type::Boolean();
1773 : default:
1774 : return Type::NonInternal();
1775 : }
1776 : }
1777 :
1778 : Type Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1779 375 : return TypeUnaryOp(node, JSCallTyper);
1780 : }
1781 :
1782 : Type Typer::Visitor::TypeJSCall(Node* node) {
1783 : // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1784 : // argument types for the JSCallTyper above.
1785 488570 : return TypeUnaryOp(node, JSCallTyper);
1786 : }
1787 :
1788 : Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1789 411 : return TypeUnaryOp(node, JSCallTyper);
1790 : }
1791 :
1792 : Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1793 889 : return TypeUnaryOp(node, JSCallTyper);
1794 : }
1795 :
1796 348285 : Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1797 348285 : switch (CallRuntimeParametersOf(node->op()).id()) {
1798 : case Runtime::kInlineIsJSReceiver:
1799 0 : return TypeUnaryOp(node, ObjectIsReceiver);
1800 : case Runtime::kInlineIsSmi:
1801 0 : return TypeUnaryOp(node, ObjectIsSmi);
1802 : case Runtime::kInlineIsArray:
1803 : case Runtime::kInlineIsTypedArray:
1804 : case Runtime::kInlineIsRegExp:
1805 : return Type::Boolean();
1806 : case Runtime::kInlineCreateIterResultObject:
1807 : return Type::OtherObject();
1808 : case Runtime::kInlineToLength:
1809 0 : return TypeUnaryOp(node, ToLength);
1810 : case Runtime::kInlineToNumber:
1811 0 : return TypeUnaryOp(node, ToNumber);
1812 : case Runtime::kInlineToObject:
1813 0 : return TypeUnaryOp(node, ToObject);
1814 : case Runtime::kInlineToString:
1815 0 : return TypeUnaryOp(node, ToString);
1816 : case Runtime::kHasInPrototypeChain:
1817 : return Type::Boolean();
1818 : default:
1819 : break;
1820 : }
1821 : // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
1822 : // have a few weird runtime calls that return the hole or even FixedArrays;
1823 : // change this once those weird runtime calls have been removed.
1824 : return Type::Any();
1825 : }
1826 :
1827 : Type Typer::Visitor::TypeJSForInEnumerate(Node* node) {
1828 : return Type::OtherInternal();
1829 : }
1830 :
1831 3145 : Type Typer::Visitor::TypeJSForInNext(Node* node) {
1832 3145 : return Type::Union(Type::String(), Type::Undefined(), zone());
1833 : }
1834 :
1835 1391 : Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1836 : STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1837 : Type const cache_type =
1838 1391 : Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1839 1391 : Type const cache_array = Type::OtherInternal();
1840 1391 : Type const cache_length = typer_->cache_->kFixedArrayLengthType;
1841 1391 : return Type::Tuple(cache_type, cache_array, cache_length, zone());
1842 : }
1843 :
1844 : Type Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1845 :
1846 0 : Type Typer::Visitor::TypeJSStoreMessage(Node* node) { UNREACHABLE(); }
1847 :
1848 : Type Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1849 :
1850 0 : Type Typer::Visitor::TypeJSStoreModule(Node* node) { UNREACHABLE(); }
1851 :
1852 0 : Type Typer::Visitor::TypeJSGeneratorStore(Node* node) { UNREACHABLE(); }
1853 :
1854 : Type Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1855 : return Type::SignedSmall();
1856 : }
1857 :
1858 : Type Typer::Visitor::TypeJSGeneratorRestoreContext(Node* node) {
1859 : return Type::Any();
1860 : }
1861 :
1862 : Type Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1863 : return Type::Any();
1864 : }
1865 :
1866 : Type Typer::Visitor::TypeJSGeneratorRestoreInputOrDebugPos(Node* node) {
1867 : return Type::Any();
1868 : }
1869 :
1870 : Type Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1871 :
1872 : Type Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1873 :
1874 : Type Typer::Visitor::TypeJSAsyncFunctionEnter(Node* node) {
1875 : return Type::OtherObject();
1876 : }
1877 :
1878 : Type Typer::Visitor::TypeJSAsyncFunctionReject(Node* node) {
1879 : return Type::OtherObject();
1880 : }
1881 :
1882 : Type Typer::Visitor::TypeJSAsyncFunctionResolve(Node* node) {
1883 : return Type::OtherObject();
1884 : }
1885 :
1886 : Type Typer::Visitor::TypeJSFulfillPromise(Node* node) {
1887 : return Type::Undefined();
1888 : }
1889 :
1890 : Type Typer::Visitor::TypeJSPerformPromiseThen(Node* node) {
1891 : return Type::Receiver();
1892 : }
1893 :
1894 : Type Typer::Visitor::TypeJSPromiseResolve(Node* node) {
1895 : return Type::Receiver();
1896 : }
1897 :
1898 : Type Typer::Visitor::TypeJSRejectPromise(Node* node) {
1899 : return Type::Undefined();
1900 : }
1901 :
1902 : Type Typer::Visitor::TypeJSResolvePromise(Node* node) {
1903 : return Type::Undefined();
1904 : }
1905 :
1906 : // Simplified operators.
1907 :
1908 : Type Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1909 :
1910 : // static
1911 32311 : Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1912 32311 : return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
1913 : }
1914 :
1915 : // static
1916 128559 : Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1917 : return FalsifyUndefined(
1918 128560 : NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
1919 : }
1920 :
1921 : // static
1922 5134 : Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1923 : return FalsifyUndefined(
1924 10268 : Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
1925 : }
1926 :
1927 : Type Typer::Visitor::TypeNumberEqual(Node* node) {
1928 15267 : return TypeBinaryOp(node, NumberEqualTyper);
1929 : }
1930 :
1931 : Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1932 37711 : return TypeBinaryOp(node, NumberLessThanTyper);
1933 : }
1934 :
1935 : Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1936 3383 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1937 : }
1938 :
1939 : Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1940 20029 : return TypeBinaryOp(node, NumberEqualTyper);
1941 : }
1942 :
1943 : Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1944 131848 : return TypeBinaryOp(node, NumberLessThanTyper);
1945 : }
1946 :
1947 : Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1948 2214 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1949 : }
1950 :
1951 : Type Typer::Visitor::TypeStringConcat(Node* node) { return Type::String(); }
1952 :
1953 : Type Typer::Visitor::TypeStringToNumber(Node* node) {
1954 0 : return TypeUnaryOp(node, ToNumber);
1955 : }
1956 :
1957 : Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1958 2298 : return TypeUnaryOp(node, ToNumber);
1959 : }
1960 :
1961 : Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1962 : return Type::Integral32();
1963 : }
1964 :
1965 : Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1966 : return Type::Number();
1967 : }
1968 :
1969 : // static
1970 242142 : Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
1971 257680 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1972 5458 : return t->singleton_true_;
1973 : }
1974 : return Type::Boolean();
1975 : }
1976 :
1977 : Type Typer::Visitor::TypeReferenceEqual(Node* node) {
1978 243545 : return TypeBinaryOp(node, ReferenceEqualTyper);
1979 : }
1980 :
1981 : // static
1982 223 : Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
1983 223 : return t->operation_typer()->SameValue(lhs, rhs);
1984 : }
1985 :
1986 : Type Typer::Visitor::TypeSameValue(Node* node) {
1987 223 : return TypeBinaryOp(node, SameValueTyper);
1988 : }
1989 :
1990 : Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
1991 :
1992 : Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
1993 :
1994 : Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
1995 : return Type::Boolean();
1996 : }
1997 :
1998 1475 : Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
1999 1475 : return Type::String();
2000 : }
2001 :
2002 246 : Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
2003 246 : return Type::String();
2004 : }
2005 :
2006 : Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
2007 : return Type::String();
2008 : }
2009 :
2010 : Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
2011 : return Type::String();
2012 : }
2013 :
2014 : Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2015 3136 : return typer_->cache_->kUint16;
2016 : }
2017 :
2018 441 : Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2019 441 : return Type::Range(0.0, String::kMaxCodePoint, zone());
2020 : }
2021 :
2022 : Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2023 1610 : return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2024 : }
2025 :
2026 : Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2027 340 : return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2028 : }
2029 :
2030 313 : Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2031 313 : return Type::Range(-1.0, String::kMaxLength, zone());
2032 : }
2033 :
2034 : Type Typer::Visitor::TypeStringLength(Node* node) {
2035 50242 : return typer_->cache_->kStringLengthType;
2036 : }
2037 :
2038 : Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
2039 :
2040 3358 : Type Typer::Visitor::TypePoisonIndex(Node* node) {
2041 6716 : return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone());
2042 : }
2043 :
2044 67116 : Type Typer::Visitor::TypeCheckBounds(Node* node) {
2045 : return typer_->operation_typer_.CheckBounds(Operand(node, 0),
2046 67116 : Operand(node, 1));
2047 : }
2048 :
2049 : Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
2050 : Type type = Operand(node, 0);
2051 : return type;
2052 : }
2053 :
2054 0 : Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
2055 :
2056 7296 : Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
2057 3648 : Type arg = Operand(node, 0);
2058 3648 : return Type::Intersect(arg, Type::InternalizedString(), zone());
2059 : }
2060 :
2061 0 : Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
2062 :
2063 : Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
2064 :
2065 3542 : Type Typer::Visitor::TypeCheckNumber(Node* node) {
2066 3542 : return typer_->operation_typer_.CheckNumber(Operand(node, 0));
2067 : }
2068 :
2069 1790 : Type Typer::Visitor::TypeCheckReceiver(Node* node) {
2070 895 : Type arg = Operand(node, 0);
2071 895 : return Type::Intersect(arg, Type::Receiver(), zone());
2072 : }
2073 :
2074 174 : Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2075 87 : Type arg = Operand(node, 0);
2076 87 : return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone());
2077 : }
2078 :
2079 91636 : Type Typer::Visitor::TypeCheckSmi(Node* node) {
2080 45818 : Type arg = Operand(node, 0);
2081 45818 : return Type::Intersect(arg, Type::SignedSmall(), zone());
2082 : }
2083 :
2084 50364 : Type Typer::Visitor::TypeCheckString(Node* node) {
2085 25182 : Type arg = Operand(node, 0);
2086 25182 : return Type::Intersect(arg, Type::String(), zone());
2087 : }
2088 :
2089 74 : Type Typer::Visitor::TypeCheckSymbol(Node* node) {
2090 37 : Type arg = Operand(node, 0);
2091 37 : return Type::Intersect(arg, Type::Symbol(), zone());
2092 : }
2093 :
2094 626 : Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2095 626 : return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2096 : }
2097 :
2098 264 : Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
2099 : Type type = Operand(node, 0);
2100 132 : type = Type::Intersect(type, Type::NonInternal(), zone());
2101 132 : return type;
2102 : }
2103 :
2104 174852 : Type Typer::Visitor::TypeConvertReceiver(Node* node) {
2105 174852 : Type arg = Operand(node, 0);
2106 174852 : return typer_->operation_typer_.ConvertReceiver(arg);
2107 : }
2108 :
2109 2252 : Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
2110 2252 : Type type = Operand(node, 0);
2111 2252 : return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2112 : }
2113 :
2114 0 : Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2115 0 : UNREACHABLE();
2116 : }
2117 :
2118 0 : Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2119 :
2120 : Type Typer::Visitor::TypeAllocate(Node* node) {
2121 139372 : return AllocateTypeOf(node->op());
2122 : }
2123 :
2124 0 : Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2125 :
2126 : Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2127 : return Type::NonInternal();
2128 : }
2129 :
2130 : Type Typer::Visitor::TypeLoadField(Node* node) {
2131 571538 : return FieldAccessOf(node->op()).type;
2132 : }
2133 :
2134 : Type Typer::Visitor::TypeLoadElement(Node* node) {
2135 26318 : return ElementAccessOf(node->op()).type;
2136 : }
2137 :
2138 5829 : Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2139 5829 : switch (ExternalArrayTypeOf(node->op())) {
2140 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2141 : case kExternal##ElemType##Array: \
2142 : return typer_->cache_->k##ElemType;
2143 689 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2144 : #undef TYPED_ARRAY_CASE
2145 : }
2146 0 : UNREACHABLE();
2147 : }
2148 :
2149 268 : Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
2150 268 : switch (ExternalArrayTypeOf(node->op())) {
2151 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2152 : case kExternal##ElemType##Array: \
2153 : return typer_->cache_->k##ElemType;
2154 41 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2155 : #undef TYPED_ARRAY_CASE
2156 : }
2157 0 : UNREACHABLE();
2158 : }
2159 :
2160 0 : Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2161 :
2162 0 : Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2163 :
2164 0 : Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2165 0 : UNREACHABLE();
2166 : }
2167 :
2168 0 : Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2169 0 : UNREACHABLE();
2170 : }
2171 :
2172 0 : Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2173 0 : UNREACHABLE();
2174 : }
2175 :
2176 0 : Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2177 :
2178 0 : Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2179 :
2180 0 : Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }
2181 :
2182 : Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2183 16 : return TypeUnaryOp(node, ObjectIsArrayBufferView);
2184 : }
2185 :
2186 : Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2187 27 : return TypeUnaryOp(node, ObjectIsBigInt);
2188 : }
2189 :
2190 : Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2191 2050 : return TypeUnaryOp(node, ObjectIsCallable);
2192 : }
2193 :
2194 : Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2195 378 : return TypeUnaryOp(node, ObjectIsConstructor);
2196 : }
2197 :
2198 : Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2199 16917 : return TypeUnaryOp(node, ObjectIsDetectableCallable);
2200 : }
2201 :
2202 : Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2203 0 : return TypeUnaryOp(node, ObjectIsMinusZero);
2204 : }
2205 :
2206 : Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
2207 0 : return TypeUnaryOp(node, NumberIsMinusZero);
2208 : }
2209 :
2210 : Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2211 : return Type::Boolean();
2212 : }
2213 :
2214 : Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2215 :
2216 : Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2217 : return Type::Boolean();
2218 : }
2219 :
2220 0 : Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2221 :
2222 : Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2223 : return Type::Boolean();
2224 : }
2225 :
2226 0 : Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2227 :
2228 : Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2229 :
2230 : Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2231 4888 : return TypeUnaryOp(node, ObjectIsNaN);
2232 : }
2233 :
2234 : Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2235 14233 : return TypeUnaryOp(node, NumberIsNaN);
2236 : }
2237 :
2238 : Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2239 8986 : return TypeUnaryOp(node, ObjectIsNonCallable);
2240 : }
2241 :
2242 : Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2243 10346 : return TypeUnaryOp(node, ObjectIsNumber);
2244 : }
2245 :
2246 : Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2247 27564 : return TypeUnaryOp(node, ObjectIsReceiver);
2248 : }
2249 :
2250 : Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2251 2473 : return TypeUnaryOp(node, ObjectIsSmi);
2252 : }
2253 :
2254 : Type Typer::Visitor::TypeObjectIsString(Node* node) {
2255 2140 : return TypeUnaryOp(node, ObjectIsString);
2256 : }
2257 :
2258 : Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2259 120 : return TypeUnaryOp(node, ObjectIsSymbol);
2260 : }
2261 :
2262 : Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2263 1917 : return TypeUnaryOp(node, ObjectIsUndetectable);
2264 : }
2265 :
2266 : Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2267 17702 : return TypeCache::Get()->kArgumentsLengthType;
2268 : }
2269 :
2270 : Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2271 : return Type::ExternalPointer();
2272 : }
2273 :
2274 : Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2275 : return Type::OtherInternal();
2276 : }
2277 :
2278 : Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2279 : return Type::OtherInternal();
2280 : }
2281 :
2282 : Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2283 : return Type::OtherInternal();
2284 : }
2285 :
2286 : Type Typer::Visitor::TypeNewConsString(Node* node) { return Type::String(); }
2287 :
2288 : Type Typer::Visitor::TypeDelayedStringConstant(Node* node) {
2289 : return Type::String();
2290 : }
2291 :
2292 209 : Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2293 209 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2294 : }
2295 :
2296 0 : Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2297 0 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2298 : }
2299 :
2300 0 : Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2301 :
2302 : // Heap constants.
2303 :
2304 6255988 : Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2305 6255988 : return Type::NewConstant(typer_->broker(), value, zone());
2306 : }
2307 :
2308 : } // namespace compiler
2309 : } // namespace internal
2310 183867 : } // namespace v8
|