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 464669 : explicit Decorator(Typer* typer) : typer_(typer) {}
30 : void Decorate(Node* node) final;
31 :
32 : private:
33 : Typer* const typer_;
34 : };
35 :
36 464669 : Typer::Typer(JSHeapBroker* broker, Flags flags, Graph* graph)
37 : : flags_(flags),
38 : graph_(graph),
39 : decorator_(nullptr),
40 464669 : cache_(TypeCache::Get()),
41 : broker_(broker),
42 929338 : operation_typer_(broker, zone()) {
43 464669 : singleton_false_ = operation_typer_.singleton_false();
44 464669 : singleton_true_ = operation_typer_.singleton_true();
45 :
46 464669 : decorator_ = new (zone()) Decorator(this);
47 464669 : graph_->AddDecorator(decorator_);
48 464668 : }
49 :
50 :
51 929339 : Typer::~Typer() {
52 464670 : graph_->RemoveDecorator(decorator_);
53 464669 : }
54 :
55 :
56 10633453 : class Typer::Visitor : public Reducer {
57 : public:
58 5316733 : explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
59 : : typer_(typer),
60 : induction_vars_(induction_vars),
61 : weakened_nodes_(typer->zone()),
62 10633363 : remembered_types_(typer->zone()) {}
63 :
64 0 : const char* reducer_name() const override { return "Typer"; }
65 :
66 37842447 : Reduction Reduce(Node* node) override {
67 37842447 : if (node->op()->ValueOutputCount() == 0) return NoChange();
68 27640422 : switch (node->opcode()) {
69 : #define DECLARE_CASE(x) \
70 : case IrOpcode::k##x: \
71 : return UpdateType(node, TypeBinaryOp(node, x##Typer));
72 18361 : 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 464177 : DECLARE_CASE(Start)
79 215468 : DECLARE_CASE(IfException)
80 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
81 2005610 : COMMON_OP_LIST(DECLARE_CASE)
82 375613 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
83 1248580 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
84 335300 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
85 78 : JS_OBJECT_OP_LIST(DECLARE_CASE)
86 308434 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
87 517305 : 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 16237 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
94 115085 : 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 96211 : 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 4852352 : Type TypeNode(Node* node) {
137 4852352 : 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 1155256 : COMMON_OP_LIST(DECLARE_CASE)
148 0 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
149 61804 : 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 6395 : 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 120444 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
160 411 : 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 653 : 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 8413655 : : Type::None();
223 : }
224 :
225 : Type Operand(Node* node, int i) {
226 8395561 : 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 63655 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
279 94273 : 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 572923 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
286 475691 : 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 StringFromSingleCharCodeTyper(Type, Typer*);
321 : static Type StringFromSingleCodePointTyper(Type, Typer*);
322 :
323 27639992 : Reduction UpdateType(Node* node, Type current) {
324 27639992 : if (NodeProperties::IsTyped(node)) {
325 : // Widen the type of a previously typed node.
326 5983384 : Type previous = NodeProperties::GetType(node);
327 5983384 : if (node->opcode() == IrOpcode::kPhi ||
328 : node->opcode() == IrOpcode::kInductionVariablePhi) {
329 : // Speed up termination in the presence of range types:
330 558383 : current = Weaken(node, current, previous);
331 : }
332 :
333 5983388 : if (V8_UNLIKELY(!previous.Is(current))) {
334 : AllowHandleDereference allow;
335 0 : std::ostringstream ostream;
336 0 : node->Print(ostream);
337 :
338 0 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
339 0 : ostream << "Previous UpdateType run (inputs first):";
340 0 : for (int i = 0; i < 3; ++i) {
341 0 : ostream << " ";
342 0 : if (remembered_types_[{node, i}].IsInvalid()) {
343 0 : ostream << "untyped";
344 : } else {
345 0 : remembered_types_[{node, i}].PrintTo(ostream);
346 : }
347 : }
348 :
349 0 : ostream << "\nCurrent (output) type: ";
350 0 : previous.PrintTo(ostream);
351 :
352 0 : ostream << "\nThis UpdateType run (inputs first):";
353 0 : for (int i = 0; i < 2; ++i) {
354 0 : ostream << " ";
355 0 : Node* input = NodeProperties::GetValueInput(node, i);
356 0 : if (NodeProperties::IsTyped(input)) {
357 0 : NodeProperties::GetType(input).PrintTo(ostream);
358 : } else {
359 0 : ostream << "untyped";
360 : }
361 : }
362 0 : ostream << " ";
363 0 : current.PrintTo(ostream);
364 0 : ostream << "\n";
365 : }
366 :
367 0 : FATAL("UpdateType error for node %s", ostream.str().c_str());
368 : }
369 :
370 5983388 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
371 23480 : for (int i = 0; i < 2; ++i) {
372 9392 : Node* input = NodeProperties::GetValueInput(node, i);
373 9392 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
374 : ? NodeProperties::GetType(input)
375 9392 : : Type::Invalid();
376 : }
377 4696 : remembered_types_[{node, 2}] = current;
378 : }
379 :
380 : NodeProperties::SetType(node, current);
381 5983377 : if (!current.Is(previous)) {
382 : // If something changed, revisit all uses.
383 : return Changed(node);
384 : }
385 : return NoChange();
386 : } else {
387 21656608 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
388 57705 : for (int i = 0; i < 2; ++i) {
389 23082 : Node* input = NodeProperties::GetValueInput(node, i);
390 23082 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
391 : ? NodeProperties::GetType(input)
392 23082 : : Type::Invalid();
393 : }
394 11541 : remembered_types_[{node, 2}] = current;
395 : }
396 :
397 : // No previous type, simply update the type.
398 : NodeProperties::SetType(node, current);
399 : return Changed(node);
400 : }
401 : }
402 : };
403 :
404 744 : void Typer::Run() { Run(NodeVector(zone()), nullptr); }
405 :
406 464412 : void Typer::Run(const NodeVector& roots,
407 : LoopVariableOptimizer* induction_vars) {
408 464412 : if (induction_vars != nullptr) {
409 464166 : induction_vars->ChangeToInductionVariablePhis();
410 : }
411 928826 : Visitor visitor(this, induction_vars);
412 928827 : GraphReducer graph_reducer(zone(), graph());
413 464415 : graph_reducer.AddReducer(&visitor);
414 6783107 : for (Node* const root : roots) graph_reducer.ReduceNode(root);
415 464414 : graph_reducer.ReduceGraph();
416 :
417 464415 : if (induction_vars != nullptr) {
418 464167 : induction_vars->ChangeToPhisAndInsertGuards();
419 : }
420 464415 : }
421 :
422 6574623 : void Typer::Decorator::Decorate(Node* node) {
423 6574623 : if (node->op()->ValueOutputCount() > 0) {
424 : // Only eagerly type-decorate nodes with known input types.
425 : // Other cases will generally require a proper fixpoint iteration with Run.
426 : bool is_typed = NodeProperties::IsTyped(node);
427 4909032 : if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
428 9704605 : Visitor typing(typer_, nullptr);
429 4852228 : Type type = typing.TypeNode(node);
430 4852278 : if (is_typed) {
431 : type = Type::Intersect(type, NodeProperties::GetType(node),
432 0 : typer_->zone());
433 : }
434 : NodeProperties::SetType(node, type);
435 : }
436 : }
437 6574625 : }
438 :
439 :
440 : // -----------------------------------------------------------------------------
441 :
442 : // Helper functions that lift a function f on types to a function on bounds,
443 : // and uses that to type the given node. Note that f is never called with None
444 : // as an argument.
445 :
446 1256903 : Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
447 : Type input = Operand(node, 0);
448 1256903 : return input.IsNone() ? Type::None() : f(input, typer_);
449 : }
450 :
451 1913937 : Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
452 : Type left = Operand(node, 0);
453 : Type right = Operand(node, 1);
454 1790981 : return left.IsNone() || right.IsNone() ? Type::None()
455 3697838 : : f(left, right, typer_);
456 : }
457 :
458 189066 : Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
459 : BinaryTyperFun f) {
460 189066 : lhs = ToNumeric(lhs, t);
461 189066 : rhs = ToNumeric(rhs, t);
462 : bool lhs_is_number = lhs.Is(Type::Number());
463 : bool rhs_is_number = rhs.Is(Type::Number());
464 189066 : if (lhs_is_number && rhs_is_number) {
465 145624 : return f(lhs, rhs, t);
466 : }
467 : // In order to maintain monotonicity, the following two conditions are
468 : // intentionally asymmetric.
469 43442 : if (lhs_is_number) {
470 : return Type::Number();
471 : }
472 32130 : if (lhs.Is(Type::BigInt())) {
473 : return Type::BigInt();
474 : }
475 : return Type::Numeric();
476 : }
477 :
478 0 : Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
479 : ComparisonOutcome outcome, Typer* t) {
480 : ComparisonOutcome result(0);
481 11860 : if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
482 11860 : if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
483 11860 : if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
484 0 : return result;
485 : }
486 :
487 0 : Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
488 375916 : if ((outcome & kComparisonFalse) != 0 ||
489 : (outcome & kComparisonUndefined) != 0) {
490 : return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
491 350290 : : t->singleton_false_;
492 : }
493 : // Type should be non empty, so we know it should be true.
494 : DCHECK_NE(0, outcome & kComparisonTrue);
495 12452 : return t->singleton_true_;
496 : }
497 :
498 166 : Type Typer::Visitor::BitwiseNot(Type type, Typer* t) {
499 166 : type = ToNumeric(type, t);
500 166 : if (type.Is(Type::Number())) {
501 34 : return NumberBitwiseXor(type, t->cache_->kSingletonMinusOne, t);
502 : }
503 : return Type::Numeric();
504 : }
505 :
506 6271 : Type Typer::Visitor::Decrement(Type type, Typer* t) {
507 6271 : type = ToNumeric(type, t);
508 6271 : if (type.Is(Type::Number())) {
509 3798 : return NumberSubtract(type, t->cache_->kSingletonOne, t);
510 : }
511 : return Type::Numeric();
512 : }
513 :
514 262681 : Type Typer::Visitor::Increment(Type type, Typer* t) {
515 262681 : type = ToNumeric(type, t);
516 262681 : if (type.Is(Type::Number())) {
517 252228 : return NumberAdd(type, t->cache_->kSingletonOne, t);
518 : }
519 : return Type::Numeric();
520 : }
521 :
522 4401 : Type Typer::Visitor::Negate(Type type, Typer* t) {
523 4401 : type = ToNumeric(type, t);
524 4401 : if (type.Is(Type::Number())) {
525 461 : return NumberMultiply(type, t->cache_->kSingletonMinusOne, t);
526 : }
527 : return Type::Numeric();
528 : }
529 :
530 : // Type conversion.
531 :
532 913737 : Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
533 913737 : if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
534 735423 : return type;
535 : }
536 : return Type::Primitive();
537 : }
538 :
539 138049 : Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
540 138049 : return t->operation_typer()->ToBoolean(type);
541 : }
542 :
543 :
544 : // static
545 116 : Type Typer::Visitor::ToInteger(Type type, Typer* t) {
546 : // ES6 section 7.1.4 ToInteger ( argument )
547 116 : type = ToNumber(type, t);
548 232 : if (type.Is(t->cache_->kIntegerOrMinusZero)) return type;
549 164 : if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
550 : return Type::Union(
551 1 : Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()),
552 1 : t->cache_->kSingletonZero, t->zone());
553 : }
554 81 : return t->cache_->kIntegerOrMinusZero;
555 : }
556 :
557 :
558 : // static
559 116 : Type Typer::Visitor::ToLength(Type type, Typer* t) {
560 : // ES6 section 7.1.15 ToLength ( argument )
561 116 : type = ToInteger(type, t);
562 116 : if (type.IsNone()) return type;
563 107 : double min = type.Min();
564 107 : double max = type.Max();
565 107 : if (max <= 0.0) {
566 6 : return Type::NewConstant(0, t->zone());
567 : }
568 101 : if (min >= kMaxSafeInteger) {
569 2 : return Type::NewConstant(kMaxSafeInteger, t->zone());
570 : }
571 99 : if (min <= 0.0) min = 0.0;
572 99 : if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
573 99 : return Type::Range(min, max, t->zone());
574 : }
575 :
576 :
577 : // static
578 1254 : Type Typer::Visitor::ToName(Type type, Typer* t) {
579 : // ES6 section 7.1.14 ToPropertyKey ( argument )
580 1254 : type = ToPrimitive(type, t);
581 1254 : if (type.Is(Type::Name())) return type;
582 1191 : if (type.Maybe(Type::Symbol())) return Type::Name();
583 98 : return ToString(type, t);
584 : }
585 :
586 :
587 : // static
588 11781 : Type Typer::Visitor::ToNumber(Type type, Typer* t) {
589 174683 : return t->operation_typer_.ToNumber(type);
590 : }
591 :
592 : // static
593 360 : Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
594 360 : return t->operation_typer_.ToNumberConvertBigInt(type);
595 : }
596 :
597 : // static
598 49320 : Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
599 1169893 : return t->operation_typer_.ToNumeric(type);
600 : }
601 :
602 : // static
603 2032 : Type Typer::Visitor::ToObject(Type type, Typer* t) {
604 : // ES6 section 7.1.13 ToObject ( argument )
605 2032 : if (type.Is(Type::Receiver())) return type;
606 1574 : if (type.Is(Type::Primitive())) return Type::OtherObject();
607 1461 : if (!type.Maybe(Type::OtherUndetectable())) {
608 : return Type::DetectableReceiver();
609 : }
610 : return Type::Receiver();
611 : }
612 :
613 :
614 : // static
615 2547 : Type Typer::Visitor::ToString(Type type, Typer* t) {
616 : // ES6 section 7.1.12 ToString ( argument )
617 2547 : type = ToPrimitive(type, t);
618 2547 : if (type.Is(Type::String())) return type;
619 : return Type::String();
620 : }
621 :
622 : // Type checks.
623 :
624 16 : Type Typer::Visitor::ObjectIsArrayBufferView(Type type, Typer* t) {
625 : // TODO(turbofan): Introduce a Type::ArrayBufferView?
626 16 : if (!type.Maybe(Type::OtherObject())) return t->singleton_false_;
627 : return Type::Boolean();
628 : }
629 :
630 27 : Type Typer::Visitor::ObjectIsBigInt(Type type, Typer* t) {
631 27 : if (type.Is(Type::BigInt())) return t->singleton_true_;
632 26 : if (!type.Maybe(Type::BigInt())) return t->singleton_false_;
633 : return Type::Boolean();
634 : }
635 :
636 2001 : Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
637 2001 : if (type.Is(Type::Callable())) return t->singleton_true_;
638 317 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
639 : return Type::Boolean();
640 : }
641 :
642 415 : Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
643 : // TODO(turbofan): Introduce a Type::Constructor?
644 415 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
645 : return Type::Boolean();
646 : }
647 :
648 17537 : Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
649 17537 : if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
650 17425 : if (!type.Maybe(Type::DetectableCallable())) return t->singleton_false_;
651 : return Type::Boolean();
652 : }
653 :
654 0 : Type Typer::Visitor::ObjectIsMinusZero(Type type, Typer* t) {
655 0 : if (type.Is(Type::MinusZero())) return t->singleton_true_;
656 0 : if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
657 : return Type::Boolean();
658 : }
659 :
660 0 : Type Typer::Visitor::NumberIsMinusZero(Type type, Typer* t) {
661 0 : if (type.Is(Type::MinusZero())) return t->singleton_true_;
662 0 : if (!type.Maybe(Type::MinusZero())) return t->singleton_false_;
663 : return Type::Boolean();
664 : }
665 :
666 4594 : Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
667 4594 : if (type.Is(Type::NaN())) return t->singleton_true_;
668 4587 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
669 : return Type::Boolean();
670 : }
671 :
672 5102 : Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
673 5102 : if (type.Is(Type::NaN())) return t->singleton_true_;
674 4506 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
675 : return Type::Boolean();
676 : }
677 :
678 9069 : Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
679 9069 : if (type.Is(Type::NonCallable())) return t->singleton_true_;
680 8743 : if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
681 : return Type::Boolean();
682 : }
683 :
684 10454 : Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
685 10454 : if (type.Is(Type::Number())) return t->singleton_true_;
686 8963 : if (!type.Maybe(Type::Number())) return t->singleton_false_;
687 : return Type::Boolean();
688 : }
689 :
690 26805 : Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
691 26805 : if (type.Is(Type::Receiver())) return t->singleton_true_;
692 24376 : if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
693 : return Type::Boolean();
694 : }
695 :
696 1533 : Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
697 1533 : if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
698 : return Type::Boolean();
699 : }
700 :
701 2442 : Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
702 2442 : if (type.Is(Type::String())) return t->singleton_true_;
703 2432 : if (!type.Maybe(Type::String())) return t->singleton_false_;
704 : return Type::Boolean();
705 : }
706 :
707 103 : Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
708 103 : if (type.Is(Type::Symbol())) return t->singleton_true_;
709 103 : if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
710 : return Type::Boolean();
711 : }
712 :
713 1897 : Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
714 1897 : if (type.Is(Type::Undetectable())) return t->singleton_true_;
715 1695 : if (!type.Maybe(Type::Undetectable())) return t->singleton_false_;
716 : return Type::Boolean();
717 : }
718 :
719 :
720 : // -----------------------------------------------------------------------------
721 :
722 :
723 : // Control operators.
724 :
725 : Type Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
726 :
727 : Type Typer::Visitor::TypeIfException(Node* node) { return Type::NonInternal(); }
728 :
729 : // Common operators.
730 :
731 2000120 : Type Typer::Visitor::TypeParameter(Node* node) {
732 : Node* const start = node->InputAt(0);
733 : DCHECK_EQ(IrOpcode::kStart, start->opcode());
734 2000120 : int const parameter_count = start->op()->ValueOutputCount() - 4;
735 : DCHECK_LE(1, parameter_count);
736 2000120 : int const index = ParameterIndexOf(node->op());
737 2000122 : if (index == Linkage::kJSCallClosureParamIndex) {
738 : return Type::Function();
739 1973575 : } else if (index == 0) {
740 919022 : if (typer_->flags() & Typer::kThisIsReceiver) {
741 : return Type::Receiver();
742 : } else {
743 : // Parameter[this] can be the_hole for derived class constructors.
744 91531 : return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
745 : }
746 1514064 : } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
747 35988 : if (typer_->flags() & Typer::kNewTargetIsReceiver) {
748 : return Type::Receiver();
749 : } else {
750 16872 : return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
751 : }
752 1496070 : } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
753 0 : return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone());
754 1496070 : } else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) {
755 : return Type::OtherInternal();
756 : }
757 : return Type::NonInternal();
758 : }
759 :
760 : Type Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }
761 :
762 0 : Type Typer::Visitor::TypeRetain(Node* node) { UNREACHABLE(); }
763 :
764 0 : Type Typer::Visitor::TypeInt32Constant(Node* node) { UNREACHABLE(); }
765 :
766 0 : Type Typer::Visitor::TypeInt64Constant(Node* node) { UNREACHABLE(); }
767 :
768 0 : Type Typer::Visitor::TypeRelocatableInt32Constant(Node* node) { UNREACHABLE(); }
769 :
770 0 : Type Typer::Visitor::TypeRelocatableInt64Constant(Node* node) { UNREACHABLE(); }
771 :
772 0 : Type Typer::Visitor::TypeFloat32Constant(Node* node) { UNREACHABLE(); }
773 :
774 0 : Type Typer::Visitor::TypeFloat64Constant(Node* node) { UNREACHABLE(); }
775 :
776 : Type Typer::Visitor::TypeNumberConstant(Node* node) {
777 1772982 : double number = OpParameter<double>(node->op());
778 1772982 : return Type::NewConstant(number, zone());
779 : }
780 :
781 6017530 : Type Typer::Visitor::TypeHeapConstant(Node* node) {
782 12035047 : return TypeConstant(HeapConstantOf(node->op()));
783 : }
784 :
785 : Type Typer::Visitor::TypeExternalConstant(Node* node) {
786 : return Type::ExternalPointer();
787 : }
788 :
789 : Type Typer::Visitor::TypePointerConstant(Node* node) {
790 : return Type::ExternalPointer();
791 : }
792 :
793 18020 : Type Typer::Visitor::TypeSelect(Node* node) {
794 18020 : return Type::Union(Operand(node, 1), Operand(node, 2), zone());
795 : }
796 :
797 874654 : Type Typer::Visitor::TypePhi(Node* node) {
798 : int arity = node->op()->ValueInputCount();
799 : Type type = Operand(node, 0);
800 3673810 : for (int i = 1; i < arity; ++i) {
801 1399562 : type = Type::Union(type, Operand(node, i), zone());
802 : }
803 874646 : return type;
804 : }
805 :
806 24729 : Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
807 24729 : int arity = NodeProperties::GetControlInput(node)->op()->ControlInputCount();
808 : DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(node)->opcode());
809 : DCHECK_EQ(2, NodeProperties::GetControlInput(node)->InputCount());
810 :
811 24729 : Type initial_type = Operand(node, 0);
812 24729 : Type increment_type = Operand(node, 2);
813 :
814 : // We only handle integer induction variables (otherwise ranges
815 : // do not apply and we cannot do anything).
816 67597 : if (!initial_type.Is(typer_->cache_->kInteger) ||
817 18139 : !increment_type.Is(typer_->cache_->kInteger)) {
818 : // Fallback to normal phi typing, but ensure monotonicity.
819 : // (Unfortunately, without baking in the previous type, monotonicity might
820 : // be violated because we might not yet have retyped the incrementing
821 : // operation even though the increment's type might been already reflected
822 : // in the induction variable phi.)
823 : Type type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
824 6824 : : Type::None();
825 34120 : for (int i = 0; i < arity; ++i) {
826 13648 : type = Type::Union(type, Operand(node, i), zone());
827 : }
828 6824 : return type;
829 : }
830 : // If we do not have enough type information for the initial value or
831 : // the increment, just return the initial value's type.
832 35789 : if (initial_type.IsNone() ||
833 17884 : increment_type.Is(typer_->cache_->kSingletonZero)) {
834 37 : return initial_type;
835 : }
836 :
837 : // Now process the bounds.
838 17868 : auto res = induction_vars_->induction_variables().find(node->id());
839 : DCHECK(res != induction_vars_->induction_variables().end());
840 17868 : InductionVariable* induction_var = res->second;
841 :
842 : InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
843 :
844 17868 : double min = -V8_INFINITY;
845 17868 : double max = V8_INFINITY;
846 :
847 : double increment_min;
848 : double increment_max;
849 17868 : if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
850 17592 : increment_min = increment_type.Min();
851 17592 : increment_max = increment_type.Max();
852 : } else {
853 : DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
854 276 : increment_min = -increment_type.Max();
855 276 : increment_max = -increment_type.Min();
856 : }
857 :
858 17868 : if (increment_min >= 0) {
859 : // increasing sequence
860 17608 : min = initial_type.Min();
861 35296 : for (auto bound : induction_var->upper_bounds()) {
862 17713 : Type bound_type = TypeOrNone(bound.bound);
863 : // If the type is not an integer, just skip the bound.
864 37492 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
865 : // If the type is not inhabited, then we can take the initial value.
866 15647 : if (bound_type.IsNone()) {
867 25 : max = initial_type.Max();
868 25 : break;
869 : }
870 15622 : double bound_max = bound_type.Max();
871 15622 : if (bound.kind == InductionVariable::kStrict) {
872 15457 : bound_max -= 1;
873 : }
874 31244 : max = std::min(max, bound_max + increment_max);
875 : }
876 : // The upper bound must be at least the initial value's upper bound.
877 35216 : max = std::max(max, initial_type.Max());
878 260 : } else if (increment_max <= 0) {
879 : // decreasing sequence
880 260 : max = initial_type.Max();
881 578 : for (auto bound : induction_var->lower_bounds()) {
882 318 : Type bound_type = TypeOrNone(bound.bound);
883 : // If the type is not an integer, just skip the bound.
884 636 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
885 : // If the type is not inhabited, then we can take the initial value.
886 318 : if (bound_type.IsNone()) {
887 0 : min = initial_type.Min();
888 0 : break;
889 : }
890 318 : double bound_min = bound_type.Min();
891 318 : if (bound.kind == InductionVariable::kStrict) {
892 144 : bound_min += 1;
893 : }
894 636 : min = std::max(min, bound_min + increment_min);
895 : }
896 : // The lower bound must be at most the initial value's lower bound.
897 520 : min = std::min(min, initial_type.Min());
898 : } else {
899 : // Shortcut: If the increment can be both positive and negative,
900 : // the variable can go arbitrarily far, so just return integer.
901 0 : return typer_->cache_->kInteger;
902 : }
903 17868 : if (FLAG_trace_turbo_loop) {
904 0 : StdoutStream{} << std::setprecision(10) << "Loop ("
905 0 : << NodeProperties::GetControlInput(node)->id()
906 : << ") variable bounds in "
907 : << (arithmetic_type ==
908 : InductionVariable::ArithmeticType::kAddition
909 : ? "addition"
910 0 : : "subtraction")
911 0 : << " for phi " << node->id() << ": (" << min << ", " << max
912 0 : << ")\n";
913 : }
914 17868 : return Type::Range(min, max, typer_->zone());
915 : }
916 :
917 0 : Type Typer::Visitor::TypeEffectPhi(Node* node) { UNREACHABLE(); }
918 :
919 0 : Type Typer::Visitor::TypeLoopExit(Node* node) { UNREACHABLE(); }
920 :
921 : Type Typer::Visitor::TypeLoopExitValue(Node* node) { return Operand(node, 0); }
922 :
923 0 : Type Typer::Visitor::TypeLoopExitEffect(Node* node) { UNREACHABLE(); }
924 :
925 : Type Typer::Visitor::TypeEnsureWritableFastElements(Node* node) {
926 : return Operand(node, 1);
927 : }
928 :
929 : Type Typer::Visitor::TypeMaybeGrowFastElements(Node* node) {
930 : return Operand(node, 1);
931 : }
932 :
933 0 : Type Typer::Visitor::TypeTransitionElementsKind(Node* node) { UNREACHABLE(); }
934 :
935 0 : Type Typer::Visitor::TypeCheckpoint(Node* node) { UNREACHABLE(); }
936 :
937 0 : Type Typer::Visitor::TypeBeginRegion(Node* node) { UNREACHABLE(); }
938 :
939 : Type Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); }
940 :
941 : Type Typer::Visitor::TypeFrameState(Node* node) {
942 : // TODO(rossberg): Ideally FrameState wouldn't have a value output.
943 : return Type::Internal();
944 : }
945 :
946 : Type Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }
947 :
948 : Type Typer::Visitor::TypeTypedStateValues(Node* node) {
949 : return Type::Internal();
950 : }
951 :
952 0 : Type Typer::Visitor::TypeObjectId(Node* node) { UNREACHABLE(); }
953 :
954 : Type Typer::Visitor::TypeArgumentsElementsState(Node* node) {
955 : return Type::Internal();
956 : }
957 :
958 : Type Typer::Visitor::TypeArgumentsLengthState(Node* node) {
959 : return Type::Internal();
960 : }
961 :
962 : Type Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
963 :
964 : Type Typer::Visitor::TypeTypedObjectState(Node* node) {
965 : return Type::Internal();
966 : }
967 :
968 : Type Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
969 :
970 0 : Type Typer::Visitor::TypeCallWithCallerSavedRegisters(Node* node) {
971 0 : UNREACHABLE();
972 : }
973 :
974 6025 : Type Typer::Visitor::TypeProjection(Node* node) {
975 6025 : Type const type = Operand(node, 0);
976 6025 : if (type.Is(Type::None())) return Type::None();
977 6025 : int const index = static_cast<int>(ProjectionIndexOf(node->op()));
978 6025 : if (type.IsTuple() && index < type.AsTuple()->Arity()) {
979 4143 : return type.AsTuple()->Element(index);
980 : }
981 : return Type::Any();
982 : }
983 :
984 0 : Type Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
985 :
986 26861 : Type Typer::Visitor::TypeTypeGuard(Node* node) {
987 26861 : Type const type = Operand(node, 0);
988 53722 : return typer_->operation_typer()->TypeTypeGuard(node->op(), type);
989 : }
990 :
991 : Type Typer::Visitor::TypeDead(Node* node) { return Type::None(); }
992 :
993 : Type Typer::Visitor::TypeDeadValue(Node* node) { return Type::None(); }
994 :
995 : Type Typer::Visitor::TypeUnreachable(Node* node) { return Type::None(); }
996 :
997 : // JS comparison operators.
998 :
999 48725 : Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
1000 97277 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
1001 48551 : if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1002 0 : return t->singleton_true_;
1003 : }
1004 172970 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
1005 73108 : (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1006 2102 : return t->singleton_false_;
1007 : }
1008 47075 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1009 : // Types are equal and are inhabited only by a single semantic value,
1010 : // which is not nan due to the earlier check.
1011 69 : return t->singleton_true_;
1012 : }
1013 : return Type::Boolean();
1014 : }
1015 :
1016 184339 : Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
1017 184339 : return t->operation_typer()->StrictEqual(lhs, rhs);
1018 : }
1019 :
1020 : // The EcmaScript specification defines the four relational comparison operators
1021 : // (<, <=, >=, >) with the help of a single abstract one. It behaves like <
1022 : // but returns undefined when the inputs cannot be compared.
1023 : // We implement the typing analogously.
1024 238179 : Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
1025 : Type rhs,
1026 : Typer* t) {
1027 238179 : lhs = ToPrimitive(lhs, t);
1028 238179 : rhs = ToPrimitive(rhs, t);
1029 238179 : if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
1030 : return ComparisonOutcome(kComparisonTrue) |
1031 : ComparisonOutcome(kComparisonFalse);
1032 : }
1033 234461 : lhs = ToNumeric(lhs, t);
1034 234461 : rhs = ToNumeric(rhs, t);
1035 461443 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
1036 48865 : return NumberCompareTyper(lhs, rhs, t);
1037 : }
1038 : return ComparisonOutcome(kComparisonTrue) |
1039 : ComparisonOutcome(kComparisonFalse) |
1040 : ComparisonOutcome(kComparisonUndefined);
1041 : }
1042 :
1043 173431 : Typer::Visitor::ComparisonOutcome Typer::Visitor::NumberCompareTyper(Type lhs,
1044 : Type rhs,
1045 : Typer* t) {
1046 : DCHECK(lhs.Is(Type::Number()));
1047 : DCHECK(rhs.Is(Type::Number()));
1048 :
1049 : // Shortcut for NaNs.
1050 346548 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
1051 :
1052 : ComparisonOutcome result;
1053 172785 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1054 : // Types are equal and are inhabited only by a single semantic value.
1055 : result = kComparisonFalse;
1056 172785 : } else if (lhs.Min() >= rhs.Max()) {
1057 : result = kComparisonFalse;
1058 170620 : } else if (lhs.Max() < rhs.Min()) {
1059 : result = kComparisonTrue;
1060 : } else {
1061 : // We cannot figure out the result, return both true and false. (We do not
1062 : // have to return undefined because that cannot affect the result of
1063 : // FalsifyUndefined.)
1064 : return ComparisonOutcome(kComparisonTrue) |
1065 : ComparisonOutcome(kComparisonFalse);
1066 : }
1067 : // Add the undefined if we could see NaN.
1068 14338 : if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1069 : result |= kComparisonUndefined;
1070 : }
1071 14338 : return result;
1072 : }
1073 :
1074 126348 : Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1075 252696 : return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
1076 : }
1077 :
1078 99971 : Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1079 199942 : return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1080 : }
1081 :
1082 3941 : Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1083 7882 : return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1084 : }
1085 :
1086 3684 : Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1087 7368 : return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1088 : }
1089 :
1090 : // JS bitwise operators.
1091 :
1092 11104 : Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1093 11104 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1094 : }
1095 :
1096 8830 : Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1097 8830 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1098 : }
1099 :
1100 1804 : Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1101 1804 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1102 : }
1103 :
1104 5164 : Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1105 5164 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1106 : }
1107 :
1108 3493 : Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1109 3493 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1110 : }
1111 :
1112 3562 : Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1113 3562 : return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1114 : }
1115 :
1116 :
1117 : // JS arithmetic operators.
1118 :
1119 216789 : Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1120 216789 : lhs = ToPrimitive(lhs, t);
1121 216789 : rhs = ToPrimitive(rhs, t);
1122 216789 : if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
1123 143874 : if (lhs.Is(Type::String()) || rhs.Is(Type::String())) {
1124 : return Type::String();
1125 : } else {
1126 : return Type::NumericOrString();
1127 : }
1128 : }
1129 : // The addition must be numeric.
1130 120772 : return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1131 : }
1132 :
1133 9383 : Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1134 9383 : return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1135 : }
1136 :
1137 10748 : Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1138 10748 : return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1139 : }
1140 :
1141 14347 : Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1142 14347 : return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1143 : }
1144 :
1145 3421 : Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1146 3421 : return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
1147 : }
1148 :
1149 184 : Type Typer::Visitor::JSExponentiateTyper(Type lhs, Type rhs, Typer* t) {
1150 : // TODO(neis): Refine using BinaryNumberOpTyper?
1151 184 : return Type::Numeric();
1152 : }
1153 :
1154 : // JS unary operators.
1155 :
1156 : Type Typer::Visitor::TypeJSBitwiseNot(Node* node) {
1157 166 : return TypeUnaryOp(node, BitwiseNot);
1158 : }
1159 :
1160 : Type Typer::Visitor::TypeJSDecrement(Node* node) {
1161 6427 : return TypeUnaryOp(node, Decrement);
1162 : }
1163 :
1164 : Type Typer::Visitor::TypeJSIncrement(Node* node) {
1165 263728 : return TypeUnaryOp(node, Increment);
1166 : }
1167 :
1168 : Type Typer::Visitor::TypeJSNegate(Node* node) {
1169 4405 : return TypeUnaryOp(node, Negate);
1170 : }
1171 :
1172 : Type Typer::Visitor::TypeTypeOf(Node* node) {
1173 : return Type::NonEmptyInternalizedOneByteString();
1174 : }
1175 :
1176 :
1177 : // JS conversion operators.
1178 :
1179 : Type Typer::Visitor::TypeToBoolean(Node* node) {
1180 143481 : return TypeUnaryOp(node, ToBoolean);
1181 : }
1182 :
1183 : Type Typer::Visitor::TypeJSToLength(Node* node) {
1184 136 : return TypeUnaryOp(node, ToLength);
1185 : }
1186 :
1187 : Type Typer::Visitor::TypeJSToName(Node* node) {
1188 1274 : return TypeUnaryOp(node, ToName);
1189 : }
1190 :
1191 : Type Typer::Visitor::TypeJSToNumber(Node* node) {
1192 9576 : return TypeUnaryOp(node, ToNumber);
1193 : }
1194 :
1195 : Type Typer::Visitor::TypeJSToNumberConvertBigInt(Node* node) {
1196 360 : return TypeUnaryOp(node, ToNumberConvertBigInt);
1197 : }
1198 :
1199 : Type Typer::Visitor::TypeJSToNumeric(Node* node) {
1200 49401 : return TypeUnaryOp(node, ToNumeric);
1201 : }
1202 :
1203 : Type Typer::Visitor::TypeJSToObject(Node* node) {
1204 2062 : return TypeUnaryOp(node, ToObject);
1205 : }
1206 :
1207 : Type Typer::Visitor::TypeJSToString(Node* node) {
1208 2511 : return TypeUnaryOp(node, ToString);
1209 : }
1210 :
1211 : // JS object operators.
1212 :
1213 : Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1214 :
1215 19365 : Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1216 19365 : switch (CreateArgumentsTypeOf(node->op())) {
1217 : case CreateArgumentsType::kRestParameter:
1218 : return Type::Array();
1219 : case CreateArgumentsType::kMappedArguments:
1220 : case CreateArgumentsType::kUnmappedArguments:
1221 : return Type::OtherObject();
1222 : }
1223 0 : UNREACHABLE();
1224 : }
1225 :
1226 : Type Typer::Visitor::TypeJSCreateArray(Node* node) { return Type::Array(); }
1227 :
1228 : Type Typer::Visitor::TypeJSCreateArrayIterator(Node* node) {
1229 : return Type::OtherObject();
1230 : }
1231 :
1232 : Type Typer::Visitor::TypeJSCreateAsyncFunctionObject(Node* node) {
1233 : return Type::OtherObject();
1234 : }
1235 :
1236 : Type Typer::Visitor::TypeJSCreateCollectionIterator(Node* node) {
1237 : return Type::OtherObject();
1238 : }
1239 :
1240 : Type Typer::Visitor::TypeJSCreateBoundFunction(Node* node) {
1241 : return Type::BoundFunction();
1242 : }
1243 :
1244 : Type Typer::Visitor::TypeJSCreateGeneratorObject(Node* node) {
1245 : return Type::OtherObject();
1246 : }
1247 :
1248 : Type Typer::Visitor::TypeJSCreateClosure(Node* node) {
1249 : return Type::Function();
1250 : }
1251 :
1252 : Type Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
1253 : return Type::OtherObject();
1254 : }
1255 :
1256 : Type Typer::Visitor::TypeJSCreateStringIterator(Node* node) {
1257 : return Type::OtherObject();
1258 : }
1259 :
1260 : Type Typer::Visitor::TypeJSCreateKeyValueArray(Node* node) {
1261 : return Type::OtherObject();
1262 : }
1263 :
1264 : Type Typer::Visitor::TypeJSCreateObject(Node* node) {
1265 : return Type::OtherObject();
1266 : }
1267 :
1268 : Type Typer::Visitor::TypeJSCreatePromise(Node* node) {
1269 : return Type::OtherObject();
1270 : }
1271 :
1272 : Type Typer::Visitor::TypeJSCreateTypedArray(Node* node) {
1273 : return Type::OtherObject();
1274 : }
1275 :
1276 : Type Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
1277 : return Type::Array();
1278 : }
1279 :
1280 : Type Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) {
1281 : return Type::Array();
1282 : }
1283 :
1284 : Type Typer::Visitor::TypeJSCreateArrayFromIterable(Node* node) {
1285 : return Type::Array();
1286 : }
1287 :
1288 : Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
1289 : return Type::OtherObject();
1290 : }
1291 :
1292 : Type Typer::Visitor::TypeJSCreateEmptyLiteralObject(Node* node) {
1293 : return Type::OtherObject();
1294 : }
1295 :
1296 : Type Typer::Visitor::TypeJSCloneObject(Node* node) {
1297 : return Type::OtherObject();
1298 : }
1299 :
1300 : Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
1301 : return Type::OtherObject();
1302 : }
1303 :
1304 : Type Typer::Visitor::TypeJSLoadProperty(Node* node) {
1305 : return Type::NonInternal();
1306 : }
1307 :
1308 : Type Typer::Visitor::TypeJSLoadNamed(Node* node) { return Type::NonInternal(); }
1309 :
1310 : Type Typer::Visitor::TypeJSLoadGlobal(Node* node) {
1311 : return Type::NonInternal();
1312 : }
1313 :
1314 : Type Typer::Visitor::TypeJSParseInt(Node* node) { return Type::Number(); }
1315 :
1316 : Type Typer::Visitor::TypeJSRegExpTest(Node* node) { return Type::Boolean(); }
1317 :
1318 : // Returns a somewhat larger range if we previously assigned
1319 : // a (smaller) range to this node. This is used to speed up
1320 : // the fixpoint calculation in case there appears to be a loop
1321 : // in the graph. In the current implementation, we are
1322 : // increasing the limits to the closest power of two.
1323 558387 : Type Typer::Visitor::Weaken(Node* node, Type current_type, Type previous_type) {
1324 : static const double kWeakenMinLimits[] = {
1325 : 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0,
1326 : -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0,
1327 : -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0,
1328 : -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0,
1329 : -70368744177664.0, -140737488355328.0, -281474976710656.0,
1330 : -562949953421312.0};
1331 : static const double kWeakenMaxLimits[] = {
1332 : 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
1333 : 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
1334 : 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
1335 : 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
1336 : 70368744177663.0, 140737488355327.0, 281474976710655.0,
1337 : 562949953421311.0};
1338 : STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
1339 :
1340 : // If the types have nothing to do with integers, return the types.
1341 558387 : Type const integer = typer_->cache_->kInteger;
1342 558387 : if (!previous_type.Maybe(integer)) {
1343 42234 : return current_type;
1344 : }
1345 : DCHECK(current_type.Maybe(integer));
1346 :
1347 516159 : Type current_integer = Type::Intersect(current_type, integer, zone());
1348 516163 : Type previous_integer = Type::Intersect(previous_type, integer, zone());
1349 :
1350 : // Once we start weakening a node, we should always weaken.
1351 516163 : if (!IsWeakened(node->id())) {
1352 : // Only weaken if there is range involved; we should converge quickly
1353 : // for all other types (the exception is a union of many constants,
1354 : // but we currently do not increase the number of constants in unions).
1355 101208 : Type previous = previous_integer.GetRange();
1356 101208 : Type current = current_integer.GetRange();
1357 202319 : if (current.IsInvalid() || previous.IsInvalid()) {
1358 320 : return current_type;
1359 : }
1360 : // Range is involved => we are weakening.
1361 : SetWeakened(node->id());
1362 : }
1363 :
1364 515843 : double current_min = current_integer.Min();
1365 : double new_min = current_min;
1366 : // Find the closest lower entry in the list of allowed
1367 : // minima (or negative infinity if there is no such entry).
1368 515841 : if (current_min != previous_integer.Min()) {
1369 : new_min = -V8_INFINITY;
1370 2093641 : for (double const min : kWeakenMinLimits) {
1371 1045201 : if (min <= current_min) {
1372 : new_min = min;
1373 : break;
1374 : }
1375 : }
1376 : }
1377 :
1378 515839 : double current_max = current_integer.Max();
1379 : double new_max = current_max;
1380 : // Find the closest greater entry in the list of allowed
1381 : // maxima (or infinity if there is no such entry).
1382 515837 : if (current_max != previous_integer.Max()) {
1383 : new_max = V8_INFINITY;
1384 9130056 : for (double const max : kWeakenMaxLimits) {
1385 4703033 : if (max >= current_max) {
1386 : new_max = max;
1387 : break;
1388 : }
1389 : }
1390 : }
1391 :
1392 : return Type::Union(current_type,
1393 : Type::Range(new_min, new_max, typer_->zone()),
1394 515836 : typer_->zone());
1395 : }
1396 :
1397 0 : Type Typer::Visitor::TypeJSStoreProperty(Node* node) { UNREACHABLE(); }
1398 :
1399 0 : Type Typer::Visitor::TypeJSStoreNamed(Node* node) { UNREACHABLE(); }
1400 :
1401 0 : Type Typer::Visitor::TypeJSStoreGlobal(Node* node) { UNREACHABLE(); }
1402 :
1403 0 : Type Typer::Visitor::TypeJSStoreNamedOwn(Node* node) { UNREACHABLE(); }
1404 :
1405 0 : Type Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
1406 0 : UNREACHABLE();
1407 : }
1408 :
1409 0 : Type Typer::Visitor::TypeJSStoreInArrayLiteral(Node* node) { UNREACHABLE(); }
1410 :
1411 : Type Typer::Visitor::TypeJSDeleteProperty(Node* node) {
1412 : return Type::Boolean();
1413 : }
1414 :
1415 : Type Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
1416 :
1417 : // JS instanceof operator.
1418 :
1419 847 : Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1420 847 : return Type::Boolean();
1421 : }
1422 :
1423 2926 : Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1424 2926 : return Type::Boolean();
1425 : }
1426 :
1427 158 : Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1428 158 : return Type::Boolean();
1429 : }
1430 :
1431 : Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1432 : return Type::Callable();
1433 : }
1434 :
1435 : // JS context operators.
1436 :
1437 308454 : Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1438 308454 : ContextAccess const& access = ContextAccessOf(node->op());
1439 : switch (access.index()) {
1440 : case Context::PREVIOUS_INDEX:
1441 : case Context::NATIVE_CONTEXT_INDEX:
1442 : case Context::SCOPE_INFO_INDEX:
1443 : return Type::OtherInternal();
1444 : default:
1445 : return Type::Any();
1446 : }
1447 : }
1448 :
1449 0 : Type Typer::Visitor::TypeJSStoreContext(Node* node) { UNREACHABLE(); }
1450 :
1451 : Type Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
1452 : return Type::OtherInternal();
1453 : }
1454 :
1455 : Type Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
1456 : return Type::OtherInternal();
1457 : }
1458 :
1459 : Type Typer::Visitor::TypeJSCreateWithContext(Node* node) {
1460 : return Type::OtherInternal();
1461 : }
1462 :
1463 : Type Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
1464 : return Type::OtherInternal();
1465 : }
1466 :
1467 : // JS other operators.
1468 :
1469 : Type Typer::Visitor::TypeJSConstructForwardVarargs(Node* node) {
1470 : return Type::Receiver();
1471 : }
1472 :
1473 : Type Typer::Visitor::TypeJSConstruct(Node* node) { return Type::Receiver(); }
1474 :
1475 : Type Typer::Visitor::TypeJSConstructWithArrayLike(Node* node) {
1476 : return Type::Receiver();
1477 : }
1478 :
1479 : Type Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
1480 : return Type::Receiver();
1481 : }
1482 :
1483 : Type Typer::Visitor::TypeJSObjectIsArray(Node* node) { return Type::Boolean(); }
1484 :
1485 : Type Typer::Visitor::TypeDateNow(Node* node) { return Type::Number(); }
1486 :
1487 522359 : Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1488 522359 : if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
1489 : return Type::NonInternal();
1490 : }
1491 31490 : JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1492 31490 : if (!function.shared().HasBuiltinId()) {
1493 : return Type::NonInternal();
1494 : }
1495 9788 : switch (function.shared().builtin_id()) {
1496 : case Builtins::kMathRandom:
1497 : return Type::PlainNumber();
1498 : case Builtins::kMathFloor:
1499 : case Builtins::kMathCeil:
1500 : case Builtins::kMathRound:
1501 : case Builtins::kMathTrunc:
1502 12 : return t->cache_->kIntegerOrMinusZeroOrNaN;
1503 : // Unary math functions.
1504 : case Builtins::kMathAbs:
1505 : case Builtins::kMathExp:
1506 6 : return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1507 : case Builtins::kMathAcos:
1508 : case Builtins::kMathAcosh:
1509 : case Builtins::kMathAsin:
1510 : case Builtins::kMathAsinh:
1511 : case Builtins::kMathAtan:
1512 : case Builtins::kMathAtanh:
1513 : case Builtins::kMathCbrt:
1514 : case Builtins::kMathCos:
1515 : case Builtins::kMathExpm1:
1516 : case Builtins::kMathFround:
1517 : case Builtins::kMathLog:
1518 : case Builtins::kMathLog1p:
1519 : case Builtins::kMathLog10:
1520 : case Builtins::kMathLog2:
1521 : case Builtins::kMathSin:
1522 : case Builtins::kMathSqrt:
1523 : case Builtins::kMathTan:
1524 : return Type::Number();
1525 : case Builtins::kMathSign:
1526 1 : return t->cache_->kMinusOneToOneOrMinusZeroOrNaN;
1527 : // Binary math functions.
1528 : case Builtins::kMathAtan2:
1529 : case Builtins::kMathPow:
1530 : case Builtins::kMathMax:
1531 : case Builtins::kMathMin:
1532 : return Type::Number();
1533 : case Builtins::kMathImul:
1534 : return Type::Signed32();
1535 : case Builtins::kMathClz32:
1536 6 : return t->cache_->kZeroToThirtyTwo;
1537 : // Date functions.
1538 : case Builtins::kDateNow:
1539 0 : return t->cache_->kTimeValueType;
1540 : case Builtins::kDatePrototypeGetDate:
1541 8 : return t->cache_->kJSDateDayType;
1542 : case Builtins::kDatePrototypeGetDay:
1543 8 : return t->cache_->kJSDateWeekdayType;
1544 : case Builtins::kDatePrototypeGetFullYear:
1545 8 : return t->cache_->kJSDateYearType;
1546 : case Builtins::kDatePrototypeGetHours:
1547 8 : return t->cache_->kJSDateHourType;
1548 : case Builtins::kDatePrototypeGetMilliseconds:
1549 : return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
1550 8 : t->zone());
1551 : case Builtins::kDatePrototypeGetMinutes:
1552 8 : return t->cache_->kJSDateMinuteType;
1553 : case Builtins::kDatePrototypeGetMonth:
1554 8 : return t->cache_->kJSDateMonthType;
1555 : case Builtins::kDatePrototypeGetSeconds:
1556 8 : return t->cache_->kJSDateSecondType;
1557 : case Builtins::kDatePrototypeGetTime:
1558 0 : return t->cache_->kJSDateValueType;
1559 :
1560 : // Symbol functions.
1561 : case Builtins::kSymbolConstructor:
1562 : return Type::Symbol();
1563 : case Builtins::kSymbolPrototypeToString:
1564 : return Type::String();
1565 : case Builtins::kSymbolPrototypeValueOf:
1566 : return Type::Symbol();
1567 :
1568 : // BigInt functions.
1569 : case Builtins::kBigIntConstructor:
1570 : return Type::BigInt();
1571 :
1572 : // Number functions.
1573 : case Builtins::kNumberConstructor:
1574 : return Type::Number();
1575 : case Builtins::kNumberIsFinite:
1576 : case Builtins::kNumberIsInteger:
1577 : case Builtins::kNumberIsNaN:
1578 : case Builtins::kNumberIsSafeInteger:
1579 : return Type::Boolean();
1580 : case Builtins::kNumberParseFloat:
1581 : return Type::Number();
1582 : case Builtins::kNumberParseInt:
1583 1 : return t->cache_->kIntegerOrMinusZeroOrNaN;
1584 : case Builtins::kNumberToString:
1585 : return Type::NonEmptyOneByteString();
1586 :
1587 : // String functions.
1588 : case Builtins::kStringConstructor:
1589 : return Type::String();
1590 : case Builtins::kStringPrototypeCharCodeAt:
1591 : return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
1592 115 : t->zone());
1593 : case Builtins::kStringCharAt:
1594 : return Type::String();
1595 : case Builtins::kStringPrototypeCodePointAt:
1596 : return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
1597 108 : Type::Undefined(), t->zone());
1598 : case Builtins::kStringPrototypeConcat:
1599 : case Builtins::kStringFromCharCode:
1600 : case Builtins::kStringFromCodePoint:
1601 : return Type::String();
1602 : case Builtins::kStringPrototypeIndexOf:
1603 : case Builtins::kStringPrototypeLastIndexOf:
1604 47 : return Type::Range(-1.0, String::kMaxLength, t->zone());
1605 : case Builtins::kStringPrototypeEndsWith:
1606 : case Builtins::kStringPrototypeIncludes:
1607 : return Type::Boolean();
1608 : case Builtins::kStringRaw:
1609 : case Builtins::kStringRepeat:
1610 : case Builtins::kStringPrototypeSlice:
1611 : return Type::String();
1612 : case Builtins::kStringPrototypeStartsWith:
1613 : return Type::Boolean();
1614 : case Builtins::kStringPrototypeSubstr:
1615 : case Builtins::kStringSubstring:
1616 : case Builtins::kStringPrototypeToString:
1617 : #ifdef V8_INTL_SUPPORT
1618 : case Builtins::kStringPrototypeToLowerCaseIntl:
1619 : case Builtins::kStringPrototypeToUpperCaseIntl:
1620 : #else
1621 : case Builtins::kStringPrototypeToLowerCase:
1622 : case Builtins::kStringPrototypeToUpperCase:
1623 : #endif
1624 : case Builtins::kStringPrototypeTrim:
1625 : case Builtins::kStringPrototypeTrimEnd:
1626 : case Builtins::kStringPrototypeTrimStart:
1627 : case Builtins::kStringPrototypeValueOf:
1628 : return Type::String();
1629 :
1630 : case Builtins::kStringPrototypeIterator:
1631 : case Builtins::kStringIteratorPrototypeNext:
1632 : return Type::OtherObject();
1633 :
1634 : case Builtins::kArrayPrototypeEntries:
1635 : case Builtins::kArrayPrototypeKeys:
1636 : case Builtins::kArrayPrototypeValues:
1637 : case Builtins::kTypedArrayPrototypeEntries:
1638 : case Builtins::kTypedArrayPrototypeKeys:
1639 : case Builtins::kTypedArrayPrototypeValues:
1640 : case Builtins::kArrayIteratorPrototypeNext:
1641 : case Builtins::kMapIteratorPrototypeNext:
1642 : case Builtins::kSetIteratorPrototypeNext:
1643 : return Type::OtherObject();
1644 : case Builtins::kTypedArrayPrototypeToStringTag:
1645 : return Type::Union(Type::InternalizedOneByteString(), Type::Undefined(),
1646 2 : t->zone());
1647 :
1648 : // Array functions.
1649 : case Builtins::kArrayIsArray:
1650 : return Type::Boolean();
1651 : case Builtins::kArrayConcat:
1652 : return Type::Receiver();
1653 : case Builtins::kArrayEvery:
1654 : return Type::Boolean();
1655 : case Builtins::kArrayPrototypeFill:
1656 : case Builtins::kArrayFilter:
1657 : return Type::Receiver();
1658 : case Builtins::kArrayPrototypeFindIndex:
1659 28 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1660 : case Builtins::kArrayForEach:
1661 : return Type::Undefined();
1662 : case Builtins::kArrayIncludes:
1663 : return Type::Boolean();
1664 : case Builtins::kArrayIndexOf:
1665 61 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1666 : case Builtins::kArrayPrototypeJoin:
1667 : return Type::String();
1668 : case Builtins::kArrayPrototypeLastIndexOf:
1669 69 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1670 : case Builtins::kArrayMap:
1671 : return Type::Receiver();
1672 : case Builtins::kArrayPush:
1673 0 : return t->cache_->kPositiveSafeInteger;
1674 : case Builtins::kArrayPrototypeReverse:
1675 : case Builtins::kArrayPrototypeSlice:
1676 : return Type::Receiver();
1677 : case Builtins::kArraySome:
1678 : return Type::Boolean();
1679 : case Builtins::kArrayPrototypeSplice:
1680 : return Type::Receiver();
1681 : case Builtins::kArrayUnshift:
1682 0 : return t->cache_->kPositiveSafeInteger;
1683 :
1684 : // ArrayBuffer functions.
1685 : case Builtins::kArrayBufferIsView:
1686 : return Type::Boolean();
1687 :
1688 : // Object functions.
1689 : case Builtins::kObjectAssign:
1690 : return Type::Receiver();
1691 : case Builtins::kObjectCreate:
1692 : return Type::OtherObject();
1693 : case Builtins::kObjectIs:
1694 : case Builtins::kObjectPrototypeHasOwnProperty:
1695 : case Builtins::kObjectPrototypeIsPrototypeOf:
1696 : return Type::Boolean();
1697 : case Builtins::kObjectToString:
1698 : return Type::String();
1699 :
1700 : case Builtins::kPromiseAll:
1701 : return Type::Receiver();
1702 : case Builtins::kPromisePrototypeThen:
1703 : return Type::Receiver();
1704 : case Builtins::kPromiseRace:
1705 : return Type::Receiver();
1706 : case Builtins::kPromiseReject:
1707 : return Type::Receiver();
1708 : case Builtins::kPromiseResolveTrampoline:
1709 : return Type::Receiver();
1710 :
1711 : // RegExp functions.
1712 : case Builtins::kRegExpPrototypeCompile:
1713 : return Type::OtherObject();
1714 : case Builtins::kRegExpPrototypeExec:
1715 128 : return Type::Union(Type::Array(), Type::Null(), t->zone());
1716 : case Builtins::kRegExpPrototypeTest:
1717 : return Type::Boolean();
1718 : case Builtins::kRegExpPrototypeToString:
1719 : return Type::String();
1720 :
1721 : // Function functions.
1722 : case Builtins::kFunctionPrototypeBind:
1723 : return Type::BoundFunction();
1724 : case Builtins::kFunctionPrototypeHasInstance:
1725 : return Type::Boolean();
1726 :
1727 : // Global functions.
1728 : case Builtins::kGlobalDecodeURI:
1729 : case Builtins::kGlobalDecodeURIComponent:
1730 : case Builtins::kGlobalEncodeURI:
1731 : case Builtins::kGlobalEncodeURIComponent:
1732 : case Builtins::kGlobalEscape:
1733 : case Builtins::kGlobalUnescape:
1734 : return Type::String();
1735 : case Builtins::kGlobalIsFinite:
1736 : case Builtins::kGlobalIsNaN:
1737 : return Type::Boolean();
1738 :
1739 : // Map functions.
1740 : case Builtins::kMapPrototypeClear:
1741 : case Builtins::kMapPrototypeForEach:
1742 : return Type::Undefined();
1743 : case Builtins::kMapPrototypeDelete:
1744 : case Builtins::kMapPrototypeHas:
1745 : return Type::Boolean();
1746 : case Builtins::kMapPrototypeEntries:
1747 : case Builtins::kMapPrototypeKeys:
1748 : case Builtins::kMapPrototypeSet:
1749 : case Builtins::kMapPrototypeValues:
1750 : return Type::OtherObject();
1751 :
1752 : // Set functions.
1753 : case Builtins::kSetPrototypeAdd:
1754 : case Builtins::kSetPrototypeEntries:
1755 : case Builtins::kSetPrototypeValues:
1756 : return Type::OtherObject();
1757 : case Builtins::kSetPrototypeClear:
1758 : case Builtins::kSetPrototypeForEach:
1759 : return Type::Undefined();
1760 : case Builtins::kSetPrototypeDelete:
1761 : case Builtins::kSetPrototypeHas:
1762 : return Type::Boolean();
1763 :
1764 : // WeakMap functions.
1765 : case Builtins::kWeakMapPrototypeDelete:
1766 : case Builtins::kWeakMapPrototypeHas:
1767 : return Type::Boolean();
1768 : case Builtins::kWeakMapPrototypeSet:
1769 : return Type::OtherObject();
1770 :
1771 : // WeakSet functions.
1772 : case Builtins::kWeakSetPrototypeAdd:
1773 : return Type::OtherObject();
1774 : case Builtins::kWeakSetPrototypeDelete:
1775 : case Builtins::kWeakSetPrototypeHas:
1776 : return Type::Boolean();
1777 : default:
1778 : return Type::NonInternal();
1779 : }
1780 : }
1781 :
1782 : Type Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1783 381 : return TypeUnaryOp(node, JSCallTyper);
1784 : }
1785 :
1786 : Type Typer::Visitor::TypeJSCall(Node* node) {
1787 : // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1788 : // argument types for the JSCallTyper above.
1789 520782 : return TypeUnaryOp(node, JSCallTyper);
1790 : }
1791 :
1792 : Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1793 379 : return TypeUnaryOp(node, JSCallTyper);
1794 : }
1795 :
1796 : Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1797 894 : return TypeUnaryOp(node, JSCallTyper);
1798 : }
1799 :
1800 369932 : Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1801 369932 : switch (CallRuntimeParametersOf(node->op()).id()) {
1802 : case Runtime::kInlineIsJSReceiver:
1803 0 : return TypeUnaryOp(node, ObjectIsReceiver);
1804 : case Runtime::kInlineIsSmi:
1805 0 : return TypeUnaryOp(node, ObjectIsSmi);
1806 : case Runtime::kInlineIsArray:
1807 : case Runtime::kInlineIsTypedArray:
1808 : case Runtime::kInlineIsRegExp:
1809 : return Type::Boolean();
1810 : case Runtime::kInlineCreateIterResultObject:
1811 : return Type::OtherObject();
1812 : case Runtime::kInlineToLength:
1813 0 : return TypeUnaryOp(node, ToLength);
1814 : case Runtime::kInlineToNumber:
1815 0 : return TypeUnaryOp(node, ToNumber);
1816 : case Runtime::kInlineToObject:
1817 0 : return TypeUnaryOp(node, ToObject);
1818 : case Runtime::kInlineToString:
1819 0 : return TypeUnaryOp(node, ToString);
1820 : case Runtime::kHasInPrototypeChain:
1821 : return Type::Boolean();
1822 : default:
1823 : break;
1824 : }
1825 : // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
1826 : // have a few weird runtime calls that return the hole or even FixedArrays;
1827 : // change this once those weird runtime calls have been removed.
1828 : return Type::Any();
1829 : }
1830 :
1831 : Type Typer::Visitor::TypeJSForInEnumerate(Node* node) {
1832 : return Type::OtherInternal();
1833 : }
1834 :
1835 : Type Typer::Visitor::TypeJSForInNext(Node* node) {
1836 3127 : return Type::Union(Type::String(), Type::Undefined(), zone());
1837 : }
1838 :
1839 1381 : Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1840 : STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1841 : Type const cache_type =
1842 1381 : Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1843 1381 : Type const cache_array = Type::OtherInternal();
1844 1381 : Type const cache_length = typer_->cache_->kFixedArrayLengthType;
1845 1381 : return Type::Tuple(cache_type, cache_array, cache_length, zone());
1846 : }
1847 :
1848 : Type Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1849 :
1850 0 : Type Typer::Visitor::TypeJSStoreMessage(Node* node) { UNREACHABLE(); }
1851 :
1852 : Type Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1853 :
1854 0 : Type Typer::Visitor::TypeJSStoreModule(Node* node) { UNREACHABLE(); }
1855 :
1856 0 : Type Typer::Visitor::TypeJSGeneratorStore(Node* node) { UNREACHABLE(); }
1857 :
1858 : Type Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1859 : return Type::SignedSmall();
1860 : }
1861 :
1862 : Type Typer::Visitor::TypeJSGeneratorRestoreContext(Node* node) {
1863 : return Type::Any();
1864 : }
1865 :
1866 : Type Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1867 : return Type::Any();
1868 : }
1869 :
1870 : Type Typer::Visitor::TypeJSGeneratorRestoreInputOrDebugPos(Node* node) {
1871 : return Type::Any();
1872 : }
1873 :
1874 : Type Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1875 :
1876 : Type Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1877 :
1878 : Type Typer::Visitor::TypeJSAsyncFunctionEnter(Node* node) {
1879 : return Type::OtherObject();
1880 : }
1881 :
1882 : Type Typer::Visitor::TypeJSAsyncFunctionReject(Node* node) {
1883 : return Type::OtherObject();
1884 : }
1885 :
1886 : Type Typer::Visitor::TypeJSAsyncFunctionResolve(Node* node) {
1887 : return Type::OtherObject();
1888 : }
1889 :
1890 : Type Typer::Visitor::TypeJSFulfillPromise(Node* node) {
1891 : return Type::Undefined();
1892 : }
1893 :
1894 : Type Typer::Visitor::TypeJSPerformPromiseThen(Node* node) {
1895 : return Type::Receiver();
1896 : }
1897 :
1898 : Type Typer::Visitor::TypeJSPromiseResolve(Node* node) {
1899 : return Type::Receiver();
1900 : }
1901 :
1902 : Type Typer::Visitor::TypeJSRejectPromise(Node* node) {
1903 : return Type::Undefined();
1904 : }
1905 :
1906 : Type Typer::Visitor::TypeJSResolvePromise(Node* node) {
1907 : return Type::Undefined();
1908 : }
1909 :
1910 : // Simplified operators.
1911 :
1912 : Type Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1913 :
1914 : // static
1915 30419 : Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1916 30419 : return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
1917 : }
1918 :
1919 : // static
1920 124570 : Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1921 : return FalsifyUndefined(
1922 249128 : NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
1923 : }
1924 :
1925 : // static
1926 4235 : Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1927 : return FalsifyUndefined(
1928 8470 : Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
1929 : }
1930 :
1931 : Type Typer::Visitor::TypeNumberEqual(Node* node) {
1932 14270 : return TypeBinaryOp(node, NumberEqualTyper);
1933 : }
1934 :
1935 : Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1936 34437 : return TypeBinaryOp(node, NumberLessThanTyper);
1937 : }
1938 :
1939 : Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1940 2668 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1941 : }
1942 :
1943 : Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1944 18755 : return TypeBinaryOp(node, NumberEqualTyper);
1945 : }
1946 :
1947 : Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1948 130711 : return TypeBinaryOp(node, NumberLessThanTyper);
1949 : }
1950 :
1951 : Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1952 2029 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1953 : }
1954 :
1955 26550 : Type Typer::Visitor::TypeStringConcat(Node* node) {
1956 26550 : Type length = Operand(node, 0);
1957 26550 : Type first = Operand(node, 1);
1958 26550 : Type second = Operand(node, 2);
1959 26550 : return typer_->operation_typer_.StringConcat(length, first, second);
1960 : }
1961 :
1962 : Type Typer::Visitor::TypeStringToNumber(Node* node) {
1963 0 : return TypeUnaryOp(node, ToNumber);
1964 : }
1965 :
1966 : Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1967 2229 : return TypeUnaryOp(node, ToNumber);
1968 : }
1969 :
1970 : Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1971 : return Type::Integral32();
1972 : }
1973 :
1974 : Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1975 : return Type::Number();
1976 : }
1977 :
1978 : // static
1979 252220 : Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
1980 268184 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1981 5585 : return t->singleton_true_;
1982 : }
1983 : return Type::Boolean();
1984 : }
1985 :
1986 : Type Typer::Visitor::TypeReferenceEqual(Node* node) {
1987 253741 : return TypeBinaryOp(node, ReferenceEqualTyper);
1988 : }
1989 :
1990 : // static
1991 311 : Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
1992 311 : return t->operation_typer()->SameValue(lhs, rhs);
1993 : }
1994 :
1995 : Type Typer::Visitor::TypeSameValue(Node* node) {
1996 311 : return TypeBinaryOp(node, SameValueTyper);
1997 : }
1998 :
1999 0 : Type Typer::Visitor::TypeNumberSameValue(Node* node) { UNREACHABLE(); }
2000 :
2001 : Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
2002 :
2003 : Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
2004 :
2005 : Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
2006 : return Type::Boolean();
2007 : }
2008 :
2009 1483 : Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
2010 1483 : return Type::NonEmptyString();
2011 : }
2012 :
2013 225 : Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
2014 225 : return Type::NonEmptyString();
2015 : }
2016 :
2017 : Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
2018 : return Type::String();
2019 : }
2020 :
2021 : Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
2022 : return Type::String();
2023 : }
2024 :
2025 : Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2026 2868 : return typer_->cache_->kUint16;
2027 : }
2028 :
2029 : Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2030 367 : return Type::Range(0.0, String::kMaxCodePoint, zone());
2031 : }
2032 :
2033 : Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2034 1617 : return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2035 : }
2036 :
2037 : Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2038 313 : return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2039 : }
2040 :
2041 : Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2042 279 : return Type::Range(-1.0, String::kMaxLength, zone());
2043 : }
2044 :
2045 : Type Typer::Visitor::TypeStringLength(Node* node) {
2046 57060 : return typer_->cache_->kStringLengthType;
2047 : }
2048 :
2049 : Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
2050 :
2051 3019 : Type Typer::Visitor::TypePoisonIndex(Node* node) {
2052 6038 : return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone());
2053 : }
2054 :
2055 71217 : Type Typer::Visitor::TypeCheckBounds(Node* node) {
2056 71217 : return typer_->operation_typer_.CheckBounds(Operand(node, 0),
2057 71217 : Operand(node, 1));
2058 : }
2059 :
2060 : Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
2061 : Type type = Operand(node, 0);
2062 : return type;
2063 : }
2064 :
2065 0 : Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
2066 :
2067 18 : Type Typer::Visitor::TypeCheckNonEmptyString(Node* node) {
2068 18 : return typer_->operation_typer_.CheckNonEmptyString(Operand(node, 0));
2069 : }
2070 :
2071 1831 : Type Typer::Visitor::TypeCheckNonEmptyOneByteString(Node* node) {
2072 1831 : return typer_->operation_typer_.CheckNonEmptyOneByteString(Operand(node, 0));
2073 : }
2074 :
2075 226 : Type Typer::Visitor::TypeCheckNonEmptyTwoByteString(Node* node) {
2076 226 : return typer_->operation_typer_.CheckNonEmptyTwoByteString(Operand(node, 0));
2077 : }
2078 :
2079 3601 : Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
2080 3601 : return typer_->operation_typer_.CheckInternalizedString(Operand(node, 0));
2081 : }
2082 :
2083 0 : Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
2084 :
2085 : Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
2086 :
2087 3217 : Type Typer::Visitor::TypeCheckNumber(Node* node) {
2088 3217 : return typer_->operation_typer_.CheckNumber(Operand(node, 0));
2089 : }
2090 :
2091 879 : Type Typer::Visitor::TypeCheckReceiver(Node* node) {
2092 879 : Type arg = Operand(node, 0);
2093 879 : return Type::Intersect(arg, Type::Receiver(), zone());
2094 : }
2095 :
2096 72 : Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2097 72 : Type arg = Operand(node, 0);
2098 72 : return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone());
2099 : }
2100 :
2101 47132 : Type Typer::Visitor::TypeCheckSmi(Node* node) {
2102 47132 : Type arg = Operand(node, 0);
2103 47132 : return Type::Intersect(arg, Type::SignedSmall(), zone());
2104 : }
2105 :
2106 23539 : Type Typer::Visitor::TypeCheckString(Node* node) {
2107 23539 : return typer_->operation_typer_.CheckString(Operand(node, 0));
2108 : }
2109 :
2110 32 : Type Typer::Visitor::TypeCheckSymbol(Node* node) {
2111 32 : Type arg = Operand(node, 0);
2112 32 : return Type::Intersect(arg, Type::Symbol(), zone());
2113 : }
2114 :
2115 654 : Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2116 654 : return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2117 : }
2118 :
2119 148 : Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
2120 : Type type = Operand(node, 0);
2121 148 : type = Type::Intersect(type, Type::NonInternal(), zone());
2122 148 : return type;
2123 : }
2124 :
2125 79905 : Type Typer::Visitor::TypeConvertReceiver(Node* node) {
2126 79905 : Type arg = Operand(node, 0);
2127 79905 : return typer_->operation_typer_.ConvertReceiver(arg);
2128 : }
2129 :
2130 2538 : Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
2131 2538 : Type type = Operand(node, 0);
2132 5076 : return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2133 : }
2134 :
2135 0 : Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2136 0 : UNREACHABLE();
2137 : }
2138 :
2139 0 : Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2140 :
2141 : Type Typer::Visitor::TypeAllocate(Node* node) {
2142 142102 : return AllocateTypeOf(node->op());
2143 : }
2144 :
2145 0 : Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2146 :
2147 : Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2148 : return Type::NonInternal();
2149 : }
2150 :
2151 : Type Typer::Visitor::TypeLoadField(Node* node) {
2152 1079722 : return FieldAccessOf(node->op()).type;
2153 : }
2154 :
2155 : Type Typer::Visitor::TypeLoadMessage(Node* node) { return Type::Any(); }
2156 :
2157 : Type Typer::Visitor::TypeLoadElement(Node* node) {
2158 25037 : return ElementAccessOf(node->op()).type;
2159 : }
2160 :
2161 : Type Typer::Visitor::TypeLoadStackArgument(Node* node) {
2162 : return Type::NonInternal();
2163 : }
2164 :
2165 5739 : Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2166 5739 : switch (ExternalArrayTypeOf(node->op())) {
2167 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2168 : case kExternal##ElemType##Array: \
2169 : return typer_->cache_->k##ElemType;
2170 565 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2171 : #undef TYPED_ARRAY_CASE
2172 : }
2173 0 : UNREACHABLE();
2174 : }
2175 :
2176 282 : Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
2177 282 : switch (ExternalArrayTypeOf(node->op())) {
2178 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2179 : case kExternal##ElemType##Array: \
2180 : return typer_->cache_->k##ElemType;
2181 39 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2182 : #undef TYPED_ARRAY_CASE
2183 : }
2184 0 : UNREACHABLE();
2185 : }
2186 :
2187 0 : Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2188 0 : Type Typer::Visitor::TypeStoreMessage(Node* node) { UNREACHABLE(); }
2189 :
2190 0 : Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2191 :
2192 0 : Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2193 0 : UNREACHABLE();
2194 : }
2195 :
2196 0 : Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2197 0 : UNREACHABLE();
2198 : }
2199 :
2200 0 : Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2201 0 : UNREACHABLE();
2202 : }
2203 :
2204 0 : Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2205 :
2206 0 : Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2207 :
2208 0 : Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }
2209 :
2210 : Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2211 16 : return TypeUnaryOp(node, ObjectIsArrayBufferView);
2212 : }
2213 :
2214 : Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2215 27 : return TypeUnaryOp(node, ObjectIsBigInt);
2216 : }
2217 :
2218 : Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2219 2001 : return TypeUnaryOp(node, ObjectIsCallable);
2220 : }
2221 :
2222 : Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2223 415 : return TypeUnaryOp(node, ObjectIsConstructor);
2224 : }
2225 :
2226 : Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2227 17699 : return TypeUnaryOp(node, ObjectIsDetectableCallable);
2228 : }
2229 :
2230 : Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2231 0 : return TypeUnaryOp(node, ObjectIsMinusZero);
2232 : }
2233 :
2234 : Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
2235 0 : return TypeUnaryOp(node, NumberIsMinusZero);
2236 : }
2237 :
2238 : Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2239 : return Type::Boolean();
2240 : }
2241 :
2242 : Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2243 :
2244 : Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2245 : return Type::Boolean();
2246 : }
2247 :
2248 0 : Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2249 :
2250 : Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2251 : return Type::Boolean();
2252 : }
2253 :
2254 0 : Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2255 :
2256 : Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2257 :
2258 : Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2259 4614 : return TypeUnaryOp(node, ObjectIsNaN);
2260 : }
2261 :
2262 : Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2263 5760 : return TypeUnaryOp(node, NumberIsNaN);
2264 : }
2265 :
2266 : Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2267 9212 : return TypeUnaryOp(node, ObjectIsNonCallable);
2268 : }
2269 :
2270 : Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2271 10639 : return TypeUnaryOp(node, ObjectIsNumber);
2272 : }
2273 :
2274 : Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2275 27830 : return TypeUnaryOp(node, ObjectIsReceiver);
2276 : }
2277 :
2278 : Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2279 1833 : return TypeUnaryOp(node, ObjectIsSmi);
2280 : }
2281 :
2282 : Type Typer::Visitor::TypeObjectIsString(Node* node) {
2283 2472 : return TypeUnaryOp(node, ObjectIsString);
2284 : }
2285 :
2286 : Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2287 123 : return TypeUnaryOp(node, ObjectIsSymbol);
2288 : }
2289 :
2290 : Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2291 1948 : return TypeUnaryOp(node, ObjectIsUndetectable);
2292 : }
2293 :
2294 : Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2295 17732 : return TypeCache::Get()->kArgumentsLengthType;
2296 : }
2297 :
2298 : Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2299 : return Type::ExternalPointer();
2300 : }
2301 :
2302 : Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2303 : return Type::OtherInternal();
2304 : }
2305 :
2306 : Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2307 : return Type::OtherInternal();
2308 : }
2309 :
2310 : Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2311 : return Type::OtherInternal();
2312 : }
2313 :
2314 0 : Type Typer::Visitor::TypeNewConsString(Node* node) { UNREACHABLE(); }
2315 :
2316 0 : Type Typer::Visitor::TypeNewConsOneByteString(Node* node) { UNREACHABLE(); }
2317 :
2318 0 : Type Typer::Visitor::TypeNewConsTwoByteString(Node* node) { UNREACHABLE(); }
2319 :
2320 : Type Typer::Visitor::TypeDelayedStringConstant(Node* node) {
2321 : return Type::String();
2322 : }
2323 :
2324 : Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2325 198 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2326 : }
2327 :
2328 : Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2329 0 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2330 : }
2331 :
2332 0 : Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2333 :
2334 : // Heap constants.
2335 :
2336 0 : Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2337 6017528 : return Type::NewConstant(typer_->broker(), value, zone());
2338 : }
2339 :
2340 : } // namespace compiler
2341 : } // namespace internal
2342 122004 : } // namespace v8
|