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 464331 : explicit Decorator(Typer* typer) : typer_(typer) {}
30 : void Decorate(Node* node) final;
31 :
32 : private:
33 : Typer* const typer_;
34 : };
35 :
36 464329 : Typer::Typer(JSHeapBroker* broker, Flags flags, Graph* graph)
37 : : flags_(flags),
38 : graph_(graph),
39 : decorator_(nullptr),
40 464329 : cache_(TypeCache::Get()),
41 : broker_(broker),
42 928668 : operation_typer_(broker, zone()) {
43 464346 : singleton_false_ = operation_typer_.singleton_false();
44 464346 : singleton_true_ = operation_typer_.singleton_true();
45 :
46 464331 : decorator_ = new (zone()) Decorator(this);
47 464331 : graph_->AddDecorator(decorator_);
48 464335 : }
49 :
50 :
51 928666 : Typer::~Typer() {
52 464338 : graph_->RemoveDecorator(decorator_);
53 464328 : }
54 :
55 :
56 10604810 : class Typer::Visitor : public Reducer {
57 : public:
58 5302411 : explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
59 : : typer_(typer),
60 : induction_vars_(induction_vars),
61 : weakened_nodes_(typer->zone()),
62 10604711 : remembered_types_(typer->zone()) {}
63 :
64 0 : const char* reducer_name() const override { return "Typer"; }
65 :
66 39075871 : Reduction Reduce(Node* node) override {
67 39075871 : if (node->op()->ValueOutputCount() == 0) return NoChange();
68 28642159 : switch (node->opcode()) {
69 : #define DECLARE_CASE(x) \
70 : case IrOpcode::k##x: \
71 : return UpdateType(node, TypeBinaryOp(node, x##Typer));
72 18220 : 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 463837 : DECLARE_CASE(Start)
79 208493 : DECLARE_CASE(IfException)
80 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
81 2154507 : COMMON_OP_LIST(DECLARE_CASE)
82 376465 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
83 1245866 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
84 333334 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
85 77 : JS_OBJECT_OP_LIST(DECLARE_CASE)
86 305176 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
87 522489 : 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 16097 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
94 116416 : 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 575 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
101 96387 : 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 4838340 : Type TypeNode(Node* node) {
137 4838340 : 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 1141917 : COMMON_OP_LIST(DECLARE_CASE)
148 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
149 61936 : 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 6326 : 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 121599 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
160 414 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
161 : #undef DECLARE_CASE
162 :
163 : #define DECLARE_CASE(x) \
164 : case IrOpcode::k##x: \
165 : return TypeUnaryOp(node, x);
166 8 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
167 646 : 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 8428672 : : Type::None();
223 : }
224 :
225 : Type Operand(Node* node, int i) {
226 8410436 : 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 : typedef Type (*UnaryTyperFun)(Type, Typer* t);
241 : typedef Type (*BinaryTyperFun)(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 : typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;
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 73599 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
279 94442 : 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 588054 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
286 480080 : 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 28641772 : Reduction UpdateType(Node* node, Type current) {
324 28641772 : if (NodeProperties::IsTyped(node)) {
325 : // Widen the type of a previously typed node.
326 5967768 : Type previous = NodeProperties::GetType(node);
327 5967768 : if (node->opcode() == IrOpcode::kPhi ||
328 : node->opcode() == IrOpcode::kInductionVariablePhi) {
329 : // Speed up termination in the presence of range types:
330 557568 : current = Weaken(node, current, previous);
331 : }
332 :
333 5967744 : 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 5967744 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
371 22495 : for (int i = 0; i < 2; ++i) {
372 8998 : Node* input = NodeProperties::GetValueInput(node, i);
373 8998 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
374 : ? NodeProperties::GetType(input)
375 8998 : : Type::Invalid();
376 : }
377 4499 : remembered_types_[{node, 2}] = current;
378 : }
379 :
380 : NodeProperties::SetType(node, current);
381 5967741 : if (!current.Is(previous)) {
382 : // If something changed, revisit all uses.
383 : return Changed(node);
384 : }
385 : return NoChange();
386 : } else {
387 22674004 : if (V8_UNLIKELY(node->opcode() == IrOpcode::kNumberAdd)) {
388 57990 : for (int i = 0; i < 2; ++i) {
389 23196 : Node* input = NodeProperties::GetValueInput(node, i);
390 23196 : remembered_types_[{node, i}] = NodeProperties::IsTyped(input)
391 : ? NodeProperties::GetType(input)
392 23196 : : Type::Invalid();
393 : }
394 11598 : 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 464063 : void Typer::Run(const NodeVector& roots,
407 : LoopVariableOptimizer* induction_vars) {
408 464063 : if (induction_vars != nullptr) {
409 463828 : induction_vars->ChangeToInductionVariablePhis();
410 : }
411 928125 : Visitor visitor(this, induction_vars);
412 928141 : GraphReducer graph_reducer(zone(), graph());
413 464086 : graph_reducer.AddReducer(&visitor);
414 6779242 : for (Node* const root : roots) graph_reducer.ReduceNode(root);
415 464089 : graph_reducer.ReduceGraph();
416 :
417 464087 : if (induction_vars != nullptr) {
418 463840 : induction_vars->ChangeToPhisAndInsertGuards();
419 : }
420 464083 : }
421 :
422 6545997 : void Typer::Decorator::Decorate(Node* node) {
423 6545997 : 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 4895053 : if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
428 9676623 : Visitor typing(typer_, nullptr);
429 4838236 : Type type = typing.TypeNode(node);
430 4838274 : if (is_typed) {
431 : type = Type::Intersect(type, NodeProperties::GetType(node),
432 0 : typer_->zone());
433 : }
434 : NodeProperties::SetType(node, type);
435 : }
436 : }
437 6546018 : }
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 1267045 : Type Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
447 : Type input = Operand(node, 0);
448 1267049 : return input.IsNone() ? Type::None() : f(input, typer_);
449 : }
450 :
451 1936286 : Type Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
452 : Type left = Operand(node, 0);
453 : Type right = Operand(node, 1);
454 1813104 : return left.IsNone() || right.IsNone() ? Type::None()
455 3742080 : : f(left, right, typer_);
456 : }
457 :
458 202974 : Type Typer::Visitor::BinaryNumberOpTyper(Type lhs, Type rhs, Typer* t,
459 : BinaryTyperFun f) {
460 202974 : lhs = ToNumeric(lhs, t);
461 202974 : rhs = ToNumeric(rhs, t);
462 : bool lhs_is_number = lhs.Is(Type::Number());
463 : bool rhs_is_number = rhs.Is(Type::Number());
464 202974 : if (lhs_is_number && rhs_is_number) {
465 158301 : return f(lhs, rhs, t);
466 : }
467 : // In order to maintain monotonicity, the following two conditions are
468 : // intentionally asymmetric.
469 44673 : if (lhs_is_number) {
470 : return Type::Number();
471 : }
472 33438 : 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 12264 : if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
482 12264 : if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
483 12264 : if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
484 0 : return result;
485 : }
486 :
487 0 : Type Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
488 377045 : if ((outcome & kComparisonFalse) != 0 ||
489 : (outcome & kComparisonUndefined) != 0) {
490 : return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
491 350407 : : t->singleton_false_;
492 : }
493 : // Type should be non empty, so we know it should be true.
494 : DCHECK_NE(0, outcome & kComparisonTrue);
495 12962 : 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 6265 : Type Typer::Visitor::Decrement(Type type, Typer* t) {
507 6265 : type = ToNumeric(type, t);
508 6265 : if (type.Is(Type::Number())) {
509 3798 : return NumberSubtract(type, t->cache_->kSingletonOne, t);
510 : }
511 : return Type::Numeric();
512 : }
513 :
514 260753 : Type Typer::Visitor::Increment(Type type, Typer* t) {
515 260753 : type = ToNumeric(type, t);
516 260753 : if (type.Is(Type::Number())) {
517 250424 : return NumberAdd(type, t->cache_->kSingletonOne, t);
518 : }
519 : return Type::Numeric();
520 : }
521 :
522 4412 : Type Typer::Visitor::Negate(Type type, Typer* t) {
523 4412 : type = ToNumeric(type, t);
524 4412 : 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 912889 : Type Typer::Visitor::ToPrimitive(Type type, Typer* t) {
533 912889 : if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
534 736908 : return type;
535 : }
536 : return Type::Primitive();
537 : }
538 :
539 136881 : Type Typer::Visitor::ToBoolean(Type type, Typer* t) {
540 136881 : return t->operation_typer()->ToBoolean(type);
541 : }
542 :
543 :
544 : // static
545 112 : Type Typer::Visitor::ToInteger(Type type, Typer* t) {
546 : // ES6 section 7.1.4 ToInteger ( argument )
547 112 : type = ToNumber(type, t);
548 224 : if (type.Is(t->cache_->kIntegerOrMinusZero)) return type;
549 154 : if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
550 : return Type::Union(
551 2 : Type::Intersect(type, t->cache_->kIntegerOrMinusZero, t->zone()),
552 2 : t->cache_->kSingletonZero, t->zone());
553 : }
554 75 : return t->cache_->kIntegerOrMinusZero;
555 : }
556 :
557 :
558 : // static
559 112 : Type Typer::Visitor::ToLength(Type type, Typer* t) {
560 : // ES6 section 7.1.15 ToLength ( argument )
561 112 : type = ToInteger(type, t);
562 112 : if (type.IsNone()) return type;
563 103 : double min = type.Min();
564 103 : double max = type.Max();
565 103 : if (max <= 0.0) {
566 4 : return Type::NewConstant(0, t->zone());
567 : }
568 99 : if (min >= kMaxSafeInteger) {
569 2 : return Type::NewConstant(kMaxSafeInteger, t->zone());
570 : }
571 97 : if (min <= 0.0) min = 0.0;
572 97 : if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
573 97 : return Type::Range(min, max, t->zone());
574 : }
575 :
576 :
577 : // static
578 1243 : Type Typer::Visitor::ToName(Type type, Typer* t) {
579 : // ES6 section 7.1.14 ToPropertyKey ( argument )
580 1243 : type = ToPrimitive(type, t);
581 1243 : if (type.Is(Type::Name())) return type;
582 1180 : if (type.Maybe(Type::Symbol())) return Type::Name();
583 102 : return ToString(type, t);
584 : }
585 :
586 :
587 : // static
588 11819 : Type Typer::Visitor::ToNumber(Type type, Typer* t) {
589 178271 : return t->operation_typer_.ToNumber(type);
590 : }
591 :
592 : // static
593 355 : Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
594 355 : return t->operation_typer_.ToNumberConvertBigInt(type);
595 : }
596 :
597 : // static
598 49225 : Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
599 1193545 : return t->operation_typer_.ToNumeric(type);
600 : }
601 :
602 : // static
603 2009 : Type Typer::Visitor::ToObject(Type type, Typer* t) {
604 : // ES6 section 7.1.13 ToObject ( argument )
605 2009 : if (type.Is(Type::Receiver())) return type;
606 1563 : if (type.Is(Type::Primitive())) return Type::OtherObject();
607 1451 : if (!type.Maybe(Type::OtherUndetectable())) {
608 : return Type::DetectableReceiver();
609 : }
610 : return Type::Receiver();
611 : }
612 :
613 :
614 : // static
615 2571 : Type Typer::Visitor::ToString(Type type, Typer* t) {
616 : // ES6 section 7.1.12 ToString ( argument )
617 2571 : type = ToPrimitive(type, t);
618 2571 : 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 1918 : Type Typer::Visitor::ObjectIsCallable(Type type, Typer* t) {
637 1918 : if (type.Is(Type::Callable())) return t->singleton_true_;
638 245 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
639 : return Type::Boolean();
640 : }
641 :
642 199 : Type Typer::Visitor::ObjectIsConstructor(Type type, Typer* t) {
643 : // TODO(turbofan): Introduce a Type::Constructor?
644 199 : if (!type.Maybe(Type::Callable())) return t->singleton_false_;
645 : return Type::Boolean();
646 : }
647 :
648 17222 : Type Typer::Visitor::ObjectIsDetectableCallable(Type type, Typer* t) {
649 17222 : if (type.Is(Type::DetectableCallable())) return t->singleton_true_;
650 17110 : 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 4582 : Type Typer::Visitor::ObjectIsNaN(Type type, Typer* t) {
667 4582 : if (type.Is(Type::NaN())) return t->singleton_true_;
668 4575 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
669 : return Type::Boolean();
670 : }
671 :
672 5180 : Type Typer::Visitor::NumberIsNaN(Type type, Typer* t) {
673 5180 : if (type.Is(Type::NaN())) return t->singleton_true_;
674 4571 : if (!type.Maybe(Type::NaN())) return t->singleton_false_;
675 : return Type::Boolean();
676 : }
677 :
678 9047 : Type Typer::Visitor::ObjectIsNonCallable(Type type, Typer* t) {
679 9047 : if (type.Is(Type::NonCallable())) return t->singleton_true_;
680 8723 : if (!type.Maybe(Type::NonCallable())) return t->singleton_false_;
681 : return Type::Boolean();
682 : }
683 :
684 10419 : Type Typer::Visitor::ObjectIsNumber(Type type, Typer* t) {
685 10419 : if (type.Is(Type::Number())) return t->singleton_true_;
686 8914 : if (!type.Maybe(Type::Number())) return t->singleton_false_;
687 : return Type::Boolean();
688 : }
689 :
690 25627 : Type Typer::Visitor::ObjectIsReceiver(Type type, Typer* t) {
691 25627 : if (type.Is(Type::Receiver())) return t->singleton_true_;
692 23637 : if (!type.Maybe(Type::Receiver())) return t->singleton_false_;
693 : return Type::Boolean();
694 : }
695 :
696 1445 : Type Typer::Visitor::ObjectIsSmi(Type type, Typer* t) {
697 1445 : if (!type.Maybe(Type::SignedSmall())) return t->singleton_false_;
698 : return Type::Boolean();
699 : }
700 :
701 2474 : Type Typer::Visitor::ObjectIsString(Type type, Typer* t) {
702 2474 : if (type.Is(Type::String())) return t->singleton_true_;
703 2464 : if (!type.Maybe(Type::String())) return t->singleton_false_;
704 : return Type::Boolean();
705 : }
706 :
707 99 : Type Typer::Visitor::ObjectIsSymbol(Type type, Typer* t) {
708 99 : if (type.Is(Type::Symbol())) return t->singleton_true_;
709 99 : if (!type.Maybe(Type::Symbol())) return t->singleton_false_;
710 : return Type::Boolean();
711 : }
712 :
713 1860 : Type Typer::Visitor::ObjectIsUndetectable(Type type, Typer* t) {
714 1860 : if (type.Is(Type::Undetectable())) return t->singleton_true_;
715 1658 : 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 2001579 : Type Typer::Visitor::TypeParameter(Node* node) {
732 : Node* const start = node->InputAt(0);
733 : DCHECK_EQ(IrOpcode::kStart, start->opcode());
734 2001579 : int const parameter_count = start->op()->ValueOutputCount() - 4;
735 : DCHECK_LE(1, parameter_count);
736 2001579 : int const index = ParameterIndexOf(node->op());
737 2001597 : if (index == Linkage::kJSCallClosureParamIndex) {
738 : return Type::Function();
739 1973624 : } else if (index == 0) {
740 918272 : if (typer_->flags() & Typer::kThisIsReceiver) {
741 : return Type::Receiver();
742 : } else {
743 : // Parameter[this] can be the_hole for derived class constructors.
744 91016 : return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
745 : }
746 1514488 : } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
747 35986 : if (typer_->flags() & Typer::kNewTargetIsReceiver) {
748 : return Type::Receiver();
749 : } else {
750 16848 : return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
751 : }
752 1496495 : } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
753 0 : return Type::Range(0.0, FixedArray::kMaxLength, typer_->zone());
754 1496495 : } 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 1931854 : double number = OpParameter<double>(node->op());
778 1931854 : return Type::NewConstant(number, zone());
779 : }
780 :
781 6005742 : Type Typer::Visitor::TypeHeapConstant(Node* node) {
782 12011481 : 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 17993 : Type Typer::Visitor::TypeSelect(Node* node) {
794 17993 : return Type::Union(Operand(node, 1), Operand(node, 2), zone());
795 : }
796 :
797 872715 : Type Typer::Visitor::TypePhi(Node* node) {
798 : int arity = node->op()->ValueInputCount();
799 : Type type = Operand(node, 0);
800 3634998 : for (int i = 1; i < arity; ++i) {
801 1381143 : type = Type::Union(type, Operand(node, i), zone());
802 : }
803 872701 : return type;
804 : }
805 :
806 24731 : Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
807 24731 : 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 24732 : Type initial_type = Operand(node, 0);
812 24732 : 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 67793 : if (!initial_type.Is(typer_->cache_->kInteger) ||
817 18329 : !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 6641 : : Type::None();
825 33205 : for (int i = 0; i < arity; ++i) {
826 13282 : type = Type::Union(type, Operand(node, i), zone());
827 : }
828 6641 : 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 36161 : if (initial_type.IsNone() ||
833 18070 : increment_type.Is(typer_->cache_->kSingletonZero)) {
834 37 : return initial_type;
835 : }
836 :
837 : // Now process the bounds.
838 18054 : auto res = induction_vars_->induction_variables().find(node->id());
839 : DCHECK(res != induction_vars_->induction_variables().end());
840 18054 : InductionVariable* induction_var = res->second;
841 :
842 : InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
843 :
844 18054 : double min = -V8_INFINITY;
845 18054 : double max = V8_INFINITY;
846 :
847 : double increment_min;
848 : double increment_max;
849 18054 : if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
850 17776 : increment_min = increment_type.Min();
851 17776 : increment_max = increment_type.Max();
852 : } else {
853 : DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
854 278 : increment_min = -increment_type.Max();
855 278 : increment_max = -increment_type.Min();
856 : }
857 :
858 18054 : if (increment_min >= 0) {
859 : // increasing sequence
860 17792 : min = initial_type.Min();
861 35660 : for (auto bound : induction_var->upper_bounds()) {
862 17897 : Type bound_type = TypeOrNone(bound.bound);
863 : // If the type is not an integer, just skip the bound.
864 37930 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
865 : // If the type is not inhabited, then we can take the initial value.
866 15761 : if (bound_type.IsNone()) {
867 29 : max = initial_type.Max();
868 29 : break;
869 : }
870 15732 : double bound_max = bound_type.Max();
871 15732 : if (bound.kind == InductionVariable::kStrict) {
872 15567 : bound_max -= 1;
873 : }
874 31464 : max = std::min(max, bound_max + increment_max);
875 : }
876 : // The upper bound must be at least the initial value's upper bound.
877 35584 : max = std::max(max, initial_type.Max());
878 262 : } else if (increment_max <= 0) {
879 : // decreasing sequence
880 262 : max = initial_type.Max();
881 582 : for (auto bound : induction_var->lower_bounds()) {
882 320 : Type bound_type = TypeOrNone(bound.bound);
883 : // If the type is not an integer, just skip the bound.
884 640 : if (!bound_type.Is(typer_->cache_->kInteger)) continue;
885 : // If the type is not inhabited, then we can take the initial value.
886 320 : if (bound_type.IsNone()) {
887 0 : min = initial_type.Min();
888 0 : break;
889 : }
890 320 : double bound_min = bound_type.Min();
891 320 : if (bound.kind == InductionVariable::kStrict) {
892 144 : bound_min += 1;
893 : }
894 640 : min = std::max(min, bound_min + increment_min);
895 : }
896 : // The lower bound must be at most the initial value's lower bound.
897 524 : 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 18054 : 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 18054 : 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 5991 : Type Typer::Visitor::TypeProjection(Node* node) {
975 5991 : Type const type = Operand(node, 0);
976 5991 : if (type.Is(Type::None())) return Type::None();
977 5991 : int const index = static_cast<int>(ProjectionIndexOf(node->op()));
978 5991 : if (type.IsTuple() && index < type.AsTuple()->Arity()) {
979 4113 : return type.AsTuple()->Element(index);
980 : }
981 : return Type::Any();
982 : }
983 :
984 0 : Type Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
985 :
986 26991 : Type Typer::Visitor::TypeTypeGuard(Node* node) {
987 26991 : Type const type = Operand(node, 0);
988 53982 : 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 48826 : Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs, Typer* t) {
1000 97479 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return t->singleton_false_;
1001 48653 : if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1002 0 : return t->singleton_true_;
1003 : }
1004 173620 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
1005 73519 : (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1006 2109 : return t->singleton_false_;
1007 : }
1008 47168 : 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 183664 : Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs, Typer* t) {
1017 183664 : 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 237139 : Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type lhs,
1025 : Type rhs,
1026 : Typer* t) {
1027 237139 : lhs = ToPrimitive(lhs, t);
1028 237140 : rhs = ToPrimitive(rhs, t);
1029 237140 : if (lhs.Maybe(Type::String()) && rhs.Maybe(Type::String())) {
1030 : return ComparisonOutcome(kComparisonTrue) |
1031 : ComparisonOutcome(kComparisonFalse);
1032 : }
1033 233388 : lhs = ToNumeric(lhs, t);
1034 233388 : rhs = ToNumeric(rhs, t);
1035 459357 : if (lhs.Is(Type::Number()) && rhs.Is(Type::Number())) {
1036 49547 : return NumberCompareTyper(lhs, rhs, t);
1037 : }
1038 : return ComparisonOutcome(kComparisonTrue) |
1039 : ComparisonOutcome(kComparisonFalse) |
1040 : ComparisonOutcome(kComparisonUndefined);
1041 : }
1042 :
1043 175777 : 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 351233 : if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN())) return kComparisonUndefined;
1051 :
1052 : ComparisonOutcome result;
1053 175132 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1054 : // Types are equal and are inhabited only by a single semantic value.
1055 : result = kComparisonFalse;
1056 175132 : } else if (lhs.Min() >= rhs.Max()) {
1057 : result = kComparisonFalse;
1058 173024 : } 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 14805 : if (lhs.Maybe(Type::NaN()) || rhs.Maybe(Type::NaN())) {
1069 : result |= kComparisonUndefined;
1070 : }
1071 14805 : return result;
1072 : }
1073 :
1074 125279 : Type Typer::Visitor::JSLessThanTyper(Type lhs, Type rhs, Typer* t) {
1075 250558 : return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
1076 : }
1077 :
1078 99597 : Type Typer::Visitor::JSGreaterThanTyper(Type lhs, Type rhs, Typer* t) {
1079 199194 : return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1080 : }
1081 :
1082 3959 : Type Typer::Visitor::JSLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1083 7918 : return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1084 : }
1085 :
1086 3683 : Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1087 7366 : return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1088 : }
1089 :
1090 : // JS bitwise operators.
1091 :
1092 12239 : Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs, Typer* t) {
1093 12239 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1094 : }
1095 :
1096 10014 : Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs, Typer* t) {
1097 10014 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1098 : }
1099 :
1100 3131 : Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs, Typer* t) {
1101 3131 : return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1102 : }
1103 :
1104 6326 : Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs, Typer* t) {
1105 6326 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1106 : }
1107 :
1108 4812 : Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs, Typer* t) {
1109 4812 : return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1110 : }
1111 :
1112 4837 : Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs, Typer* t) {
1113 4837 : return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1114 : }
1115 :
1116 :
1117 : // JS arithmetic operators.
1118 :
1119 217398 : Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs, Typer* t) {
1120 217398 : lhs = ToPrimitive(lhs, t);
1121 217398 : rhs = ToPrimitive(rhs, t);
1122 217398 : if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
1123 142932 : 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 122046 : return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1131 : }
1132 :
1133 10510 : Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs, Typer* t) {
1134 10510 : return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1135 : }
1136 :
1137 13559 : Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs, Typer* t) {
1138 13559 : return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1139 : }
1140 :
1141 15542 : Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs, Typer* t) {
1142 15542 : return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1143 : }
1144 :
1145 4795 : Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs, Typer* t) {
1146 4795 : 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 6421 : return TypeUnaryOp(node, Decrement);
1162 : }
1163 :
1164 : Type Typer::Visitor::TypeJSIncrement(Node* node) {
1165 261786 : return TypeUnaryOp(node, Increment);
1166 : }
1167 :
1168 : Type Typer::Visitor::TypeJSNegate(Node* node) {
1169 4416 : 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 142282 : 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 1267 : 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 355 : return TypeUnaryOp(node, ToNumberConvertBigInt);
1197 : }
1198 :
1199 : Type Typer::Visitor::TypeJSToNumeric(Node* node) {
1200 49306 : return TypeUnaryOp(node, ToNumeric);
1201 : }
1202 :
1203 : Type Typer::Visitor::TypeJSToObject(Node* node) {
1204 2043 : return TypeUnaryOp(node, ToObject);
1205 : }
1206 :
1207 : Type Typer::Visitor::TypeJSToString(Node* node) {
1208 2551 : return TypeUnaryOp(node, ToString);
1209 : }
1210 :
1211 : // JS object operators.
1212 :
1213 : Type Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1214 :
1215 19016 : Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1216 19016 : 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 557567 : 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 557567 : Type const integer = typer_->cache_->kInteger;
1342 557567 : if (!previous_type.Maybe(integer)) {
1343 42669 : return current_type;
1344 : }
1345 : DCHECK(current_type.Maybe(integer));
1346 :
1347 514905 : Type current_integer = Type::Intersect(current_type, integer, zone());
1348 514900 : Type previous_integer = Type::Intersect(previous_type, integer, zone());
1349 :
1350 : // Once we start weakening a node, we should always weaken.
1351 514903 : 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 101518 : Type previous = previous_integer.GetRange();
1356 101519 : Type current = current_integer.GetRange();
1357 202938 : if (current.IsInvalid() || previous.IsInvalid()) {
1358 322 : return current_type;
1359 : }
1360 : // Range is involved => we are weakening.
1361 : SetWeakened(node->id());
1362 : }
1363 :
1364 514583 : 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 514583 : if (current_min != previous_integer.Min()) {
1369 : new_min = -V8_INFINITY;
1370 2108883 : for (double const min : kWeakenMinLimits) {
1371 1052938 : if (min <= current_min) {
1372 : new_min = min;
1373 : break;
1374 : }
1375 : }
1376 : }
1377 :
1378 514583 : 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 514579 : if (current_max != previous_integer.Max()) {
1383 : new_max = V8_INFINITY;
1384 9085394 : for (double const max : kWeakenMaxLimits) {
1385 4679686 : 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 514579 : 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 777 : Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs, Typer* t) {
1420 777 : return Type::Boolean();
1421 : }
1422 :
1423 2891 : Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs, Typer* t) {
1424 2891 : return Type::Boolean();
1425 : }
1426 :
1427 211 : Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs, Typer* t) {
1428 211 : return Type::Boolean();
1429 : }
1430 :
1431 : Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1432 : return Type::Callable();
1433 : }
1434 :
1435 : // JS context operators.
1436 :
1437 305196 : Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1438 305196 : 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 527409 : Type Typer::Visitor::JSCallTyper(Type fun, Typer* t) {
1488 527409 : if (!fun.IsHeapConstant() || !fun.AsHeapConstant()->Ref().IsJSFunction()) {
1489 : return Type::NonInternal();
1490 : }
1491 29666 : JSFunctionRef function = fun.AsHeapConstant()->Ref().AsJSFunction();
1492 29666 : if (!function.shared().HasBuiltinId()) {
1493 : return Type::NonInternal();
1494 : }
1495 7870 : 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 9 : return t->cache_->kZeroToThirtyTwo;
1537 : // Date functions.
1538 : case Builtins::kDateNow:
1539 0 : return t->cache_->kTimeValueType;
1540 : case Builtins::kDatePrototypeGetDate:
1541 0 : return t->cache_->kJSDateDayType;
1542 : case Builtins::kDatePrototypeGetDay:
1543 0 : return t->cache_->kJSDateWeekdayType;
1544 : case Builtins::kDatePrototypeGetFullYear:
1545 0 : return t->cache_->kJSDateYearType;
1546 : case Builtins::kDatePrototypeGetHours:
1547 0 : return t->cache_->kJSDateHourType;
1548 : case Builtins::kDatePrototypeGetMilliseconds:
1549 : return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
1550 0 : t->zone());
1551 : case Builtins::kDatePrototypeGetMinutes:
1552 0 : return t->cache_->kJSDateMinuteType;
1553 : case Builtins::kDatePrototypeGetMonth:
1554 0 : return t->cache_->kJSDateMonthType;
1555 : case Builtins::kDatePrototypeGetSeconds:
1556 0 : 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 31 : 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 4 : 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 47 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1666 : case Builtins::kArrayPrototypeJoin:
1667 : return Type::String();
1668 : case Builtins::kArrayPrototypeLastIndexOf:
1669 61 : 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 121 : 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 377 : 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 525804 : return TypeUnaryOp(node, JSCallTyper);
1790 : }
1791 :
1792 : Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1793 419 : return TypeUnaryOp(node, JSCallTyper);
1794 : }
1795 :
1796 : Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1797 888 : return TypeUnaryOp(node, JSCallTyper);
1798 : }
1799 :
1800 366586 : Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
1801 366586 : 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 3097 : return Type::Union(Type::String(), Type::Undefined(), zone());
1837 : }
1838 :
1839 1371 : Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
1840 : STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1841 : Type const cache_type =
1842 1371 : Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1843 1371 : Type const cache_array = Type::OtherInternal();
1844 1371 : Type const cache_length = typer_->cache_->kFixedArrayLengthType;
1845 1371 : 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 30655 : Type Typer::Visitor::NumberEqualTyper(Type lhs, Type rhs, Typer* t) {
1916 30655 : return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
1917 : }
1918 :
1919 : // static
1920 126227 : Type Typer::Visitor::NumberLessThanTyper(Type lhs, Type rhs, Typer* t) {
1921 : return FalsifyUndefined(
1922 252458 : NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
1923 : }
1924 :
1925 : // static
1926 4621 : Type Typer::Visitor::NumberLessThanOrEqualTyper(Type lhs, Type rhs, Typer* t) {
1927 : return FalsifyUndefined(
1928 9243 : Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
1929 : }
1930 :
1931 : Type Typer::Visitor::TypeNumberEqual(Node* node) {
1932 14488 : return TypeBinaryOp(node, NumberEqualTyper);
1933 : }
1934 :
1935 : Type Typer::Visitor::TypeNumberLessThan(Node* node) {
1936 35067 : return TypeBinaryOp(node, NumberLessThanTyper);
1937 : }
1938 :
1939 : Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1940 2847 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1941 : }
1942 :
1943 : Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1944 18751 : return TypeBinaryOp(node, NumberEqualTyper);
1945 : }
1946 :
1947 : Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1948 131871 : return TypeBinaryOp(node, NumberLessThanTyper);
1949 : }
1950 :
1951 : Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1952 2232 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1953 : }
1954 :
1955 26586 : Type Typer::Visitor::TypeStringConcat(Node* node) {
1956 26586 : Type length = Operand(node, 0);
1957 26586 : Type first = Operand(node, 1);
1958 26586 : Type second = Operand(node, 2);
1959 26586 : 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 2271 : 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 252276 : Type Typer::Visitor::ReferenceEqualTyper(Type lhs, Type rhs, Typer* t) {
1980 267290 : if (lhs.IsHeapConstant() && rhs.Is(lhs)) {
1981 5352 : return t->singleton_true_;
1982 : }
1983 : return Type::Boolean();
1984 : }
1985 :
1986 : Type Typer::Visitor::TypeReferenceEqual(Node* node) {
1987 253714 : return TypeBinaryOp(node, ReferenceEqualTyper);
1988 : }
1989 :
1990 : // static
1991 243 : Type Typer::Visitor::SameValueTyper(Type lhs, Type rhs, Typer* t) {
1992 243 : return t->operation_typer()->SameValue(lhs, rhs);
1993 : }
1994 :
1995 : Type Typer::Visitor::TypeSameValue(Node* node) {
1996 243 : return TypeBinaryOp(node, SameValueTyper);
1997 : }
1998 :
1999 : Type Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
2000 :
2001 : Type Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
2002 :
2003 : Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
2004 : return Type::Boolean();
2005 : }
2006 :
2007 1455 : Type Typer::Visitor::StringFromSingleCharCodeTyper(Type type, Typer* t) {
2008 1455 : return Type::NonEmptyString();
2009 : }
2010 :
2011 225 : Type Typer::Visitor::StringFromSingleCodePointTyper(Type type, Typer* t) {
2012 225 : return Type::NonEmptyString();
2013 : }
2014 :
2015 : Type Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) {
2016 : return Type::String();
2017 : }
2018 :
2019 : Type Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) {
2020 : return Type::String();
2021 : }
2022 :
2023 : Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2024 2918 : return typer_->cache_->kUint16;
2025 : }
2026 :
2027 : Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2028 359 : return Type::Range(0.0, String::kMaxCodePoint, zone());
2029 : }
2030 :
2031 : Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2032 1590 : return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2033 : }
2034 :
2035 : Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2036 313 : return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2037 : }
2038 :
2039 : Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2040 296 : return Type::Range(-1.0, String::kMaxLength, zone());
2041 : }
2042 :
2043 : Type Typer::Visitor::TypeStringLength(Node* node) {
2044 57246 : return typer_->cache_->kStringLengthType;
2045 : }
2046 :
2047 : Type Typer::Visitor::TypeStringSubstring(Node* node) { return Type::String(); }
2048 :
2049 3063 : Type Typer::Visitor::TypePoisonIndex(Node* node) {
2050 6126 : return Type::Union(Operand(node, 0), typer_->cache_->kSingletonZero, zone());
2051 : }
2052 :
2053 70518 : Type Typer::Visitor::TypeCheckBounds(Node* node) {
2054 70518 : return typer_->operation_typer_.CheckBounds(Operand(node, 0),
2055 70518 : Operand(node, 1));
2056 : }
2057 :
2058 : Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
2059 : Type type = Operand(node, 0);
2060 : return type;
2061 : }
2062 :
2063 0 : Type Typer::Visitor::TypeCheckIf(Node* node) { UNREACHABLE(); }
2064 :
2065 0 : Type Typer::Visitor::TypeCheckNonEmptyString(Node* node) {
2066 0 : return typer_->operation_typer_.CheckNonEmptyString(Operand(node, 0));
2067 : }
2068 :
2069 1854 : Type Typer::Visitor::TypeCheckNonEmptyOneByteString(Node* node) {
2070 1854 : return typer_->operation_typer_.CheckNonEmptyOneByteString(Operand(node, 0));
2071 : }
2072 :
2073 216 : Type Typer::Visitor::TypeCheckNonEmptyTwoByteString(Node* node) {
2074 216 : return typer_->operation_typer_.CheckNonEmptyTwoByteString(Operand(node, 0));
2075 : }
2076 :
2077 3624 : Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
2078 3624 : return typer_->operation_typer_.CheckInternalizedString(Operand(node, 0));
2079 : }
2080 :
2081 0 : Type Typer::Visitor::TypeCheckMaps(Node* node) { UNREACHABLE(); }
2082 :
2083 : Type Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
2084 :
2085 3289 : Type Typer::Visitor::TypeCheckNumber(Node* node) {
2086 3289 : return typer_->operation_typer_.CheckNumber(Operand(node, 0));
2087 : }
2088 :
2089 884 : Type Typer::Visitor::TypeCheckReceiver(Node* node) {
2090 884 : Type arg = Operand(node, 0);
2091 884 : return Type::Intersect(arg, Type::Receiver(), zone());
2092 : }
2093 :
2094 72 : Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2095 72 : Type arg = Operand(node, 0);
2096 72 : return Type::Intersect(arg, Type::ReceiverOrNullOrUndefined(), zone());
2097 : }
2098 :
2099 47292 : Type Typer::Visitor::TypeCheckSmi(Node* node) {
2100 47292 : Type arg = Operand(node, 0);
2101 47292 : return Type::Intersect(arg, Type::SignedSmall(), zone());
2102 : }
2103 :
2104 23481 : Type Typer::Visitor::TypeCheckString(Node* node) {
2105 23481 : return typer_->operation_typer_.CheckString(Operand(node, 0));
2106 : }
2107 :
2108 32 : Type Typer::Visitor::TypeCheckSymbol(Node* node) {
2109 32 : Type arg = Operand(node, 0);
2110 32 : return Type::Intersect(arg, Type::Symbol(), zone());
2111 : }
2112 :
2113 990 : Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2114 990 : return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
2115 : }
2116 :
2117 145 : Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
2118 : Type type = Operand(node, 0);
2119 145 : type = Type::Intersect(type, Type::NonInternal(), zone());
2120 145 : return type;
2121 : }
2122 :
2123 79434 : Type Typer::Visitor::TypeConvertReceiver(Node* node) {
2124 79434 : Type arg = Operand(node, 0);
2125 79434 : return typer_->operation_typer_.ConvertReceiver(arg);
2126 : }
2127 :
2128 2053 : Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
2129 2053 : Type type = Operand(node, 0);
2130 4106 : return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
2131 : }
2132 :
2133 0 : Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2134 0 : UNREACHABLE();
2135 : }
2136 :
2137 0 : Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
2138 :
2139 : Type Typer::Visitor::TypeAllocate(Node* node) {
2140 139722 : return AllocateTypeOf(node->op());
2141 : }
2142 :
2143 0 : Type Typer::Visitor::TypeAllocateRaw(Node* node) { UNREACHABLE(); }
2144 :
2145 : Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2146 : return Type::NonInternal();
2147 : }
2148 :
2149 : Type Typer::Visitor::TypeLoadField(Node* node) {
2150 1080542 : return FieldAccessOf(node->op()).type;
2151 : }
2152 :
2153 : Type Typer::Visitor::TypeLoadMessage(Node* node) { return Type::Any(); }
2154 :
2155 : Type Typer::Visitor::TypeLoadElement(Node* node) {
2156 24481 : return ElementAccessOf(node->op()).type;
2157 : }
2158 :
2159 : Type Typer::Visitor::TypeLoadStackArgument(Node* node) {
2160 : return Type::NonInternal();
2161 : }
2162 :
2163 5635 : Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2164 5635 : switch (ExternalArrayTypeOf(node->op())) {
2165 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2166 : case kExternal##ElemType##Array: \
2167 : return typer_->cache_->k##ElemType;
2168 544 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2169 : #undef TYPED_ARRAY_CASE
2170 : }
2171 0 : UNREACHABLE();
2172 : }
2173 :
2174 282 : Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
2175 282 : switch (ExternalArrayTypeOf(node->op())) {
2176 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2177 : case kExternal##ElemType##Array: \
2178 : return typer_->cache_->k##ElemType;
2179 39 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
2180 : #undef TYPED_ARRAY_CASE
2181 : }
2182 0 : UNREACHABLE();
2183 : }
2184 :
2185 0 : Type Typer::Visitor::TypeStoreField(Node* node) { UNREACHABLE(); }
2186 0 : Type Typer::Visitor::TypeStoreMessage(Node* node) { UNREACHABLE(); }
2187 :
2188 0 : Type Typer::Visitor::TypeStoreElement(Node* node) { UNREACHABLE(); }
2189 :
2190 0 : Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2191 0 : UNREACHABLE();
2192 : }
2193 :
2194 0 : Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2195 0 : UNREACHABLE();
2196 : }
2197 :
2198 0 : Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2199 0 : UNREACHABLE();
2200 : }
2201 :
2202 0 : Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2203 :
2204 0 : Type Typer::Visitor::TypeStoreTypedElement(Node* node) { UNREACHABLE(); }
2205 :
2206 0 : Type Typer::Visitor::TypeStoreDataViewElement(Node* node) { UNREACHABLE(); }
2207 :
2208 : Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2209 16 : return TypeUnaryOp(node, ObjectIsArrayBufferView);
2210 : }
2211 :
2212 : Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2213 27 : return TypeUnaryOp(node, ObjectIsBigInt);
2214 : }
2215 :
2216 : Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2217 1918 : return TypeUnaryOp(node, ObjectIsCallable);
2218 : }
2219 :
2220 : Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2221 199 : return TypeUnaryOp(node, ObjectIsConstructor);
2222 : }
2223 :
2224 : Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2225 17389 : return TypeUnaryOp(node, ObjectIsDetectableCallable);
2226 : }
2227 :
2228 : Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2229 0 : return TypeUnaryOp(node, ObjectIsMinusZero);
2230 : }
2231 :
2232 : Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
2233 0 : return TypeUnaryOp(node, NumberIsMinusZero);
2234 : }
2235 :
2236 : Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2237 : return Type::Boolean();
2238 : }
2239 :
2240 : Type Typer::Visitor::TypeNumberIsFinite(Node* node) { return Type::Boolean(); }
2241 :
2242 : Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2243 : return Type::Boolean();
2244 : }
2245 :
2246 0 : Type Typer::Visitor::TypeNumberIsInteger(Node* node) { UNREACHABLE(); }
2247 :
2248 : Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2249 : return Type::Boolean();
2250 : }
2251 :
2252 0 : Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) { UNREACHABLE(); }
2253 :
2254 : Type Typer::Visitor::TypeObjectIsInteger(Node* node) { return Type::Boolean(); }
2255 :
2256 : Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2257 4606 : return TypeUnaryOp(node, ObjectIsNaN);
2258 : }
2259 :
2260 : Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2261 5840 : return TypeUnaryOp(node, NumberIsNaN);
2262 : }
2263 :
2264 : Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2265 9195 : return TypeUnaryOp(node, ObjectIsNonCallable);
2266 : }
2267 :
2268 : Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2269 10611 : return TypeUnaryOp(node, ObjectIsNumber);
2270 : }
2271 :
2272 : Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2273 26638 : return TypeUnaryOp(node, ObjectIsReceiver);
2274 : }
2275 :
2276 : Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2277 1749 : return TypeUnaryOp(node, ObjectIsSmi);
2278 : }
2279 :
2280 : Type Typer::Visitor::TypeObjectIsString(Node* node) {
2281 2508 : return TypeUnaryOp(node, ObjectIsString);
2282 : }
2283 :
2284 : Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2285 123 : return TypeUnaryOp(node, ObjectIsSymbol);
2286 : }
2287 :
2288 : Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2289 1915 : return TypeUnaryOp(node, ObjectIsUndetectable);
2290 : }
2291 :
2292 : Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2293 17579 : return TypeCache::Get()->kArgumentsLengthType;
2294 : }
2295 :
2296 : Type Typer::Visitor::TypeArgumentsFrame(Node* node) {
2297 : return Type::ExternalPointer();
2298 : }
2299 :
2300 : Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2301 : return Type::OtherInternal();
2302 : }
2303 :
2304 : Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2305 : return Type::OtherInternal();
2306 : }
2307 :
2308 : Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2309 : return Type::OtherInternal();
2310 : }
2311 :
2312 0 : Type Typer::Visitor::TypeNewConsString(Node* node) { UNREACHABLE(); }
2313 :
2314 0 : Type Typer::Visitor::TypeNewConsOneByteString(Node* node) { UNREACHABLE(); }
2315 :
2316 0 : Type Typer::Visitor::TypeNewConsTwoByteString(Node* node) { UNREACHABLE(); }
2317 :
2318 : Type Typer::Visitor::TypeDelayedStringConstant(Node* node) {
2319 : return Type::String();
2320 : }
2321 :
2322 : Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2323 184 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2324 : }
2325 :
2326 : Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2327 0 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2328 : }
2329 :
2330 0 : Type Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2331 :
2332 : // Heap constants.
2333 :
2334 0 : Type Typer::Visitor::TypeConstant(Handle<Object> value) {
2335 6005751 : return Type::NewConstant(typer_->broker(), value, zone());
2336 : }
2337 :
2338 : } // namespace compiler
2339 : } // namespace internal
2340 120216 : } // namespace v8
|