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 443953 : explicit Decorator(Typer* typer) : typer_(typer) {}
30 : void Decorate(Node* node) final;
31 :
32 : private:
33 : Typer* const typer_;
34 : };
35 :
36 443952 : Typer::Typer(Isolate* isolate, Flags flags, Graph* graph)
37 : : isolate_(isolate),
38 : flags_(flags),
39 : graph_(graph),
40 : decorator_(nullptr),
41 443952 : cache_(TypeCache::Get()),
42 1775811 : operation_typer_(isolate, zone()) {
43 : Zone* zone = this->zone();
44 : Factory* const factory = isolate->factory();
45 :
46 443953 : singleton_empty_string_ = Type::HeapConstant(factory->empty_string(), zone);
47 443953 : singleton_false_ = operation_typer_.singleton_false();
48 443953 : singleton_true_ = operation_typer_.singleton_true();
49 : falsish_ = Type::Union(
50 : Type::Undetectable(),
51 : Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
52 : Type::Union(singleton_empty_string_, Type::Hole(), zone),
53 : zone),
54 443953 : zone);
55 : truish_ = Type::Union(
56 : singleton_true_,
57 443953 : Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
58 :
59 443953 : decorator_ = new (zone) Decorator(this);
60 443953 : graph_->AddDecorator(decorator_);
61 443952 : }
62 :
63 :
64 443953 : Typer::~Typer() {
65 443953 : graph_->RemoveDecorator(decorator_);
66 443953 : }
67 :
68 :
69 2992208 : class Typer::Visitor : public Reducer {
70 : public:
71 : explicit Visitor(Typer* typer, LoopVariableOptimizer* induction_vars)
72 : : typer_(typer),
73 : induction_vars_(induction_vars),
74 2992205 : weakened_nodes_(typer->zone()) {}
75 :
76 0 : const char* reducer_name() const override { return "Typer"; }
77 :
78 31995733 : Reduction Reduce(Node* node) override {
79 31995733 : if (node->op()->ValueOutputCount() == 0) return NoChange();
80 23526954 : switch (node->opcode()) {
81 : #define DECLARE_CASE(x) \
82 : case IrOpcode::k##x: \
83 : return UpdateType(node, TypeBinaryOp(node, x##Typer));
84 16487 : JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
85 : #undef DECLARE_CASE
86 :
87 : #define DECLARE_CASE(x) \
88 : case IrOpcode::k##x: \
89 : return UpdateType(node, Type##x(node));
90 443380 : DECLARE_CASE(Start)
91 145891 : DECLARE_CASE(IfException)
92 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
93 5707399 : COMMON_OP_LIST(DECLARE_CASE)
94 333695 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
95 467921 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
96 63930 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
97 6418 : JS_OBJECT_OP_LIST(DECLARE_CASE)
98 532518 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
99 529674 : JS_OTHER_OP_LIST(DECLARE_CASE)
100 : #undef DECLARE_CASE
101 :
102 : #define DECLARE_CASE(x) \
103 : case IrOpcode::k##x: \
104 : return UpdateType(node, TypeBinaryOp(node, x));
105 2680 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
106 118014 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
107 : #undef DECLARE_CASE
108 :
109 : #define DECLARE_CASE(x) \
110 : case IrOpcode::k##x: \
111 : return UpdateType(node, TypeUnaryOp(node, x));
112 0 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
113 44765 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
114 : #undef DECLARE_CASE
115 :
116 : #define DECLARE_CASE(x) case IrOpcode::k##x:
117 : DECLARE_CASE(Loop)
118 : DECLARE_CASE(Branch)
119 : DECLARE_CASE(IfTrue)
120 : DECLARE_CASE(IfFalse)
121 : DECLARE_CASE(IfSuccess)
122 : DECLARE_CASE(Switch)
123 : DECLARE_CASE(IfValue)
124 : DECLARE_CASE(IfDefault)
125 : DECLARE_CASE(Merge)
126 : DECLARE_CASE(Deoptimize)
127 : DECLARE_CASE(DeoptimizeIf)
128 : DECLARE_CASE(DeoptimizeUnless)
129 : DECLARE_CASE(TrapIf)
130 : DECLARE_CASE(TrapUnless)
131 : DECLARE_CASE(Return)
132 : DECLARE_CASE(TailCall)
133 : DECLARE_CASE(Terminate)
134 : DECLARE_CASE(OsrNormalEntry)
135 : DECLARE_CASE(OsrLoopEntry)
136 : DECLARE_CASE(Throw)
137 : DECLARE_CASE(End)
138 : SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
139 : SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
140 : MACHINE_SIMD_OP_LIST(DECLARE_CASE)
141 : MACHINE_OP_LIST(DECLARE_CASE)
142 : #undef DECLARE_CASE
143 : break;
144 : }
145 : return NoChange();
146 : }
147 :
148 2548967 : Type* TypeNode(Node* node) {
149 2548544 : switch (node->opcode()) {
150 : #define DECLARE_CASE(x) \
151 : case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
152 518 : JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
153 : #undef DECLARE_CASE
154 :
155 : #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
156 : DECLARE_CASE(Start)
157 0 : DECLARE_CASE(IfException)
158 : // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
159 650594 : COMMON_OP_LIST(DECLARE_CASE)
160 22207 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
161 478826 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
162 895 : JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
163 1 : JS_OBJECT_OP_LIST(DECLARE_CASE)
164 158476 : JS_CONTEXT_OP_LIST(DECLARE_CASE)
165 719 : JS_OTHER_OP_LIST(DECLARE_CASE)
166 : #undef DECLARE_CASE
167 :
168 : #define DECLARE_CASE(x) \
169 : case IrOpcode::k##x: \
170 : return TypeBinaryOp(node, x);
171 12418 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
172 100 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
173 : #undef DECLARE_CASE
174 :
175 : #define DECLARE_CASE(x) \
176 : case IrOpcode::k##x: \
177 : return TypeUnaryOp(node, x);
178 390 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
179 0 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
180 : #undef DECLARE_CASE
181 :
182 : #define DECLARE_CASE(x) case IrOpcode::k##x:
183 : DECLARE_CASE(Loop)
184 : DECLARE_CASE(Branch)
185 : DECLARE_CASE(IfTrue)
186 : DECLARE_CASE(IfFalse)
187 : DECLARE_CASE(IfSuccess)
188 : DECLARE_CASE(Switch)
189 : DECLARE_CASE(IfValue)
190 : DECLARE_CASE(IfDefault)
191 : DECLARE_CASE(Merge)
192 : DECLARE_CASE(Deoptimize)
193 : DECLARE_CASE(DeoptimizeIf)
194 : DECLARE_CASE(DeoptimizeUnless)
195 : DECLARE_CASE(TrapIf)
196 : DECLARE_CASE(TrapUnless)
197 : DECLARE_CASE(Return)
198 : DECLARE_CASE(TailCall)
199 : DECLARE_CASE(Terminate)
200 : DECLARE_CASE(OsrNormalEntry)
201 : DECLARE_CASE(OsrLoopEntry)
202 : DECLARE_CASE(Throw)
203 : DECLARE_CASE(End)
204 : SIMPLIFIED_CHANGE_OP_LIST(DECLARE_CASE)
205 : SIMPLIFIED_CHECKED_OP_LIST(DECLARE_CASE)
206 : MACHINE_SIMD_OP_LIST(DECLARE_CASE)
207 : MACHINE_OP_LIST(DECLARE_CASE)
208 : #undef DECLARE_CASE
209 : break;
210 : }
211 0 : UNREACHABLE();
212 : }
213 :
214 : Type* TypeConstant(Handle<Object> value);
215 :
216 : private:
217 : Typer* typer_;
218 : LoopVariableOptimizer* induction_vars_;
219 : ZoneSet<NodeId> weakened_nodes_;
220 :
221 : #define DECLARE_METHOD(x) inline Type* Type##x(Node* node);
222 : DECLARE_METHOD(Start)
223 : DECLARE_METHOD(IfException)
224 : COMMON_OP_LIST(DECLARE_METHOD)
225 : SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_METHOD)
226 : SIMPLIFIED_OTHER_OP_LIST(DECLARE_METHOD)
227 : JS_OP_LIST(DECLARE_METHOD)
228 : #undef DECLARE_METHOD
229 :
230 : Type* TypeOrNone(Node* node) {
231 : return NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
232 5918881 : : Type::None();
233 : }
234 :
235 : Type* Operand(Node* node, int i) {
236 5879393 : Node* operand_node = NodeProperties::GetValueInput(node, i);
237 : return TypeOrNone(operand_node);
238 : }
239 :
240 : Type* Weaken(Node* node, Type* current_type, Type* previous_type);
241 :
242 : Zone* zone() { return typer_->zone(); }
243 : Isolate* isolate() { return typer_->isolate(); }
244 : Graph* graph() { return typer_->graph(); }
245 :
246 : void SetWeakened(NodeId node_id) { weakened_nodes_.insert(node_id); }
247 : bool IsWeakened(NodeId node_id) {
248 : return weakened_nodes_.find(node_id) != weakened_nodes_.end();
249 : }
250 :
251 : typedef Type* (*UnaryTyperFun)(Type*, Typer* t);
252 : typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t);
253 :
254 : Type* TypeUnaryOp(Node* node, UnaryTyperFun);
255 : Type* TypeBinaryOp(Node* node, BinaryTyperFun);
256 :
257 : enum ComparisonOutcomeFlags {
258 : kComparisonTrue = 1,
259 : kComparisonFalse = 2,
260 : kComparisonUndefined = 4
261 : };
262 : typedef base::Flags<ComparisonOutcomeFlags> ComparisonOutcome;
263 :
264 : static ComparisonOutcome Invert(ComparisonOutcome, Typer*);
265 : static Type* FalsifyUndefined(ComparisonOutcome, Typer*);
266 :
267 : static Type* ToPrimitive(Type*, Typer*);
268 : static Type* ToBoolean(Type*, Typer*);
269 : static Type* ToInteger(Type*, Typer*);
270 : static Type* ToLength(Type*, Typer*);
271 : static Type* ToName(Type*, Typer*);
272 : static Type* ToNumber(Type*, Typer*);
273 : static Type* ToObject(Type*, Typer*);
274 : static Type* ToString(Type*, Typer*);
275 : #define DECLARE_METHOD(Name) \
276 : static Type* Name(Type* type, Typer* t) { \
277 : return t->operation_typer_.Name(type); \
278 : }
279 44421 : SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
280 44086 : SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_METHOD)
281 : #undef DECLARE_METHOD
282 : #define DECLARE_METHOD(Name) \
283 : static Type* Name(Type* lhs, Type* rhs, Typer* t) { \
284 : return t->operation_typer_.Name(lhs, rhs); \
285 : }
286 226538 : SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
287 385728 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
288 : #undef DECLARE_METHOD
289 :
290 : static Type* ObjectIsArrayBufferView(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* ObjectIsNaN(Type*, Typer*);
296 : static Type* ObjectIsNonCallable(Type*, Typer*);
297 : static Type* ObjectIsNumber(Type*, Typer*);
298 : static Type* ObjectIsReceiver(Type*, Typer*);
299 : static Type* ObjectIsSmi(Type*, Typer*);
300 : static Type* ObjectIsString(Type*, Typer*);
301 : static Type* ObjectIsSymbol(Type*, Typer*);
302 : static Type* ObjectIsUndetectable(Type*, Typer*);
303 :
304 : static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*);
305 : static ComparisonOutcome NumberCompareTyper(Type*, Type*, Typer*);
306 :
307 : #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*);
308 : JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
309 : #undef DECLARE_METHOD
310 :
311 : static Type* JSCallTyper(Type*, Typer*);
312 :
313 : static Type* NumberEqualTyper(Type*, Type*, Typer*);
314 : static Type* NumberLessThanTyper(Type*, Type*, Typer*);
315 : static Type* NumberLessThanOrEqualTyper(Type*, Type*, Typer*);
316 : static Type* ReferenceEqualTyper(Type*, Type*, Typer*);
317 : static Type* StringFromCharCodeTyper(Type*, Typer*);
318 : static Type* StringFromCodePointTyper(Type*, Typer*);
319 :
320 27174500 : Reduction UpdateType(Node* node, Type* current) {
321 23526910 : if (NodeProperties::IsTyped(node)) {
322 : // Widen the type of a previously typed node.
323 : Type* previous = NodeProperties::GetType(node);
324 3647590 : if (node->opcode() == IrOpcode::kPhi ||
325 : node->opcode() == IrOpcode::kInductionVariablePhi) {
326 : // Speed up termination in the presence of range types:
327 305371 : current = Weaken(node, current, previous);
328 : }
329 :
330 3647593 : CHECK(previous->Is(current));
331 :
332 : NodeProperties::SetType(node, current);
333 3647593 : if (!current->Is(previous)) {
334 : // If something changed, revisit all uses.
335 : return Changed(node);
336 : }
337 : return NoChange();
338 : } else {
339 : // No previous type, simply update the type.
340 : NodeProperties::SetType(node, current);
341 : return Changed(node);
342 : }
343 : }
344 : };
345 :
346 564 : void Typer::Run() { Run(NodeVector(zone()), nullptr); }
347 :
348 443663 : void Typer::Run(const NodeVector& roots,
349 : LoopVariableOptimizer* induction_vars) {
350 443663 : if (induction_vars != nullptr) {
351 443382 : induction_vars->ChangeToInductionVariablePhis();
352 : }
353 : Visitor visitor(this, induction_vars);
354 887324 : GraphReducer graph_reducer(zone(), graph());
355 443664 : graph_reducer.AddReducer(&visitor);
356 6370900 : for (Node* const root : roots) graph_reducer.ReduceNode(root);
357 443664 : graph_reducer.ReduceGraph();
358 :
359 443664 : if (induction_vars != nullptr) {
360 443382 : induction_vars->ChangeToPhisAndInsertGuards();
361 : }
362 443663 : }
363 :
364 3642231 : void Typer::Decorator::Decorate(Node* node) {
365 7284462 : if (node->op()->ValueOutputCount() > 0) {
366 : // Only eagerly type-decorate nodes with known input types.
367 : // Other cases will generally require a proper fixpoint iteration with Run.
368 : bool is_typed = NodeProperties::IsTyped(node);
369 2610508 : if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
370 2548544 : Visitor typing(typer_, nullptr);
371 2548544 : Type* type = typing.TypeNode(node);
372 2548544 : if (is_typed) {
373 : type = Type::Intersect(type, NodeProperties::GetType(node),
374 0 : typer_->zone());
375 : }
376 : NodeProperties::SetType(node, type);
377 : }
378 : }
379 3642232 : }
380 :
381 :
382 : // -----------------------------------------------------------------------------
383 :
384 : // Helper functions that lift a function f on types to a function on bounds,
385 : // and uses that to type the given node. Note that f is never called with None
386 : // as an argument.
387 :
388 :
389 914285 : Type* Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
390 : Type* input = Operand(node, 0);
391 914284 : return input->IsInhabited() ? f(input, typer_) : Type::None();
392 : }
393 :
394 :
395 1359346 : Type* Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
396 : Type* left = Operand(node, 0);
397 : Type* right = Operand(node, 1);
398 1229681 : return left->IsInhabited() && right->IsInhabited() ? f(left, right, typer_)
399 2582143 : : Type::None();
400 : }
401 :
402 :
403 0 : Typer::Visitor::ComparisonOutcome Typer::Visitor::Invert(
404 : ComparisonOutcome outcome, Typer* t) {
405 : ComparisonOutcome result(0);
406 11019 : if ((outcome & kComparisonUndefined) != 0) result |= kComparisonUndefined;
407 11019 : if ((outcome & kComparisonTrue) != 0) result |= kComparisonFalse;
408 11019 : if ((outcome & kComparisonFalse) != 0) result |= kComparisonTrue;
409 0 : return result;
410 : }
411 :
412 :
413 0 : Type* Typer::Visitor::FalsifyUndefined(ComparisonOutcome outcome, Typer* t) {
414 118896 : if ((outcome & kComparisonFalse) != 0 ||
415 : (outcome & kComparisonUndefined) != 0) {
416 : return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
417 112833 : : t->singleton_false_;
418 : }
419 : // Type should be non empty, so we know it should be true.
420 : DCHECK_NE(0, outcome & kComparisonTrue);
421 2497 : return t->singleton_true_;
422 : }
423 :
424 : // Type conversion.
425 :
426 335557 : Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
427 335557 : if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
428 253588 : return type;
429 : }
430 : return Type::Primitive();
431 : }
432 :
433 :
434 147331 : Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
435 147331 : if (type->Is(Type::Boolean())) return type;
436 207344 : if (type->Is(t->falsish_)) return t->singleton_false_;
437 202300 : if (type->Is(t->truish_)) return t->singleton_true_;
438 100844 : if (type->Is(Type::Number())) {
439 45568 : return t->operation_typer()->NumberToBoolean(type);
440 : }
441 : return Type::Boolean();
442 : }
443 :
444 :
445 : // static
446 1190 : Type* Typer::Visitor::ToInteger(Type* type, Typer* t) {
447 : // ES6 section 7.1.4 ToInteger ( argument )
448 : type = ToNumber(type, t);
449 2380 : if (type->Is(t->cache_.kIntegerOrMinusZero)) return type;
450 2288 : if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) {
451 : return Type::Union(
452 : Type::Intersect(type, t->cache_.kIntegerOrMinusZero, t->zone()),
453 6 : t->cache_.kSingletonZero, t->zone());
454 : }
455 1138 : return t->cache_.kIntegerOrMinusZero;
456 : }
457 :
458 :
459 : // static
460 941 : Type* Typer::Visitor::ToLength(Type* type, Typer* t) {
461 : // ES6 section 7.1.15 ToLength ( argument )
462 941 : type = ToInteger(type, t);
463 941 : double min = type->Min();
464 941 : double max = type->Max();
465 941 : if (max <= 0.0) {
466 9 : return Type::NewConstant(0, t->zone());
467 : }
468 932 : if (min >= kMaxSafeInteger) {
469 2 : return Type::NewConstant(kMaxSafeInteger, t->zone());
470 : }
471 930 : if (min <= 0.0) min = 0.0;
472 930 : if (max >= kMaxSafeInteger) max = kMaxSafeInteger;
473 930 : return Type::Range(min, max, t->zone());
474 : }
475 :
476 :
477 : // static
478 1291 : Type* Typer::Visitor::ToName(Type* type, Typer* t) {
479 : // ES6 section 7.1.14 ToPropertyKey ( argument )
480 1291 : type = ToPrimitive(type, t);
481 1291 : if (type->Is(Type::Name())) return type;
482 1124 : if (type->Maybe(Type::Symbol())) return Type::Name();
483 110 : return ToString(type, t);
484 : }
485 :
486 :
487 : // static
488 64884 : Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
489 417505 : return t->operation_typer_.ToNumber(type);
490 : }
491 :
492 :
493 : // static
494 3182 : Type* Typer::Visitor::ToObject(Type* type, Typer* t) {
495 : // ES6 section 7.1.13 ToObject ( argument )
496 3182 : if (type->Is(Type::Receiver())) return type;
497 2350 : if (type->Is(Type::Primitive())) return Type::OtherObject();
498 2245 : if (!type->Maybe(Type::OtherUndetectable())) {
499 : return Type::DetectableReceiver();
500 : }
501 2241 : return Type::Receiver();
502 : }
503 :
504 :
505 : // static
506 3076 : Type* Typer::Visitor::ToString(Type* type, Typer* t) {
507 : // ES6 section 7.1.12 ToString ( argument )
508 3076 : type = ToPrimitive(type, t);
509 3076 : if (type->Is(Type::String())) return type;
510 : return Type::String();
511 : }
512 :
513 : // Type checks.
514 :
515 0 : Type* Typer::Visitor::ObjectIsArrayBufferView(Type* type, Typer* t) {
516 : // TODO(turbofan): Introduce a Type::ArrayBufferView?
517 0 : if (!type->Maybe(Type::OtherObject())) return t->singleton_false_;
518 : return Type::Boolean();
519 : }
520 :
521 409 : Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) {
522 409 : if (type->Is(Type::Callable())) return t->singleton_true_;
523 50 : if (!type->Maybe(Type::Callable())) return t->singleton_false_;
524 : return Type::Boolean();
525 : }
526 :
527 237 : Type* Typer::Visitor::ObjectIsConstructor(Type* type, Typer* t) {
528 : // TODO(turbofan): Introduce a Type::Constructor?
529 237 : if (!type->Maybe(Type::Callable())) return t->singleton_false_;
530 : return Type::Boolean();
531 : }
532 :
533 13697 : Type* Typer::Visitor::ObjectIsDetectableCallable(Type* type, Typer* t) {
534 13697 : if (type->Is(Type::DetectableCallable())) return t->singleton_true_;
535 13676 : if (!type->Maybe(Type::DetectableCallable())) return t->singleton_false_;
536 : return Type::Boolean();
537 : }
538 :
539 28 : Type* Typer::Visitor::ObjectIsMinusZero(Type* type, Typer* t) {
540 28 : if (type->Is(Type::MinusZero())) return t->singleton_true_;
541 28 : if (!type->Maybe(Type::MinusZero())) return t->singleton_false_;
542 : return Type::Boolean();
543 : }
544 :
545 4676 : Type* Typer::Visitor::ObjectIsNaN(Type* type, Typer* t) {
546 4676 : if (type->Is(Type::NaN())) return t->singleton_true_;
547 4667 : if (!type->Maybe(Type::NaN())) return t->singleton_false_;
548 : return Type::Boolean();
549 : }
550 :
551 7382 : Type* Typer::Visitor::ObjectIsNonCallable(Type* type, Typer* t) {
552 7382 : if (type->Is(Type::NonCallable())) return t->singleton_true_;
553 7108 : if (!type->Maybe(Type::NonCallable())) return t->singleton_false_;
554 : return Type::Boolean();
555 : }
556 :
557 9835 : Type* Typer::Visitor::ObjectIsNumber(Type* type, Typer* t) {
558 9835 : if (type->Is(Type::Number())) return t->singleton_true_;
559 8550 : if (!type->Maybe(Type::Number())) return t->singleton_false_;
560 : return Type::Boolean();
561 : }
562 :
563 :
564 23455 : Type* Typer::Visitor::ObjectIsReceiver(Type* type, Typer* t) {
565 23455 : if (type->Is(Type::Receiver())) return t->singleton_true_;
566 21662 : if (!type->Maybe(Type::Receiver())) return t->singleton_false_;
567 : return Type::Boolean();
568 : }
569 :
570 :
571 4343 : Type* Typer::Visitor::ObjectIsSmi(Type* type, Typer* t) {
572 4343 : if (!type->Maybe(Type::SignedSmall())) return t->singleton_false_;
573 : return Type::Boolean();
574 : }
575 :
576 2335 : Type* Typer::Visitor::ObjectIsString(Type* type, Typer* t) {
577 2335 : if (type->Is(Type::String())) return t->singleton_true_;
578 2325 : if (!type->Maybe(Type::String())) return t->singleton_false_;
579 : return Type::Boolean();
580 : }
581 :
582 206 : Type* Typer::Visitor::ObjectIsSymbol(Type* type, Typer* t) {
583 206 : if (type->Is(Type::Symbol())) return t->singleton_true_;
584 206 : if (!type->Maybe(Type::Symbol())) return t->singleton_false_;
585 : return Type::Boolean();
586 : }
587 :
588 6032 : Type* Typer::Visitor::ObjectIsUndetectable(Type* type, Typer* t) {
589 6032 : if (type->Is(Type::Undetectable())) return t->singleton_true_;
590 5781 : if (!type->Maybe(Type::Undetectable())) return t->singleton_false_;
591 : return Type::Boolean();
592 : }
593 :
594 :
595 : // -----------------------------------------------------------------------------
596 :
597 :
598 : // Control operators.
599 :
600 : Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
601 :
602 : Type* Typer::Visitor::TypeIfException(Node* node) {
603 : return Type::NonInternal();
604 : }
605 :
606 : // Common operators.
607 :
608 4080810 : Type* Typer::Visitor::TypeParameter(Node* node) {
609 2040405 : Node* const start = node->InputAt(0);
610 : DCHECK_EQ(IrOpcode::kStart, start->opcode());
611 4080810 : int const parameter_count = start->op()->ValueOutputCount() - 4;
612 : DCHECK_LE(1, parameter_count);
613 2040405 : int const index = ParameterIndexOf(node->op());
614 2040406 : if (index == Linkage::kJSCallClosureParamIndex) {
615 : return Type::Function();
616 2017313 : } else if (index == 0) {
617 875146 : if (typer_->flags() & Typer::kThisIsReceiver) {
618 : return Type::Receiver();
619 : } else {
620 : // Parameter[this] can be the_hole for derived class constructors.
621 102079 : return Type::Union(Type::Hole(), Type::NonInternal(), typer_->zone());
622 : }
623 1579740 : } else if (index == Linkage::GetJSCallNewTargetParamIndex(parameter_count)) {
624 36266 : if (typer_->flags() & Typer::kNewTargetIsReceiver) {
625 : return Type::Receiver();
626 : } else {
627 15428 : return Type::Union(Type::Receiver(), Type::Undefined(), typer_->zone());
628 : }
629 1561607 : } else if (index == Linkage::GetJSCallArgCountParamIndex(parameter_count)) {
630 0 : return Type::Range(0.0, Code::kMaxArguments, typer_->zone());
631 1561607 : } else if (index == Linkage::GetJSCallContextParamIndex(parameter_count)) {
632 : return Type::OtherInternal();
633 : }
634 1124035 : return Type::NonInternal();
635 : }
636 :
637 : Type* Typer::Visitor::TypeOsrValue(Node* node) { return Type::Any(); }
638 :
639 0 : Type* Typer::Visitor::TypeRetain(Node* node) {
640 0 : UNREACHABLE();
641 : }
642 :
643 0 : Type* Typer::Visitor::TypeInt32Constant(Node* node) {
644 0 : UNREACHABLE();
645 : }
646 :
647 0 : Type* Typer::Visitor::TypeInt64Constant(Node* node) {
648 0 : UNREACHABLE();
649 : }
650 :
651 0 : Type* Typer::Visitor::TypeRelocatableInt32Constant(Node* node) {
652 0 : UNREACHABLE();
653 : }
654 :
655 0 : Type* Typer::Visitor::TypeRelocatableInt64Constant(Node* node) {
656 0 : UNREACHABLE();
657 : }
658 :
659 0 : Type* Typer::Visitor::TypeFloat32Constant(Node* node) {
660 0 : UNREACHABLE();
661 : }
662 :
663 0 : Type* Typer::Visitor::TypeFloat64Constant(Node* node) {
664 0 : UNREACHABLE();
665 : }
666 :
667 2125290 : Type* Typer::Visitor::TypeNumberConstant(Node* node) {
668 2125290 : double number = OpParameter<double>(node);
669 2125290 : return Type::NewConstant(number, zone());
670 : }
671 :
672 : Type* Typer::Visitor::TypeHeapConstant(Node* node) {
673 3947009 : return TypeConstant(OpParameter<Handle<HeapObject>>(node));
674 : }
675 :
676 : Type* Typer::Visitor::TypeExternalConstant(Node* node) {
677 : return Type::ExternalPointer();
678 : }
679 :
680 : Type* Typer::Visitor::TypePointerConstant(Node* node) {
681 : return Type::ExternalPointer();
682 : }
683 :
684 17404 : Type* Typer::Visitor::TypeSelect(Node* node) {
685 17404 : return Type::Union(Operand(node, 1), Operand(node, 2), zone());
686 : }
687 :
688 1585198 : Type* Typer::Visitor::TypePhi(Node* node) {
689 583943 : int arity = node->op()->ValueInputCount();
690 : Type* type = Operand(node, 0);
691 1585198 : for (int i = 1; i < arity; ++i) {
692 1001255 : type = Type::Union(type, Operand(node, i), zone());
693 : }
694 583943 : return type;
695 : }
696 :
697 107031 : Type* Typer::Visitor::TypeInductionVariablePhi(Node* node) {
698 49103 : int arity = NodeProperties::GetControlInput(node)->op()->ControlInputCount();
699 : DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(node)->opcode());
700 : DCHECK_EQ(2, NodeProperties::GetControlInput(node)->InputCount());
701 :
702 : Type* initial_type = Operand(node, 0);
703 : Type* increment_type = Operand(node, 2);
704 :
705 : // We only handle integer induction variables (otherwise ranges
706 : // do not apply and we cannot do anything).
707 138026 : if (!initial_type->Is(typer_->cache_.kInteger) ||
708 39820 : !increment_type->Is(typer_->cache_.kInteger)) {
709 : // Fallback to normal phi typing, but ensure monotonicity.
710 : // (Unfortunately, without baking in the previous type, monotonicity might
711 : // be violated because we might not yet have retyped the incrementing
712 : // operation even though the increment's type might been already reflected
713 : // in the induction variable phi.)
714 : Type* type = NodeProperties::IsTyped(node) ? NodeProperties::GetType(node)
715 9354 : : Type::None();
716 28062 : for (int i = 0; i < arity; ++i) {
717 18708 : type = Type::Union(type, Operand(node, i), zone());
718 : }
719 : return type;
720 : }
721 : // If we do not have enough type information for the initial value or
722 : // the increment, just return the initial value's type.
723 78987 : if (!initial_type->IsInhabited() ||
724 39238 : increment_type->Is(typer_->cache_.kSingletonZero)) {
725 : return initial_type;
726 : }
727 :
728 : // Now process the bounds.
729 78440 : auto res = induction_vars_->induction_variables().find(node->id());
730 : DCHECK(res != induction_vars_->induction_variables().end());
731 39220 : InductionVariable* induction_var = res->second;
732 :
733 : InductionVariable::ArithmeticType arithmetic_type = induction_var->Type();
734 :
735 39220 : double min = -V8_INFINITY;
736 39220 : double max = V8_INFINITY;
737 :
738 : double increment_min;
739 : double increment_max;
740 39220 : if (arithmetic_type == InductionVariable::ArithmeticType::kAddition) {
741 4644 : increment_min = increment_type->Min();
742 4644 : increment_max = increment_type->Max();
743 : } else {
744 : DCHECK_EQ(InductionVariable::ArithmeticType::kSubtraction, arithmetic_type);
745 34576 : increment_min = -increment_type->Max();
746 34576 : increment_max = -increment_type->Min();
747 : }
748 :
749 39220 : if (increment_min >= 0) {
750 : // increasing sequence
751 38737 : min = initial_type->Min();
752 116075 : for (auto bound : induction_var->upper_bounds()) {
753 : Type* bound_type = TypeOrNone(bound.bound);
754 : // If the type is not an integer, just skip the bound.
755 77868 : if (!bound_type->Is(typer_->cache_.kInteger)) continue;
756 : // If the type is not inhabited, then we can take the initial value.
757 20764 : if (!bound_type->IsInhabited()) {
758 333 : max = initial_type->Max();
759 333 : break;
760 : }
761 20431 : double bound_max = bound_type->Max();
762 20431 : if (bound.kind == InductionVariable::kStrict) {
763 20034 : bound_max -= 1;
764 : }
765 40862 : max = std::min(max, bound_max + increment_max);
766 : }
767 : // The upper bound must be at least the initial value's upper bound.
768 77474 : max = std::max(max, initial_type->Max());
769 483 : } else if (increment_max <= 0) {
770 : // decreasing sequence
771 483 : max = initial_type->Max();
772 1518 : for (auto bound : induction_var->lower_bounds()) {
773 : Type* bound_type = TypeOrNone(bound.bound);
774 : // If the type is not an integer, just skip the bound.
775 1110 : if (!bound_type->Is(typer_->cache_.kInteger)) continue;
776 : // If the type is not inhabited, then we can take the initial value.
777 385 : if (!bound_type->IsInhabited()) {
778 3 : min = initial_type->Min();
779 3 : break;
780 : }
781 382 : double bound_min = bound_type->Min();
782 382 : if (bound.kind == InductionVariable::kStrict) {
783 162 : bound_min += 1;
784 : }
785 764 : min = std::max(min, bound_min + increment_min);
786 : }
787 : // The lower bound must be at most the initial value's lower bound.
788 966 : min = std::min(min, initial_type->Min());
789 : } else {
790 : // Shortcut: If the increment can be both positive and negative,
791 : // the variable can go arbitrarily far, so just return integer.
792 0 : return typer_->cache_.kInteger;
793 : }
794 39220 : if (FLAG_trace_turbo_loop) {
795 0 : OFStream os(stdout);
796 : os << std::setprecision(10);
797 0 : os << "Loop (" << NodeProperties::GetControlInput(node)->id()
798 0 : << ") variable bounds in "
799 : << (arithmetic_type == InductionVariable::ArithmeticType::kAddition
800 : ? "addition"
801 0 : : "subtraction")
802 0 : << " for phi " << node->id() << ": (" << min << ", " << max << ")\n";
803 : }
804 117660 : return Type::Range(min, max, typer_->zone());
805 : }
806 :
807 0 : Type* Typer::Visitor::TypeEffectPhi(Node* node) {
808 0 : UNREACHABLE();
809 : }
810 :
811 0 : Type* Typer::Visitor::TypeLoopExit(Node* node) {
812 0 : UNREACHABLE();
813 : }
814 :
815 : Type* Typer::Visitor::TypeLoopExitValue(Node* node) { return Operand(node, 0); }
816 :
817 0 : Type* Typer::Visitor::TypeLoopExitEffect(Node* node) {
818 0 : UNREACHABLE();
819 : }
820 :
821 : Type* Typer::Visitor::TypeEnsureWritableFastElements(Node* node) {
822 : return Operand(node, 1);
823 : }
824 :
825 : Type* Typer::Visitor::TypeMaybeGrowFastElements(Node* node) {
826 : return Operand(node, 1);
827 : }
828 :
829 0 : Type* Typer::Visitor::TypeTransitionElementsKind(Node* node) {
830 0 : UNREACHABLE();
831 : }
832 :
833 0 : Type* Typer::Visitor::TypeCheckpoint(Node* node) {
834 0 : UNREACHABLE();
835 : }
836 :
837 0 : Type* Typer::Visitor::TypeBeginRegion(Node* node) {
838 0 : UNREACHABLE();
839 : }
840 :
841 :
842 : Type* Typer::Visitor::TypeFinishRegion(Node* node) { return Operand(node, 0); }
843 :
844 :
845 : Type* Typer::Visitor::TypeFrameState(Node* node) {
846 : // TODO(rossberg): Ideally FrameState wouldn't have a value output.
847 : return Type::Internal();
848 : }
849 :
850 : Type* Typer::Visitor::TypeStateValues(Node* node) { return Type::Internal(); }
851 :
852 : Type* Typer::Visitor::TypeTypedStateValues(Node* node) {
853 : return Type::Internal();
854 : }
855 :
856 0 : Type* Typer::Visitor::TypeObjectId(Node* node) { UNREACHABLE(); }
857 :
858 : Type* Typer::Visitor::TypeArgumentsElementsState(Node* node) {
859 : return Type::Internal();
860 : }
861 :
862 : Type* Typer::Visitor::TypeArgumentsLengthState(Node* node) {
863 : return Type::Internal();
864 : }
865 :
866 : Type* Typer::Visitor::TypeObjectState(Node* node) { return Type::Internal(); }
867 :
868 : Type* Typer::Visitor::TypeTypedObjectState(Node* node) {
869 : return Type::Internal();
870 : }
871 :
872 : Type* Typer::Visitor::TypeCall(Node* node) { return Type::Any(); }
873 :
874 0 : Type* Typer::Visitor::TypeCallWithCallerSavedRegisters(Node* node) {
875 0 : UNREACHABLE();
876 : }
877 :
878 10591 : Type* Typer::Visitor::TypeProjection(Node* node) {
879 : Type* const type = Operand(node, 0);
880 5296 : if (type->Is(Type::None())) return Type::None();
881 5295 : int const index = static_cast<int>(ProjectionIndexOf(node->op()));
882 9852 : if (type->IsTuple() && index < type->AsTuple()->Arity()) {
883 : return type->AsTuple()->Element(index);
884 : }
885 : return Type::Any();
886 : }
887 :
888 0 : Type* Typer::Visitor::TypeMapGuard(Node* node) { UNREACHABLE(); }
889 :
890 27986 : Type* Typer::Visitor::TypeTypeGuard(Node* node) {
891 : Type* const type = Operand(node, 0);
892 13993 : return typer_->operation_typer()->TypeTypeGuard(node->op(), type);
893 : }
894 :
895 : Type* Typer::Visitor::TypeDead(Node* node) { return Type::None(); }
896 :
897 : // JS comparison operators.
898 :
899 :
900 44346 : Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) {
901 88084 : if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
902 43695 : if (lhs->Is(Type::NullOrUndefined()) && rhs->Is(Type::NullOrUndefined())) {
903 0 : return t->singleton_true_;
904 : }
905 157411 : if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
906 68267 : (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
907 1460 : return t->singleton_false_;
908 : }
909 42911 : if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
910 : // Types are equal and are inhabited only by a single semantic value,
911 : // which is not nan due to the earlier check.
912 163 : return t->singleton_true_;
913 : }
914 : return Type::Boolean();
915 : }
916 :
917 :
918 331646 : static Type* JSType(Type* type) {
919 331646 : if (type->Is(Type::Boolean())) return Type::Boolean();
920 326371 : if (type->Is(Type::String())) return Type::String();
921 250840 : if (type->Is(Type::Number())) return Type::Number();
922 138700 : if (type->Is(Type::Undefined())) return Type::Undefined();
923 137263 : if (type->Is(Type::Null())) return Type::Null();
924 137250 : if (type->Is(Type::Symbol())) return Type::Symbol();
925 137250 : if (type->Is(Type::Receiver())) return Type::Receiver(); // JS "Object"
926 132807 : return Type::Any();
927 : }
928 :
929 :
930 165823 : Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
931 165823 : if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false_;
932 323778 : if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false_;
933 397210 : if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
934 73239 : (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
935 1779 : return t->singleton_false_;
936 : }
937 318872 : if ((lhs->Is(Type::Hole()) || rhs->Is(Type::Hole())) && !lhs->Maybe(rhs)) {
938 6 : return t->singleton_false_;
939 : }
940 160793 : if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
941 : // Types are equal and are inhabited only by a single semantic value,
942 : // which is not nan due to the earlier check.
943 1031 : return t->singleton_true_;
944 : }
945 : return Type::Boolean();
946 : }
947 :
948 :
949 : // The EcmaScript specification defines the four relational comparison operators
950 : // (<, <=, >=, >) with the help of a single abstract one. It behaves like <
951 : // but returns undefined when the inputs cannot be compared.
952 : // We implement the typing analogously.
953 45158 : Typer::Visitor::ComparisonOutcome Typer::Visitor::JSCompareTyper(Type* lhs,
954 : Type* rhs,
955 : Typer* t) {
956 45158 : lhs = ToPrimitive(lhs, t);
957 45158 : rhs = ToPrimitive(rhs, t);
958 45158 : if (lhs->Maybe(Type::String()) && rhs->Maybe(Type::String())) {
959 : return ComparisonOutcome(kComparisonTrue) |
960 : ComparisonOutcome(kComparisonFalse);
961 : }
962 41898 : return NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
963 : }
964 :
965 112070 : Typer::Visitor::ComparisonOutcome Typer::Visitor::NumberCompareTyper(Type* lhs,
966 : Type* rhs,
967 : Typer* t) {
968 : // Shortcut for NaNs.
969 223627 : if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return kComparisonUndefined;
970 :
971 : ComparisonOutcome result;
972 111074 : if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
973 : // Types are equal and are inhabited only by a single semantic value.
974 : result = kComparisonFalse;
975 111074 : } else if (lhs->Min() >= rhs->Max()) {
976 : result = kComparisonFalse;
977 109093 : } else if (lhs->Max() < rhs->Min()) {
978 : result = kComparisonTrue;
979 : } else {
980 : // We cannot figure out the result, return both true and false. (We do not
981 : // have to return undefined because that cannot affect the result of
982 : // FalsifyUndefined.)
983 : return ComparisonOutcome(kComparisonTrue) |
984 : ComparisonOutcome(kComparisonFalse);
985 : }
986 : // Add the undefined if we could see NaN.
987 4225 : if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
988 : result |= kComparisonUndefined;
989 : }
990 4225 : return result;
991 : }
992 :
993 :
994 20589 : Type* Typer::Visitor::JSLessThanTyper(Type* lhs, Type* rhs, Typer* t) {
995 41178 : return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
996 : }
997 :
998 :
999 13550 : Type* Typer::Visitor::JSGreaterThanTyper(Type* lhs, Type* rhs, Typer* t) {
1000 27100 : return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1001 : }
1002 :
1003 :
1004 3388 : Type* Typer::Visitor::JSLessThanOrEqualTyper(Type* lhs, Type* rhs, Typer* t) {
1005 6776 : return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1006 : }
1007 :
1008 :
1009 4006 : Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
1010 : Type* lhs, Type* rhs, Typer* t) {
1011 8012 : return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1012 : }
1013 :
1014 : // JS bitwise operators.
1015 :
1016 :
1017 11849 : Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
1018 11849 : return NumberBitwiseOr(ToNumber(lhs, t), ToNumber(rhs, t), t);
1019 : }
1020 :
1021 :
1022 9376 : Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
1023 9376 : return NumberBitwiseAnd(ToNumber(lhs, t), ToNumber(rhs, t), t);
1024 : }
1025 :
1026 :
1027 3393 : Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
1028 3393 : return NumberBitwiseXor(ToNumber(lhs, t), ToNumber(rhs, t), t);
1029 : }
1030 :
1031 :
1032 3765 : Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
1033 3765 : return NumberShiftLeft(ToNumber(lhs, t), ToNumber(rhs, t), t);
1034 : }
1035 :
1036 :
1037 4815 : Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
1038 4815 : return NumberShiftRight(ToNumber(lhs, t), ToNumber(rhs, t), t);
1039 : }
1040 :
1041 :
1042 4182 : Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
1043 4182 : return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1044 : }
1045 :
1046 :
1047 : // JS arithmetic operators.
1048 :
1049 120437 : Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
1050 120437 : lhs = ToPrimitive(lhs, t);
1051 120437 : rhs = ToPrimitive(rhs, t);
1052 120437 : if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
1053 106945 : if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
1054 : return Type::String();
1055 : } else {
1056 22228 : return Type::NumberOrString();
1057 : }
1058 : }
1059 : // The addition must be numeric.
1060 45931 : return NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t), t);
1061 : }
1062 :
1063 88686 : Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
1064 88686 : return NumberSubtract(ToNumber(lhs, t), ToNumber(rhs, t), t);
1065 : }
1066 :
1067 14202 : Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
1068 14202 : return NumberMultiply(ToNumber(lhs, t), ToNumber(rhs, t), t);
1069 : }
1070 :
1071 15602 : Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
1072 15602 : return NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t), t);
1073 : }
1074 :
1075 4602 : Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
1076 4602 : return NumberModulus(ToNumber(lhs, t), ToNumber(rhs, t), t);
1077 : }
1078 :
1079 :
1080 : // JS unary operators.
1081 :
1082 : Type* Typer::Visitor::TypeClassOf(Node* node) {
1083 : return Type::InternalizedStringOrNull();
1084 : }
1085 :
1086 : Type* Typer::Visitor::TypeTypeOf(Node* node) {
1087 : return Type::InternalizedString();
1088 : }
1089 :
1090 :
1091 : // JS conversion operators.
1092 :
1093 : Type* Typer::Visitor::TypeToBoolean(Node* node) {
1094 151853 : return TypeUnaryOp(node, ToBoolean);
1095 : }
1096 :
1097 : Type* Typer::Visitor::TypeJSToInteger(Node* node) {
1098 275 : return TypeUnaryOp(node, ToInteger);
1099 : }
1100 :
1101 : Type* Typer::Visitor::TypeJSToLength(Node* node) {
1102 967 : return TypeUnaryOp(node, ToLength);
1103 : }
1104 :
1105 : Type* Typer::Visitor::TypeJSToName(Node* node) {
1106 1317 : return TypeUnaryOp(node, ToName);
1107 : }
1108 :
1109 : Type* Typer::Visitor::TypeJSToNumber(Node* node) {
1110 55985 : return TypeUnaryOp(node, ToNumber);
1111 : }
1112 :
1113 : Type* Typer::Visitor::TypeJSToObject(Node* node) {
1114 3281 : return TypeUnaryOp(node, ToObject);
1115 : }
1116 :
1117 : Type* Typer::Visitor::TypeJSToString(Node* node) {
1118 3000 : return TypeUnaryOp(node, ToString);
1119 : }
1120 :
1121 : // JS object operators.
1122 :
1123 :
1124 : Type* Typer::Visitor::TypeJSCreate(Node* node) { return Type::Object(); }
1125 :
1126 :
1127 17954 : Type* Typer::Visitor::TypeJSCreateArguments(Node* node) {
1128 17954 : switch (CreateArgumentsTypeOf(node->op())) {
1129 : case CreateArgumentsType::kRestParameter:
1130 : return Type::Array();
1131 : case CreateArgumentsType::kMappedArguments:
1132 : case CreateArgumentsType::kUnmappedArguments:
1133 : return Type::OtherObject();
1134 : }
1135 0 : UNREACHABLE();
1136 : }
1137 :
1138 : Type* Typer::Visitor::TypeJSCreateArray(Node* node) { return Type::Array(); }
1139 :
1140 : Type* Typer::Visitor::TypeJSCreateBoundFunction(Node* node) {
1141 : return Type::BoundFunction();
1142 : }
1143 :
1144 : Type* Typer::Visitor::TypeJSCreateGeneratorObject(Node* node) {
1145 : return Type::OtherObject();
1146 : }
1147 :
1148 : Type* Typer::Visitor::TypeJSCreateClosure(Node* node) {
1149 : return Type::Function();
1150 : }
1151 :
1152 :
1153 : Type* Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
1154 : return Type::OtherObject();
1155 : }
1156 :
1157 : Type* Typer::Visitor::TypeJSCreateKeyValueArray(Node* node) {
1158 : return Type::OtherObject();
1159 : }
1160 :
1161 : Type* Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
1162 : return Type::Array();
1163 : }
1164 :
1165 : Type* Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) {
1166 : return Type::Array();
1167 : }
1168 :
1169 : Type* Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
1170 : return Type::OtherObject();
1171 : }
1172 :
1173 : Type* Typer::Visitor::TypeJSCreateEmptyLiteralObject(Node* node) {
1174 : return Type::OtherObject();
1175 : }
1176 :
1177 : Type* Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
1178 : return Type::OtherObject();
1179 : }
1180 :
1181 :
1182 : Type* Typer::Visitor::TypeJSLoadProperty(Node* node) {
1183 : return Type::NonInternal();
1184 : }
1185 :
1186 :
1187 : Type* Typer::Visitor::TypeJSLoadNamed(Node* node) {
1188 : return Type::NonInternal();
1189 : }
1190 :
1191 : Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) {
1192 : return Type::NonInternal();
1193 : }
1194 :
1195 : // Returns a somewhat larger range if we previously assigned
1196 : // a (smaller) range to this node. This is used to speed up
1197 : // the fixpoint calculation in case there appears to be a loop
1198 : // in the graph. In the current implementation, we are
1199 : // increasing the limits to the closest power of two.
1200 668523 : Type* Typer::Visitor::Weaken(Node* node, Type* current_type,
1201 514402 : Type* previous_type) {
1202 : static const double kWeakenMinLimits[] = {
1203 : 0.0, -1073741824.0, -2147483648.0, -4294967296.0, -8589934592.0,
1204 : -17179869184.0, -34359738368.0, -68719476736.0, -137438953472.0,
1205 : -274877906944.0, -549755813888.0, -1099511627776.0, -2199023255552.0,
1206 : -4398046511104.0, -8796093022208.0, -17592186044416.0, -35184372088832.0,
1207 : -70368744177664.0, -140737488355328.0, -281474976710656.0,
1208 : -562949953421312.0};
1209 : static const double kWeakenMaxLimits[] = {
1210 : 0.0, 1073741823.0, 2147483647.0, 4294967295.0, 8589934591.0,
1211 : 17179869183.0, 34359738367.0, 68719476735.0, 137438953471.0,
1212 : 274877906943.0, 549755813887.0, 1099511627775.0, 2199023255551.0,
1213 : 4398046511103.0, 8796093022207.0, 17592186044415.0, 35184372088831.0,
1214 : 70368744177663.0, 140737488355327.0, 281474976710655.0,
1215 : 562949953421311.0};
1216 : STATIC_ASSERT(arraysize(kWeakenMinLimits) == arraysize(kWeakenMaxLimits));
1217 :
1218 : // If the types have nothing to do with integers, return the types.
1219 305371 : Type* const integer = typer_->cache_.kInteger;
1220 305371 : if (!previous_type->Maybe(integer)) {
1221 : return current_type;
1222 : }
1223 : DCHECK(current_type->Maybe(integer));
1224 :
1225 257201 : Type* current_integer = Type::Intersect(current_type, integer, zone());
1226 257201 : Type* previous_integer = Type::Intersect(previous_type, integer, zone());
1227 :
1228 : // Once we start weakening a node, we should always weaken.
1229 257201 : if (!IsWeakened(node->id())) {
1230 : // Only weaken if there is range involved; we should converge quickly
1231 : // for all other types (the exception is a union of many constants,
1232 : // but we currently do not increase the number of constants in unions).
1233 106150 : Type* previous = previous_integer->GetRange();
1234 106150 : Type* current = current_integer->GetRange();
1235 106150 : if (current == nullptr || previous == nullptr) {
1236 : return current_type;
1237 : }
1238 : // Range is involved => we are weakening.
1239 : SetWeakened(node->id());
1240 : }
1241 :
1242 257002 : double current_min = current_integer->Min();
1243 : double new_min = current_min;
1244 : // Find the closest lower entry in the list of allowed
1245 : // minima (or negative infinity if there is no such entry).
1246 257002 : if (current_min != previous_integer->Min()) {
1247 : new_min = -V8_INFINITY;
1248 1945671 : for (double const min : kWeakenMinLimits) {
1249 985591 : if (min <= current_min) {
1250 : new_min = min;
1251 : break;
1252 : }
1253 : }
1254 : }
1255 :
1256 257002 : double current_max = current_integer->Max();
1257 : double new_max = current_max;
1258 : // Find the closest greater entry in the list of allowed
1259 : // maxima (or infinity if there is no such entry).
1260 257002 : if (current_max != previous_integer->Max()) {
1261 : new_max = V8_INFINITY;
1262 3554776 : for (double const max : kWeakenMaxLimits) {
1263 1826209 : if (max >= current_max) {
1264 : new_max = max;
1265 : break;
1266 : }
1267 : }
1268 : }
1269 :
1270 : return Type::Union(current_type,
1271 : Type::Range(new_min, new_max, typer_->zone()),
1272 514004 : typer_->zone());
1273 : }
1274 :
1275 :
1276 0 : Type* Typer::Visitor::TypeJSStoreProperty(Node* node) {
1277 0 : UNREACHABLE();
1278 : }
1279 :
1280 :
1281 0 : Type* Typer::Visitor::TypeJSStoreNamed(Node* node) {
1282 0 : UNREACHABLE();
1283 : }
1284 :
1285 :
1286 0 : Type* Typer::Visitor::TypeJSStoreGlobal(Node* node) {
1287 0 : UNREACHABLE();
1288 : }
1289 :
1290 0 : Type* Typer::Visitor::TypeJSStoreNamedOwn(Node* node) {
1291 0 : UNREACHABLE();
1292 : }
1293 :
1294 0 : Type* Typer::Visitor::TypeJSStoreDataPropertyInLiteral(Node* node) {
1295 0 : UNREACHABLE();
1296 : }
1297 :
1298 : Type* Typer::Visitor::TypeJSDeleteProperty(Node* node) {
1299 : return Type::Boolean();
1300 : }
1301 :
1302 : Type* Typer::Visitor::TypeJSHasProperty(Node* node) { return Type::Boolean(); }
1303 :
1304 : // JS instanceof operator.
1305 :
1306 1590 : Type* Typer::Visitor::JSHasInPrototypeChainTyper(Type* lhs, Type* rhs,
1307 : Typer* t) {
1308 1590 : return Type::Boolean();
1309 : }
1310 :
1311 2094 : Type* Typer::Visitor::JSInstanceOfTyper(Type* lhs, Type* rhs, Typer* t) {
1312 2094 : return Type::Boolean();
1313 : }
1314 :
1315 129 : Type* Typer::Visitor::JSOrdinaryHasInstanceTyper(Type* lhs, Type* rhs,
1316 : Typer* t) {
1317 129 : return Type::Boolean();
1318 : }
1319 :
1320 : Type* Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1321 : return Type::Callable();
1322 : }
1323 :
1324 : // JS context operators.
1325 :
1326 :
1327 690994 : Type* Typer::Visitor::TypeJSLoadContext(Node* node) {
1328 690994 : ContextAccess const& access = ContextAccessOf(node->op());
1329 690994 : switch (access.index()) {
1330 : case Context::PREVIOUS_INDEX:
1331 : case Context::NATIVE_CONTEXT_INDEX:
1332 : return Type::OtherInternal();
1333 : case Context::CLOSURE_INDEX:
1334 : return Type::Function();
1335 : default:
1336 : return Type::Any();
1337 : }
1338 : }
1339 :
1340 :
1341 0 : Type* Typer::Visitor::TypeJSStoreContext(Node* node) {
1342 0 : UNREACHABLE();
1343 : }
1344 :
1345 :
1346 : Type* Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
1347 : return Type::OtherInternal();
1348 : }
1349 :
1350 : Type* Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
1351 : return Type::OtherInternal();
1352 : }
1353 :
1354 : Type* Typer::Visitor::TypeJSCreateWithContext(Node* node) {
1355 : return Type::OtherInternal();
1356 : }
1357 :
1358 : Type* Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
1359 : return Type::OtherInternal();
1360 : }
1361 :
1362 : Type* Typer::Visitor::TypeJSCreateScriptContext(Node* node) {
1363 : return Type::OtherInternal();
1364 : }
1365 :
1366 : // JS other operators.
1367 :
1368 : Type* Typer::Visitor::TypeJSConstructForwardVarargs(Node* node) {
1369 : return Type::Receiver();
1370 : }
1371 :
1372 : Type* Typer::Visitor::TypeJSConstruct(Node* node) { return Type::Receiver(); }
1373 :
1374 : Type* Typer::Visitor::TypeJSConstructWithArrayLike(Node* node) {
1375 : return Type::Receiver();
1376 : }
1377 :
1378 : Type* Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
1379 : return Type::Receiver();
1380 : }
1381 :
1382 524665 : Type* Typer::Visitor::JSCallTyper(Type* fun, Typer* t) {
1383 755853 : if (fun->IsHeapConstant() && fun->AsHeapConstant()->Value()->IsJSFunction()) {
1384 : Handle<JSFunction> function =
1385 : Handle<JSFunction>::cast(fun->AsHeapConstant()->Value());
1386 231033 : if (function->shared()->HasBuiltinFunctionId()) {
1387 75166 : switch (function->shared()->builtin_function_id()) {
1388 : case kMathRandom:
1389 : return Type::PlainNumber();
1390 : case kMathFloor:
1391 : case kMathCeil:
1392 : case kMathRound:
1393 : case kMathTrunc:
1394 44700 : return t->cache_.kIntegerOrMinusZeroOrNaN;
1395 : // Unary math functions.
1396 : case kMathAbs:
1397 : case kMathExp:
1398 : case kMathExpm1:
1399 534 : return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1400 : case kMathAcos:
1401 : case kMathAcosh:
1402 : case kMathAsin:
1403 : case kMathAsinh:
1404 : case kMathAtan:
1405 : case kMathAtanh:
1406 : case kMathCbrt:
1407 : case kMathCos:
1408 : case kMathFround:
1409 : case kMathLog:
1410 : case kMathLog1p:
1411 : case kMathLog10:
1412 : case kMathLog2:
1413 : case kMathSin:
1414 : case kMathSqrt:
1415 : case kMathTan:
1416 1858 : return Type::Number();
1417 : case kMathSign:
1418 34 : return t->cache_.kMinusOneToOneOrMinusZeroOrNaN;
1419 : // Binary math functions.
1420 : case kMathAtan2:
1421 : case kMathPow:
1422 : case kMathMax:
1423 : case kMathMin:
1424 2383 : return Type::Number();
1425 : case kMathImul:
1426 851 : return Type::Signed32();
1427 : case kMathClz32:
1428 46 : return t->cache_.kZeroToThirtyTwo;
1429 : // Date functions.
1430 : case kDateNow:
1431 8 : return t->cache_.kTimeValueType;
1432 : case kDateGetDate:
1433 0 : return t->cache_.kJSDateDayType;
1434 : case kDateGetDay:
1435 0 : return t->cache_.kJSDateWeekdayType;
1436 : case kDateGetFullYear:
1437 0 : return t->cache_.kJSDateYearType;
1438 : case kDateGetHours:
1439 0 : return t->cache_.kJSDateHourType;
1440 : case kDateGetMilliseconds:
1441 : return Type::Union(Type::Range(0.0, 999.0, t->zone()), Type::NaN(),
1442 0 : t->zone());
1443 : case kDateGetMinutes:
1444 0 : return t->cache_.kJSDateMinuteType;
1445 : case kDateGetMonth:
1446 0 : return t->cache_.kJSDateMonthType;
1447 : case kDateGetSeconds:
1448 0 : return t->cache_.kJSDateSecondType;
1449 : case kDateGetTime:
1450 0 : return t->cache_.kJSDateValueType;
1451 :
1452 : // Number functions.
1453 : case kNumberIsFinite:
1454 : case kNumberIsInteger:
1455 : case kNumberIsNaN:
1456 : case kNumberIsSafeInteger:
1457 119 : return Type::Boolean();
1458 : case kNumberParseFloat:
1459 21 : return Type::Number();
1460 : case kNumberParseInt:
1461 423 : return t->cache_.kIntegerOrMinusZeroOrNaN;
1462 : case kNumberToString:
1463 156 : return Type::String();
1464 :
1465 : // String functions.
1466 : case kStringCharCodeAt:
1467 : return Type::Union(Type::Range(0, kMaxUInt16, t->zone()), Type::NaN(),
1468 813 : t->zone());
1469 : case kStringCharAt:
1470 143 : return Type::String();
1471 : case kStringCodePointAt:
1472 : return Type::Union(Type::Range(0.0, String::kMaxCodePoint, t->zone()),
1473 16 : Type::Undefined(), t->zone());
1474 : case kStringConcat:
1475 : case kStringFromCharCode:
1476 : case kStringFromCodePoint:
1477 252 : return Type::String();
1478 : case kStringIndexOf:
1479 : case kStringLastIndexOf:
1480 211 : return Type::Range(-1.0, String::kMaxLength, t->zone());
1481 : case kStringEndsWith:
1482 : case kStringIncludes:
1483 1 : return Type::Boolean();
1484 : case kStringRaw:
1485 : case kStringRepeat:
1486 : case kStringSlice:
1487 13 : return Type::String();
1488 : case kStringStartsWith:
1489 0 : return Type::Boolean();
1490 : case kStringSubstr:
1491 : case kStringSubstring:
1492 : case kStringToLowerCase:
1493 : case kStringToString:
1494 : case kStringToUpperCase:
1495 : case kStringTrim:
1496 : case kStringTrimLeft:
1497 : case kStringTrimRight:
1498 : case kStringValueOf:
1499 1593 : return Type::String();
1500 :
1501 : case kStringIterator:
1502 : case kStringIteratorNext:
1503 73 : return Type::OtherObject();
1504 :
1505 : case kArrayEntries:
1506 : case kArrayKeys:
1507 : case kArrayValues:
1508 : case kTypedArrayEntries:
1509 : case kTypedArrayKeys:
1510 : case kTypedArrayValues:
1511 : case kArrayIteratorNext:
1512 : case kMapIteratorNext:
1513 : case kSetIteratorNext:
1514 1663 : return Type::OtherObject();
1515 : case kTypedArrayToStringTag:
1516 : return Type::Union(Type::InternalizedString(), Type::Undefined(),
1517 23 : t->zone());
1518 :
1519 : // Array functions.
1520 : case kArrayIsArray:
1521 15 : return Type::Boolean();
1522 : case kArrayConcat:
1523 110 : return Type::Receiver();
1524 : case kArrayEvery:
1525 1 : return Type::Boolean();
1526 : case kArrayFill:
1527 : case kArrayFilter:
1528 4 : return Type::Receiver();
1529 : case kArrayFindIndex:
1530 0 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1531 : case kArrayForEach:
1532 31 : return Type::Undefined();
1533 : case kArrayIncludes:
1534 15 : return Type::Boolean();
1535 : case kArrayIndexOf:
1536 146 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1537 : case kArrayJoin:
1538 35 : return Type::String();
1539 : case kArrayLastIndexOf:
1540 62 : return Type::Range(-1, kMaxSafeInteger, t->zone());
1541 : case kArrayMap:
1542 10 : return Type::Receiver();
1543 : case kArrayPush:
1544 2754 : return t->cache_.kPositiveSafeInteger;
1545 : case kArrayReverse:
1546 : case kArraySlice:
1547 127 : return Type::Receiver();
1548 : case kArraySome:
1549 1 : return Type::Boolean();
1550 : case kArraySplice:
1551 133 : return Type::Receiver();
1552 : case kArrayUnshift:
1553 45 : return t->cache_.kPositiveSafeInteger;
1554 :
1555 : // ArrayBuffer functions.
1556 : case kArrayBufferIsView:
1557 0 : return Type::Boolean();
1558 :
1559 : // Object functions.
1560 : case kObjectAssign:
1561 0 : return Type::Receiver();
1562 : case kObjectCreate:
1563 58 : return Type::OtherObject();
1564 : case kObjectIs:
1565 : case kObjectHasOwnProperty:
1566 : case kObjectIsPrototypeOf:
1567 570 : return Type::Boolean();
1568 : case kObjectToString:
1569 154 : return Type::String();
1570 :
1571 : // RegExp functions.
1572 : case kRegExpCompile:
1573 0 : return Type::OtherObject();
1574 : case kRegExpExec:
1575 109 : return Type::Union(Type::Array(), Type::Null(), t->zone());
1576 : case kRegExpTest:
1577 345 : return Type::Boolean();
1578 : case kRegExpToString:
1579 0 : return Type::String();
1580 :
1581 : // Function functions.
1582 : case kFunctionBind:
1583 0 : return Type::BoundFunction();
1584 : case kFunctionHasInstance:
1585 0 : return Type::Boolean();
1586 :
1587 : // Global functions.
1588 : case kGlobalDecodeURI:
1589 : case kGlobalDecodeURIComponent:
1590 : case kGlobalEncodeURI:
1591 : case kGlobalEncodeURIComponent:
1592 : case kGlobalEscape:
1593 : case kGlobalUnescape:
1594 456 : return Type::String();
1595 : case kGlobalIsFinite:
1596 : case kGlobalIsNaN:
1597 12074 : return Type::Boolean();
1598 :
1599 : // Map functions.
1600 : case kMapClear:
1601 : case kMapForEach:
1602 0 : return Type::Undefined();
1603 : case kMapDelete:
1604 : case kMapHas:
1605 7 : return Type::Boolean();
1606 : case kMapEntries:
1607 : case kMapKeys:
1608 : case kMapSet:
1609 : case kMapValues:
1610 126 : return Type::OtherObject();
1611 :
1612 : // Set functions.
1613 : case kSetAdd:
1614 : case kSetEntries:
1615 : case kSetValues:
1616 259 : return Type::OtherObject();
1617 : case kSetClear:
1618 : case kSetForEach:
1619 0 : return Type::Undefined();
1620 : case kSetDelete:
1621 : case kSetHas:
1622 92 : return Type::Boolean();
1623 :
1624 : // WeakMap functions.
1625 : case kWeakMapDelete:
1626 : case kWeakMapHas:
1627 0 : return Type::Boolean();
1628 : case kWeakMapSet:
1629 4 : return Type::OtherObject();
1630 :
1631 : // WeakSet functions.
1632 : case kWeakSetAdd:
1633 0 : return Type::OtherObject();
1634 : case kWeakSetDelete:
1635 : case kWeakSetHas:
1636 0 : return Type::Boolean();
1637 : default:
1638 : break;
1639 : }
1640 : }
1641 : }
1642 : return Type::NonInternal();
1643 : }
1644 :
1645 : Type* Typer::Visitor::TypeJSCallForwardVarargs(Node* node) {
1646 384 : return TypeUnaryOp(node, JSCallTyper);
1647 : }
1648 :
1649 : Type* Typer::Visitor::TypeJSCall(Node* node) {
1650 : // TODO(bmeurer): We could infer better types if we wouldn't ignore the
1651 : // argument types for the JSCallTyper above.
1652 523434 : return TypeUnaryOp(node, JSCallTyper);
1653 : }
1654 :
1655 : Type* Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
1656 305 : return TypeUnaryOp(node, JSCallTyper);
1657 : }
1658 :
1659 : Type* Typer::Visitor::TypeJSCallWithSpread(Node* node) {
1660 829 : return TypeUnaryOp(node, JSCallTyper);
1661 : }
1662 :
1663 275167 : Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
1664 275167 : switch (CallRuntimeParametersOf(node->op()).id()) {
1665 : case Runtime::kInlineIsJSReceiver:
1666 0 : return TypeUnaryOp(node, ObjectIsReceiver);
1667 : case Runtime::kInlineIsSmi:
1668 0 : return TypeUnaryOp(node, ObjectIsSmi);
1669 : case Runtime::kInlineIsArray:
1670 : case Runtime::kInlineIsDate:
1671 : case Runtime::kInlineIsTypedArray:
1672 : case Runtime::kInlineIsRegExp:
1673 : return Type::Boolean();
1674 : case Runtime::kInlineCreateIterResultObject:
1675 0 : return Type::OtherObject();
1676 : case Runtime::kInlineStringCharFromCode:
1677 0 : return Type::String();
1678 : case Runtime::kInlineToInteger:
1679 0 : return TypeUnaryOp(node, ToInteger);
1680 : case Runtime::kInlineToLength:
1681 0 : return TypeUnaryOp(node, ToLength);
1682 : case Runtime::kInlineToNumber:
1683 0 : return TypeUnaryOp(node, ToNumber);
1684 : case Runtime::kInlineToObject:
1685 0 : return TypeUnaryOp(node, ToObject);
1686 : case Runtime::kInlineToString:
1687 0 : return TypeUnaryOp(node, ToString);
1688 : case Runtime::kInlineClassOf:
1689 0 : return Type::InternalizedStringOrNull();
1690 : case Runtime::kHasInPrototypeChain:
1691 : return Type::Boolean();
1692 : default:
1693 : break;
1694 : }
1695 : // TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
1696 : // have a few weird runtime calls that return the hole or even FixedArrays;
1697 : // change this once those weird runtime calls have been removed.
1698 273902 : return Type::Any();
1699 : }
1700 :
1701 :
1702 : Type* Typer::Visitor::TypeJSConvertReceiver(Node* node) {
1703 : return Type::Receiver();
1704 : }
1705 :
1706 : Type* Typer::Visitor::TypeJSForInEnumerate(Node* node) {
1707 : return Type::OtherInternal();
1708 : }
1709 :
1710 3403 : Type* Typer::Visitor::TypeJSForInNext(Node* node) {
1711 3403 : return Type::Union(Type::String(), Type::Undefined(), zone());
1712 : }
1713 :
1714 :
1715 1520 : Type* Typer::Visitor::TypeJSForInPrepare(Node* node) {
1716 : STATIC_ASSERT(Map::EnumLengthBits::kMax <= FixedArray::kMaxLength);
1717 : Type* const cache_type =
1718 1520 : Type::Union(Type::SignedSmall(), Type::OtherInternal(), zone());
1719 : Type* const cache_array = Type::OtherInternal();
1720 1520 : Type* const cache_length = typer_->cache_.kFixedArrayLengthType;
1721 1520 : return Type::Tuple(cache_type, cache_array, cache_length, zone());
1722 : }
1723 :
1724 :
1725 : Type* Typer::Visitor::TypeJSLoadMessage(Node* node) { return Type::Any(); }
1726 :
1727 :
1728 0 : Type* Typer::Visitor::TypeJSStoreMessage(Node* node) {
1729 0 : UNREACHABLE();
1730 : }
1731 :
1732 : Type* Typer::Visitor::TypeJSLoadModule(Node* node) { return Type::Any(); }
1733 :
1734 0 : Type* Typer::Visitor::TypeJSStoreModule(Node* node) {
1735 0 : UNREACHABLE();
1736 : }
1737 :
1738 0 : Type* Typer::Visitor::TypeJSGeneratorStore(Node* node) {
1739 0 : UNREACHABLE();
1740 : }
1741 :
1742 : Type* Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
1743 : return Type::SignedSmall();
1744 : }
1745 :
1746 : Type* Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
1747 : return Type::Any();
1748 : }
1749 :
1750 : Type* Typer::Visitor::TypeJSStackCheck(Node* node) { return Type::Any(); }
1751 :
1752 : Type* Typer::Visitor::TypeJSDebugger(Node* node) { return Type::Any(); }
1753 :
1754 : // Simplified operators.
1755 :
1756 : Type* Typer::Visitor::TypeBooleanNot(Node* node) { return Type::Boolean(); }
1757 :
1758 : // static
1759 29333 : Type* Typer::Visitor::NumberEqualTyper(Type* lhs, Type* rhs, Typer* t) {
1760 29333 : return JSEqualTyper(ToNumber(lhs, t), ToNumber(rhs, t), t);
1761 : }
1762 :
1763 : // static
1764 70172 : Type* Typer::Visitor::NumberLessThanTyper(Type* lhs, Type* rhs, Typer* t) {
1765 : return FalsifyUndefined(
1766 140344 : NumberCompareTyper(ToNumber(lhs, t), ToNumber(rhs, t), t), t);
1767 : }
1768 :
1769 : // static
1770 3625 : Type* Typer::Visitor::NumberLessThanOrEqualTyper(Type* lhs, Type* rhs,
1771 : Typer* t) {
1772 : return FalsifyUndefined(
1773 7250 : Invert(JSCompareTyper(ToNumber(rhs, t), ToNumber(lhs, t), t), t), t);
1774 : }
1775 :
1776 : Type* Typer::Visitor::TypeNumberEqual(Node* node) {
1777 7939 : return TypeBinaryOp(node, NumberEqualTyper);
1778 : }
1779 :
1780 : Type* Typer::Visitor::TypeNumberLessThan(Node* node) {
1781 9853 : return TypeBinaryOp(node, NumberLessThanTyper);
1782 : }
1783 :
1784 : Type* Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
1785 1593 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1786 : }
1787 :
1788 : Type* Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
1789 24680 : return TypeBinaryOp(node, NumberEqualTyper);
1790 : }
1791 :
1792 : Type* Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1793 101481 : return TypeBinaryOp(node, NumberLessThanTyper);
1794 : }
1795 :
1796 : Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1797 2783 : return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
1798 : }
1799 :
1800 : Type* Typer::Visitor::TypeStringToNumber(Node* node) {
1801 0 : return TypeUnaryOp(node, ToNumber);
1802 : }
1803 :
1804 : Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1805 9027 : return TypeUnaryOp(node, ToNumber);
1806 : }
1807 :
1808 : Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1809 : return Type::Integral32();
1810 : }
1811 :
1812 : Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1813 : return Type::Number();
1814 : }
1815 :
1816 : // static
1817 206713 : Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) {
1818 218856 : if (lhs->IsHeapConstant() && rhs->Is(lhs)) {
1819 6067 : return t->singleton_true_;
1820 : }
1821 : return Type::Boolean();
1822 : }
1823 :
1824 :
1825 : Type* Typer::Visitor::TypeReferenceEqual(Node* node) {
1826 207573 : return TypeBinaryOp(node, ReferenceEqualTyper);
1827 : }
1828 :
1829 : Type* Typer::Visitor::TypeStringEqual(Node* node) { return Type::Boolean(); }
1830 :
1831 : Type* Typer::Visitor::TypeStringLessThan(Node* node) { return Type::Boolean(); }
1832 :
1833 : Type* Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
1834 : return Type::Boolean();
1835 : }
1836 :
1837 154 : Type* Typer::Visitor::StringFromCharCodeTyper(Type* type, Typer* t) {
1838 154 : return Type::String();
1839 : }
1840 :
1841 32 : Type* Typer::Visitor::StringFromCodePointTyper(Type* type, Typer* t) {
1842 32 : return Type::String();
1843 : }
1844 :
1845 : Type* Typer::Visitor::TypeStringCharAt(Node* node) { return Type::String(); }
1846 :
1847 0 : Type* Typer::Visitor::TypeStringToLowerCaseIntl(Node* node) { UNREACHABLE(); }
1848 :
1849 0 : Type* Typer::Visitor::TypeStringToUpperCaseIntl(Node* node) { UNREACHABLE(); }
1850 :
1851 : Type* Typer::Visitor::TypeStringCharCodeAt(Node* node) {
1852 423 : return typer_->cache_.kUint16;
1853 : }
1854 :
1855 : Type* Typer::Visitor::TypeSeqStringCharCodeAt(Node* node) {
1856 0 : return typer_->cache_.kUint16;
1857 : }
1858 :
1859 : Type* Typer::Visitor::TypeStringFromCharCode(Node* node) {
1860 154 : return TypeUnaryOp(node, StringFromCharCodeTyper);
1861 : }
1862 :
1863 : Type* Typer::Visitor::TypeStringFromCodePoint(Node* node) {
1864 32 : return TypeUnaryOp(node, StringFromCodePointTyper);
1865 : }
1866 :
1867 0 : Type* Typer::Visitor::TypeStringIndexOf(Node* node) { UNREACHABLE(); }
1868 :
1869 121133 : Type* Typer::Visitor::TypeCheckBounds(Node* node) {
1870 : Type* index = Operand(node, 0);
1871 : Type* length = Operand(node, 1);
1872 42993 : if (index->Maybe(Type::MinusZero())) {
1873 4176 : index = Type::Union(index, typer_->cache_.kSingletonZero, zone());
1874 : }
1875 42993 : index = Type::Intersect(index, Type::Integral32(), zone());
1876 74022 : if (!index->IsInhabited() || !length->IsInhabited()) return Type::None();
1877 62058 : double min = std::max(index->Min(), 0.0);
1878 62058 : double max = std::min(index->Max(), length->Max() - 1);
1879 31029 : if (max < min) return Type::None();
1880 30971 : return Type::Range(min, max, zone());
1881 : }
1882 :
1883 : Type* Typer::Visitor::TypeCheckHeapObject(Node* node) {
1884 : Type* type = Operand(node, 0);
1885 : return type;
1886 : }
1887 :
1888 0 : Type* Typer::Visitor::TypeCheckIf(Node* node) {
1889 0 : UNREACHABLE();
1890 : }
1891 :
1892 8298 : Type* Typer::Visitor::TypeCheckInternalizedString(Node* node) {
1893 : Type* arg = Operand(node, 0);
1894 4149 : return Type::Intersect(arg, Type::InternalizedString(), zone());
1895 : }
1896 :
1897 0 : Type* Typer::Visitor::TypeCheckMaps(Node* node) {
1898 0 : UNREACHABLE();
1899 : }
1900 :
1901 : Type* Typer::Visitor::TypeCompareMaps(Node* node) { return Type::Boolean(); }
1902 :
1903 1792 : Type* Typer::Visitor::TypeCheckNumber(Node* node) {
1904 1792 : return typer_->operation_typer_.CheckNumber(Operand(node, 0));
1905 : }
1906 :
1907 1786 : Type* Typer::Visitor::TypeCheckReceiver(Node* node) {
1908 : Type* arg = Operand(node, 0);
1909 893 : return Type::Intersect(arg, Type::Receiver(), zone());
1910 : }
1911 :
1912 99126 : Type* Typer::Visitor::TypeCheckSmi(Node* node) {
1913 : Type* arg = Operand(node, 0);
1914 49563 : return Type::Intersect(arg, Type::SignedSmall(), zone());
1915 : }
1916 :
1917 8974 : Type* Typer::Visitor::TypeCheckString(Node* node) {
1918 : Type* arg = Operand(node, 0);
1919 4487 : return Type::Intersect(arg, Type::String(), zone());
1920 : }
1921 :
1922 5958 : Type* Typer::Visitor::TypeCheckSeqString(Node* node) {
1923 : Type* arg = Operand(node, 0);
1924 2979 : return Type::Intersect(arg, Type::SeqString(), zone());
1925 : }
1926 :
1927 0 : Type* Typer::Visitor::TypeCheckSymbol(Node* node) {
1928 : Type* arg = Operand(node, 0);
1929 0 : return Type::Intersect(arg, Type::Symbol(), zone());
1930 : }
1931 :
1932 775 : Type* Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
1933 775 : return typer_->operation_typer_.CheckFloat64Hole(Operand(node, 0));
1934 : }
1935 :
1936 1952 : Type* Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
1937 : Type* type = Operand(node, 0);
1938 976 : type = Type::Intersect(type, Type::NonInternal(), zone());
1939 976 : return type;
1940 : }
1941 :
1942 1500 : Type* Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
1943 : Type* type = Operand(node, 0);
1944 1500 : return typer_->operation_typer()->ConvertTaggedHoleToUndefined(type);
1945 : }
1946 :
1947 0 : Type* Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
1948 0 : UNREACHABLE();
1949 : }
1950 :
1951 0 : Type* Typer::Visitor::TypeCheckEqualsSymbol(Node* node) { UNREACHABLE(); }
1952 :
1953 : Type* Typer::Visitor::TypeAllocate(Node* node) {
1954 121824 : return AllocateTypeOf(node->op());
1955 : }
1956 :
1957 : Type* Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
1958 : return Type::NonInternal();
1959 : }
1960 :
1961 : Type* Typer::Visitor::TypeLoadField(Node* node) {
1962 499096 : return FieldAccessOf(node->op()).type;
1963 : }
1964 :
1965 : Type* Typer::Visitor::TypeLoadElement(Node* node) {
1966 22044 : return ElementAccessOf(node->op()).type;
1967 : }
1968 :
1969 6173 : Type* Typer::Visitor::TypeLoadTypedElement(Node* node) {
1970 6173 : switch (ExternalArrayTypeOf(node->op())) {
1971 : #define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype, size) \
1972 : case kExternal##ElemType##Array: \
1973 : return typer_->cache_.k##ElemType;
1974 697 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
1975 : #undef TYPED_ARRAY_CASE
1976 : }
1977 0 : UNREACHABLE();
1978 : }
1979 :
1980 0 : Type* Typer::Visitor::TypeStoreField(Node* node) {
1981 0 : UNREACHABLE();
1982 : }
1983 :
1984 0 : Type* Typer::Visitor::TypeStoreElement(Node* node) {
1985 0 : UNREACHABLE();
1986 : }
1987 :
1988 0 : Type* Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
1989 0 : UNREACHABLE();
1990 : }
1991 :
1992 0 : Type* Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
1993 0 : UNREACHABLE();
1994 : }
1995 :
1996 0 : Type* Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
1997 0 : UNREACHABLE();
1998 : }
1999 :
2000 0 : Type* Typer::Visitor::TypeStoreSignedSmallElement(Node* node) { UNREACHABLE(); }
2001 :
2002 0 : Type* Typer::Visitor::TypeStoreTypedElement(Node* node) {
2003 0 : UNREACHABLE();
2004 : }
2005 :
2006 : Type* Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2007 0 : return TypeUnaryOp(node, ObjectIsArrayBufferView);
2008 : }
2009 :
2010 : Type* Typer::Visitor::TypeObjectIsCallable(Node* node) {
2011 417 : return TypeUnaryOp(node, ObjectIsCallable);
2012 : }
2013 :
2014 : Type* Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2015 237 : return TypeUnaryOp(node, ObjectIsConstructor);
2016 : }
2017 :
2018 : Type* Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2019 13796 : return TypeUnaryOp(node, ObjectIsDetectableCallable);
2020 : }
2021 :
2022 : Type* Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2023 28 : return TypeUnaryOp(node, ObjectIsMinusZero);
2024 : }
2025 :
2026 : Type* Typer::Visitor::TypeObjectIsNaN(Node* node) {
2027 4702 : return TypeUnaryOp(node, ObjectIsNaN);
2028 : }
2029 :
2030 : Type* Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2031 7466 : return TypeUnaryOp(node, ObjectIsNonCallable);
2032 : }
2033 :
2034 : Type* Typer::Visitor::TypeObjectIsNumber(Node* node) {
2035 9998 : return TypeUnaryOp(node, ObjectIsNumber);
2036 : }
2037 :
2038 :
2039 : Type* Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2040 24518 : return TypeUnaryOp(node, ObjectIsReceiver);
2041 : }
2042 :
2043 :
2044 : Type* Typer::Visitor::TypeObjectIsSmi(Node* node) {
2045 4369 : return TypeUnaryOp(node, ObjectIsSmi);
2046 : }
2047 :
2048 : Type* Typer::Visitor::TypeObjectIsString(Node* node) {
2049 2372 : return TypeUnaryOp(node, ObjectIsString);
2050 : }
2051 :
2052 : Type* Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2053 232 : return TypeUnaryOp(node, ObjectIsSymbol);
2054 : }
2055 :
2056 : Type* Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2057 6094 : return TypeUnaryOp(node, ObjectIsUndetectable);
2058 : }
2059 :
2060 : Type* Typer::Visitor::TypeArgumentsLength(Node* node) {
2061 16652 : return TypeCache::Get().kArgumentsLengthType;
2062 : }
2063 :
2064 : Type* Typer::Visitor::TypeArgumentsFrame(Node* node) {
2065 : return Type::ExternalPointer();
2066 : }
2067 :
2068 : Type* Typer::Visitor::TypeNewDoubleElements(Node* node) {
2069 : return Type::OtherInternal();
2070 : }
2071 :
2072 : Type* Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2073 : return Type::OtherInternal();
2074 : }
2075 :
2076 : Type* Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2077 : return Type::OtherInternal();
2078 : }
2079 :
2080 : Type* Typer::Visitor::TypeArrayBufferWasNeutered(Node* node) {
2081 : return Type::Boolean();
2082 : }
2083 :
2084 8 : Type* Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2085 8 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2086 : }
2087 :
2088 0 : Type* Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2089 0 : return Type::Range(-1.0, FixedArray::kMaxLength, zone());
2090 : }
2091 :
2092 0 : Type* Typer::Visitor::TypeRuntimeAbort(Node* node) { UNREACHABLE(); }
2093 :
2094 : // Heap constants.
2095 :
2096 7894017 : Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
2097 3947007 : if (Type::IsInteger(*value)) {
2098 0 : return Type::Range(value->Number(), value->Number(), zone());
2099 : }
2100 3947010 : return Type::NewConstant(value, zone());
2101 : }
2102 :
2103 : } // namespace compiler
2104 : } // namespace internal
2105 : } // namespace v8
|