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 :
23 : namespace v8 {
24 : namespace internal {
25 : namespace compiler {
26 :
27 0 : class Typer::Decorator final : public GraphDecorator {
28 : public:
29 464399 : explicit Decorator(Typer* typer) : typer_(typer) {}
30 : void Decorate(Node* node) final;
31 :
32 : private:
33 : Typer* const typer_;
34 : };
35 :
36 464398 : Typer::Typer(JSHeapBroker* broker, Flags flags, Graph* graph)
37 : : flags_(flags),
38 : graph_(graph),
39 : decorator_(nullptr),
40 464398 : cache_(TypeCache::Get()),
41 : broker_(broker),
42 928796 : operation_typer_(broker, zone()) {
43 464401 : singleton_false_ = operation_typer_.singleton_false();
44 464401 : singleton_true_ = operation_typer_.singleton_true();
45 :
46 464399 : decorator_ = new (zone()) Decorator(this);
47 464399 : graph_->AddDecorator(decorator_);
48 464396 : }
49 :
50 :
51 928793 : Typer::~Typer() {
52 464399 : graph_->RemoveDecorator(decorator_);
53 464394 : }
54 :
55 :
56 10607080 : class Typer::Visitor : public Reducer {
57 : public:
58 5303545 : explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
59 : : typer_(typer),
60 : induction_vars_(induction_vars),
61 : weakened_nodes_(typer->zone()),
62 10607016 : remembered_types_(typer->zone()) {}
63 :
64 0 : const char* reducer_name() const override { return "Typer"; }
65 :
66 37791047 : Reduction Reduce(Node* node) override {
67 37791047 : if (node->op()->ValueOutputCount() == 0) return NoChange();
68 27608837 : switch (node->opcode()) {
69 : #define DECLARE_CASE(x) \
70 : case IrOpcode::k##x: \
71 : return UpdateType(node, TypeBinaryOp(node, x##Typer));
72 18350 : JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
73 : #undef DECLARE_CASE
74 :
75 : #define DECLARE_CASE(x) \
76 : case IrOpcode::k##x: \
77 : return UpdateType(node, Type##x(node));
78 463908 : DECLARE_CASE(Start)
79 214064 : DECLARE_CASE(IfException)
80 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
81 1999930 : COMMON_OP_LIST(DECLARE_CASE)
82 375192 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
83 1243316 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
84 334912 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
85 78 : JS_OBJECT_OP_LIST(DECLARE_CASE)
86 308596 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
87 516998 : JS_OTHER_OP_LIST(DECLARE_CASE)
88 : #undef DECLARE_CASE
89 :
90 : #define DECLARE_CASE(x) \
91 : case IrOpcode::k##x: \
92 : return UpdateType(node, TypeBinaryOp(node, x));
93 16252 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
94 115774 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
95 : #undef DECLARE_CASE
96 :
97 : #define DECLARE_CASE(x) \
98 : case IrOpcode::k##x: \
99 : return UpdateType(node, TypeUnaryOp(node, x));
100 577 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
101 96155 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
102 : #undef DECLARE_CASE
103 :
104 : #define DECLARE_CASE(x) case IrOpcode::k##x:
105 : DECLARE_CASE(Loop)
106 : DECLARE_CASE(Branch)
107 : DECLARE_CASE(IfTrue)
108 : DECLARE_CASE(IfFalse)
109 : DECLARE_CASE(IfSuccess)
110 : DECLARE_CASE(Switch)
111 : DECLARE_CASE(IfValue)
112 : DECLARE_CASE(IfDefault)
113 : DECLARE_CASE(Merge)
114 : DECLARE_CASE(Deoptimize)
115 : DECLARE_CASE(DeoptimizeIf)
116 : DECLARE_CASE(DeoptimizeUnless)
117 : DECLARE_CASE(TrapIf)
118 : DECLARE_CASE(TrapUnless)
119 : DECLARE_CASE(Return)
120 : DECLARE_CASE(TailCall)
121 : DECLARE_CASE(Terminate)
122 : DECLARE_CASE(OsrNormalEntry)
123 : DECLARE_CASE(OsrLoopEntry)
124 : DECLARE_CASE(Throw)
125 : DECLARE_CASE(End)
126 : SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
127 : SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
128 : MACHINE_SIMD_OP_LIST(DECLARE_CASE)
129 : MACHINE_OP_LIST(DECLARE_CASE)
130 : #undef DECLARE_CASE
131 : break;
132 : }
133 : return NoChange();
134 : }
135 :
136 4839450 : Type TypeNode(Node* node) {
137 4839450 : switch (node->opcode()) {
138 : #define DECLARE_CASE(x) \
139 : case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
140 1364 : JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
141 : #undef DECLARE_CASE
142 :
143 : #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
144 : DECLARE_CASE(Start)
145 : DECLARE_CASE(IfException)
146 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
147 1151729 : COMMON_OP_LIST(DECLARE_CASE)
148 0 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
149 35433 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
150 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
151 3 : JS_OBJECT_OP_LIST(DECLARE_CASE)
152 20 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
153 6376 : JS_OTHER_OP_LIST(DECLARE_CASE)
154 : #undef DECLARE_CASE
155 :
156 : #define DECLARE_CASE(x) \
157 : case IrOpcode::k##x: \
158 : return TypeBinaryOp(node, x);
159 120697 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
160 414 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
161 : #undef DECLARE_CASE
162 :
163 : #define DECLARE_CASE(x) \
164 : case IrOpcode::k##x: \
165 : return TypeUnaryOp(node, x);
166 8 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
167 645 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
168 : #undef DECLARE_CASE
169 :
170 : #define DECLARE_CASE(x) case IrOpcode::k##x:
171 : DECLARE_CASE(Loop)
172 : DECLARE_CASE(Branch)
173 : DECLARE_CASE(IfTrue)
174 : DECLARE_CASE(IfFalse)
175 : DECLARE_CASE(IfSuccess)
176 : DECLARE_CASE(Switch)
177 : DECLARE_CASE(IfValue)
178 : DECLARE_CASE(IfDefault)
179 : DECLARE_CASE(Merge)
180 : DECLARE_CASE(Deoptimize)
181 : DECLARE_CASE(DeoptimizeIf)
182 : DECLARE_CASE(DeoptimizeUnless)
183 : DECLARE_CASE(TrapIf)
184 : DECLARE_CASE(TrapUnless)
185 : DECLARE_CASE(Return)
186 : DECLARE_CASE(TailCall)
187 : DECLARE_CASE(Terminate)
188 : DECLARE_CASE(OsrNormalEntry)
189 : DECLARE_CASE(OsrLoopEntry)
190 : DECLARE_CASE(Throw)
191 : DECLARE_CASE(End)
192 : SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
193 : SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
194 : MACHINE_SIMD_OP_LIST(DECLARE_CASE)
195 : MACHINE_OP_LIST(DECLARE_CASE)
196 : #undef DECLARE_CASE
197 : break;
198 : }
199 0 : UNREACHABLE();
200 : }
201 :
202 : Type TypeConstant(Handle<Object> value);
203 :
204 : private:
205 : Typer* typer_;
206 : LoopVariableOptimizer* induction_vars_;
207 : ZoneSet<NodeId> weakened_nodes_;
208 : // TODO(tebbi): remove once chromium:906567 is resolved.
209 : ZoneUnorderedMap<std::pair<Node*, int>, Type> remembered_types_;
210 :
211 : #define DECLARE_METHOD(x) inline Type Type##x(Node* node);
212 : DECLARE_METHOD(Start)
213 : DECLARE_METHOD(IfException)
214 : COMMON_OP_LIST(DECLARE_METHOD)
215 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
216 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
217 : JS_OP_LIST(DECLARE_METHOD)
218 : #undef DECLARE_METHOD
219 :
220 : Type TypeOrNone(Node* node) {
221 : return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
222 8316418 : : Type::None();
223 : }
224 :
225 : Type Operand(Node* node, int i) {
226 8298374 : Node* operand_node = NodeProperties::GetValueInput(node, i);
227 : return TypeOrNone(operand_node);
228 : }
229 :
230 : Type Weaken(Node* node, Type current_type, Type previous_type);
231 :
232 : Zone* zone() { return typer_->zone(); }
233 : Graph* graph() { return typer_->graph(); }
234 :
235 : void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
236 : bool IsWeakened(NodeId node_id) {
237 : return weakened_nodes_.find(node_id) != weakened_nodes_.end();
238 : }
239 :
240 : using UnaryTyperFun = Type (*)(Type, Typer* t);
241 : using BinaryTyperFun = Type (*)(Type, Type, Typer* t);
242 :
243 : Type TypeUnaryOp(Node* node, UnaryTyperFun);
244 : Type TypeBinaryOp(Node* node, BinaryTyperFun);
245 :
246 : static Type BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
247 : BinaryTyperFun f);
248 :
249 : enum ComparisonOutcomeFlags {
250 : kComparisonTrue = 1,
251 : kComparisonFalse = 2,
252 : kComparisonUndefined = 4
253 : };
254 : using ComparisonOutcome = base::Flags<ComparisonOutcomeFlags>;
255 :
256 : static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
257 : static Type FalsifyUndefined(ComparisonOutcome, Typer*);
258 :
259 : static Type BitwiseNot(Type, Typer*);
260 : static Type Decrement(Type, Typer*);
261 : static Type Increment(Type, Typer*);
262 : static Type Negate(Type, Typer*);
263 :
264 : static Type ToPrimitive(Type, Typer*);
265 : static Type ToBoolean(Type, Typer*);
266 : static Type ToInteger(Type, Typer*);
267 : static Type ToLength(Type, Typer*);
268 : static Type ToName(Type, Typer*);
269 : static Type ToNumber(Type, Typer*);
270 : static Type ToNumberConvertBigInt(Type, Typer*);
271 : static Type ToNumeric(Type, Typer*);
272 : static Type ToObject(Type, Typer*);
273 : static Type ToString(Type, Typer*);
274 : #define DECLARE_METHOD(Name) \
275 : static Type Name(Type type, Typer* t) { \
276 : return t->operation_typer_.Name(type); \
277 : }
278 63741 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
279 94227 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_METHOD)
280 : #undef DECLARE_METHOD
281 : #define DECLARE_METHOD(Name) \
282 : static Type Name(Type lhs, Type rhs, Typer* t) { \
283 : return t->operation_typer_.Name(lhs, rhs); \
284 : }
285 572965 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
286 476362 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
287 : #undef DECLARE_METHOD
288 :
289 : static Type ObjectIsArrayBufferView(Type, Typer*);
290 : static Type ObjectIsBigInt(Type, Typer*);
291 : static Type ObjectIsCallable(Type, Typer*);
292 : static Type ObjectIsConstructor(Type, Typer*);
293 : static Type ObjectIsDetectableCallable(Type, Typer*);
294 : static Type ObjectIsMinusZero(Type, Typer*);
295 : static Type NumberIsMinusZero(Type, Typer*);
296 : static Type ObjectIsNaN(Type, Typer*);
297 : static Type NumberIsNaN(Type, Typer*);
298 : static Type ObjectIsNonCallable(Type, Typer*);
299 : static Type ObjectIsNumber(Type, Typer*);
300 : static Type ObjectIsReceiver(Type, Typer*);
301 : static Type ObjectIsSmi(Type, Typer*);
302 : static Type ObjectIsString(Type, Typer*);
303 : static Type ObjectIsSymbol(Type, Typer*);
304 : static Type ObjectIsUndetectable(Type, Typer*);
305 :
306 : static ComparisonOutcome JSCompareTyper(Type, Type, Typer*);
307 : static ComparisonOutcome NumberCompareTyper(Type, Type, Typer*);
308 :
309 : #define DECLARE_METHOD(x) static Type x##Typer(Type, Type, Typer*);
310 : JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
311 : #undef DECLARE_METHOD
312 :
313 : static Type JSCallTyper(Type, Typer*);
314 :
315 : static Type NumberEqualTyper(Type, Type, Typer*);
316 : static Type NumberLessThanTyper(Type, Type, Typer*);
317 : static Type NumberLessThanOrEqualTyper(Type, Type, Typer*);
318 : static Type ReferenceEqualTyper(Type, Type, Typer*);
319 : static Type SameValueTyper(Type, Type, Typer*);
320 : static Type SameValueNumbersOnlyTyper(Type, Type, Typer*);
321 : static Type StringFromSingleCharCodeTyper(Type, Typer*);
322 : static Type StringFromSingleCodePointTyper(Type, Typer*);
323 :
324 27608277 : Reduction UpdateType(Node* node, Type current) {
325 27608277 : if (NodeProperties::IsTyped(node)) {
326 : // Widen the type of a previously typed node.
327 5977584 : Type previous = NodeProperties::GetType(node);
328 5977584 : if (node->opcode() == IrOpcode::kPhi ||
329 : node->opcode() == IrOpcode::kInductionVariablePhi) {
330 : // Speed up termination in the presence of range types:
331 558477 : current = Weaken(node, current, previous);
332 : }
333 :
334 5977587 : 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 5977587 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
372 23605 : for (int i = 0; i < 2; ++i) {
373 9442 : Node* input = NodeProperties::GetValueInput(node, i);
374 9442 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
375 : ? NodeProperties::GetType(input)
376 9442 : : Type::Invalid();
377 : }
378 4721 : remembered_types_[{node, 2}] = current;
379 : }
380 :
381 : NodeProperties::SetType(node, current);
382 5977581 : if (!current.Is(previous)) {
383 : // If something changed, revisit all uses.
384 : return Changed(node);
385 : }
386 : return NoChange();
387 : } else {
388 21630693 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
389 57655 : for (int i = 0; i < 2; ++i) {
390 23062 : Node* input = NodeProperties::GetValueInput(node, i);
391 23062 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
392 : ? NodeProperties::GetType(input)
393 23062 : : Type::Invalid();
394 : }
395 11531 : 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 744 : void Typer::Run() { Run(NodeVector(zone()), nullptr); }
406 :
407 464138 : void Typer::Run(const NodeVector& roots,
408 : LoopVariableOptimizer* induction_vars) {
409 464138 : if (induction_vars != nullptr) {
410 463894 : induction_vars->ChangeToInductionVariablePhis();
411 : }
412 928278 : Visitor visitor(this, induction_vars);
413 928279 : GraphReducer graph_reducer(zone(), graph());
414 464144 : graph_reducer.AddReducer(&visitor);
415 6777513 : for (Node* const root : roots) graph_reducer.ReduceNode(root);
416 464148 : graph_reducer.ReduceGraph();
417 :
418 464148 : if (induction_vars != nullptr) {
419 463900 : induction_vars->ChangeToPhisAndInsertGuards();
420 : }
421 464146 : }
422 :
423 6551093 : void Typer::Decorator::Decorate(Node* node) {
424 6551093 : 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 4896120 : if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
429 9678767 : Visitor typing(typer_, nullptr);
430 4839338 : Type type = typing.TypeNode(node);
431 4839352 : if (is_typed) {
432 : type = Type::Intersect(type, NodeProperties::GetType(node),
433 0 : typer_->zone());
434 : }
435 : NodeProperties::SetType(node, type);
436 : }
437 : }
438 6551117 : }
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 1255744 : Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
448 : Type input = Operand(node, 0);
449 1255744 : return input.IsNone() ? Type::None() : f(input, typer_);
450 : }
451 :
452 1912624 : Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
453 : Type left = Operand(node, 0);
454 : Type right = Operand(node, 1);
455 1789726 : return left.IsNone() || right.IsNone() ? Type::None()
456 3695454 : : f(left, right, typer_);
457 : }
458 :
459 189245 : Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
460 : BinaryTyperFun f) {
461 189245 : lhs = ToNumeric(lhs, t);
462 189245 : rhs = ToNumeric(rhs, t);
463 : bool lhs_is_number = lhs.Is(Type::Number());
464 : bool rhs_is_number = rhs.Is(Type::Number());
465 189245 : if (lhs_is_number && rhs_is_number) {
466 145590 : return f(lhs, rhs, t);
467 : }
468 : // In order to maintain monotonicity, the following two conditions are
469 : // intentionally asymmetric.
470 43655 : if (lhs_is_number) {
471 : return Type::Number();
472 : }
473 32313 : 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 11934 : if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
483 11934 : if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
484 11934 : if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
485 0 : return result;
486 : }
487 :
488 0 : Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
489 373830 : if ((outcome & kComparisonFalse) != 0 ||
490 : (outcome & kComparisonUndefined) != 0) {
491 : return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
492 348259 : : t->singleton_false_;
493 : }
494 : // Type should be non empty, so we know it should be true.
495 : DCHECK_NE(0, outcome & kComparisonTrue);
496 12428 : return t->singleton_true_;
497 : }
498 :
499 166 : Type Typer::Visitor::BitwiseNot(Type type, Typer* t) {
500 166 : type = ToNumeric(type, t);
501 166 : if (type.Is(Type::Number())) {
502 34 : return NumberBitwiseXor(type, t->cache_->kSingletonMinusOne, t);
503 : }
504 : return Type::Numeric();
505 : }
506 :
507 6273 : Type Typer::Visitor::Decrement(Type type, Typer* t) {
508 6273 : type = ToNumeric(type, t);
509 6273 : if (type.Is(Type::Number())) {
510 3798 : return NumberSubtract(type, t->cache_->kSingletonOne, t);
511 : }
512 : return Type::Numeric();
513 : }
514 :
515 262309 : Type Typer::Visitor::Increment(Type type, Typer* t) {
516 262309 : type = ToNumeric(type, t);
517 262309 : if (type.Is(Type::Number())) {
518 251848 : return NumberAdd(type, t->cache_->kSingletonOne, t);
519 : }
520 : return Type::Numeric();
521 : }
522 :
523 4400 : Type Typer::Visitor::Negate(Type type, Typer* t) {
524 4400 : type = ToNumeric(type, t);
525 4400 : if (type.Is(Type::Number())) {
526 461 : return NumberMultiply(type, t->cache_->kSingletonMinusOne, t);
527 : }
528 : return Type::Numeric();
529 : }
530 :
531 : // Type conversion.
532 :
533 913189 : Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
534 913189 : if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
535 734866 : return type;
536 : }
537 : return Type::Primitive();
538 : }
539 :
540 137860 : Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
541 137860 : return t->operation_typer()->ToBoolean(type);
542 : }
543 :
544 :
545 : // static
546 122 : Type Typer::Visitor::ToInteger(Type type, Typer* t) {
547 : // ES6 section 7.1.4 ToInteger ( argument )
548 122 : type = ToNumber(type, t);
549 244 : if (type.Is(t->cache_->kIntegerOrMinusZero)) return type;
550 184 : if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
551 : return Type::Union(
552 1 : Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()),
553 1 : t->cache_->kSingletonZero, t->zone());
554 : }
555 91 : return t->cache_->kIntegerOrMinusZero;
556 : }
557 :
558 :
559 : // static
560 122 : Type Typer::Visitor::ToLength(Type type, Typer* t) {
561 : // ES6 section 7.1.15 ToLength ( argument )
562 122 : type = ToInteger(type, t);
563 122 : if (type.IsNone()) return type;
564 113 : double min = type.Min();
565 113 : double max = type.Max();
566 113 : if (max <= 0.0) {
567 6 : return Type::NewConstant(0, t->zone());
568 : }
569 107 : if (min >= kMaxSafeInteger) {
570 2 : return Type::NewConstant(kMaxSafeInteger, t->zone());
571 : }
572 105 : if (min <= 0.0) min = 0.0;
573 105 : if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
574 105 : return Type::Range(min, max, t->zone());
575 : }
576 :
577 :
578 : // static
579 1262 : Type Typer::Visitor::ToName(Type type, Typer* t) {
580 : // ES6 section 7.1.14 ToPropertyKey ( argument )
581 1262 : type = ToPrimitive(type, t);
582 1262 : if (type.Is(Type::Name())) return type;
583 1199 : if (type.Maybe(Type::Symbol())) return Type::Name();
584 93 : return ToString(type, t);
585 : }
586 :
587 :
588 : // static
589 11790 : Type Typer::Visitor::ToNumber(Type type, Typer* t) {
590 172686 : return t->operation_typer_.ToNumber(type);
591 : }
592 :
593 : // static
594 359 : Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
595 359 : return t->operation_typer_.ToNumberConvertBigInt(type);
596 : }
597 :
598 : // static
599 49296 : Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
600 1169842 : return t->operation_typer_.ToNumeric(type);
601 : }
602 :
603 : // static
604 2032 : Type Typer::Visitor::ToObject(Type type, Typer* t) {
605 : // ES6 section 7.1.13 ToObject ( argument )
606 2032 : if (type.Is(Type::Receiver())) return type;
607 1569 : if (type.Is(Type::Primitive())) return Type::OtherObject();
608 1462 : if (!type.Maybe(Type::OtherUndetectable())) {
609 : return Type::DetectableReceiver();
610 : }
611 : return Type::Receiver();
612 : }
613 :
614 :
615 : // static
616 2565 : Type Typer::Visitor::ToString(Type type, Typer* t) {
617 : // ES6 section 7.1.12 ToString ( argument )
618 2565 : type = ToPrimitive(type, t);
619 2565 : 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 2006 : Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
638 2006 : if (type.Is(Type::Callable())) return t->singleton_true_;
639 319 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
640 : return Type::Boolean();
641 : }
642 :
643 465 : Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
644 : // TODO(turbofan): Introduce a Type::Constructor?
645 465 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
646 : return Type::Boolean();
647 : }
648 :
649 17496 : Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
650 17496 : if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
651 17382 : 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 4594 : Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
668 4594 : if (type.Is(Type::NaN())) return t->singleton_true_;
669 4587 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
670 : return Type::Boolean();
671 : }
672 :
673 5117 : Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
674 5117 : if (type.Is(Type::NaN())) return t->singleton_true_;
675 4525 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
676 : return Type::Boolean();
677 : }
678 :
679 9075 : Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
680 9075 : if (type.Is(Type::NonCallable())) return t->singleton_true_;
681 8750 : if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
682 : return Type::Boolean();
683 : }
684 :
685 10463 : Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
686 10463 : if (type.Is(Type::Number())) return t->singleton_true_;
687 8982 : if (!type.Maybe(Type::Number())) return t->singleton_false_;
688 : return Type::Boolean();
689 : }
690 :
691 26650 : Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
692 26650 : if (type.Is(Type::Receiver())) return t->singleton_true_;
693 24287 : if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
694 : return Type::Boolean();
695 : }
696 :
697 1515 : Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
698 1515 : if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
699 : return Type::Boolean();
700 : }
701 :
702 2458 : Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
703 2458 : if (type.Is(Type::String())) return t->singleton_true_;
704 2448 : if (!type.Maybe(Type::String())) return t->singleton_false_;
705 : return Type::Boolean();
706 : }
707 :
708 109 : Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
709 109 : if (type.Is(Type::Symbol())) return t->singleton_true_;
710 109 : if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
711 : return Type::Boolean();
712 : }
713 :
714 1887 : Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
715 1887 : if (type.Is(Type::Undetectable())) return t->singleton_true_;
716 1685 : 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 1999250 : Type Typer::Visitor::TypeParameter(Node* node) {
733 : Node* const start = node->InputAt(0);
734 : DCHECK_EQ(IrOpcode::kStart, start->opcode());
735 1999250 : int const parameter_count = start->op()->ValueOutputCount() - 4;
736 : DCHECK_LE(1, parameter_count);
737 1999250 : int const index = ParameterIndexOf(node->op());
738 1999250 : if (index == Linkage::kJSCallClosureParamIndex) {
739 : return Type::Function();
740 1972750 : } else if (index == 0) {
741 918530 : if (typer_->flags() & Typer::kThisIsReceiver) {
742 : return Type::Receiver();
743 : } else {
744 : // Parameter[this] can be the_hole for derived class constructors.
745 91462 : return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
746 : }
747 1513485 : } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
748 36008 : if (typer_->flags() & Typer::kNewTargetIsReceiver) {
749 : return Type::Receiver();
750 : } else {
751 16880 : return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
752 : }
753 1495481 : } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
754 0 : return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone());
755 1495481 : } 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 : Type Typer::Visitor::TypeNumberConstant(Node* node) {
778 1770364 : double number = OpParameter<double>(node->op());
779 1770364 : return Type::NewConstant(number, zone());
780 : }
781 :
782 6010888 : Type Typer::Visitor::TypeHeapConstant(Node* node) {
783 12021748 : 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 18011 : Type Typer::Visitor::TypeSelect(Node* node) {
795 18011 : return Type::Union(Operand(node, 1), Operand(node, 2), zone());
796 : }
797 :
798 874634 : Type Typer::Visitor::TypePhi(Node* node) {
799 : int arity = node->op()->ValueInputCount();
800 : Type type = Operand(node, 0);
801 3665876 : for (int i = 1; i < arity; ++i) {
802 1395611 : type = Type::Union(type, Operand(node, i), zone());
803 : }
804 874623 : return type;
805 : }
806 :
807 24639 : Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
808 24639 : 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 24639 : Type initial_type = Operand(node, 0);
813 24639 : 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 67399 : if (!initial_type.Is(typer_->cache_->kInteger) ||
818 18121 : !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 6748 : : Type::None();
826 33740 : for (int i = 0; i < arity; ++i) {
827 13496 : type = Type::Union(type, Operand(node, i), zone());
828 : }
829 6748 : 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 35761 : if (initial_type.IsNone() ||
834 17870 : increment_type.Is(typer_->cache_->kSingletonZero)) {
835 37 : return initial_type;
836 : }
837 :
838 : // Now process the bounds.
839 17854 : auto res = induction_vars_->induction_variables().find(node->id());
840 : DCHECK(res != induction_vars_->induction_variables().end());
841 17854 : InductionVariable* induction_var = res->second;
842 :
843 : InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
844 :
845 17854 : double min = -V8_INFINITY;
846 17854 : double max = V8_INFINITY;
847 :
848 : double increment_min;
849 : double increment_max;
850 17854 : if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
851 17576 : increment_min = increment_type.Min();
852 17576 : increment_max = increment_type.Max();
853 : } else {
854 : DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
855 278 : increment_min = -increment_type.Max();
856 278 : increment_max = -increment_type.Min();
857 : }
858 :
859 17854 : if (increment_min >= 0) {
860 : // increasing sequence
861 17592 : min = initial_type.Min();
862 35264 : for (auto bound : induction_var->upper_bounds()) {
863 17697 : Type bound_type = TypeOrNone(bound.bound);
864 : // If the type is not an integer, just skip the bound.
865 37510 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
866 : // If the type is not inhabited, then we can take the initial value.
867 15581 : if (bound_type.IsNone()) {
868 25 : max = initial_type.Max();
869 25 : break;
870 : }
871 15556 : double bound_max = bound_type.Max();
872 15556 : if (bound.kind == InductionVariable::kStrict) {
873 15391 : bound_max -= 1;
874 : }
875 31112 : max = std::min(max, bound_max + increment_max);
876 : }
877 : // The upper bound must be at least the initial value's upper bound.
878 35184 : max = std::max(max, initial_type.Max());
879 262 : } else if (increment_max <= 0) {
880 : // decreasing sequence
881 262 : max = initial_type.Max();
882 582 : for (auto bound : induction_var->lower_bounds()) {
883 320 : Type bound_type = TypeOrNone(bound.bound);
884 : // If the type is not an integer, just skip the bound.
885 640 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
886 : // If the type is not inhabited, then we can take the initial value.
887 320 : if (bound_type.IsNone()) {
888 0 : min = initial_type.Min();
889 0 : break;
890 : }
891 320 : double bound_min = bound_type.Min();
892 320 : if (bound.kind == InductionVariable::kStrict) {
893 144 : bound_min += 1;
894 : }
895 640 : min = std::max(min, bound_min + increment_min);
896 : }
897 : // The lower bound must be at most the initial value's lower bound.
898 524 : 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 17854 : if (FLAG_trace_turbo_loop) {
905 0 : StdoutStream{} << std::setprecision(10) << "Loop ("
906 0 : << NodeProperties::GetControlInput(node)->id()
907 : << ") 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 17854 : 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 6008 : Type Typer::Visitor::TypeProjection(Node* node) {
976 6008 : Type const type = Operand(node, 0);
977 6008 : if (type.Is(Type::None())) return Type::None();
978 6008 : int const index = static_cast<int>(ProjectionIndexOf(node->op()));
979 6008 : if (type.IsTuple() && index < type.AsTuple()->Arity()) {
980 4128 : return type.AsTuple()->Element(index);
981 : }
982 : return Type::Any();
983 : }
984 :
985 0 : Type Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
986 :
987 24608 : Type Typer::Visitor::TypeTypeGuard(Node* node) {
988 24608 : Type const type = Operand(node, 0);
989 49216 : 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 48725 : Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
1001 97279 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
1002 48548 : if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1003 0 : return t->singleton_true_;
1004 : }
1005 172951 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
1006 73106 : (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1007 2084 : return t->singleton_false_;
1008 : }
1009 47092 : 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 69 : return t->singleton_true_;
1013 : }
1014 : return Type::Boolean();
1015 : }
1016 :
1017 184641 : Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
1018 184641 : 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 238190 : Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
1026 : Type rhs,
1027 : Typer* t) {
1028 238190 : lhs = ToPrimitive(lhs, t);
1029 238190 : rhs = ToPrimitive(rhs, t);
1030 238190 : if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
1031 : return ComparisonOutcome(kComparisonTrue) |
1032 : ComparisonOutcome(kComparisonFalse);
1033 : }
1034 234454 : lhs = ToNumeric(lhs, t);
1035 234454 : rhs = ToNumeric(rhs, t);
1036 461419 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
1037 48759 : return NumberCompareTyper(lhs, rhs, t);
1038 : }
1039 : return ComparisonOutcome(kComparisonTrue) |
1040 : ComparisonOutcome(kComparisonFalse) |
1041 : ComparisonOutcome(kComparisonUndefined);
1042 : }
1043 :
1044 171261 : 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 342195 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
1052 :
1053 : ComparisonOutcome result;
1054 170607 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1055 : // Types are equal and are inhabited only by a single semantic value.
1056 : result = kComparisonFalse;
1057 170607 : } else if (lhs.Min() >= rhs.Max()) {
1058 : result = kComparisonFalse;
1059 168480 : } 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 14288 : if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1070 : result |= kComparisonUndefined;
1071 : }
1072 14288 : return result;
1073 : }
1074 :
1075 126291 : Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1076 252582 : return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
1077 : }
1078 :
1079 99965 : Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1080 199930 : return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1081 : }
1082 :
1083 3953 : Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1084 7906 : return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1085 : }
1086 :
1087 3693 : Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1088 7386 : return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1089 : }
1090 :
1091 : // JS bitwise operators.
1092 :
1093 11130 : Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1094 11130 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1095 : }
1096 :
1097 8851 : Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1098 8851 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1099 : }
1100 :
1101 1822 : Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1102 1822 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1103 : }
1104 :
1105 5188 : Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1106 5188 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1107 : }
1108 :
1109 3511 : Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1110 3511 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1111 : }
1112 :
1113 3581 : Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1114 3581 : return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1115 : }
1116 :
1117 :
1118 : // JS arithmetic operators.
1119 :
1120 216491 : Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1121 216491 : lhs = ToPrimitive(lhs, t);
1122 216491 : rhs = ToPrimitive(rhs, t);
1123 216491 : if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
1124 143464 : 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 120759 : return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1132 : }
1133 :
1134 9405 : Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1135 9405 : return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1136 : }
1137 :
1138 10771 : Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1139 10771 : return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1140 : }
1141 :
1142 14367 : Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1143 14367 : return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1144 : }
1145 :
1146 3441 : Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1147 3441 : return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
1148 : }
1149 :
1150 184 : Type Typer::Visitor::JSExponentiateTyper(Type lhs, Type rhs, Typer* t) {
1151 : // TODO(neis): Refine using BinaryNumberOpTyper?
1152 184 : return Type::Numeric();
1153 : }
1154 :
1155 : // JS unary operators.
1156 :
1157 : Type Typer::Visitor::TypeJSBitwiseNot(Node* node) {
1158 166 : return TypeUnaryOp(node, BitwiseNot);
1159 : }
1160 :
1161 : Type Typer::Visitor::TypeJSDecrement(Node* node) {
1162 6429 : return TypeUnaryOp(node, Decrement);
1163 : }
1164 :
1165 : Type Typer::Visitor::TypeJSIncrement(Node* node) {
1166 263339 : return TypeUnaryOp(node, Increment);
1167 : }
1168 :
1169 : Type Typer::Visitor::TypeJSNegate(Node* node) {
1170 4404 : 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 143259 : 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 1276 : return TypeUnaryOp(node, ToName);
1190 : }
1191 :
1192 : Type Typer::Visitor::TypeJSToNumber(Node* node) {
1193 9576 : return TypeUnaryOp(node, ToNumber);
1194 : }
1195 :
1196 : Type Typer::Visitor::TypeJSToNumberConvertBigInt(Node* node) {
1197 359 : return TypeUnaryOp(node, ToNumberConvertBigInt);
1198 : }
1199 :
1200 : Type Typer::Visitor::TypeJSToNumeric(Node* node) {
1201 49377 : return TypeUnaryOp(node, ToNumeric);
1202 : }
1203 :
1204 : Type Typer::Visitor::TypeJSToObject(Node* node) {
1205 2056 : return TypeUnaryOp(node, ToObject);
1206 : }
1207 :
1208 : Type Typer::Visitor::TypeJSToString(Node* node) {
1209 2544 : return TypeUnaryOp(node, ToString);
1210 : }
1211 :
1212 : // JS object operators.
1213 :
1214 : Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1215 :
1216 19441 : Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1217 19441 : 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 558474 : 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 558474 : Type const integer = typer_->cache_->kInteger;
1343 558474 : if (!previous_type.Maybe(integer)) {
1344 42541 : return current_type;
1345 : }
1346 : DCHECK(current_type.Maybe(integer));
1347 :
1348 515945 : Type current_integer = Type::Intersect(current_type, integer, zone());
1349 515942 : Type previous_integer = Type::Intersect(previous_type, integer, zone());
1350 :
1351 : // Once we start weakening a node, we should always weaken.
1352 515947 : 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 101530 : Type previous = previous_integer.GetRange();
1357 101530 : Type current = current_integer.GetRange();
1358 202959 : if (current.IsInvalid() || previous.IsInvalid()) {
1359 322 : return current_type;
1360 : }
1361 : // Range is involved => we are weakening.
1362 : SetWeakened(node->id());
1363 : }
1364 :
1365 515626 : 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 515623 : if (current_min != previous_integer.Min()) {
1370 : new_min = -V8_INFINITY;
1371 2101642 : for (double const min : kWeakenMinLimits) {
1372 1049109 : if (min <= current_min) {
1373 : new_min = min;
1374 : break;
1375 : }
1376 : }
1377 : }
1378 :
1379 515620 : 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 515619 : if (current_max != previous_integer.Max()) {
1384 : new_max = V8_INFINITY;
1385 9117769 : for (double const max : kWeakenMaxLimits) {
1386 4696482 : 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 515617 : 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 817 : Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1421 817 : return Type::Boolean();
1422 : }
1423 :
1424 2949 : Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1425 2949 : return Type::Boolean();
1426 : }
1427 :
1428 176 : Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1429 176 : return Type::Boolean();
1430 : }
1431 :
1432 : Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1433 : return Type::Callable();
1434 : }
1435 :
1436 : // JS context operators.
1437 :
1438 308616 : Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1439 308616 : 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 522036 : Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1489 522036 : if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
1490 : return Type::NonInternal();
1491 : }
1492 31364 : JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1493 31364 : if (!function.shared().HasBuiltinId()) {
1494 : return Type::NonInternal();
1495 : }
1496 9748 : switch (function.shared().builtin_id()) {
1497 : case Builtins::kMathRandom:
1498 : return Type::PlainNumber();
1499 : case Builtins::kMathFloor:
1500 : case Builtins::kMathCeil:
1501 : case Builtins::kMathRound:
1502 : case Builtins::kMathTrunc:
1503 12 : return t->cache_->kIntegerOrMinusZeroOrNaN;
1504 : // Unary math functions.
1505 : case Builtins::kMathAbs:
1506 : case Builtins::kMathExp:
1507 6 : return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1508 : case Builtins::kMathAcos:
1509 : case Builtins::kMathAcosh:
1510 : case Builtins::kMathAsin:
1511 : case Builtins::kMathAsinh:
1512 : case Builtins::kMathAtan:
1513 : case Builtins::kMathAtanh:
1514 : case Builtins::kMathCbrt:
1515 : case Builtins::kMathCos:
1516 : case Builtins::kMathExpm1:
1517 : case Builtins::kMathFround:
1518 : case Builtins::kMathLog:
1519 : case Builtins::kMathLog1p:
1520 : case Builtins::kMathLog10:
1521 : case Builtins::kMathLog2:
1522 : case Builtins::kMathSin:
1523 : case Builtins::kMathSqrt:
1524 : case Builtins::kMathTan:
1525 : return Type::Number();
1526 : case Builtins::kMathSign:
1527 1 : return t->cache_->kMinusOneToOneOrMinusZeroOrNaN;
1528 : // Binary math functions.
1529 : case Builtins::kMathAtan2:
1530 : case Builtins::kMathPow:
1531 : case Builtins::kMathMax:
1532 : case Builtins::kMathMin:
1533 : return Type::Number();
1534 : case Builtins::kMathImul:
1535 : return Type::Signed32();
1536 : case Builtins::kMathClz32:
1537 7 : return t->cache_->kZeroToThirtyTwo;
1538 : // Date functions.
1539 : case Builtins::kDateNow:
1540 0 : return t->cache_->kTimeValueType;
1541 : case Builtins::kDatePrototypeGetDate:
1542 8 : return t->cache_->kJSDateDayType;
1543 : case Builtins::kDatePrototypeGetDay:
1544 8 : return t->cache_->kJSDateWeekdayType;
1545 : case Builtins::kDatePrototypeGetFullYear:
1546 8 : return t->cache_->kJSDateYearType;
1547 : case Builtins::kDatePrototypeGetHours:
1548 8 : return t->cache_->kJSDateHourType;
1549 : case Builtins::kDatePrototypeGetMilliseconds:
1550 : return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
1551 8 : t->zone());
1552 : case Builtins::kDatePrototypeGetMinutes:
1553 8 : return t->cache_->kJSDateMinuteType;
1554 : case Builtins::kDatePrototypeGetMonth:
1555 8 : return t->cache_->kJSDateMonthType;
1556 : case Builtins::kDatePrototypeGetSeconds:
1557 8 : return t->cache_->kJSDateSecondType;
1558 : case Builtins::kDatePrototypeGetTime:
1559 0 : return t->cache_->kJSDateValueType;
1560 :
1561 : // Symbol functions.
1562 : case Builtins::kSymbolConstructor:
1563 : return Type::Symbol();
1564 : case Builtins::kSymbolPrototypeToString:
1565 : return Type::String();
1566 : case Builtins::kSymbolPrototypeValueOf:
1567 : return Type::Symbol();
1568 :
1569 : // BigInt functions.
1570 : case Builtins::kBigIntConstructor:
1571 : return Type::BigInt();
1572 :
1573 : // Number functions.
1574 : case Builtins::kNumberConstructor:
1575 : return Type::Number();
1576 : case Builtins::kNumberIsFinite:
1577 : case Builtins::kNumberIsInteger:
1578 : case Builtins::kNumberIsNaN:
1579 : case Builtins::kNumberIsSafeInteger:
1580 : return Type::Boolean();
1581 : case Builtins::kNumberParseFloat:
1582 : return Type::Number();
1583 : case Builtins::kNumberParseInt:
1584 1 : return t->cache_->kIntegerOrMinusZeroOrNaN;
1585 : case Builtins::kNumberToString:
1586 : return Type::String();
1587 :
1588 : // String functions.
1589 : case Builtins::kStringConstructor:
1590 : return Type::String();
1591 : case Builtins::kStringPrototypeCharCodeAt:
1592 : return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
1593 115 : t->zone());
1594 : case Builtins::kStringCharAt:
1595 : return Type::String();
1596 : case Builtins::kStringPrototypeCodePointAt:
1597 : return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
1598 108 : Type::Undefined(), t->zone());
1599 : case Builtins::kStringPrototypeConcat:
1600 : case Builtins::kStringFromCharCode:
1601 : case Builtins::kStringFromCodePoint:
1602 : return Type::String();
1603 : case Builtins::kStringPrototypeIndexOf:
1604 : case Builtins::kStringPrototypeLastIndexOf:
1605 47 : return Type::Range(-1.0, String::kMaxLength, t->zone());
1606 : case Builtins::kStringPrototypeEndsWith:
1607 : case Builtins::kStringPrototypeIncludes:
1608 : return Type::Boolean();
1609 : case Builtins::kStringRaw:
1610 : case Builtins::kStringRepeat:
1611 : case Builtins::kStringPrototypeSlice:
1612 : return Type::String();
1613 : case Builtins::kStringPrototypeStartsWith:
1614 : return Type::Boolean();
1615 : case Builtins::kStringPrototypeSubstr:
1616 : case Builtins::kStringSubstring:
1617 : case Builtins::kStringPrototypeToString:
1618 : #ifdef V8_INTL_SUPPORT
1619 : case Builtins::kStringPrototypeToLowerCaseIntl:
1620 : case Builtins::kStringPrototypeToUpperCaseIntl:
1621 : #else
1622 : case Builtins::kStringPrototypeToLowerCase:
1623 : case Builtins::kStringPrototypeToUpperCase:
1624 : #endif
1625 : case Builtins::kStringPrototypeTrim:
1626 : case Builtins::kStringPrototypeTrimEnd:
1627 : case Builtins::kStringPrototypeTrimStart:
1628 : case Builtins::kStringPrototypeValueOf:
1629 : return Type::String();
1630 :
1631 : case Builtins::kStringPrototypeIterator:
1632 : case Builtins::kStringIteratorPrototypeNext:
1633 : return Type::OtherObject();
1634 :
1635 : case Builtins::kArrayPrototypeEntries:
1636 : case Builtins::kArrayPrototypeKeys:
1637 : case Builtins::kArrayPrototypeValues:
1638 : case Builtins::kTypedArrayPrototypeEntries:
1639 : case Builtins::kTypedArrayPrototypeKeys:
1640 : case Builtins::kTypedArrayPrototypeValues:
1641 : case Builtins::kArrayIteratorPrototypeNext:
1642 : case Builtins::kMapIteratorPrototypeNext:
1643 : case Builtins::kSetIteratorPrototypeNext:
1644 : return Type::OtherObject();
1645 : case Builtins::kTypedArrayPrototypeToStringTag:
1646 : return Type::Union(Type::InternalizedString(), Type::Undefined(),
1647 2 : t->zone());
1648 :
1649 : // Array functions.
1650 : case Builtins::kArrayIsArray:
1651 : return Type::Boolean();
1652 : case Builtins::kArrayConcat:
1653 : return Type::Receiver();
1654 : case Builtins::kArrayEvery:
1655 : return Type::Boolean();
1656 : case Builtins::kArrayPrototypeFill:
1657 : case Builtins::kArrayFilter:
1658 : return Type::Receiver();
1659 : case Builtins::kArrayPrototypeFindIndex:
1660 28 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1661 : case Builtins::kArrayForEach:
1662 : return Type::Undefined();
1663 : case Builtins::kArrayIncludes:
1664 : return Type::Boolean();
1665 : case Builtins::kArrayIndexOf:
1666 61 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1667 : case Builtins::kArrayPrototypeJoin:
1668 : return Type::String();
1669 : case Builtins::kArrayPrototypeLastIndexOf:
1670 69 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1671 : case Builtins::kArrayMap:
1672 : return Type::Receiver();
1673 : case Builtins::kArrayPush:
1674 0 : return t->cache_->kPositiveSafeInteger;
1675 : case Builtins::kArrayPrototypeReverse:
1676 : case Builtins::kArrayPrototypeSlice:
1677 : return Type::Receiver();
1678 : case Builtins::kArraySome:
1679 : return Type::Boolean();
1680 : case Builtins::kArrayPrototypeSplice:
1681 : return Type::Receiver();
1682 : case Builtins::kArrayUnshift:
1683 0 : return t->cache_->kPositiveSafeInteger;
1684 :
1685 : // ArrayBuffer functions.
1686 : case Builtins::kArrayBufferIsView:
1687 : return Type::Boolean();
1688 :
1689 : // Object functions.
1690 : case Builtins::kObjectAssign:
1691 : return Type::Receiver();
1692 : case Builtins::kObjectCreate:
1693 : return Type::OtherObject();
1694 : case Builtins::kObjectIs:
1695 : case Builtins::kObjectPrototypeHasOwnProperty:
1696 : case Builtins::kObjectPrototypeIsPrototypeOf:
1697 : return Type::Boolean();
1698 : case Builtins::kObjectToString:
1699 : return Type::String();
1700 :
1701 : case Builtins::kPromiseAll:
1702 : return Type::Receiver();
1703 : case Builtins::kPromisePrototypeThen:
1704 : return Type::Receiver();
1705 : case Builtins::kPromiseRace:
1706 : return Type::Receiver();
1707 : case Builtins::kPromiseReject:
1708 : return Type::Receiver();
1709 : case Builtins::kPromiseResolveTrampoline:
1710 : return Type::Receiver();
1711 :
1712 : // RegExp functions.
1713 : case Builtins::kRegExpPrototypeCompile:
1714 : return Type::OtherObject();
1715 : case Builtins::kRegExpPrototypeExec:
1716 128 : return Type::Union(Type::Array(), Type::Null(), t->zone());
1717 : case Builtins::kRegExpPrototypeTest:
1718 : return Type::Boolean();
1719 : case Builtins::kRegExpPrototypeToString:
1720 : return Type::String();
1721 :
1722 : // Function functions.
1723 : case Builtins::kFunctionPrototypeBind:
1724 : return Type::BoundFunction();
1725 : case Builtins::kFunctionPrototypeHasInstance:
1726 : return Type::Boolean();
1727 :
1728 : // Global functions.
1729 : case Builtins::kGlobalDecodeURI:
1730 : case Builtins::kGlobalDecodeURIComponent:
1731 : case Builtins::kGlobalEncodeURI:
1732 : case Builtins::kGlobalEncodeURIComponent:
1733 : case Builtins::kGlobalEscape:
1734 : case Builtins::kGlobalUnescape:
1735 : return Type::String();
1736 : case Builtins::kGlobalIsFinite:
1737 : case Builtins::kGlobalIsNaN:
1738 : return Type::Boolean();
1739 :
1740 : // Map functions.
1741 : case Builtins::kMapPrototypeClear:
1742 : case Builtins::kMapPrototypeForEach:
1743 : return Type::Undefined();
1744 : case Builtins::kMapPrototypeDelete:
1745 : case Builtins::kMapPrototypeHas:
1746 : return Type::Boolean();
1747 : case Builtins::kMapPrototypeEntries:
1748 : case Builtins::kMapPrototypeKeys:
1749 : case Builtins::kMapPrototypeSet:
1750 : case Builtins::kMapPrototypeValues:
1751 : return Type::OtherObject();
1752 :
1753 : // Set functions.
1754 : case Builtins::kSetPrototypeAdd:
1755 : case Builtins::kSetPrototypeEntries:
1756 : case Builtins::kSetPrototypeValues:
1757 : return Type::OtherObject();
1758 : case Builtins::kSetPrototypeClear:
1759 : case Builtins::kSetPrototypeForEach:
1760 : return Type::Undefined();
1761 : case Builtins::kSetPrototypeDelete:
1762 : case Builtins::kSetPrototypeHas:
1763 : return Type::Boolean();
1764 :
1765 : // WeakMap functions.
1766 : case Builtins::kWeakMapPrototypeDelete:
1767 : case Builtins::kWeakMapPrototypeHas:
1768 : return Type::Boolean();
1769 : case Builtins::kWeakMapPrototypeSet:
1770 : return Type::OtherObject();
1771 :
1772 : // WeakSet functions.
1773 : case Builtins::kWeakSetPrototypeAdd:
1774 : return Type::OtherObject();
1775 : case Builtins::kWeakSetPrototypeDelete:
1776 : case Builtins::kWeakSetPrototypeHas:
1777 : return Type::Boolean();
1778 : default:
1779 : return Type::NonInternal();
1780 : }
1781 : }
1782 :
1783 : Type Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1784 380 : return TypeUnaryOp(node, JSCallTyper);
1785 : }
1786 :
1787 : Type Typer::Visitor::TypeJSCall(Node* node) {
1788 : // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1789 : // argument types for the JSCallTyper above.
1790 520454 : return TypeUnaryOp(node, JSCallTyper);
1791 : }
1792 :
1793 : Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1794 379 : return TypeUnaryOp(node, JSCallTyper);
1795 : }
1796 :
1797 : Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1798 897 : return TypeUnaryOp(node, JSCallTyper);
1799 : }
1800 :
1801 369041 : Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1802 369041 : switch (CallRuntimeParametersOf(node->op()).id()) {
1803 : case Runtime::kInlineIsJSReceiver:
1804 0 : return TypeUnaryOp(node, ObjectIsReceiver);
1805 : case Runtime::kInlineIsSmi:
1806 0 : return TypeUnaryOp(node, ObjectIsSmi);
1807 : case Runtime::kInlineIsArray:
1808 : case Runtime::kInlineIsTypedArray:
1809 : case Runtime::kInlineIsRegExp:
1810 : return Type::Boolean();
1811 : case Runtime::kInlineCreateIterResultObject:
1812 : return Type::OtherObject();
1813 : case Runtime::kInlineToLength:
1814 0 : return TypeUnaryOp(node, ToLength);
1815 : case Runtime::kInlineToNumber:
1816 0 : return TypeUnaryOp(node, ToNumber);
1817 : case Runtime::kInlineToObject:
1818 0 : return TypeUnaryOp(node, ToObject);
1819 : case Runtime::kInlineToString:
1820 0 : return TypeUnaryOp(node, ToString);
1821 : case Runtime::kHasInPrototypeChain:
1822 : return Type::Boolean();
1823 : default:
1824 : break;
1825 : }
1826 : // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
1827 : // have a few weird runtime calls that return the hole or even FixedArrays;
1828 : // change this once those weird runtime calls have been removed.
1829 : return Type::Any();
1830 : }
1831 :
1832 : Type Typer::Visitor::TypeJSForInEnumerate(Node* node) {
1833 : return Type::OtherInternal();
1834 : }
1835 :
1836 : Type Typer::Visitor::TypeJSForInNext(Node* node) {
1837 3127 : return Type::Union(Type::String(), Type::Undefined(), zone());
1838 : }
1839 :
1840 1376 : Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1841 : STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1842 : Type const cache_type =
1843 1376 : Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1844 1376 : Type const cache_array = Type::OtherInternal();
1845 1376 : Type const cache_length = typer_->cache_->kFixedArrayLengthType;
1846 1376 : return Type::Tuple(cache_type, cache_array, cache_length, zone());
1847 : }
1848 :
1849 : Type Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1850 :
1851 0 : Type Typer::Visitor::TypeJSStoreMessage(Node* node) { UNREACHABLE(); }
1852 :
1853 : Type Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1854 :
1855 0 : Type Typer::Visitor::TypeJSStoreModule(Node* node) { UNREACHABLE(); }
1856 :
1857 0 : Type Typer::Visitor::TypeJSGeneratorStore(Node* node) { UNREACHABLE(); }
1858 :
1859 : Type Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1860 : return Type::SignedSmall();
1861 : }
1862 :
1863 : Type Typer::Visitor::TypeJSGeneratorRestoreContext(Node* node) {
1864 : return Type::Any();
1865 : }
1866 :
1867 : Type Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1868 : return Type::Any();
1869 : }
1870 :
1871 : Type Typer::Visitor::TypeJSGeneratorRestoreInputOrDebugPos(Node* node) {
1872 : return Type::Any();
1873 : }
1874 :
1875 : Type Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1876 :
1877 : Type Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1878 :
1879 : Type Typer::Visitor::TypeJSAsyncFunctionEnter(Node* node) {
1880 : return Type::OtherObject();
1881 : }
1882 :
1883 : Type Typer::Visitor::TypeJSAsyncFunctionReject(Node* node) {
1884 : return Type::OtherObject();
1885 : }
1886 :
1887 : Type Typer::Visitor::TypeJSAsyncFunctionResolve(Node* node) {
1888 : return Type::OtherObject();
1889 : }
1890 :
1891 : Type Typer::Visitor::TypeJSFulfillPromise(Node* node) {
1892 : return Type::Undefined();
1893 : }
1894 :
1895 : Type Typer::Visitor::TypeJSPerformPromiseThen(Node* node) {
1896 : return Type::Receiver();
1897 : }
1898 :
1899 : Type Typer::Visitor::TypeJSPromiseResolve(Node* node) {
1900 : return Type::Receiver();
1901 : }
1902 :
1903 : Type Typer::Visitor::TypeJSRejectPromise(Node* node) {
1904 : return Type::Undefined();
1905 : }
1906 :
1907 : Type Typer::Visitor::TypeJSResolvePromise(Node* node) {
1908 : return Type::Undefined();
1909 : }
1910 :
1911 : // Simplified operators.
1912 :
1913 : Type Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1914 :
1915 : // static
1916 30413 : Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1917 30413 : return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
1918 : }
1919 :
1920 : // static
1921 122492 : Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1922 : return FalsifyUndefined(
1923 244997 : NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
1924 : }
1925 :
1926 : // static
1927 4288 : Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1928 : return FalsifyUndefined(
1929 8576 : Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
1930 : }
1931 :
1932 : Type Typer::Visitor::TypeNumberEqual(Node* node) {
1933 14271 : return TypeBinaryOp(node, NumberEqualTyper);
1934 : }
1935 :
1936 : Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1937 32286 : return TypeBinaryOp(node, NumberLessThanTyper);
1938 : }
1939 :
1940 : Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1941 2690 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1942 : }
1943 :
1944 : Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1945 18712 : return TypeBinaryOp(node, NumberEqualTyper);
1946 : }
1947 :
1948 : Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1949 130933 : return TypeBinaryOp(node, NumberLessThanTyper);
1950 : }
1951 :
1952 : Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1953 2043 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1954 : }
1955 :
1956 : Type Typer::Visitor::TypeStringConcat(Node* node) { return Type::String(); }
1957 :
1958 : Type Typer::Visitor::TypeStringToNumber(Node* node) {
1959 0 : return TypeUnaryOp(node, ToNumber);
1960 : }
1961 :
1962 : Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1963 2232 : return TypeUnaryOp(node, ToNumber);
1964 : }
1965 :
1966 : Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1967 : return Type::Integral32();
1968 : }
1969 :
1970 : Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1971 : return Type::Number();
1972 : }
1973 :
1974 : // static
1975 251656 : Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
1976 267693 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1977 5626 : return t->singleton_true_;
1978 : }
1979 : return Type::Boolean();
1980 : }
1981 :
1982 : Type Typer::Visitor::TypeReferenceEqual(Node* node) {
1983 253127 : return TypeBinaryOp(node, ReferenceEqualTyper);
1984 : }
1985 :
1986 : // static
1987 311 : Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
1988 311 : return t->operation_typer()->SameValue(lhs, rhs);
1989 : }
1990 :
1991 : // static
1992 199 : Type Typer::Visitor::SameValueNumbersOnlyTyper(Type lhs, Type rhs, Typer* t) {
1993 199 : return t->operation_typer()->SameValueNumbersOnly(lhs, rhs);
1994 : }
1995 :
1996 : Type Typer::Visitor::TypeSameValue(Node* node) {
1997 311 : return TypeBinaryOp(node, SameValueTyper);
1998 : }
1999 :
2000 : Type Typer::Visitor::TypeSameValueNumbersOnly(Node* node) {
2001 206 : return TypeBinaryOp(node, SameValueNumbersOnlyTyper);
2002 : }
2003 :
2004 0 : Type Typer::Visitor::TypeNumberSameValue(Node* node) { UNREACHABLE(); }
2005 :
2006 : Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
2007 :
2008 : Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
2009 :
2010 : Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
2011 : return Type::Boolean();
2012 : }
2013 :
2014 1462 : Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
2015 1462 : return Type::String();
2016 : }
2017 :
2018 225 : Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
2019 225 : return Type::String();
2020 : }
2021 :
2022 : Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
2023 : return Type::String();
2024 : }
2025 :
2026 : Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
2027 : return Type::String();
2028 : }
2029 :
2030 : Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2031 2823 : return typer_->cache_->kUint16;
2032 : }
2033 :
2034 : Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2035 367 : return Type::Range(0.0, String::kMaxCodePoint, zone());
2036 : }
2037 :
2038 : Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2039 1597 : return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2040 : }
2041 :
2042 : Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2043 313 : return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2044 : }
2045 :
2046 : Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2047 291 : return Type::Range(-1.0, String::kMaxLength, zone());
2048 : }
2049 :
2050 : Type Typer::Visitor::TypeStringLength(Node* node) {
2051 56989 : return typer_->cache_->kStringLengthType;
2052 : }
2053 :
2054 : Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
2055 :
2056 2978 : Type Typer::Visitor::TypePoisonIndex(Node* node) {
2057 5956 : return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone());
2058 : }
2059 :
2060 71264 : Type Typer::Visitor::TypeCheckBounds(Node* node) {
2061 71264 : return typer_->operation_typer_.CheckBounds(Operand(node, 0),
2062 71264 : Operand(node, 1));
2063 : }
2064 :
2065 : Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
2066 : Type type = Operand(node, 0);
2067 : return type;
2068 : }
2069 :
2070 0 : Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
2071 :
2072 3597 : Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
2073 3597 : Type arg = Operand(node, 0);
2074 3597 : return Type::Intersect(arg, Type::InternalizedString(), zone());
2075 : }
2076 :
2077 0 : Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
2078 :
2079 : Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
2080 :
2081 3211 : Type Typer::Visitor::TypeCheckNumber(Node* node) {
2082 3211 : return typer_->operation_typer_.CheckNumber(Operand(node, 0));
2083 : }
2084 :
2085 881 : Type Typer::Visitor::TypeCheckReceiver(Node* node) {
2086 881 : Type arg = Operand(node, 0);
2087 881 : return Type::Intersect(arg, Type::Receiver(), zone());
2088 : }
2089 :
2090 72 : Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2091 72 : Type arg = Operand(node, 0);
2092 72 : return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone());
2093 : }
2094 :
2095 46204 : Type Typer::Visitor::TypeCheckSmi(Node* node) {
2096 46204 : Type arg = Operand(node, 0);
2097 46204 : return Type::Intersect(arg, Type::SignedSmall(), zone());
2098 : }
2099 :
2100 24738 : Type Typer::Visitor::TypeCheckString(Node* node) {
2101 24738 : Type arg = Operand(node, 0);
2102 24738 : return Type::Intersect(arg, Type::String(), zone());
2103 : }
2104 :
2105 32 : Type Typer::Visitor::TypeCheckSymbol(Node* node) {
2106 32 : Type arg = Operand(node, 0);
2107 32 : return Type::Intersect(arg, Type::Symbol(), zone());
2108 : }
2109 :
2110 651 : Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2111 651 : return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2112 : }
2113 :
2114 144 : Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
2115 : Type type = Operand(node, 0);
2116 144 : type = Type::Intersect(type, Type::NonInternal(), zone());
2117 144 : return type;
2118 : }
2119 :
2120 79952 : Type Typer::Visitor::TypeConvertReceiver(Node* node) {
2121 79952 : Type arg = Operand(node, 0);
2122 79952 : return typer_->operation_typer_.ConvertReceiver(arg);
2123 : }
2124 :
2125 2528 : Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
2126 2528 : Type type = Operand(node, 0);
2127 5056 : return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2128 : }
2129 :
2130 0 : Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2131 0 : UNREACHABLE();
2132 : }
2133 :
2134 0 : Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2135 :
2136 : Type Typer::Visitor::TypeAllocate(Node* node) {
2137 141352 : return AllocateTypeOf(node->op());
2138 : }
2139 :
2140 0 : Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2141 :
2142 : Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2143 : return Type::NonInternal();
2144 : }
2145 :
2146 : Type Typer::Visitor::TypeLoadField(Node* node) {
2147 1074436 : return FieldAccessOf(node->op()).type;
2148 : }
2149 :
2150 : Type Typer::Visitor::TypeLoadMessage(Node* node) { return Type::Any(); }
2151 :
2152 : Type Typer::Visitor::TypeLoadElement(Node* node) {
2153 24926 : return ElementAccessOf(node->op()).type;
2154 : }
2155 :
2156 : Type Typer::Visitor::TypeLoadStackArgument(Node* node) {
2157 : return Type::NonInternal();
2158 : }
2159 :
2160 5803 : Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2161 5803 : switch (ExternalArrayTypeOf(node->op())) {
2162 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2163 : case kExternal##ElemType##Array: \
2164 : return typer_->cache_->k##ElemType;
2165 604 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2166 : #undef TYPED_ARRAY_CASE
2167 : }
2168 0 : UNREACHABLE();
2169 : }
2170 :
2171 282 : Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
2172 282 : switch (ExternalArrayTypeOf(node->op())) {
2173 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2174 : case kExternal##ElemType##Array: \
2175 : return typer_->cache_->k##ElemType;
2176 39 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2177 : #undef TYPED_ARRAY_CASE
2178 : }
2179 0 : UNREACHABLE();
2180 : }
2181 :
2182 0 : Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2183 0 : Type Typer::Visitor::TypeStoreMessage(Node* node) { UNREACHABLE(); }
2184 :
2185 0 : Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2186 :
2187 0 : Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2188 0 : UNREACHABLE();
2189 : }
2190 :
2191 0 : Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2192 0 : UNREACHABLE();
2193 : }
2194 :
2195 0 : Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2196 0 : UNREACHABLE();
2197 : }
2198 :
2199 0 : Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2200 :
2201 0 : Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2202 :
2203 0 : Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }
2204 :
2205 : Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2206 16 : return TypeUnaryOp(node, ObjectIsArrayBufferView);
2207 : }
2208 :
2209 : Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2210 27 : return TypeUnaryOp(node, ObjectIsBigInt);
2211 : }
2212 :
2213 : Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2214 2006 : return TypeUnaryOp(node, ObjectIsCallable);
2215 : }
2216 :
2217 : Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2218 465 : return TypeUnaryOp(node, ObjectIsConstructor);
2219 : }
2220 :
2221 : Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2222 17649 : return TypeUnaryOp(node, ObjectIsDetectableCallable);
2223 : }
2224 :
2225 : Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2226 0 : return TypeUnaryOp(node, ObjectIsMinusZero);
2227 : }
2228 :
2229 : Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
2230 0 : return TypeUnaryOp(node, NumberIsMinusZero);
2231 : }
2232 :
2233 : Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2234 : return Type::Boolean();
2235 : }
2236 :
2237 : Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2238 :
2239 : Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2240 : return Type::Boolean();
2241 : }
2242 :
2243 0 : Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2244 :
2245 : Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2246 : return Type::Boolean();
2247 : }
2248 :
2249 0 : Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2250 :
2251 : Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2252 :
2253 : Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2254 4608 : return TypeUnaryOp(node, ObjectIsNaN);
2255 : }
2256 :
2257 : Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2258 5774 : return TypeUnaryOp(node, NumberIsNaN);
2259 : }
2260 :
2261 : Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2262 9209 : return TypeUnaryOp(node, ObjectIsNonCallable);
2263 : }
2264 :
2265 : Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2266 10639 : return TypeUnaryOp(node, ObjectIsNumber);
2267 : }
2268 :
2269 : Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2270 27613 : return TypeUnaryOp(node, ObjectIsReceiver);
2271 : }
2272 :
2273 : Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2274 1809 : return TypeUnaryOp(node, ObjectIsSmi);
2275 : }
2276 :
2277 : Type Typer::Visitor::TypeObjectIsString(Node* node) {
2278 2482 : return TypeUnaryOp(node, ObjectIsString);
2279 : }
2280 :
2281 : Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2282 123 : return TypeUnaryOp(node, ObjectIsSymbol);
2283 : }
2284 :
2285 : Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2286 1932 : return TypeUnaryOp(node, ObjectIsUndetectable);
2287 : }
2288 :
2289 : Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2290 17747 : return TypeCache::Get()->kArgumentsLengthType;
2291 : }
2292 :
2293 : Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2294 : return Type::ExternalPointer();
2295 : }
2296 :
2297 : Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2298 : return Type::OtherInternal();
2299 : }
2300 :
2301 : Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2302 : return Type::OtherInternal();
2303 : }
2304 :
2305 : Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2306 : return Type::OtherInternal();
2307 : }
2308 :
2309 : Type Typer::Visitor::TypeNewConsString(Node* node) { return Type::String(); }
2310 :
2311 : Type Typer::Visitor::TypeDelayedStringConstant(Node* node) {
2312 : return Type::String();
2313 : }
2314 :
2315 : Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2316 181 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2317 : }
2318 :
2319 : Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2320 0 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2321 : }
2322 :
2323 0 : Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2324 :
2325 : // Heap constants.
2326 :
2327 0 : Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2328 6010889 : return Type::NewConstant(typer_->broker(), value, zone());
2329 : }
2330 :
2331 : } // namespace compiler
2332 : } // namespace internal
2333 122036 : } // namespace v8
|