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