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 464157 : explicit Decorator(Typer* typer) : typer_(typer) {}
30 : void Decorate(Node* node) final;
31 :
32 : private:
33 : Typer* const typer_;
34 : };
35 :
36 464160 : Typer::Typer(JSHeapBroker* broker, Flags flags, Graph* graph)
37 : : flags_(flags),
38 : graph_(graph),
39 : decorator_(nullptr),
40 464160 : cache_(TypeCache::Get()),
41 : broker_(broker),
42 928320 : operation_typer_(broker, zone()) {
43 464158 : singleton_false_ = operation_typer_.singleton_false();
44 464158 : singleton_true_ = operation_typer_.singleton_true();
45 :
46 464157 : decorator_ = new (zone()) Decorator(this);
47 464157 : graph_->AddDecorator(decorator_);
48 464158 : }
49 :
50 :
51 928318 : Typer::~Typer() {
52 464159 : graph_->RemoveDecorator(decorator_);
53 464159 : }
54 :
55 :
56 10629265 : class Typer::Visitor : public Reducer {
57 : public:
58 5314621 : explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
59 : : typer_(typer),
60 : induction_vars_(induction_vars),
61 : weakened_nodes_(typer->zone()),
62 10629190 : remembered_types_(typer->zone()) {}
63 :
64 0 : const char* reducer_name() const override { return "Typer"; }
65 :
66 37813820 : Reduction Reduce(Node* node) override {
67 37813820 : if (node->op()->ValueOutputCount() == 0) return NoChange();
68 27618916 : switch (node->opcode()) {
69 : #define DECLARE_CASE(x) \
70 : case IrOpcode::k##x: \
71 : return UpdateType(node, TypeBinaryOp(node, x##Typer));
72 18380 : 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 463669 : DECLARE_CASE(Start)
79 213535 : DECLARE_CASE(IfException)
80 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
81 2002306 : COMMON_OP_LIST(DECLARE_CASE)
82 375358 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
83 1247113 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
84 334633 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
85 78 : JS_OBJECT_OP_LIST(DECLARE_CASE)
86 308370 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
87 516565 : 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 16289 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
94 115700 : 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 576 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
101 96264 : 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 4850786 : Type TypeNode(Node* node) {
137 4850786 : 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 1151475 : COMMON_OP_LIST(DECLARE_CASE)
148 0 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
149 61863 : 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 6371 : 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 120675 : 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 643 : 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 8408368 : : Type::None();
223 : }
224 :
225 : Type Operand(Node* node, int i) {
226 8390142 : 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 63689 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
279 94325 : 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 572850 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
286 477439 : 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 27618527 : Reduction UpdateType(Node* node, Type current) {
325 27618527 : if (NodeProperties::IsTyped(node)) {
326 : // Widen the type of a previously typed node.
327 5978229 : Type previous = NodeProperties::GetType(node);
328 5978229 : if (node->opcode() == IrOpcode::kPhi ||
329 : node->opcode() == IrOpcode::kInductionVariablePhi) {
330 : // Speed up termination in the presence of range types:
331 558677 : current = Weaken(node, current, previous);
332 : }
333 :
334 5978234 : 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 5978234 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
372 23480 : for (int i = 0; i < 2; ++i) {
373 9392 : Node* input = NodeProperties::GetValueInput(node, i);
374 9392 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
375 : ? NodeProperties::GetType(input)
376 9392 : : Type::Invalid();
377 : }
378 4696 : remembered_types_[{node, 2}] = current;
379 : }
380 :
381 : NodeProperties::SetType(node, current);
382 5978225 : if (!current.Is(previous)) {
383 : // If something changed, revisit all uses.
384 : return Changed(node);
385 : }
386 : return NoChange();
387 : } else {
388 21640298 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
389 57965 : for (int i = 0; i < 2; ++i) {
390 23186 : Node* input = NodeProperties::GetValueInput(node, i);
391 23186 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
392 : ? NodeProperties::GetType(input)
393 23186 : : Type::Invalid();
394 : }
395 11593 : 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 463904 : void Typer::Run(const NodeVector& roots,
408 : LoopVariableOptimizer* induction_vars) {
409 463904 : if (induction_vars != nullptr) {
410 463657 : induction_vars->ChangeToInductionVariablePhis();
411 : }
412 927809 : Visitor visitor(this, induction_vars);
413 927809 : GraphReducer graph_reducer(zone(), graph());
414 463906 : graph_reducer.AddReducer(&visitor);
415 6777456 : for (Node* const root : roots) graph_reducer.ReduceNode(root);
416 463904 : graph_reducer.ReduceGraph();
417 :
418 463905 : if (induction_vars != nullptr) {
419 463657 : induction_vars->ChangeToPhisAndInsertGuards();
420 : }
421 463906 : }
422 :
423 6582734 : void Typer::Decorator::Decorate(Node* node) {
424 6582734 : 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 4907439 : if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
429 9701422 : Visitor typing(typer_, nullptr);
430 4850673 : Type type = typing.TypeNode(node);
431 4850695 : if (is_typed) {
432 : type = Type::Intersect(type, NodeProperties::GetType(node),
433 0 : typer_->zone());
434 : }
435 : NodeProperties::SetType(node, type);
436 : }
437 : }
438 6582761 : }
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 1254975 : Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
448 : Type input = Operand(node, 0);
449 1254975 : return input.IsNone() ? Type::None() : f(input, typer_);
450 : }
451 :
452 1916074 : Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
453 : Type left = Operand(node, 0);
454 : Type right = Operand(node, 1);
455 1793078 : return left.IsNone() || right.IsNone() ? Type::None()
456 3702116 : : f(left, right, typer_);
457 : }
458 :
459 189137 : Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
460 : BinaryTyperFun f) {
461 189137 : lhs = ToNumeric(lhs, t);
462 189137 : rhs = ToNumeric(rhs, t);
463 : bool lhs_is_number = lhs.Is(Type::Number());
464 : bool rhs_is_number = rhs.Is(Type::Number());
465 189137 : if (lhs_is_number && rhs_is_number) {
466 145600 : return f(lhs, rhs, t);
467 : }
468 : // In order to maintain monotonicity, the following two conditions are
469 : // intentionally asymmetric.
470 43537 : if (lhs_is_number) {
471 : return Type::Number();
472 : }
473 32200 : 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 11966 : if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
483 11966 : if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
484 11966 : if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
485 0 : return result;
486 : }
487 :
488 0 : Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
489 376036 : if ((outcome & kComparisonFalse) != 0 ||
490 : (outcome & kComparisonUndefined) != 0) {
491 : return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
492 350478 : : 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 6271 : Type Typer::Visitor::Decrement(Type type, Typer* t) {
508 6271 : type = ToNumeric(type, t);
509 6271 : if (type.Is(Type::Number())) {
510 3798 : return NumberSubtract(type, t->cache_->kSingletonOne, t);
511 : }
512 : return Type::Numeric();
513 : }
514 :
515 262027 : Type Typer::Visitor::Increment(Type type, Typer* t) {
516 262027 : type = ToNumeric(type, t);
517 262027 : if (type.Is(Type::Number())) {
518 251584 : return NumberAdd(type, t->cache_->kSingletonOne, t);
519 : }
520 : return Type::Numeric();
521 : }
522 :
523 4398 : Type Typer::Visitor::Negate(Type type, Typer* t) {
524 4398 : type = ToNumeric(type, t);
525 4398 : 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 913251 : Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
534 913251 : if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
535 735059 : return type;
536 : }
537 : return Type::Primitive();
538 : }
539 :
540 137855 : Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
541 137855 : return t->operation_typer()->ToBoolean(type);
542 : }
543 :
544 :
545 : // static
546 113 : Type Typer::Visitor::ToInteger(Type type, Typer* t) {
547 : // ES6 section 7.1.4 ToInteger ( argument )
548 113 : type = ToNumber(type, t);
549 226 : if (type.Is(t->cache_->kIntegerOrMinusZero)) return type;
550 166 : if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
551 : return Type::Union(
552 3 : Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()),
553 3 : t->cache_->kSingletonZero, t->zone());
554 : }
555 80 : return t->cache_->kIntegerOrMinusZero;
556 : }
557 :
558 :
559 : // static
560 113 : Type Typer::Visitor::ToLength(Type type, Typer* t) {
561 : // ES6 section 7.1.15 ToLength ( argument )
562 113 : type = ToInteger(type, t);
563 113 : if (type.IsNone()) return type;
564 104 : double min = type.Min();
565 104 : double max = type.Max();
566 104 : if (max <= 0.0) {
567 6 : return Type::NewConstant(0, t->zone());
568 : }
569 98 : if (min >= kMaxSafeInteger) {
570 1 : return Type::NewConstant(kMaxSafeInteger, t->zone());
571 : }
572 97 : if (min <= 0.0) min = 0.0;
573 97 : if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
574 97 : return Type::Range(min, max, t->zone());
575 : }
576 :
577 :
578 : // static
579 1253 : Type Typer::Visitor::ToName(Type type, Typer* t) {
580 : // ES6 section 7.1.14 ToPropertyKey ( argument )
581 1253 : type = ToPrimitive(type, t);
582 1253 : if (type.Is(Type::Name())) return type;
583 1190 : if (type.Maybe(Type::Symbol())) return Type::Name();
584 96 : return ToString(type, t);
585 : }
586 :
587 :
588 : // static
589 11784 : Type Typer::Visitor::ToNumber(Type type, Typer* t) {
590 175105 : 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 49286 : Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
600 1168926 : return t->operation_typer_.ToNumeric(type);
601 : }
602 :
603 : // static
604 2035 : Type Typer::Visitor::ToObject(Type type, Typer* t) {
605 : // ES6 section 7.1.13 ToObject ( argument )
606 2035 : if (type.Is(Type::Receiver())) return type;
607 1564 : if (type.Is(Type::Primitive())) return Type::OtherObject();
608 1454 : if (!type.Maybe(Type::OtherUndetectable())) {
609 : return Type::DetectableReceiver();
610 : }
611 : return Type::Receiver();
612 : }
613 :
614 :
615 : // static
616 2558 : Type Typer::Visitor::ToString(Type type, Typer* t) {
617 : // ES6 section 7.1.12 ToString ( argument )
618 2558 : type = ToPrimitive(type, t);
619 2558 : 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 1996 : Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
638 1996 : if (type.Is(Type::Callable())) return t->singleton_true_;
639 317 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
640 : return Type::Boolean();
641 : }
642 :
643 415 : Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
644 : // TODO(turbofan): Introduce a Type::Constructor?
645 415 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
646 : return Type::Boolean();
647 : }
648 :
649 17453 : Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
650 17453 : if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
651 17341 : 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 4588 : Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
668 4588 : if (type.Is(Type::NaN())) return t->singleton_true_;
669 4581 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
670 : return Type::Boolean();
671 : }
672 :
673 5113 : Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
674 5113 : if (type.Is(Type::NaN())) return t->singleton_true_;
675 4520 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
676 : return Type::Boolean();
677 : }
678 :
679 9065 : Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
680 9065 : if (type.Is(Type::NonCallable())) return t->singleton_true_;
681 8741 : if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
682 : return Type::Boolean();
683 : }
684 :
685 10473 : Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
686 10473 : if (type.Is(Type::Number())) return t->singleton_true_;
687 8986 : if (!type.Maybe(Type::Number())) return t->singleton_false_;
688 : return Type::Boolean();
689 : }
690 :
691 26563 : Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
692 26563 : if (type.Is(Type::Receiver())) return t->singleton_true_;
693 24206 : if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
694 : return Type::Boolean();
695 : }
696 :
697 1509 : Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
698 1509 : if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
699 : return Type::Boolean();
700 : }
701 :
702 2467 : Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
703 2467 : if (type.Is(Type::String())) return t->singleton_true_;
704 2457 : if (!type.Maybe(Type::String())) return t->singleton_false_;
705 : return Type::Boolean();
706 : }
707 :
708 100 : Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
709 100 : if (type.Is(Type::Symbol())) return t->singleton_true_;
710 100 : if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
711 : return Type::Boolean();
712 : }
713 :
714 1879 : Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
715 1879 : if (type.Is(Type::Undetectable())) return t->singleton_true_;
716 1676 : 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 1998128 : Type Typer::Visitor::TypeParameter(Node* node) {
733 : Node* const start = node->InputAt(0);
734 : DCHECK_EQ(IrOpcode::kStart, start->opcode());
735 1998128 : int const parameter_count = start->op()->ValueOutputCount() - 4;
736 : DCHECK_LE(1, parameter_count);
737 1998128 : int const index = ParameterIndexOf(node->op());
738 1998131 : if (index == Linkage::kJSCallClosureParamIndex) {
739 : return Type::Function();
740 1971603 : } else if (index == 0) {
741 918008 : if (typer_->flags() & Typer::kThisIsReceiver) {
742 : return Type::Receiver();
743 : } else {
744 : // Parameter[this] can be the_hole for derived class constructors.
745 91420 : return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
746 : }
747 1512599 : } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
748 36068 : if (typer_->flags() & Typer::kNewTargetIsReceiver) {
749 : return Type::Receiver();
750 : } else {
751 16912 : return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
752 : }
753 1494565 : } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
754 0 : return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone());
755 1494565 : } 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 1772705 : double number = OpParameter<double>(node->op());
779 1772705 : return Type::NewConstant(number, zone());
780 : }
781 :
782 6008501 : Type Typer::Visitor::TypeHeapConstant(Node* node) {
783 12016984 : 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 18009 : Type Typer::Visitor::TypeSelect(Node* node) {
795 18009 : return Type::Union(Operand(node, 1), Operand(node, 2), zone());
796 : }
797 :
798 875324 : Type Typer::Visitor::TypePhi(Node* node) {
799 : int arity = node->op()->ValueInputCount();
800 : Type type = Operand(node, 0);
801 3664696 : for (int i = 1; i < arity; ++i) {
802 1394682 : type = Type::Union(type, Operand(node, i), zone());
803 : }
804 875301 : return type;
805 : }
806 :
807 24859 : Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
808 24859 : 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 24859 : Type initial_type = Operand(node, 0);
813 24859 : 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 68029 : if (!initial_type.Is(typer_->cache_->kInteger) ||
818 18311 : !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 6790 : : Type::None();
826 33950 : for (int i = 0; i < arity; ++i) {
827 13580 : type = Type::Union(type, Operand(node, i), zone());
828 : }
829 6790 : 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 36116 : if (initial_type.IsNone() ||
834 18047 : increment_type.Is(typer_->cache_->kSingletonZero)) {
835 37 : return initial_type;
836 : }
837 :
838 : // Now process the bounds.
839 18032 : auto res = induction_vars_->induction_variables().find(node->id());
840 : DCHECK(res != induction_vars_->induction_variables().end());
841 18032 : InductionVariable* induction_var = res->second;
842 :
843 : InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
844 :
845 18032 : double min = -V8_INFINITY;
846 18032 : double max = V8_INFINITY;
847 :
848 : double increment_min;
849 : double increment_max;
850 18032 : if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
851 17756 : increment_min = increment_type.Min();
852 17756 : increment_max = increment_type.Max();
853 : } else {
854 : DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
855 276 : increment_min = -increment_type.Max();
856 276 : increment_max = -increment_type.Min();
857 : }
858 :
859 18032 : if (increment_min >= 0) {
860 : // increasing sequence
861 17772 : min = initial_type.Min();
862 35620 : for (auto bound : induction_var->upper_bounds()) {
863 17876 : Type bound_type = TypeOrNone(bound.bound);
864 : // If the type is not an integer, just skip the bound.
865 37873 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
866 : // If the type is not inhabited, then we can take the initial value.
867 15757 : if (bound_type.IsNone()) {
868 29 : max = initial_type.Max();
869 29 : break;
870 : }
871 15728 : double bound_max = bound_type.Max();
872 15728 : if (bound.kind == InductionVariable::kStrict) {
873 15563 : bound_max -= 1;
874 : }
875 31456 : max = std::min(max, bound_max + increment_max);
876 : }
877 : // The upper bound must be at least the initial value's upper bound.
878 35545 : max = std::max(max, initial_type.Max());
879 260 : } else if (increment_max <= 0) {
880 : // decreasing sequence
881 260 : max = initial_type.Max();
882 578 : for (auto bound : induction_var->lower_bounds()) {
883 318 : Type bound_type = TypeOrNone(bound.bound);
884 : // If the type is not an integer, just skip the bound.
885 636 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
886 : // If the type is not inhabited, then we can take the initial value.
887 318 : if (bound_type.IsNone()) {
888 0 : min = initial_type.Min();
889 0 : break;
890 : }
891 318 : double bound_min = bound_type.Min();
892 318 : if (bound.kind == InductionVariable::kStrict) {
893 144 : bound_min += 1;
894 : }
895 636 : min = std::max(min, bound_min + increment_min);
896 : }
897 : // The lower bound must be at most the initial value's lower bound.
898 520 : 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 18032 : 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 18032 : 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 6051 : Type Typer::Visitor::TypeProjection(Node* node) {
976 6051 : Type const type = Operand(node, 0);
977 6051 : if (type.Is(Type::None())) return Type::None();
978 6051 : int const index = static_cast<int>(ProjectionIndexOf(node->op()));
979 6051 : 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 26832 : Type Typer::Visitor::TypeTypeGuard(Node* node) {
988 26832 : Type const type = Operand(node, 0);
989 53664 : 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 48769 : Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
1001 97365 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
1002 48596 : if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1003 0 : return t->singleton_true_;
1004 : }
1005 173098 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
1006 73173 : (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1007 2066 : return t->singleton_false_;
1008 : }
1009 47156 : 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 184537 : Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
1018 184537 : 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 238029 : Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
1026 : Type rhs,
1027 : Typer* t) {
1028 238029 : lhs = ToPrimitive(lhs, t);
1029 238029 : rhs = ToPrimitive(rhs, t);
1030 238029 : if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
1031 : return ComparisonOutcome(kComparisonTrue) |
1032 : ComparisonOutcome(kComparisonFalse);
1033 : }
1034 234252 : lhs = ToNumeric(lhs, t);
1035 234252 : rhs = ToNumeric(rhs, t);
1036 461041 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
1037 48802 : return NumberCompareTyper(lhs, rhs, t);
1038 : }
1039 : return ComparisonOutcome(kComparisonTrue) |
1040 : ComparisonOutcome(kComparisonFalse) |
1041 : ComparisonOutcome(kComparisonUndefined);
1042 : }
1043 :
1044 173679 : 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 347037 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
1052 :
1053 : ComparisonOutcome result;
1054 173035 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1055 : // Types are equal and are inhabited only by a single semantic value.
1056 : result = kComparisonFalse;
1057 173036 : } else if (lhs.Min() >= rhs.Max()) {
1058 : result = kComparisonFalse;
1059 170928 : } 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 14275 : if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1070 : result |= kComparisonUndefined;
1071 : }
1072 14276 : return result;
1073 : }
1074 :
1075 126142 : Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1076 252284 : return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
1077 : }
1078 :
1079 99921 : Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1080 199842 : return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1081 : }
1082 :
1083 3951 : Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1084 7902 : return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1085 : }
1086 :
1087 3689 : Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1088 7378 : return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1089 : }
1090 :
1091 : // JS bitwise operators.
1092 :
1093 11109 : Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1094 11109 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1095 : }
1096 :
1097 8840 : Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1098 8840 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1099 : }
1100 :
1101 1817 : Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1102 1817 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1103 : }
1104 :
1105 5171 : Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1106 5171 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1107 : }
1108 :
1109 3506 : Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1110 3506 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1111 : }
1112 :
1113 3572 : Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1114 3572 : return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1115 : }
1116 :
1117 :
1118 : // JS arithmetic operators.
1119 :
1120 216691 : Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1121 216691 : lhs = ToPrimitive(lhs, t);
1122 216691 : rhs = ToPrimitive(rhs, t);
1123 216691 : if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
1124 143701 : 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 9392 : Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1135 9392 : return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1136 : }
1137 :
1138 10756 : Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1139 10756 : return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1140 : }
1141 :
1142 14352 : Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1143 14352 : return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1144 : }
1145 :
1146 3435 : Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1147 3435 : 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 6427 : return TypeUnaryOp(node, Decrement);
1163 : }
1164 :
1165 : Type Typer::Visitor::TypeJSIncrement(Node* node) {
1166 263055 : return TypeUnaryOp(node, Increment);
1167 : }
1168 :
1169 : Type Typer::Visitor::TypeJSNegate(Node* node) {
1170 4402 : return TypeUnaryOp(node, Negate);
1171 : }
1172 :
1173 : Type Typer::Visitor::TypeTypeOf(Node* node) {
1174 : return Type::NonEmptyInternalizedOneByteString();
1175 : }
1176 :
1177 :
1178 : // JS conversion operators.
1179 :
1180 : Type Typer::Visitor::TypeToBoolean(Node* node) {
1181 143287 : 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 49367 : return TypeUnaryOp(node, ToNumeric);
1202 : }
1203 :
1204 : Type Typer::Visitor::TypeJSToObject(Node* node) {
1205 2068 : return TypeUnaryOp(node, ToObject);
1206 : }
1207 :
1208 : Type Typer::Visitor::TypeJSToString(Node* node) {
1209 2543 : return TypeUnaryOp(node, ToString);
1210 : }
1211 :
1212 : // JS object operators.
1213 :
1214 : Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1215 :
1216 19368 : Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1217 19368 : 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 558676 : 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 558676 : Type const integer = typer_->cache_->kInteger;
1343 558676 : if (!previous_type.Maybe(integer)) {
1344 42503 : return current_type;
1345 : }
1346 : DCHECK(current_type.Maybe(integer));
1347 :
1348 516178 : Type current_integer = Type::Intersect(current_type, integer, zone());
1349 516184 : Type previous_integer = Type::Intersect(previous_type, integer, zone());
1350 :
1351 : // Once we start weakening a node, we should always weaken.
1352 516180 : 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 101702 : Type previous = previous_integer.GetRange();
1357 101701 : Type current = current_integer.GetRange();
1358 203268 : if (current.IsInvalid() || previous.IsInvalid()) {
1359 353 : return current_type;
1360 : }
1361 : // Range is involved => we are weakening.
1362 : SetWeakened(node->id());
1363 : }
1364 :
1365 515823 : 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 515821 : if (current_min != previous_integer.Min()) {
1370 : new_min = -V8_INFINITY;
1371 2102466 : for (double const min : kWeakenMinLimits) {
1372 1049513 : if (min <= current_min) {
1373 : new_min = min;
1374 : break;
1375 : }
1376 : }
1377 : }
1378 :
1379 515819 : 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 515821 : if (current_max != previous_integer.Max()) {
1384 : new_max = V8_INFINITY;
1385 9120370 : for (double const max : kWeakenMaxLimits) {
1386 4697772 : 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 515819 : 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 822 : Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1421 822 : return Type::Boolean();
1422 : }
1423 :
1424 2936 : Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1425 2936 : return Type::Boolean();
1426 : }
1427 :
1428 170 : Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1429 170 : return Type::Boolean();
1430 : }
1431 :
1432 : Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1433 : return Type::Callable();
1434 : }
1435 :
1436 : // JS context operators.
1437 :
1438 308390 : Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1439 308390 : 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 521559 : Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1489 521559 : if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
1490 : return Type::NonInternal();
1491 : }
1492 31457 : JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1493 31457 : if (!function.shared().HasBuiltinId()) {
1494 : return Type::NonInternal();
1495 : }
1496 9798 : 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::NonEmptyOneByteString();
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::InternalizedOneByteString(), 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 381 : 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 519978 : return TypeUnaryOp(node, JSCallTyper);
1791 : }
1792 :
1793 : Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1794 382 : return TypeUnaryOp(node, JSCallTyper);
1795 : }
1796 :
1797 : Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1798 891 : return TypeUnaryOp(node, JSCallTyper);
1799 : }
1800 :
1801 370048 : Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1802 370048 : 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 3136 : return Type::Union(Type::String(), Type::Undefined(), zone());
1838 : }
1839 :
1840 1391 : Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1841 : STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1842 : Type const cache_type =
1843 1391 : Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1844 1391 : Type const cache_array = Type::OtherInternal();
1845 1391 : Type const cache_length = typer_->cache_->kFixedArrayLengthType;
1846 1391 : 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 30436 : Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1917 30436 : return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
1918 : }
1919 :
1920 : // static
1921 124874 : Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1922 : return FalsifyUndefined(
1923 249754 : NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
1924 : }
1925 :
1926 : // static
1927 4326 : Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1928 : return FalsifyUndefined(
1929 8652 : Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
1930 : }
1931 :
1932 : Type Typer::Visitor::TypeNumberEqual(Node* node) {
1933 14273 : return TypeBinaryOp(node, NumberEqualTyper);
1934 : }
1935 :
1936 : Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1937 34433 : return TypeBinaryOp(node, NumberLessThanTyper);
1938 : }
1939 :
1940 : Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1941 2657 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1942 : }
1943 :
1944 : Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1945 18736 : return TypeBinaryOp(node, NumberEqualTyper);
1946 : }
1947 :
1948 : Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1949 131196 : return TypeBinaryOp(node, NumberLessThanTyper);
1950 : }
1951 :
1952 : Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1953 2120 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1954 : }
1955 :
1956 26509 : Type Typer::Visitor::TypeStringConcat(Node* node) {
1957 26509 : Type length = Operand(node, 0);
1958 26509 : Type first = Operand(node, 1);
1959 26509 : Type second = Operand(node, 2);
1960 26509 : return typer_->operation_typer_.StringConcat(length, first, second);
1961 : }
1962 :
1963 : Type Typer::Visitor::TypeStringToNumber(Node* node) {
1964 0 : return TypeUnaryOp(node, ToNumber);
1965 : }
1966 :
1967 : Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1968 2235 : return TypeUnaryOp(node, ToNumber);
1969 : }
1970 :
1971 : Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1972 : return Type::Integral32();
1973 : }
1974 :
1975 : Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1976 : return Type::Number();
1977 : }
1978 :
1979 : // static
1980 251447 : Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
1981 267388 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1982 5577 : return t->singleton_true_;
1983 : }
1984 : return Type::Boolean();
1985 : }
1986 :
1987 : Type Typer::Visitor::TypeReferenceEqual(Node* node) {
1988 252928 : return TypeBinaryOp(node, ReferenceEqualTyper);
1989 : }
1990 :
1991 : // static
1992 310 : Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
1993 310 : return t->operation_typer()->SameValue(lhs, rhs);
1994 : }
1995 :
1996 : // static
1997 203 : Type Typer::Visitor::SameValueNumbersOnlyTyper(Type lhs, Type rhs, Typer* t) {
1998 203 : return t->operation_typer()->SameValueNumbersOnly(lhs, rhs);
1999 : }
2000 :
2001 : Type Typer::Visitor::TypeSameValue(Node* node) {
2002 310 : return TypeBinaryOp(node, SameValueTyper);
2003 : }
2004 :
2005 : Type Typer::Visitor::TypeSameValueNumbersOnly(Node* node) {
2006 210 : return TypeBinaryOp(node, SameValueNumbersOnlyTyper);
2007 : }
2008 :
2009 0 : Type Typer::Visitor::TypeNumberSameValue(Node* node) { UNREACHABLE(); }
2010 :
2011 : Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
2012 :
2013 : Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
2014 :
2015 : Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
2016 : return Type::Boolean();
2017 : }
2018 :
2019 1473 : Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
2020 1473 : return Type::NonEmptyString();
2021 : }
2022 :
2023 225 : Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
2024 225 : return Type::NonEmptyString();
2025 : }
2026 :
2027 : Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
2028 : return Type::String();
2029 : }
2030 :
2031 : Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
2032 : return Type::String();
2033 : }
2034 :
2035 : Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2036 2823 : return typer_->cache_->kUint16;
2037 : }
2038 :
2039 : Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2040 367 : return Type::Range(0.0, String::kMaxCodePoint, zone());
2041 : }
2042 :
2043 : Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2044 1609 : return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2045 : }
2046 :
2047 : Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2048 313 : return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2049 : }
2050 :
2051 : Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2052 291 : return Type::Range(-1.0, String::kMaxLength, zone());
2053 : }
2054 :
2055 : Type Typer::Visitor::TypeStringLength(Node* node) {
2056 56962 : return typer_->cache_->kStringLengthType;
2057 : }
2058 :
2059 : Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
2060 :
2061 2978 : Type Typer::Visitor::TypePoisonIndex(Node* node) {
2062 5956 : return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone());
2063 : }
2064 :
2065 71260 : Type Typer::Visitor::TypeCheckBounds(Node* node) {
2066 71260 : return typer_->operation_typer_.CheckBounds(Operand(node, 0),
2067 71260 : Operand(node, 1));
2068 : }
2069 :
2070 : Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
2071 : Type type = Operand(node, 0);
2072 : return type;
2073 : }
2074 :
2075 0 : Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
2076 :
2077 18 : Type Typer::Visitor::TypeCheckNonEmptyString(Node* node) {
2078 18 : return typer_->operation_typer_.CheckNonEmptyString(Operand(node, 0));
2079 : }
2080 :
2081 1795 : Type Typer::Visitor::TypeCheckNonEmptyOneByteString(Node* node) {
2082 1795 : return typer_->operation_typer_.CheckNonEmptyOneByteString(Operand(node, 0));
2083 : }
2084 :
2085 216 : Type Typer::Visitor::TypeCheckNonEmptyTwoByteString(Node* node) {
2086 216 : return typer_->operation_typer_.CheckNonEmptyTwoByteString(Operand(node, 0));
2087 : }
2088 :
2089 3628 : Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
2090 3628 : return typer_->operation_typer_.CheckInternalizedString(Operand(node, 0));
2091 : }
2092 :
2093 0 : Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
2094 :
2095 : Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
2096 :
2097 3231 : Type Typer::Visitor::TypeCheckNumber(Node* node) {
2098 3231 : return typer_->operation_typer_.CheckNumber(Operand(node, 0));
2099 : }
2100 :
2101 885 : Type Typer::Visitor::TypeCheckReceiver(Node* node) {
2102 885 : Type arg = Operand(node, 0);
2103 885 : return Type::Intersect(arg, Type::Receiver(), zone());
2104 : }
2105 :
2106 73 : Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2107 73 : Type arg = Operand(node, 0);
2108 73 : return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone());
2109 : }
2110 :
2111 47935 : Type Typer::Visitor::TypeCheckSmi(Node* node) {
2112 47935 : Type arg = Operand(node, 0);
2113 47935 : return Type::Intersect(arg, Type::SignedSmall(), zone());
2114 : }
2115 :
2116 23605 : Type Typer::Visitor::TypeCheckString(Node* node) {
2117 23605 : return typer_->operation_typer_.CheckString(Operand(node, 0));
2118 : }
2119 :
2120 32 : Type Typer::Visitor::TypeCheckSymbol(Node* node) {
2121 32 : Type arg = Operand(node, 0);
2122 32 : return Type::Intersect(arg, Type::Symbol(), zone());
2123 : }
2124 :
2125 654 : Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2126 654 : return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2127 : }
2128 :
2129 144 : Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
2130 : Type type = Operand(node, 0);
2131 144 : type = Type::Intersect(type, Type::NonInternal(), zone());
2132 144 : return type;
2133 : }
2134 :
2135 79931 : Type Typer::Visitor::TypeConvertReceiver(Node* node) {
2136 79931 : Type arg = Operand(node, 0);
2137 79931 : return typer_->operation_typer_.ConvertReceiver(arg);
2138 : }
2139 :
2140 2535 : Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
2141 2535 : Type type = Operand(node, 0);
2142 5070 : return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2143 : }
2144 :
2145 0 : Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2146 0 : UNREACHABLE();
2147 : }
2148 :
2149 0 : Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2150 :
2151 : Type Typer::Visitor::TypeAllocate(Node* node) {
2152 143015 : return AllocateTypeOf(node->op());
2153 : }
2154 :
2155 0 : Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2156 :
2157 : Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2158 : return Type::NonInternal();
2159 : }
2160 :
2161 : Type Typer::Visitor::TypeLoadField(Node* node) {
2162 1082830 : return FieldAccessOf(node->op()).type;
2163 : }
2164 :
2165 : Type Typer::Visitor::TypeLoadMessage(Node* node) { return Type::Any(); }
2166 :
2167 : Type Typer::Visitor::TypeLoadElement(Node* node) {
2168 25051 : return ElementAccessOf(node->op()).type;
2169 : }
2170 :
2171 : Type Typer::Visitor::TypeLoadStackArgument(Node* node) {
2172 : return Type::NonInternal();
2173 : }
2174 :
2175 5718 : Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2176 5718 : switch (ExternalArrayTypeOf(node->op())) {
2177 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2178 : case kExternal##ElemType##Array: \
2179 : return typer_->cache_->k##ElemType;
2180 573 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2181 : #undef TYPED_ARRAY_CASE
2182 : }
2183 0 : UNREACHABLE();
2184 : }
2185 :
2186 282 : Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
2187 282 : switch (ExternalArrayTypeOf(node->op())) {
2188 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2189 : case kExternal##ElemType##Array: \
2190 : return typer_->cache_->k##ElemType;
2191 39 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2192 : #undef TYPED_ARRAY_CASE
2193 : }
2194 0 : UNREACHABLE();
2195 : }
2196 :
2197 0 : Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2198 0 : Type Typer::Visitor::TypeStoreMessage(Node* node) { UNREACHABLE(); }
2199 :
2200 0 : Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2201 :
2202 0 : Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2203 0 : UNREACHABLE();
2204 : }
2205 :
2206 0 : Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2207 0 : UNREACHABLE();
2208 : }
2209 :
2210 0 : Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2211 0 : UNREACHABLE();
2212 : }
2213 :
2214 0 : Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2215 :
2216 0 : Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2217 :
2218 0 : Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }
2219 :
2220 : Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2221 16 : return TypeUnaryOp(node, ObjectIsArrayBufferView);
2222 : }
2223 :
2224 : Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2225 27 : return TypeUnaryOp(node, ObjectIsBigInt);
2226 : }
2227 :
2228 : Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2229 1996 : return TypeUnaryOp(node, ObjectIsCallable);
2230 : }
2231 :
2232 : Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2233 415 : return TypeUnaryOp(node, ObjectIsConstructor);
2234 : }
2235 :
2236 : Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2237 17618 : return TypeUnaryOp(node, ObjectIsDetectableCallable);
2238 : }
2239 :
2240 : Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2241 0 : return TypeUnaryOp(node, ObjectIsMinusZero);
2242 : }
2243 :
2244 : Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
2245 0 : return TypeUnaryOp(node, NumberIsMinusZero);
2246 : }
2247 :
2248 : Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2249 : return Type::Boolean();
2250 : }
2251 :
2252 : Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2253 :
2254 : Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2255 : return Type::Boolean();
2256 : }
2257 :
2258 0 : Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2259 :
2260 : Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2261 : return Type::Boolean();
2262 : }
2263 :
2264 0 : Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2265 :
2266 : Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2267 :
2268 : Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2269 4611 : return TypeUnaryOp(node, ObjectIsNaN);
2270 : }
2271 :
2272 : Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2273 5769 : return TypeUnaryOp(node, NumberIsNaN);
2274 : }
2275 :
2276 : Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2277 9211 : return TypeUnaryOp(node, ObjectIsNonCallable);
2278 : }
2279 :
2280 : Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2281 10662 : return TypeUnaryOp(node, ObjectIsNumber);
2282 : }
2283 :
2284 : Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2285 27560 : return TypeUnaryOp(node, ObjectIsReceiver);
2286 : }
2287 :
2288 : Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2289 1812 : return TypeUnaryOp(node, ObjectIsSmi);
2290 : }
2291 :
2292 : Type Typer::Visitor::TypeObjectIsString(Node* node) {
2293 2500 : return TypeUnaryOp(node, ObjectIsString);
2294 : }
2295 :
2296 : Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2297 123 : return TypeUnaryOp(node, ObjectIsSymbol);
2298 : }
2299 :
2300 : Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2301 1933 : return TypeUnaryOp(node, ObjectIsUndetectable);
2302 : }
2303 :
2304 : Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2305 17734 : return TypeCache::Get()->kArgumentsLengthType;
2306 : }
2307 :
2308 : Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2309 : return Type::ExternalPointer();
2310 : }
2311 :
2312 : Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2313 : return Type::OtherInternal();
2314 : }
2315 :
2316 : Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2317 : return Type::OtherInternal();
2318 : }
2319 :
2320 : Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2321 : return Type::OtherInternal();
2322 : }
2323 :
2324 0 : Type Typer::Visitor::TypeNewConsString(Node* node) { UNREACHABLE(); }
2325 :
2326 0 : Type Typer::Visitor::TypeNewConsOneByteString(Node* node) { UNREACHABLE(); }
2327 :
2328 0 : Type Typer::Visitor::TypeNewConsTwoByteString(Node* node) { UNREACHABLE(); }
2329 :
2330 : Type Typer::Visitor::TypeDelayedStringConstant(Node* node) {
2331 : return Type::String();
2332 : }
2333 :
2334 : Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2335 197 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2336 : }
2337 :
2338 : Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2339 0 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2340 : }
2341 :
2342 0 : Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2343 :
2344 : // Heap constants.
2345 :
2346 0 : Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2347 6008499 : return Type::NewConstant(typer_->broker(), value, zone());
2348 : }
2349 :
2350 : } // namespace compiler
2351 : } // namespace internal
2352 122028 : } // namespace v8
|