Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/compiler/typer.h"
6 :
7 : #include <iomanip>
8 :
9 : #include "src/base/flags.h"
10 : #include "src/bootstrapper.h"
11 : #include "src/compiler/common-operator.h"
12 : #include "src/compiler/graph-reducer.h"
13 : #include "src/compiler/js-operator.h"
14 : #include "src/compiler/linkage.h"
15 : #include "src/compiler/loop-variable-optimizer.h"
16 : #include "src/compiler/node-properties.h"
17 : #include "src/compiler/node.h"
18 : #include "src/compiler/operation-typer.h"
19 : #include "src/compiler/simplified-operator.h"
20 : #include "src/compiler/type-cache.h"
21 : #include "src/objects-inl.h"
22 : #include "src/objects/builtin-function-id.h"
23 :
24 : namespace v8 {
25 : namespace internal {
26 : namespace compiler {
27 :
28 0 : class Typer::Decorator final : public GraphDecorator {
29 : public:
30 457198 : explicit Decorator(Typer* typer) : typer_(typer) {}
31 : void Decorate(Node* node) final;
32 :
33 : private:
34 : Typer* const typer_;
35 : };
36 :
37 457199 : Typer::Typer(JSHeapBroker* broker, Flags flags, Graph* graph)
38 : : flags_(flags),
39 : graph_(graph),
40 : decorator_(nullptr),
41 457199 : cache_(TypeCache::Get()),
42 : broker_(broker),
43 1371597 : operation_typer_(broker, zone()) {
44 457199 : singleton_false_ = operation_typer_.singleton_false();
45 457199 : singleton_true_ = operation_typer_.singleton_true();
46 :
47 457198 : decorator_ = new (zone()) Decorator(this);
48 457198 : graph_->AddDecorator(decorator_);
49 457198 : }
50 :
51 :
52 457198 : Typer::~Typer() {
53 457198 : graph_->RemoveDecorator(decorator_);
54 457198 : }
55 :
56 :
57 5238923 : class Typer::Visitor : public Reducer {
58 : public:
59 5238927 : explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
60 : : typer_(typer),
61 : induction_vars_(induction_vars),
62 : weakened_nodes_(typer->zone()),
63 10477854 : remembered_types_(typer->zone()) {}
64 :
65 0 : const char* reducer_name() const override { return "Typer"; }
66 :
67 38719842 : Reduction Reduce(Node* node) override {
68 38710924 : if (node->op()->ValueOutputCount() == 0) return NoChange();
69 28378720 : switch (node->opcode()) {
70 : #define DECLARE_CASE(x) \
71 : case IrOpcode::k##x: \
72 : return UpdateType(node, TypeBinaryOp(node, x##Typer));
73 18321 : JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
74 : #undef DECLARE_CASE
75 :
76 : #define DECLARE_CASE(x) \
77 : case IrOpcode::k##x: \
78 : return UpdateType(node, Type##x(node));
79 456707 : DECLARE_CASE(Start)
80 206080 : DECLARE_CASE(IfException)
81 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
82 2215002 : COMMON_OP_LIST(DECLARE_CASE)
83 372490 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
84 1252403 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
85 328553 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
86 76 : JS_OBJECT_OP_LIST(DECLARE_CASE)
87 297010 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
88 512987 : JS_OTHER_OP_LIST(DECLARE_CASE)
89 : #undef DECLARE_CASE
90 :
91 : #define DECLARE_CASE(x) \
92 : case IrOpcode::k##x: \
93 : return UpdateType(node, TypeBinaryOp(node, x));
94 16361 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
95 116427 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
96 : #undef DECLARE_CASE
97 :
98 : #define DECLARE_CASE(x) \
99 : case IrOpcode::k##x: \
100 : return UpdateType(node, TypeUnaryOp(node, x));
101 563 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
102 94215 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
103 : #undef DECLARE_CASE
104 :
105 : #define DECLARE_CASE(x) case IrOpcode::k##x:
106 : DECLARE_CASE(Loop)
107 : DECLARE_CASE(Branch)
108 : DECLARE_CASE(IfTrue)
109 : DECLARE_CASE(IfFalse)
110 : DECLARE_CASE(IfSuccess)
111 : DECLARE_CASE(Switch)
112 : DECLARE_CASE(IfValue)
113 : DECLARE_CASE(IfDefault)
114 : DECLARE_CASE(Merge)
115 : DECLARE_CASE(Deoptimize)
116 : DECLARE_CASE(DeoptimizeIf)
117 : DECLARE_CASE(DeoptimizeUnless)
118 : DECLARE_CASE(TrapIf)
119 : DECLARE_CASE(TrapUnless)
120 : DECLARE_CASE(Return)
121 : DECLARE_CASE(TailCall)
122 : DECLARE_CASE(Terminate)
123 : DECLARE_CASE(OsrNormalEntry)
124 : DECLARE_CASE(OsrLoopEntry)
125 : DECLARE_CASE(Throw)
126 : DECLARE_CASE(End)
127 : SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
128 : SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
129 : MACHINE_SIMD_OP_LIST(DECLARE_CASE)
130 : MACHINE_OP_LIST(DECLARE_CASE)
131 : #undef DECLARE_CASE
132 : break;
133 : }
134 : return NoChange();
135 : }
136 :
137 4832680 : Type TypeNode(Node* node) {
138 4782013 : switch (node->opcode()) {
139 : #define DECLARE_CASE(x) \
140 : case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
141 1363 : JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
142 : #undef DECLARE_CASE
143 :
144 : #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
145 : DECLARE_CASE(Start)
146 : DECLARE_CASE(IfException)
147 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
148 1126587 : COMMON_OP_LIST(DECLARE_CASE)
149 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
150 35243 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
151 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
152 3 : JS_OBJECT_OP_LIST(DECLARE_CASE)
153 20 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
154 6347 : JS_OTHER_OP_LIST(DECLARE_CASE)
155 : #undef DECLARE_CASE
156 :
157 : #define DECLARE_CASE(x) \
158 : case IrOpcode::k##x: \
159 : return TypeBinaryOp(node, x);
160 120976 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
161 409 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
162 : #undef DECLARE_CASE
163 :
164 : #define DECLARE_CASE(x) \
165 : case IrOpcode::k##x: \
166 : return TypeUnaryOp(node, x);
167 8 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
168 633 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
169 : #undef DECLARE_CASE
170 :
171 : #define DECLARE_CASE(x) case IrOpcode::k##x:
172 : DECLARE_CASE(Loop)
173 : DECLARE_CASE(Branch)
174 : DECLARE_CASE(IfTrue)
175 : DECLARE_CASE(IfFalse)
176 : DECLARE_CASE(IfSuccess)
177 : DECLARE_CASE(Switch)
178 : DECLARE_CASE(IfValue)
179 : DECLARE_CASE(IfDefault)
180 : DECLARE_CASE(Merge)
181 : DECLARE_CASE(Deoptimize)
182 : DECLARE_CASE(DeoptimizeIf)
183 : DECLARE_CASE(DeoptimizeUnless)
184 : DECLARE_CASE(TrapIf)
185 : DECLARE_CASE(TrapUnless)
186 : DECLARE_CASE(Return)
187 : DECLARE_CASE(TailCall)
188 : DECLARE_CASE(Terminate)
189 : DECLARE_CASE(OsrNormalEntry)
190 : DECLARE_CASE(OsrLoopEntry)
191 : DECLARE_CASE(Throw)
192 : DECLARE_CASE(End)
193 : SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
194 : SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
195 : MACHINE_SIMD_OP_LIST(DECLARE_CASE)
196 : MACHINE_OP_LIST(DECLARE_CASE)
197 : #undef DECLARE_CASE
198 : break;
199 : }
200 0 : UNREACHABLE();
201 : }
202 :
203 : Type TypeConstant(Handle<Object> value);
204 :
205 : private:
206 : Typer* typer_;
207 : LoopVariableOptimizer* induction_vars_;
208 : ZoneSet<NodeId> weakened_nodes_;
209 : // TODO(tebbi): remove once chromium:906567 is resolved.
210 : ZoneUnorderedMap<std::pair<Node*, int>, Type> remembered_types_;
211 :
212 : #define DECLARE_METHOD(x) inline Type Type##x(Node* node);
213 : DECLARE_METHOD(Start)
214 : DECLARE_METHOD(IfException)
215 : COMMON_OP_LIST(DECLARE_METHOD)
216 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
217 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
218 : JS_OP_LIST(DECLARE_METHOD)
219 : #undef DECLARE_METHOD
220 :
221 : Type TypeOrNone(Node* node) {
222 : return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
223 8262188 : : Type::None();
224 : }
225 :
226 : Type Operand(Node* node, int i) {
227 8243324 : Node* operand_node = NodeProperties::GetValueInput(node, i);
228 : return TypeOrNone(operand_node);
229 : }
230 :
231 : Type Weaken(Node* node, Type current_type, Type previous_type);
232 :
233 : Zone* zone() { return typer_->zone(); }
234 : Graph* graph() { return typer_->graph(); }
235 :
236 : void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
237 : bool IsWeakened(NodeId node_id) {
238 : return weakened_nodes_.find(node_id) != weakened_nodes_.end();
239 : }
240 :
241 : typedef Type (*UnaryTyperFun)(Type, Typer* t);
242 : typedef Type (*BinaryTyperFun)(Type, Type, Typer* t);
243 :
244 : Type TypeUnaryOp(Node* node, UnaryTyperFun);
245 : Type TypeBinaryOp(Node* node, BinaryTyperFun);
246 :
247 : static Type BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
248 : BinaryTyperFun f);
249 :
250 : enum ComparisonOutcomeFlags {
251 : kComparisonTrue = 1,
252 : kComparisonFalse = 2,
253 : kComparisonUndefined = 4
254 : };
255 : typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;
256 :
257 : static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
258 : static Type FalsifyUndefined(ComparisonOutcome, Typer*);
259 :
260 : static Type BitwiseNot(Type, Typer*);
261 : static Type Decrement(Type, Typer*);
262 : static Type Increment(Type, Typer*);
263 : static Type Negate(Type, Typer*);
264 :
265 : static Type ToPrimitive(Type, Typer*);
266 : static Type ToBoolean(Type, Typer*);
267 : static Type ToInteger(Type, Typer*);
268 : static Type ToLength(Type, Typer*);
269 : static Type ToName(Type, Typer*);
270 : static Type ToNumber(Type, Typer*);
271 : static Type ToNumberConvertBigInt(Type, Typer*);
272 : static Type ToNumeric(Type, Typer*);
273 : static Type ToObject(Type, Typer*);
274 : static Type ToString(Type, Typer*);
275 : #define DECLARE_METHOD(Name) \
276 : static Type Name(Type type, Typer* t) { \
277 : return t->operation_typer_.Name(type); \
278 : }
279 72124 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
280 92317 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_METHOD)
281 : #undef DECLARE_METHOD
282 : #define DECLARE_METHOD(Name) \
283 : static Type Name(Type lhs, Type rhs, Typer* t) { \
284 : return t->operation_typer_.Name(lhs, rhs); \
285 : }
286 584571 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
287 476518 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
288 : #undef DECLARE_METHOD
289 :
290 : static Type ObjectIsArrayBufferView(Type, Typer*);
291 : static Type ObjectIsBigInt(Type, Typer*);
292 : static Type ObjectIsCallable(Type, Typer*);
293 : static Type ObjectIsConstructor(Type, Typer*);
294 : static Type ObjectIsDetectableCallable(Type, Typer*);
295 : static Type ObjectIsMinusZero(Type, Typer*);
296 : static Type NumberIsMinusZero(Type, Typer*);
297 : static Type ObjectIsNaN(Type, Typer*);
298 : static Type NumberIsNaN(Type, Typer*);
299 : static Type ObjectIsNonCallable(Type, Typer*);
300 : static Type ObjectIsNumber(Type, Typer*);
301 : static Type ObjectIsReceiver(Type, Typer*);
302 : static Type ObjectIsSmi(Type, Typer*);
303 : static Type ObjectIsString(Type, Typer*);
304 : static Type ObjectIsSymbol(Type, Typer*);
305 : static Type ObjectIsUndetectable(Type, Typer*);
306 :
307 : static ComparisonOutcome JSCompareTyper(Type, Type, Typer*);
308 : static ComparisonOutcome NumberCompareTyper(Type, Type, Typer*);
309 :
310 : #define DECLARE_METHOD(x) static Type x##Typer(Type, Type, Typer*);
311 : JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
312 : #undef DECLARE_METHOD
313 :
314 : static Type JSCallTyper(Type, Typer*);
315 :
316 : static Type NumberEqualTyper(Type, Type, Typer*);
317 : static Type NumberLessThanTyper(Type, Type, Typer*);
318 : static Type NumberLessThanOrEqualTyper(Type, Type, Typer*);
319 : static Type ReferenceEqualTyper(Type, Type, Typer*);
320 : static Type SameValueTyper(Type, Type, Typer*);
321 : static Type StringFromSingleCharCodeTyper(Type, Typer*);
322 : static Type StringFromSingleCodePointTyper(Type, Typer*);
323 :
324 28378544 : Reduction UpdateType(Node* node, Type current) {
325 62624482 : if (NodeProperties::IsTyped(node)) {
326 : // Widen the type of a previously typed node.
327 5867390 : Type previous = NodeProperties::GetType(node);
328 5867390 : if (node->opcode() == IrOpcode::kPhi ||
329 : node->opcode() == IrOpcode::kInductionVariablePhi) {
330 : // Speed up termination in the presence of range types:
331 552571 : current = Weaken(node, current, previous);
332 : }
333 :
334 5867394 : 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 5867394 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
372 9142 : for (int i = 0; i < 2; ++i) {
373 9142 : Node* input = NodeProperties::GetValueInput(node, i);
374 9142 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
375 : ? NodeProperties::GetType(input)
376 9142 : : Type::Invalid();
377 : }
378 4571 : remembered_types_[{node, 2}] = current;
379 : }
380 :
381 : NodeProperties::SetType(node, current);
382 5867386 : if (!current.Is(previous)) {
383 : // If something changed, revisit all uses.
384 : return Changed(node);
385 : }
386 : return NoChange();
387 : } else {
388 22511154 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
389 23580 : for (int i = 0; i < 2; ++i) {
390 23580 : Node* input = NodeProperties::GetValueInput(node, i);
391 23580 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
392 : ? NodeProperties::GetType(input)
393 23580 : : Type::Invalid();
394 : }
395 11790 : remembered_types_[{node, 2}] = current;
396 : }
397 :
398 : // No previous type, simply update the type.
399 : NodeProperties::SetType(node, current);
400 : return Changed(node);
401 : }
402 : }
403 : };
404 :
405 496 : void Typer::Run() { Run(NodeVector(zone()), nullptr); }
406 :
407 456943 : void Typer::Run(const NodeVector& roots,
408 456943 : LoopVariableOptimizer* induction_vars) {
409 456943 : if (induction_vars != nullptr) {
410 456695 : induction_vars->ChangeToInductionVariablePhis();
411 : }
412 456944 : Visitor visitor(this, induction_vars);
413 913884 : GraphReducer graph_reducer(zone(), graph());
414 456945 : graph_reducer.AddReducer(&visitor);
415 7138224 : for (Node* const root : roots) graph_reducer.ReduceNode(root);
416 456945 : graph_reducer.ReduceGraph();
417 :
418 456941 : if (induction_vars != nullptr) {
419 456694 : induction_vars->ChangeToPhisAndInsertGuards();
420 : }
421 456944 : }
422 :
423 6490086 : void Typer::Decorator::Decorate(Node* node) {
424 12980172 : 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 4838685 : if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
429 4781988 : Visitor typing(typer_, nullptr);
430 4781909 : Type type = typing.TypeNode(node);
431 4781980 : if (is_typed) {
432 : type = Type::Intersect(type, NodeProperties::GetType(node),
433 0 : typer_->zone());
434 : }
435 : NodeProperties::SetType(node, type);
436 : }
437 : }
438 6490103 : }
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 1255366 : Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
448 : Type input = Operand(node, 0);
449 1255366 : return input.IsNone() ? Type::None() : f(input, typer_);
450 : }
451 :
452 1913135 : Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
453 : Type left = Operand(node, 0);
454 : Type right = Operand(node, 1);
455 1788298 : return left.IsNone() || right.IsNone() ? Type::None()
456 3694635 : : f(left, right, typer_);
457 : }
458 :
459 200150 : Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
460 : BinaryTyperFun f) {
461 200150 : lhs = ToNumeric(lhs, t);
462 200150 : rhs = ToNumeric(rhs, t);
463 : bool lhs_is_number = lhs.Is(Type::Number());
464 : bool rhs_is_number = rhs.Is(Type::Number());
465 200150 : if (lhs_is_number && rhs_is_number) {
466 158680 : return f(lhs, rhs, t);
467 : }
468 : // In order to maintain monotonicity, the following two conditions are
469 : // intentionally asymmetric.
470 41470 : if (lhs_is_number) {
471 : return Type::Number();
472 : }
473 30372 : 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 11734 : if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
483 11734 : if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
484 11734 : if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
485 0 : return result;
486 : }
487 :
488 355614 : Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
489 369134 : if ((outcome & kComparisonFalse) != 0 ||
490 : (outcome & kComparisonUndefined) != 0) {
491 : return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
492 342805 : : t->singleton_false_;
493 : }
494 : // Type should be non empty, so we know it should be true.
495 : DCHECK_NE(0, outcome & kComparisonTrue);
496 12809 : return t->singleton_true_;
497 : }
498 :
499 165 : Type Typer::Visitor::BitwiseNot(Type type, Typer* t) {
500 165 : type = ToNumeric(type, t);
501 165 : if (type.Is(Type::Number())) {
502 34 : return NumberBitwiseXor(type, t->cache_->kSingletonMinusOne, t);
503 : }
504 : return Type::Numeric();
505 : }
506 :
507 6257 : Type Typer::Visitor::Decrement(Type type, Typer* t) {
508 6257 : type = ToNumeric(type, t);
509 6257 : if (type.Is(Type::Number())) {
510 3798 : return NumberSubtract(type, t->cache_->kSingletonOne, t);
511 : }
512 : return Type::Numeric();
513 : }
514 :
515 256339 : Type Typer::Visitor::Increment(Type type, Typer* t) {
516 256339 : type = ToNumeric(type, t);
517 256339 : if (type.Is(Type::Number())) {
518 247467 : return NumberAdd(type, t->cache_->kSingletonOne, t);
519 : }
520 : return Type::Numeric();
521 : }
522 :
523 4409 : Type Typer::Visitor::Negate(Type type, Typer* t) {
524 4409 : type = ToNumeric(type, t);
525 4409 : 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 889891 : Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
534 889891 : if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
535 724804 : return type;
536 : }
537 : return Type::Primitive();
538 : }
539 :
540 137607 : Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
541 137607 : return t->operation_typer()->ToBoolean(type);
542 : }
543 :
544 :
545 : // static
546 111 : Type Typer::Visitor::ToInteger(Type type, Typer* t) {
547 : // ES6 section 7.1.4 ToInteger ( argument )
548 111 : type = ToNumber(type, t);
549 222 : if (type.Is(t->cache_->kIntegerOrMinusZero)) return type;
550 160 : if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
551 : return Type::Union(
552 : Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()),
553 3 : t->cache_->kSingletonZero, t->zone());
554 : }
555 77 : return t->cache_->kIntegerOrMinusZero;
556 : }
557 :
558 :
559 : // static
560 111 : Type Typer::Visitor::ToLength(Type type, Typer* t) {
561 : // ES6 section 7.1.15 ToLength ( argument )
562 111 : type = ToInteger(type, t);
563 111 : if (type.IsNone()) return type;
564 101 : double min = type.Min();
565 101 : double max = type.Max();
566 101 : if (max <= 0.0) {
567 8 : return Type::NewConstant(0, t->zone());
568 : }
569 93 : if (min >= kMaxSafeInteger) {
570 1 : return Type::NewConstant(kMaxSafeInteger, t->zone());
571 : }
572 92 : if (min <= 0.0) min = 0.0;
573 92 : if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
574 92 : return Type::Range(min, max, t->zone());
575 : }
576 :
577 :
578 : // static
579 1235 : Type Typer::Visitor::ToName(Type type, Typer* t) {
580 : // ES6 section 7.1.14 ToPropertyKey ( argument )
581 1235 : type = ToPrimitive(type, t);
582 1235 : if (type.Is(Type::Name())) return type;
583 1171 : if (type.Maybe(Type::Symbol())) return Type::Name();
584 99 : return ToString(type, t);
585 : }
586 :
587 :
588 : // static
589 11878 : Type Typer::Visitor::ToNumber(Type type, Typer* t) {
590 177850 : 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 47811 : Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
600 1169907 : return t->operation_typer_.ToNumeric(type);
601 : }
602 :
603 : // static
604 2012 : Type Typer::Visitor::ToObject(Type type, Typer* t) {
605 : // ES6 section 7.1.13 ToObject ( argument )
606 2012 : if (type.Is(Type::Receiver())) return type;
607 1559 : if (type.Is(Type::Primitive())) return Type::OtherObject();
608 1450 : if (!type.Maybe(Type::OtherUndetectable())) {
609 : return Type::DetectableReceiver();
610 : }
611 : return Type::Receiver();
612 : }
613 :
614 :
615 : // static
616 2508 : Type Typer::Visitor::ToString(Type type, Typer* t) {
617 : // ES6 section 7.1.12 ToString ( argument )
618 2508 : type = ToPrimitive(type, t);
619 2508 : if (type.Is(Type::String())) return type;
620 : return Type::String();
621 : }
622 :
623 : // Type checks.
624 :
625 14 : Type Typer::Visitor::ObjectIsArrayBufferView(Type type, Typer* t) {
626 : // TODO(turbofan): Introduce a Type::ArrayBufferView?
627 14 : 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 1896 : Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
638 1896 : if (type.Is(Type::Callable())) return t->singleton_true_;
639 225 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
640 : return Type::Boolean();
641 : }
642 :
643 403 : Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
644 : // TODO(turbofan): Introduce a Type::Constructor?
645 403 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
646 : return Type::Boolean();
647 : }
648 :
649 17188 : Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
650 17188 : if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
651 17074 : 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 4595 : Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
668 4595 : 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 5233 : Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
674 5233 : if (type.Is(Type::NaN())) return t->singleton_true_;
675 4626 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
676 : return Type::Boolean();
677 : }
678 :
679 9048 : Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
680 9048 : if (type.Is(Type::NonCallable())) return t->singleton_true_;
681 8720 : if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
682 : return Type::Boolean();
683 : }
684 :
685 10392 : Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
686 10392 : if (type.Is(Type::Number())) return t->singleton_true_;
687 8888 : if (!type.Maybe(Type::Number())) return t->singleton_false_;
688 : return Type::Boolean();
689 : }
690 :
691 26781 : Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
692 26781 : if (type.Is(Type::Receiver())) return t->singleton_true_;
693 23614 : if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
694 : return Type::Boolean();
695 : }
696 :
697 1497 : Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
698 1497 : if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
699 : return Type::Boolean();
700 : }
701 :
702 3042 : Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
703 3042 : if (type.Is(Type::String())) return t->singleton_true_;
704 3031 : if (!type.Maybe(Type::String())) return t->singleton_false_;
705 : return Type::Boolean();
706 : }
707 :
708 93 : Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
709 93 : if (type.Is(Type::Symbol())) return t->singleton_true_;
710 93 : if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
711 : return Type::Boolean();
712 : }
713 :
714 1861 : Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
715 1861 : if (type.Is(Type::Undetectable())) return t->singleton_true_;
716 1659 : 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 3961450 : Type Typer::Visitor::TypeParameter(Node* node) {
733 1980725 : Node* const start = node->InputAt(0);
734 : DCHECK_EQ(IrOpcode::kStart, start->opcode());
735 3961450 : int const parameter_count = start->op()->ValueOutputCount() - 4;
736 : DCHECK_LE(1, parameter_count);
737 1980725 : int const index = ParameterIndexOf(node->op());
738 1980726 : if (index == Linkage::kJSCallClosureParamIndex) {
739 : return Type::Function();
740 1954294 : } else if (index == 0) {
741 903410 : if (typer_->flags() & Typer::kThisIsReceiver) {
742 : return Type::Receiver();
743 : } else {
744 : // Parameter[this] can be the_hole for derived class constructors.
745 89323 : return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
746 : }
747 1502589 : } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
748 36236 : if (typer_->flags() & Typer::kNewTargetIsReceiver) {
749 : return Type::Receiver();
750 : } else {
751 16741 : return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
752 : }
753 1484471 : } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
754 0 : return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone());
755 1484471 : } 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 2000233 : Type Typer::Visitor::TypeNumberConstant(Node* node) {
778 2000233 : double number = OpParameter<double>(node->op());
779 2000233 : return Type::NewConstant(number, zone());
780 : }
781 :
782 5923644 : Type Typer::Visitor::TypeHeapConstant(Node* node) {
783 11847276 : 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 17891 : Type Typer::Visitor::TypeSelect(Node* node) {
795 17891 : return Type::Union(Operand(node, 1), Operand(node, 2), zone());
796 : }
797 :
798 2231254 : Type Typer::Visitor::TypePhi(Node* node) {
799 869639 : int arity = node->op()->ValueInputCount();
800 : Type type = Operand(node, 0);
801 2231247 : for (int i = 1; i < arity; ++i) {
802 1361613 : type = Type::Union(type, Operand(node, i), zone());
803 : }
804 869632 : return type;
805 : }
806 :
807 58650 : Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
808 25790 : 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 25790 : Type initial_type = Operand(node, 0);
813 25790 : 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 70499 : if (!initial_type.Is(typer_->cache_->kInteger) ||
818 18919 : !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 7107 : : Type::None();
826 14214 : for (int i = 0; i < arity; ++i) {
827 14214 : type = Type::Union(type, Operand(node, i), zone());
828 : }
829 7107 : 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 37345 : if (initial_type.IsNone() ||
834 18662 : increment_type.Is(typer_->cache_->kSingletonZero)) {
835 37 : return initial_type;
836 : }
837 :
838 : // Now process the bounds.
839 37291 : auto res = induction_vars_->induction_variables().find(node->id());
840 : DCHECK(res != induction_vars_->induction_variables().end());
841 18645 : InductionVariable* induction_var = res->second;
842 :
843 : InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
844 :
845 18645 : double min = -V8_INFINITY;
846 18645 : double max = V8_INFINITY;
847 :
848 : double increment_min;
849 : double increment_max;
850 18645 : if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
851 18367 : increment_min = increment_type.Min();
852 18367 : 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 18645 : if (increment_min >= 0) {
860 : // increasing sequence
861 18383 : min = initial_type.Min();
862 55212 : for (auto bound : induction_var->upper_bounds()) {
863 18489 : Type bound_type = TypeOrNone(bound.bound);
864 : // If the type is not an integer, just skip the bound.
865 39084 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
866 : // If the type is not inhabited, then we can take the initial value.
867 16383 : if (bound_type.IsNone()) {
868 45 : max = initial_type.Max();
869 45 : break;
870 : }
871 16338 : double bound_max = bound_type.Max();
872 16338 : if (bound.kind == InductionVariable::kStrict) {
873 16173 : bound_max -= 1;
874 : }
875 32676 : max = std::min(max, bound_max + increment_max);
876 : }
877 : // The upper bound must be at least the initial value's upper bound.
878 36768 : max = std::max(max, initial_type.Max());
879 262 : } else if (increment_max <= 0) {
880 : // decreasing sequence
881 262 : max = initial_type.Max();
882 844 : 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 18646 : if (FLAG_trace_turbo_loop) {
905 0 : StdoutStream{} << std::setprecision(10) << "Loop ("
906 0 : << NodeProperties::GetControlInput(node)->id()
907 0 : << ") variable bounds in "
908 : << (arithmetic_type ==
909 : InductionVariable::ArithmeticType::kAddition
910 : ? "addition"
911 0 : : "subtraction")
912 0 : << " for phi " << node->id() << ": (" << min << ", " << max
913 0 : << ")\n";
914 : }
915 37292 : 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 12060 : Type Typer::Visitor::TypeProjection(Node* node) {
976 6030 : Type const type = Operand(node, 0);
977 6030 : if (type.Is(Type::None())) return Type::None();
978 6030 : int const index = static_cast<int>(ProjectionIndexOf(node->op()));
979 10182 : if (type.IsTuple() && index < type.AsTuple()->Arity()) {
980 4152 : return type.AsTuple()->Element(index);
981 : }
982 : return Type::Any();
983 : }
984 :
985 0 : Type Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
986 :
987 50664 : Type Typer::Visitor::TypeTypeGuard(Node* node) {
988 25332 : Type const type = Operand(node, 0);
989 25332 : 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 50261 : Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
1001 100351 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
1002 50085 : if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1003 0 : return t->singleton_true_;
1004 : }
1005 179536 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
1006 76570 : (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1007 2103 : return t->singleton_false_;
1008 : }
1009 48607 : 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 183366 : Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
1018 183366 : 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 231082 : Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
1026 : Type rhs,
1027 : Typer* t) {
1028 231082 : lhs = ToPrimitive(lhs, t);
1029 231082 : rhs = ToPrimitive(rhs, t);
1030 231082 : if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
1031 : return ComparisonOutcome(kComparisonTrue) |
1032 : ComparisonOutcome(kComparisonFalse);
1033 : }
1034 227313 : lhs = ToNumeric(lhs, t);
1035 227313 : rhs = ToNumeric(rhs, t);
1036 448083 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
1037 48895 : return NumberCompareTyper(lhs, rhs, t);
1038 : }
1039 : return ComparisonOutcome(kComparisonTrue) |
1040 : ComparisonOutcome(kComparisonFalse) |
1041 : ComparisonOutcome(kComparisonUndefined);
1042 : }
1043 :
1044 173429 : 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 346538 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
1052 :
1053 : ComparisonOutcome result;
1054 172782 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1055 : // Types are equal and are inhabited only by a single semantic value.
1056 : result = kComparisonFalse;
1057 172781 : } else if (lhs.Min() >= rhs.Max()) {
1058 : result = kComparisonFalse;
1059 170615 : } 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 14689 : if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1070 : result |= kComparisonUndefined;
1071 : }
1072 14689 : return result;
1073 : }
1074 :
1075 120350 : Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1076 120350 : return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
1077 : }
1078 :
1079 98998 : Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1080 98998 : return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1081 : }
1082 :
1083 3958 : Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1084 7916 : return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1085 : }
1086 :
1087 3393 : Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1088 6786 : return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1089 : }
1090 :
1091 : // JS bitwise operators.
1092 :
1093 12699 : Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1094 12699 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1095 : }
1096 :
1097 10544 : Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1098 10544 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1099 : }
1100 :
1101 3135 : Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1102 3135 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1103 : }
1104 :
1105 4725 : Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1106 4725 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1107 : }
1108 :
1109 4927 : Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1110 4927 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1111 : }
1112 :
1113 4900 : Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1114 4900 : return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1115 : }
1116 :
1117 :
1118 : // JS arithmetic operators.
1119 :
1120 211992 : Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1121 211992 : lhs = ToPrimitive(lhs, t);
1122 211992 : rhs = ToPrimitive(rhs, t);
1123 211992 : if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
1124 133500 : 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 122089 : return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1132 : }
1133 :
1134 9720 : Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1135 9720 : return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1136 : }
1137 :
1138 11139 : Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1139 11139 : return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1140 : }
1141 :
1142 16092 : Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1143 16092 : return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1144 : }
1145 :
1146 5080 : Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1147 5080 : return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
1148 : }
1149 :
1150 183 : Type Typer::Visitor::JSExponentiateTyper(Type lhs, Type rhs, Typer* t) {
1151 : // TODO(neis): Refine using BinaryNumberOpTyper?
1152 183 : return Type::Numeric();
1153 : }
1154 :
1155 : // JS unary operators.
1156 :
1157 : Type Typer::Visitor::TypeJSBitwiseNot(Node* node) {
1158 165 : return TypeUnaryOp(node, BitwiseNot);
1159 : }
1160 :
1161 : Type Typer::Visitor::TypeJSDecrement(Node* node) {
1162 6413 : return TypeUnaryOp(node, Decrement);
1163 : }
1164 :
1165 : Type Typer::Visitor::TypeJSIncrement(Node* node) {
1166 257356 : return TypeUnaryOp(node, Increment);
1167 : }
1168 :
1169 : Type Typer::Visitor::TypeJSNegate(Node* node) {
1170 4413 : 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 143360 : 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 1260 : return TypeUnaryOp(node, ToName);
1190 : }
1191 :
1192 : Type Typer::Visitor::TypeJSToNumber(Node* node) {
1193 9627 : 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 47891 : return TypeUnaryOp(node, ToNumeric);
1202 : }
1203 :
1204 : Type Typer::Visitor::TypeJSToObject(Node* node) {
1205 2047 : return TypeUnaryOp(node, ToObject);
1206 : }
1207 :
1208 : Type Typer::Visitor::TypeJSToString(Node* node) {
1209 2476 : return TypeUnaryOp(node, ToString);
1210 : }
1211 :
1212 : // JS object operators.
1213 :
1214 : Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1215 :
1216 19281 : Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1217 19281 : 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 2183973 : 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 552571 : Type const integer = typer_->cache_->kInteger;
1343 552571 : if (!previous_type.Maybe(integer)) {
1344 42595 : return current_type;
1345 : }
1346 : DCHECK(current_type.Maybe(integer));
1347 :
1348 509979 : Type current_integer = Type::Intersect(current_type, integer, zone());
1349 509978 : Type previous_integer = Type::Intersect(previous_type, integer, zone());
1350 :
1351 : // Once we start weakening a node, we should always weaken.
1352 509976 : 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 101845 : Type previous = previous_integer.GetRange();
1357 101845 : Type current = current_integer.GetRange();
1358 203534 : if (current.IsInvalid() || previous.IsInvalid()) {
1359 378 : return current_type;
1360 : }
1361 : // Range is involved => we are weakening.
1362 : SetWeakened(node->id());
1363 : }
1364 :
1365 509602 : 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 509602 : if (current_min != previous_integer.Min()) {
1370 : new_min = -V8_INFINITY;
1371 2074501 : for (double const min : kWeakenMinLimits) {
1372 1052325 : if (min <= current_min) {
1373 : new_min = min;
1374 : break;
1375 : }
1376 : }
1377 : }
1378 :
1379 509601 : 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 509601 : if (current_max != previous_integer.Max()) {
1384 : new_max = V8_INFINITY;
1385 8916630 : for (double const max : kWeakenMaxLimits) {
1386 4616936 : 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 1019200 : 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 855 : Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1421 855 : return Type::Boolean();
1422 : }
1423 :
1424 2801 : Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1425 2801 : return Type::Boolean();
1426 : }
1427 :
1428 214 : Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1429 214 : return Type::Boolean();
1430 : }
1431 :
1432 : Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1433 : return Type::Callable();
1434 : }
1435 :
1436 : // JS context operators.
1437 :
1438 297030 : Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1439 297030 : 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 521823 : Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1489 521823 : if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
1490 : return Type::NonInternal();
1491 : }
1492 32175 : JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1493 32175 : if (!function.shared().HasBuiltinFunctionId()) {
1494 : return Type::NonInternal();
1495 : }
1496 7427 : switch (function.shared().builtin_function_id()) {
1497 : case BuiltinFunctionId::kMathRandom:
1498 : return Type::PlainNumber();
1499 : case BuiltinFunctionId::kMathFloor:
1500 : case BuiltinFunctionId::kMathCeil:
1501 : case BuiltinFunctionId::kMathRound:
1502 : case BuiltinFunctionId::kMathTrunc:
1503 12 : return t->cache_->kIntegerOrMinusZeroOrNaN;
1504 : // Unary math functions.
1505 : case BuiltinFunctionId::kMathAbs:
1506 : case BuiltinFunctionId::kMathExp:
1507 6 : return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1508 : case BuiltinFunctionId::kMathAcos:
1509 : case BuiltinFunctionId::kMathAcosh:
1510 : case BuiltinFunctionId::kMathAsin:
1511 : case BuiltinFunctionId::kMathAsinh:
1512 : case BuiltinFunctionId::kMathAtan:
1513 : case BuiltinFunctionId::kMathAtanh:
1514 : case BuiltinFunctionId::kMathCbrt:
1515 : case BuiltinFunctionId::kMathCos:
1516 : case BuiltinFunctionId::kMathExpm1:
1517 : case BuiltinFunctionId::kMathFround:
1518 : case BuiltinFunctionId::kMathLog:
1519 : case BuiltinFunctionId::kMathLog1p:
1520 : case BuiltinFunctionId::kMathLog10:
1521 : case BuiltinFunctionId::kMathLog2:
1522 : case BuiltinFunctionId::kMathSin:
1523 : case BuiltinFunctionId::kMathSqrt:
1524 : case BuiltinFunctionId::kMathTan:
1525 : return Type::Number();
1526 : case BuiltinFunctionId::kMathSign:
1527 1 : return t->cache_->kMinusOneToOneOrMinusZeroOrNaN;
1528 : // Binary math functions.
1529 : case BuiltinFunctionId::kMathAtan2:
1530 : case BuiltinFunctionId::kMathPow:
1531 : case BuiltinFunctionId::kMathMax:
1532 : case BuiltinFunctionId::kMathMin:
1533 : return Type::Number();
1534 : case BuiltinFunctionId::kMathImul:
1535 : return Type::Signed32();
1536 : case BuiltinFunctionId::kMathClz32:
1537 9 : return t->cache_->kZeroToThirtyTwo;
1538 : // Date functions.
1539 : case BuiltinFunctionId::kDateNow:
1540 0 : return t->cache_->kTimeValueType;
1541 : case BuiltinFunctionId::kDateGetDate:
1542 0 : return t->cache_->kJSDateDayType;
1543 : case BuiltinFunctionId::kDateGetDay:
1544 0 : return t->cache_->kJSDateWeekdayType;
1545 : case BuiltinFunctionId::kDateGetFullYear:
1546 0 : return t->cache_->kJSDateYearType;
1547 : case BuiltinFunctionId::kDateGetHours:
1548 0 : return t->cache_->kJSDateHourType;
1549 : case BuiltinFunctionId::kDateGetMilliseconds:
1550 : return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
1551 0 : t->zone());
1552 : case BuiltinFunctionId::kDateGetMinutes:
1553 0 : return t->cache_->kJSDateMinuteType;
1554 : case BuiltinFunctionId::kDateGetMonth:
1555 0 : return t->cache_->kJSDateMonthType;
1556 : case BuiltinFunctionId::kDateGetSeconds:
1557 0 : return t->cache_->kJSDateSecondType;
1558 : case BuiltinFunctionId::kDateGetTime:
1559 0 : return t->cache_->kJSDateValueType;
1560 :
1561 : // Symbol functions.
1562 : case BuiltinFunctionId::kSymbolConstructor:
1563 : return Type::Symbol();
1564 : case BuiltinFunctionId::kSymbolPrototypeToString:
1565 : return Type::String();
1566 : case BuiltinFunctionId::kSymbolPrototypeValueOf:
1567 : return Type::Symbol();
1568 :
1569 : // BigInt functions.
1570 : case BuiltinFunctionId::kBigIntConstructor:
1571 : return Type::BigInt();
1572 :
1573 : // Number functions.
1574 : case BuiltinFunctionId::kNumberConstructor:
1575 : return Type::Number();
1576 : case BuiltinFunctionId::kNumberIsFinite:
1577 : case BuiltinFunctionId::kNumberIsInteger:
1578 : case BuiltinFunctionId::kNumberIsNaN:
1579 : case BuiltinFunctionId::kNumberIsSafeInteger:
1580 : return Type::Boolean();
1581 : case BuiltinFunctionId::kNumberParseFloat:
1582 : return Type::Number();
1583 : case BuiltinFunctionId::kNumberParseInt:
1584 1 : return t->cache_->kIntegerOrMinusZeroOrNaN;
1585 : case BuiltinFunctionId::kNumberToString:
1586 : return Type::String();
1587 :
1588 : // String functions.
1589 : case BuiltinFunctionId::kStringConstructor:
1590 : return Type::String();
1591 : case BuiltinFunctionId::kStringCharCodeAt:
1592 : return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
1593 115 : t->zone());
1594 : case BuiltinFunctionId::kStringCharAt:
1595 : return Type::String();
1596 : case BuiltinFunctionId::kStringCodePointAt:
1597 : return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
1598 108 : Type::Undefined(), t->zone());
1599 : case BuiltinFunctionId::kStringConcat:
1600 : case BuiltinFunctionId::kStringFromCharCode:
1601 : case BuiltinFunctionId::kStringFromCodePoint:
1602 : return Type::String();
1603 : case BuiltinFunctionId::kStringIndexOf:
1604 : case BuiltinFunctionId::kStringLastIndexOf:
1605 31 : return Type::Range(-1.0, String::kMaxLength, t->zone());
1606 : case BuiltinFunctionId::kStringEndsWith:
1607 : case BuiltinFunctionId::kStringIncludes:
1608 : return Type::Boolean();
1609 : case BuiltinFunctionId::kStringRaw:
1610 : case BuiltinFunctionId::kStringRepeat:
1611 : case BuiltinFunctionId::kStringSlice:
1612 : return Type::String();
1613 : case BuiltinFunctionId::kStringStartsWith:
1614 : return Type::Boolean();
1615 : case BuiltinFunctionId::kStringSubstr:
1616 : case BuiltinFunctionId::kStringSubstring:
1617 : case BuiltinFunctionId::kStringToLowerCase:
1618 : case BuiltinFunctionId::kStringToString:
1619 : case BuiltinFunctionId::kStringToUpperCase:
1620 : case BuiltinFunctionId::kStringTrim:
1621 : case BuiltinFunctionId::kStringTrimEnd:
1622 : case BuiltinFunctionId::kStringTrimStart:
1623 : case BuiltinFunctionId::kStringValueOf:
1624 : return Type::String();
1625 :
1626 : case BuiltinFunctionId::kStringIterator:
1627 : case BuiltinFunctionId::kStringIteratorNext:
1628 : return Type::OtherObject();
1629 :
1630 : case BuiltinFunctionId::kArrayEntries:
1631 : case BuiltinFunctionId::kArrayKeys:
1632 : case BuiltinFunctionId::kArrayValues:
1633 : case BuiltinFunctionId::kTypedArrayEntries:
1634 : case BuiltinFunctionId::kTypedArrayKeys:
1635 : case BuiltinFunctionId::kTypedArrayValues:
1636 : case BuiltinFunctionId::kArrayIteratorNext:
1637 : case BuiltinFunctionId::kMapIteratorNext:
1638 : case BuiltinFunctionId::kSetIteratorNext:
1639 : return Type::OtherObject();
1640 : case BuiltinFunctionId::kTypedArrayToStringTag:
1641 : return Type::Union(Type::InternalizedString(), Type::Undefined(),
1642 2 : t->zone());
1643 :
1644 : // Array functions.
1645 : case BuiltinFunctionId::kArrayIsArray:
1646 : return Type::Boolean();
1647 : case BuiltinFunctionId::kArrayConcat:
1648 : return Type::Receiver();
1649 : case BuiltinFunctionId::kArrayEvery:
1650 : return Type::Boolean();
1651 : case BuiltinFunctionId::kArrayFill:
1652 : case BuiltinFunctionId::kArrayFilter:
1653 : return Type::Receiver();
1654 : case BuiltinFunctionId::kArrayFindIndex:
1655 3 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1656 : case BuiltinFunctionId::kArrayForEach:
1657 : return Type::Undefined();
1658 : case BuiltinFunctionId::kArrayIncludes:
1659 : return Type::Boolean();
1660 : case BuiltinFunctionId::kArrayIndexOf:
1661 42 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1662 : case BuiltinFunctionId::kArrayJoin:
1663 : return Type::String();
1664 : case BuiltinFunctionId::kArrayLastIndexOf:
1665 60 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1666 : case BuiltinFunctionId::kArrayMap:
1667 : return Type::Receiver();
1668 : case BuiltinFunctionId::kArrayPush:
1669 2738 : return t->cache_->kPositiveSafeInteger;
1670 : case BuiltinFunctionId::kArrayReverse:
1671 : case BuiltinFunctionId::kArraySlice:
1672 : return Type::Receiver();
1673 : case BuiltinFunctionId::kArraySome:
1674 : return Type::Boolean();
1675 : case BuiltinFunctionId::kArraySplice:
1676 : return Type::Receiver();
1677 : case BuiltinFunctionId::kArrayUnshift:
1678 37 : return t->cache_->kPositiveSafeInteger;
1679 :
1680 : // ArrayBuffer functions.
1681 : case BuiltinFunctionId::kArrayBufferIsView:
1682 : return Type::Boolean();
1683 :
1684 : // Object functions.
1685 : case BuiltinFunctionId::kObjectAssign:
1686 : return Type::Receiver();
1687 : case BuiltinFunctionId::kObjectCreate:
1688 : return Type::OtherObject();
1689 : case BuiltinFunctionId::kObjectIs:
1690 : case BuiltinFunctionId::kObjectHasOwnProperty:
1691 : case BuiltinFunctionId::kObjectIsPrototypeOf:
1692 : return Type::Boolean();
1693 : case BuiltinFunctionId::kObjectToString:
1694 : return Type::String();
1695 :
1696 : case BuiltinFunctionId::kPromiseAll:
1697 : return Type::Receiver();
1698 : case BuiltinFunctionId::kPromisePrototypeThen:
1699 : return Type::Receiver();
1700 : case BuiltinFunctionId::kPromiseRace:
1701 : return Type::Receiver();
1702 : case BuiltinFunctionId::kPromiseReject:
1703 : return Type::Receiver();
1704 : case BuiltinFunctionId::kPromiseResolve:
1705 : return Type::Receiver();
1706 :
1707 : // RegExp functions.
1708 : case BuiltinFunctionId::kRegExpCompile:
1709 : return Type::OtherObject();
1710 : case BuiltinFunctionId::kRegExpExec:
1711 121 : return Type::Union(Type::Array(), Type::Null(), t->zone());
1712 : case BuiltinFunctionId::kRegExpTest:
1713 : return Type::Boolean();
1714 : case BuiltinFunctionId::kRegExpToString:
1715 : return Type::String();
1716 :
1717 : // Function functions.
1718 : case BuiltinFunctionId::kFunctionBind:
1719 : return Type::BoundFunction();
1720 : case BuiltinFunctionId::kFunctionHasInstance:
1721 : return Type::Boolean();
1722 :
1723 : // Global functions.
1724 : case BuiltinFunctionId::kGlobalDecodeURI:
1725 : case BuiltinFunctionId::kGlobalDecodeURIComponent:
1726 : case BuiltinFunctionId::kGlobalEncodeURI:
1727 : case BuiltinFunctionId::kGlobalEncodeURIComponent:
1728 : case BuiltinFunctionId::kGlobalEscape:
1729 : case BuiltinFunctionId::kGlobalUnescape:
1730 : return Type::String();
1731 : case BuiltinFunctionId::kGlobalIsFinite:
1732 : case BuiltinFunctionId::kGlobalIsNaN:
1733 : return Type::Boolean();
1734 :
1735 : // Map functions.
1736 : case BuiltinFunctionId::kMapClear:
1737 : case BuiltinFunctionId::kMapForEach:
1738 : return Type::Undefined();
1739 : case BuiltinFunctionId::kMapDelete:
1740 : case BuiltinFunctionId::kMapHas:
1741 : return Type::Boolean();
1742 : case BuiltinFunctionId::kMapEntries:
1743 : case BuiltinFunctionId::kMapKeys:
1744 : case BuiltinFunctionId::kMapSet:
1745 : case BuiltinFunctionId::kMapValues:
1746 : return Type::OtherObject();
1747 :
1748 : // Set functions.
1749 : case BuiltinFunctionId::kSetAdd:
1750 : case BuiltinFunctionId::kSetEntries:
1751 : case BuiltinFunctionId::kSetValues:
1752 : return Type::OtherObject();
1753 : case BuiltinFunctionId::kSetClear:
1754 : case BuiltinFunctionId::kSetForEach:
1755 : return Type::Undefined();
1756 : case BuiltinFunctionId::kSetDelete:
1757 : case BuiltinFunctionId::kSetHas:
1758 : return Type::Boolean();
1759 :
1760 : // WeakMap functions.
1761 : case BuiltinFunctionId::kWeakMapDelete:
1762 : case BuiltinFunctionId::kWeakMapHas:
1763 : return Type::Boolean();
1764 : case BuiltinFunctionId::kWeakMapSet:
1765 : return Type::OtherObject();
1766 :
1767 : // WeakSet functions.
1768 : case BuiltinFunctionId::kWeakSetAdd:
1769 : return Type::OtherObject();
1770 : case BuiltinFunctionId::kWeakSetDelete:
1771 : case BuiltinFunctionId::kWeakSetHas:
1772 : return Type::Boolean();
1773 : default:
1774 : return Type::NonInternal();
1775 : }
1776 : }
1777 :
1778 : Type Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1779 373 : return TypeUnaryOp(node, JSCallTyper);
1780 : }
1781 :
1782 : Type Typer::Visitor::TypeJSCall(Node* node) {
1783 : // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1784 : // argument types for the JSCallTyper above.
1785 520207 : return TypeUnaryOp(node, JSCallTyper);
1786 : }
1787 :
1788 : Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1789 396 : return TypeUnaryOp(node, JSCallTyper);
1790 : }
1791 :
1792 : Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1793 895 : return TypeUnaryOp(node, JSCallTyper);
1794 : }
1795 :
1796 355975 : Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1797 355975 : switch (CallRuntimeParametersOf(node->op()).id()) {
1798 : case Runtime::kInlineIsJSReceiver:
1799 0 : return TypeUnaryOp(node, ObjectIsReceiver);
1800 : case Runtime::kInlineIsSmi:
1801 0 : return TypeUnaryOp(node, ObjectIsSmi);
1802 : case Runtime::kInlineIsArray:
1803 : case Runtime::kInlineIsTypedArray:
1804 : case Runtime::kInlineIsRegExp:
1805 : return Type::Boolean();
1806 : case Runtime::kInlineCreateIterResultObject:
1807 : return Type::OtherObject();
1808 : case Runtime::kInlineToLength:
1809 0 : return TypeUnaryOp(node, ToLength);
1810 : case Runtime::kInlineToNumber:
1811 0 : return TypeUnaryOp(node, ToNumber);
1812 : case Runtime::kInlineToObject:
1813 0 : return TypeUnaryOp(node, ToObject);
1814 : case Runtime::kInlineToString:
1815 0 : return TypeUnaryOp(node, ToString);
1816 : case Runtime::kHasInPrototypeChain:
1817 : return Type::Boolean();
1818 : default:
1819 : break;
1820 : }
1821 : // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
1822 : // have a few weird runtime calls that return the hole or even FixedArrays;
1823 : // change this once those weird runtime calls have been removed.
1824 : return Type::Any();
1825 : }
1826 :
1827 : Type Typer::Visitor::TypeJSForInEnumerate(Node* node) {
1828 : return Type::OtherInternal();
1829 : }
1830 :
1831 3133 : Type Typer::Visitor::TypeJSForInNext(Node* node) {
1832 3133 : return Type::Union(Type::String(), Type::Undefined(), zone());
1833 : }
1834 :
1835 1384 : Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1836 : STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1837 : Type const cache_type =
1838 1384 : Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1839 1384 : Type const cache_array = Type::OtherInternal();
1840 1384 : Type const cache_length = typer_->cache_->kFixedArrayLengthType;
1841 1384 : return Type::Tuple(cache_type, cache_array, cache_length, zone());
1842 : }
1843 :
1844 : Type Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1845 :
1846 0 : Type Typer::Visitor::TypeJSStoreMessage(Node* node) { UNREACHABLE(); }
1847 :
1848 : Type Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1849 :
1850 0 : Type Typer::Visitor::TypeJSStoreModule(Node* node) { UNREACHABLE(); }
1851 :
1852 0 : Type Typer::Visitor::TypeJSGeneratorStore(Node* node) { UNREACHABLE(); }
1853 :
1854 : Type Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1855 : return Type::SignedSmall();
1856 : }
1857 :
1858 : Type Typer::Visitor::TypeJSGeneratorRestoreContext(Node* node) {
1859 : return Type::Any();
1860 : }
1861 :
1862 : Type Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1863 : return Type::Any();
1864 : }
1865 :
1866 : Type Typer::Visitor::TypeJSGeneratorRestoreInputOrDebugPos(Node* node) {
1867 : return Type::Any();
1868 : }
1869 :
1870 : Type Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1871 :
1872 : Type Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1873 :
1874 : Type Typer::Visitor::TypeJSAsyncFunctionEnter(Node* node) {
1875 : return Type::OtherObject();
1876 : }
1877 :
1878 : Type Typer::Visitor::TypeJSAsyncFunctionReject(Node* node) {
1879 : return Type::OtherObject();
1880 : }
1881 :
1882 : Type Typer::Visitor::TypeJSAsyncFunctionResolve(Node* node) {
1883 : return Type::OtherObject();
1884 : }
1885 :
1886 : Type Typer::Visitor::TypeJSFulfillPromise(Node* node) {
1887 : return Type::Undefined();
1888 : }
1889 :
1890 : Type Typer::Visitor::TypeJSPerformPromiseThen(Node* node) {
1891 : return Type::Receiver();
1892 : }
1893 :
1894 : Type Typer::Visitor::TypeJSPromiseResolve(Node* node) {
1895 : return Type::Receiver();
1896 : }
1897 :
1898 : Type Typer::Visitor::TypeJSRejectPromise(Node* node) {
1899 : return Type::Undefined();
1900 : }
1901 :
1902 : Type Typer::Visitor::TypeJSResolvePromise(Node* node) {
1903 : return Type::Undefined();
1904 : }
1905 :
1906 : // Simplified operators.
1907 :
1908 : Type Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1909 :
1910 : // static
1911 32049 : Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1912 32049 : return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
1913 : }
1914 :
1915 : // static
1916 124529 : Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1917 : return FalsifyUndefined(
1918 124533 : NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
1919 : }
1920 :
1921 : // static
1922 4383 : Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1923 : return FalsifyUndefined(
1924 8766 : Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
1925 : }
1926 :
1927 : Type Typer::Visitor::TypeNumberEqual(Node* node) {
1928 15259 : return TypeBinaryOp(node, NumberEqualTyper);
1929 : }
1930 :
1931 : Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1932 33457 : return TypeBinaryOp(node, NumberLessThanTyper);
1933 : }
1934 :
1935 : Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1936 2682 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1937 : }
1938 :
1939 : Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1940 19733 : return TypeBinaryOp(node, NumberEqualTyper);
1941 : }
1942 :
1943 : Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1944 131982 : return TypeBinaryOp(node, NumberLessThanTyper);
1945 : }
1946 :
1947 : Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1948 2167 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1949 : }
1950 :
1951 : Type Typer::Visitor::TypeStringConcat(Node* node) { return Type::String(); }
1952 :
1953 : Type Typer::Visitor::TypeStringToNumber(Node* node) {
1954 0 : return TypeUnaryOp(node, ToNumber);
1955 : }
1956 :
1957 : Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1958 2280 : return TypeUnaryOp(node, ToNumber);
1959 : }
1960 :
1961 : Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1962 : return Type::Integral32();
1963 : }
1964 :
1965 : Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1966 : return Type::Number();
1967 : }
1968 :
1969 : // static
1970 247324 : Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
1971 262249 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1972 5397 : return t->singleton_true_;
1973 : }
1974 : return Type::Boolean();
1975 : }
1976 :
1977 : Type Typer::Visitor::TypeReferenceEqual(Node* node) {
1978 248733 : return TypeBinaryOp(node, ReferenceEqualTyper);
1979 : }
1980 :
1981 : // static
1982 220 : Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
1983 220 : return t->operation_typer()->SameValue(lhs, rhs);
1984 : }
1985 :
1986 : Type Typer::Visitor::TypeSameValue(Node* node) {
1987 220 : return TypeBinaryOp(node, SameValueTyper);
1988 : }
1989 :
1990 : Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
1991 :
1992 : Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
1993 :
1994 : Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
1995 : return Type::Boolean();
1996 : }
1997 :
1998 1430 : Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
1999 1430 : return Type::String();
2000 : }
2001 :
2002 225 : Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
2003 225 : return Type::String();
2004 : }
2005 :
2006 : Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
2007 : return Type::String();
2008 : }
2009 :
2010 : Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
2011 : return Type::String();
2012 : }
2013 :
2014 : Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2015 3076 : return typer_->cache_->kUint16;
2016 : }
2017 :
2018 359 : Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2019 359 : return Type::Range(0.0, String::kMaxCodePoint, zone());
2020 : }
2021 :
2022 : Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2023 1566 : return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2024 : }
2025 :
2026 : Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2027 313 : return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2028 : }
2029 :
2030 309 : Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2031 309 : return Type::Range(-1.0, String::kMaxLength, zone());
2032 : }
2033 :
2034 : Type Typer::Visitor::TypeStringLength(Node* node) {
2035 56509 : return typer_->cache_->kStringLengthType;
2036 : }
2037 :
2038 : Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
2039 :
2040 3227 : Type Typer::Visitor::TypePoisonIndex(Node* node) {
2041 6454 : return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone());
2042 : }
2043 :
2044 70633 : Type Typer::Visitor::TypeCheckBounds(Node* node) {
2045 : return typer_->operation_typer_.CheckBounds(Operand(node, 0),
2046 70633 : Operand(node, 1));
2047 : }
2048 :
2049 : Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
2050 : Type type = Operand(node, 0);
2051 : return type;
2052 : }
2053 :
2054 0 : Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
2055 :
2056 7206 : Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
2057 3603 : Type arg = Operand(node, 0);
2058 3603 : return Type::Intersect(arg, Type::InternalizedString(), zone());
2059 : }
2060 :
2061 0 : Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
2062 :
2063 : Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
2064 :
2065 3151 : Type Typer::Visitor::TypeCheckNumber(Node* node) {
2066 3151 : return typer_->operation_typer_.CheckNumber(Operand(node, 0));
2067 : }
2068 :
2069 1770 : Type Typer::Visitor::TypeCheckReceiver(Node* node) {
2070 885 : Type arg = Operand(node, 0);
2071 885 : return Type::Intersect(arg, Type::Receiver(), zone());
2072 : }
2073 :
2074 144 : Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2075 72 : Type arg = Operand(node, 0);
2076 72 : return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone());
2077 : }
2078 :
2079 95514 : Type Typer::Visitor::TypeCheckSmi(Node* node) {
2080 47757 : Type arg = Operand(node, 0);
2081 47757 : return Type::Intersect(arg, Type::SignedSmall(), zone());
2082 : }
2083 :
2084 49484 : Type Typer::Visitor::TypeCheckString(Node* node) {
2085 24742 : Type arg = Operand(node, 0);
2086 24742 : return Type::Intersect(arg, Type::String(), zone());
2087 : }
2088 :
2089 62 : Type Typer::Visitor::TypeCheckSymbol(Node* node) {
2090 31 : Type arg = Operand(node, 0);
2091 31 : return Type::Intersect(arg, Type::Symbol(), zone());
2092 : }
2093 :
2094 622 : Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2095 622 : return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2096 : }
2097 :
2098 794 : Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
2099 : Type type = Operand(node, 0);
2100 397 : type = Type::Intersect(type, Type::NonInternal(), zone());
2101 397 : return type;
2102 : }
2103 :
2104 79092 : Type Typer::Visitor::TypeConvertReceiver(Node* node) {
2105 79092 : Type arg = Operand(node, 0);
2106 79092 : return typer_->operation_typer_.ConvertReceiver(arg);
2107 : }
2108 :
2109 2519 : Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
2110 2519 : Type type = Operand(node, 0);
2111 2519 : return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2112 : }
2113 :
2114 0 : Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2115 0 : UNREACHABLE();
2116 : }
2117 :
2118 0 : Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2119 :
2120 : Type Typer::Visitor::TypeAllocate(Node* node) {
2121 140297 : return AllocateTypeOf(node->op());
2122 : }
2123 :
2124 0 : Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2125 :
2126 : Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2127 : return Type::NonInternal();
2128 : }
2129 :
2130 : Type Typer::Visitor::TypeLoadField(Node* node) {
2131 1085922 : return FieldAccessOf(node->op()).type;
2132 : }
2133 :
2134 : Type Typer::Visitor::TypeLoadMessage(Node* node) { return Type::Any(); }
2135 :
2136 : Type Typer::Visitor::TypeLoadElement(Node* node) {
2137 25745 : return ElementAccessOf(node->op()).type;
2138 : }
2139 :
2140 5832 : Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2141 5832 : switch (ExternalArrayTypeOf(node->op())) {
2142 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2143 : case kExternal##ElemType##Array: \
2144 : return typer_->cache_->k##ElemType;
2145 695 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2146 : #undef TYPED_ARRAY_CASE
2147 : }
2148 0 : UNREACHABLE();
2149 : }
2150 :
2151 248 : Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
2152 248 : switch (ExternalArrayTypeOf(node->op())) {
2153 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2154 : case kExternal##ElemType##Array: \
2155 : return typer_->cache_->k##ElemType;
2156 37 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2157 : #undef TYPED_ARRAY_CASE
2158 : }
2159 0 : UNREACHABLE();
2160 : }
2161 :
2162 0 : Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2163 0 : Type Typer::Visitor::TypeStoreMessage(Node* node) { UNREACHABLE(); }
2164 :
2165 0 : Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2166 :
2167 0 : Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2168 0 : UNREACHABLE();
2169 : }
2170 :
2171 0 : Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2172 0 : UNREACHABLE();
2173 : }
2174 :
2175 0 : Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2176 0 : UNREACHABLE();
2177 : }
2178 :
2179 0 : Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2180 :
2181 0 : Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2182 :
2183 0 : Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }
2184 :
2185 : Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2186 14 : return TypeUnaryOp(node, ObjectIsArrayBufferView);
2187 : }
2188 :
2189 : Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2190 27 : return TypeUnaryOp(node, ObjectIsBigInt);
2191 : }
2192 :
2193 : Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2194 1896 : return TypeUnaryOp(node, ObjectIsCallable);
2195 : }
2196 :
2197 : Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2198 403 : return TypeUnaryOp(node, ObjectIsConstructor);
2199 : }
2200 :
2201 : Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2202 17354 : return TypeUnaryOp(node, ObjectIsDetectableCallable);
2203 : }
2204 :
2205 : Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2206 0 : return TypeUnaryOp(node, ObjectIsMinusZero);
2207 : }
2208 :
2209 : Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
2210 0 : return TypeUnaryOp(node, NumberIsMinusZero);
2211 : }
2212 :
2213 : Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2214 : return Type::Boolean();
2215 : }
2216 :
2217 : Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2218 :
2219 : Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2220 : return Type::Boolean();
2221 : }
2222 :
2223 0 : Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2224 :
2225 : Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2226 : return Type::Boolean();
2227 : }
2228 :
2229 0 : Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2230 :
2231 : Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2232 :
2233 : Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2234 4620 : return TypeUnaryOp(node, ObjectIsNaN);
2235 : }
2236 :
2237 : Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2238 5907 : return TypeUnaryOp(node, NumberIsNaN);
2239 : }
2240 :
2241 : Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2242 9195 : return TypeUnaryOp(node, ObjectIsNonCallable);
2243 : }
2244 :
2245 : Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2246 10585 : return TypeUnaryOp(node, ObjectIsNumber);
2247 : }
2248 :
2249 : Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2250 28261 : return TypeUnaryOp(node, ObjectIsReceiver);
2251 : }
2252 :
2253 : Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2254 1802 : return TypeUnaryOp(node, ObjectIsSmi);
2255 : }
2256 :
2257 : Type Typer::Visitor::TypeObjectIsString(Node* node) {
2258 3083 : return TypeUnaryOp(node, ObjectIsString);
2259 : }
2260 :
2261 : Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2262 118 : return TypeUnaryOp(node, ObjectIsSymbol);
2263 : }
2264 :
2265 : Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2266 1917 : return TypeUnaryOp(node, ObjectIsUndetectable);
2267 : }
2268 :
2269 : Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2270 17671 : return TypeCache::Get()->kArgumentsLengthType;
2271 : }
2272 :
2273 : Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2274 : return Type::ExternalPointer();
2275 : }
2276 :
2277 : Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2278 : return Type::OtherInternal();
2279 : }
2280 :
2281 : Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2282 : return Type::OtherInternal();
2283 : }
2284 :
2285 : Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2286 : return Type::OtherInternal();
2287 : }
2288 :
2289 : Type Typer::Visitor::TypeNewConsString(Node* node) { return Type::String(); }
2290 :
2291 : Type Typer::Visitor::TypeDelayedStringConstant(Node* node) {
2292 : return Type::String();
2293 : }
2294 :
2295 192 : Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2296 192 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2297 : }
2298 :
2299 0 : Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2300 0 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2301 : }
2302 :
2303 0 : Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2304 :
2305 : // Heap constants.
2306 :
2307 5923645 : Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2308 5923645 : return Type::NewConstant(typer_->broker(), value, zone());
2309 : }
2310 :
2311 : } // namespace compiler
2312 : } // namespace internal
2313 178779 : } // namespace v8
|