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 <iomanip>
6 :
7 : #include "src/compiler/types.h"
8 :
9 : #include "src/handles-inl.h"
10 : #include "src/objects-inl.h"
11 : #include "src/ostreams.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 : namespace compiler {
16 :
17 : // -----------------------------------------------------------------------------
18 : // Range-related helper functions.
19 :
20 3187465 : bool RangeType::Limits::IsEmpty() { return this->min > this->max; }
21 :
22 0 : RangeType::Limits RangeType::Limits::Intersect(Limits lhs, Limits rhs) {
23 : DisallowHeapAllocation no_allocation;
24 : Limits result(lhs);
25 1885280 : if (lhs.min < rhs.min) result.min = rhs.min;
26 1885280 : if (lhs.max > rhs.max) result.max = rhs.max;
27 0 : return result;
28 : }
29 :
30 0 : RangeType::Limits RangeType::Limits::Union(Limits lhs, Limits rhs) {
31 : DisallowHeapAllocation no_allocation;
32 3618016 : if (lhs.IsEmpty()) return rhs;
33 3618013 : if (rhs.IsEmpty()) return lhs;
34 : Limits result(lhs);
35 2994283 : if (lhs.min > rhs.min) result.min = rhs.min;
36 2994283 : if (lhs.max < rhs.max) result.max = rhs.max;
37 0 : return result;
38 : }
39 :
40 0 : bool Type::Overlap(const RangeType* lhs, const RangeType* rhs) {
41 : DisallowHeapAllocation no_allocation;
42 : return !RangeType::Limits::Intersect(RangeType::Limits(lhs),
43 : RangeType::Limits(rhs))
44 1261350 : .IsEmpty();
45 : }
46 :
47 0 : bool Type::Contains(const RangeType* lhs, const RangeType* rhs) {
48 : DisallowHeapAllocation no_allocation;
49 22934461 : return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
50 : }
51 :
52 : // -----------------------------------------------------------------------------
53 : // Min and Max computation.
54 :
55 12878109 : double Type::Min() const {
56 : DCHECK(this->Is(Number()));
57 : DCHECK(!this->Is(NaN()));
58 13542946 : if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
59 12213272 : if (this->IsUnion()) {
60 49997 : double min = +V8_INFINITY;
61 208473 : for (int i = 1, n = AsUnion()->Length(); i < n; ++i) {
62 158477 : min = std::min(min, AsUnion()->Get(i).Min());
63 : }
64 49996 : Type bitset = AsUnion()->Get(0);
65 69286 : if (!bitset.Is(NaN())) min = std::min(min, bitset.Min());
66 49996 : return min;
67 : }
68 24283315 : if (this->IsRange()) return this->AsRange()->Min();
69 : DCHECK(this->IsOtherNumberConstant());
70 43235 : return this->AsOtherNumberConstant()->Value();
71 : }
72 :
73 13064653 : double Type::Max() const {
74 : DCHECK(this->Is(Number()));
75 : DCHECK(!this->Is(NaN()));
76 13905325 : if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
77 12223981 : if (this->IsUnion()) {
78 45385 : double max = -V8_INFINITY;
79 194639 : for (int i = 1, n = this->AsUnion()->Length(); i < n; ++i) {
80 149254 : max = std::max(max, this->AsUnion()->Get(i).Max());
81 : }
82 45385 : Type bitset = this->AsUnion()->Get(0);
83 60051 : if (!bitset.Is(NaN())) max = std::max(max, bitset.Max());
84 45385 : return max;
85 : }
86 24318668 : if (this->IsRange()) return this->AsRange()->Max();
87 : DCHECK(this->IsOtherNumberConstant());
88 38524 : return this->AsOtherNumberConstant()->Value();
89 : }
90 :
91 : // -----------------------------------------------------------------------------
92 : // Glb and lub computation.
93 :
94 : // The largest bitset subsumed by this type.
95 124125243 : Type::bitset Type::BitsetGlb() const {
96 : DisallowHeapAllocation no_allocation;
97 : // Fast case.
98 124125243 : if (IsBitset()) {
99 36644710 : return AsBitset();
100 87480533 : } else if (IsUnion()) {
101 : SLOW_DCHECK(AsUnion()->Wellformed());
102 52684693 : return AsUnion()->Get(0).BitsetGlb() |
103 26342399 : AsUnion()->Get(1).BitsetGlb(); // Shortcut.
104 61138044 : } else if (IsRange()) {
105 38256939 : bitset glb = BitsetType::Glb(AsRange()->Min(), AsRange()->Max());
106 38257364 : return glb;
107 : } else {
108 : return BitsetType::kNone;
109 : }
110 : }
111 :
112 : // The smallest bitset subsuming this type, possibly not a proper one.
113 374008657 : Type::bitset Type::BitsetLub() const {
114 : DisallowHeapAllocation no_allocation;
115 620005026 : if (IsBitset()) return AsBitset();
116 128012288 : if (IsUnion()) {
117 : // Take the representation from the first element, which is always
118 : // a bitset.
119 10763374 : int bitset = AsUnion()->Get(0).BitsetLub();
120 69371546 : for (int i = 0, n = AsUnion()->Length(); i < n; ++i) {
121 : // Other elements only contribute their semantic part.
122 29306803 : bitset |= AsUnion()->Get(i).BitsetLub();
123 : }
124 10764834 : return bitset;
125 : }
126 155418582 : if (IsHeapConstant()) return AsHeapConstant()->Lub();
127 79079246 : if (IsOtherNumberConstant()) {
128 : return AsOtherNumberConstant()->Lub();
129 : }
130 134783429 : if (IsRange()) return AsRange()->Lub();
131 4113 : if (IsTuple()) return BitsetType::kOtherInternal;
132 0 : UNREACHABLE();
133 : }
134 :
135 : // TODO(neis): Once the broker mode kDisabled is gone, change the input type to
136 : // MapRef and get rid of the HeapObjectType class.
137 : template <typename MapRefLike>
138 18193215 : Type::bitset BitsetType::Lub(const MapRefLike& map) {
139 18193215 : switch (map.instance_type()) {
140 : case EMPTY_STRING_TYPE:
141 : return kEmptyString;
142 : case CONS_STRING_TYPE:
143 : case SLICED_STRING_TYPE:
144 : case EXTERNAL_STRING_TYPE:
145 : case UNCACHED_EXTERNAL_STRING_TYPE:
146 : case STRING_TYPE:
147 : case THIN_STRING_TYPE:
148 639 : return kNonEmptyTwoByteString;
149 : case CONS_ONE_BYTE_STRING_TYPE:
150 : case SLICED_ONE_BYTE_STRING_TYPE:
151 : case EXTERNAL_ONE_BYTE_STRING_TYPE:
152 : case UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE:
153 : case ONE_BYTE_STRING_TYPE:
154 : case THIN_ONE_BYTE_STRING_TYPE:
155 330 : return kNonEmptyOneByteString;
156 : case EXTERNAL_INTERNALIZED_STRING_TYPE:
157 : case UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE:
158 : case INTERNALIZED_STRING_TYPE:
159 9300 : return kNonEmptyInternalizedTwoByteString;
160 : case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
161 : case UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
162 : case ONE_BYTE_INTERNALIZED_STRING_TYPE:
163 3131642 : return kNonEmptyInternalizedOneByteString;
164 : case SYMBOL_TYPE:
165 785 : return kSymbol;
166 : case BIGINT_TYPE:
167 2387 : return kBigInt;
168 : case ODDBALL_TYPE:
169 10621761 : switch (map.oddball_type()) {
170 : case OddballType::kNone:
171 : break;
172 : case OddballType::kHole:
173 : return kHole;
174 : case OddballType::kBoolean:
175 6620271 : return kBoolean;
176 : case OddballType::kNull:
177 32087 : return kNull;
178 : case OddballType::kUndefined:
179 965006 : return kUndefined;
180 : case OddballType::kUninitialized:
181 : case OddballType::kOther:
182 : // TODO(neis): We should add a kOtherOddball type.
183 1418028 : return kOtherInternal;
184 : }
185 0 : UNREACHABLE();
186 : case HEAP_NUMBER_TYPE:
187 0 : return kNumber;
188 : case JS_OBJECT_TYPE:
189 : case JS_ARGUMENTS_TYPE:
190 : case JS_ERROR_TYPE:
191 : case JS_GLOBAL_OBJECT_TYPE:
192 : case JS_GLOBAL_PROXY_TYPE:
193 : case JS_API_OBJECT_TYPE:
194 : case JS_SPECIAL_API_OBJECT_TYPE:
195 1040888 : if (map.is_undetectable()) {
196 : // Currently we assume that every undetectable receiver is also
197 : // callable, which is what we need to support document.all. We
198 : // could add another Type bit to support other use cases in the
199 : // future if necessary.
200 : DCHECK(map.is_callable());
201 : return kOtherUndetectable;
202 : }
203 1040822 : if (map.is_callable()) {
204 : return kOtherCallable;
205 : }
206 1040822 : return kOtherObject;
207 : case JS_ARRAY_TYPE:
208 502988 : return kArray;
209 : case JS_VALUE_TYPE:
210 : case JS_MESSAGE_OBJECT_TYPE:
211 : case JS_DATE_TYPE:
212 : #ifdef V8_INTL_SUPPORT
213 : case JS_INTL_V8_BREAK_ITERATOR_TYPE:
214 : case JS_INTL_COLLATOR_TYPE:
215 : case JS_INTL_DATE_TIME_FORMAT_TYPE:
216 : case JS_INTL_LIST_FORMAT_TYPE:
217 : case JS_INTL_LOCALE_TYPE:
218 : case JS_INTL_NUMBER_FORMAT_TYPE:
219 : case JS_INTL_PLURAL_RULES_TYPE:
220 : case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
221 : case JS_INTL_SEGMENT_ITERATOR_TYPE:
222 : case JS_INTL_SEGMENTER_TYPE:
223 : #endif // V8_INTL_SUPPORT
224 : case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
225 : case JS_GENERATOR_OBJECT_TYPE:
226 : case JS_ASYNC_FUNCTION_OBJECT_TYPE:
227 : case JS_ASYNC_GENERATOR_OBJECT_TYPE:
228 : case JS_MODULE_NAMESPACE_TYPE:
229 : case JS_ARRAY_BUFFER_TYPE:
230 : case JS_ARRAY_ITERATOR_TYPE:
231 : case JS_REGEXP_TYPE: // TODO(rossberg): there should be a RegExp type.
232 : case JS_REGEXP_STRING_ITERATOR_TYPE:
233 : case JS_TYPED_ARRAY_TYPE:
234 : case JS_DATA_VIEW_TYPE:
235 : case JS_SET_TYPE:
236 : case JS_MAP_TYPE:
237 : case JS_SET_KEY_VALUE_ITERATOR_TYPE:
238 : case JS_SET_VALUE_ITERATOR_TYPE:
239 : case JS_MAP_KEY_ITERATOR_TYPE:
240 : case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
241 : case JS_MAP_VALUE_ITERATOR_TYPE:
242 : case JS_STRING_ITERATOR_TYPE:
243 : case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
244 : case JS_FINALIZATION_GROUP_TYPE:
245 : case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE:
246 : case JS_WEAK_MAP_TYPE:
247 : case JS_WEAK_REF_TYPE:
248 : case JS_WEAK_SET_TYPE:
249 : case JS_PROMISE_TYPE:
250 : case WASM_EXCEPTION_TYPE:
251 : case WASM_GLOBAL_TYPE:
252 : case WASM_INSTANCE_TYPE:
253 : case WASM_MEMORY_TYPE:
254 : case WASM_MODULE_TYPE:
255 : case WASM_TABLE_TYPE:
256 : case WEAK_CELL_TYPE:
257 : DCHECK(!map.is_callable());
258 : DCHECK(!map.is_undetectable());
259 6428 : return kOtherObject;
260 : case JS_BOUND_FUNCTION_TYPE:
261 : DCHECK(!map.is_undetectable());
262 169 : return kBoundFunction;
263 : case JS_FUNCTION_TYPE:
264 : DCHECK(!map.is_undetectable());
265 545647 : return kFunction;
266 : case JS_PROXY_TYPE:
267 : DCHECK(!map.is_undetectable());
268 393 : if (map.is_callable()) return kCallableProxy;
269 190 : return kOtherProxy;
270 : case MAP_TYPE:
271 : case ALLOCATION_SITE_TYPE:
272 : case ACCESSOR_INFO_TYPE:
273 : case SHARED_FUNCTION_INFO_TYPE:
274 : case FUNCTION_TEMPLATE_INFO_TYPE:
275 : case FUNCTION_TEMPLATE_RARE_DATA_TYPE:
276 : case ACCESSOR_PAIR_TYPE:
277 : case EMBEDDER_DATA_ARRAY_TYPE:
278 : case FIXED_ARRAY_TYPE:
279 : case HASH_TABLE_TYPE:
280 : case ORDERED_HASH_MAP_TYPE:
281 : case ORDERED_HASH_SET_TYPE:
282 : case ORDERED_NAME_DICTIONARY_TYPE:
283 : case NAME_DICTIONARY_TYPE:
284 : case GLOBAL_DICTIONARY_TYPE:
285 : case NUMBER_DICTIONARY_TYPE:
286 : case SIMPLE_NUMBER_DICTIONARY_TYPE:
287 : case STRING_TABLE_TYPE:
288 : case EPHEMERON_HASH_TABLE_TYPE:
289 : case WEAK_FIXED_ARRAY_TYPE:
290 : case WEAK_ARRAY_LIST_TYPE:
291 : case FIXED_DOUBLE_ARRAY_TYPE:
292 : case FEEDBACK_METADATA_TYPE:
293 : case BYTE_ARRAY_TYPE:
294 : case BYTECODE_ARRAY_TYPE:
295 : case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
296 : case ARRAY_BOILERPLATE_DESCRIPTION_TYPE:
297 : case DESCRIPTOR_ARRAY_TYPE:
298 : case TRANSITION_ARRAY_TYPE:
299 : case FEEDBACK_CELL_TYPE:
300 : case FEEDBACK_VECTOR_TYPE:
301 : case PROPERTY_ARRAY_TYPE:
302 : case FOREIGN_TYPE:
303 : case SCOPE_INFO_TYPE:
304 : case SCRIPT_CONTEXT_TABLE_TYPE:
305 : case AWAIT_CONTEXT_TYPE:
306 : case BLOCK_CONTEXT_TYPE:
307 : case CATCH_CONTEXT_TYPE:
308 : case DEBUG_EVALUATE_CONTEXT_TYPE:
309 : case EVAL_CONTEXT_TYPE:
310 : case FUNCTION_CONTEXT_TYPE:
311 : case MODULE_CONTEXT_TYPE:
312 : case NATIVE_CONTEXT_TYPE:
313 : case SCRIPT_CONTEXT_TYPE:
314 : case WITH_CONTEXT_TYPE:
315 : case SCRIPT_TYPE:
316 : case CODE_TYPE:
317 : case PROPERTY_CELL_TYPE:
318 : case MODULE_TYPE:
319 : case MODULE_INFO_ENTRY_TYPE:
320 : case CELL_TYPE:
321 : case PREPARSE_DATA_TYPE:
322 : case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
323 : case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
324 926041 : return kOtherInternal;
325 :
326 : // Remaining instance types are unsupported for now. If any of them do
327 : // require bit set types, they should get kOtherInternal.
328 : case MUTABLE_HEAP_NUMBER_TYPE:
329 : case FREE_SPACE_TYPE:
330 : #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
331 : case FIXED_##TYPE##_ARRAY_TYPE:
332 :
333 : TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
334 : #undef FIXED_TYPED_ARRAY_CASE
335 : case FILLER_TYPE:
336 : case ACCESS_CHECK_INFO_TYPE:
337 : case ASM_WASM_DATA_TYPE:
338 : case CALL_HANDLER_INFO_TYPE:
339 : case INTERCEPTOR_INFO_TYPE:
340 : case OBJECT_TEMPLATE_INFO_TYPE:
341 : case ALLOCATION_MEMENTO_TYPE:
342 : case ALIASED_ARGUMENTS_ENTRY_TYPE:
343 : case PROMISE_CAPABILITY_TYPE:
344 : case PROMISE_REACTION_TYPE:
345 : case CLASS_POSITIONS_TYPE:
346 : case DEBUG_INFO_TYPE:
347 : case STACK_FRAME_INFO_TYPE:
348 : case STACK_TRACE_FRAME_TYPE:
349 : case SMALL_ORDERED_HASH_MAP_TYPE:
350 : case SMALL_ORDERED_HASH_SET_TYPE:
351 : case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
352 : case PROTOTYPE_INFO_TYPE:
353 : case INTERPRETER_DATA_TYPE:
354 : case TUPLE2_TYPE:
355 : case TUPLE3_TYPE:
356 : case WASM_DEBUG_INFO_TYPE:
357 : case WASM_EXCEPTION_TAG_TYPE:
358 : case WASM_EXPORTED_FUNCTION_DATA_TYPE:
359 : case LOAD_HANDLER_TYPE:
360 : case STORE_HANDLER_TYPE:
361 : case ASYNC_GENERATOR_REQUEST_TYPE:
362 : case CODE_DATA_CONTAINER_TYPE:
363 : case CALLBACK_TASK_TYPE:
364 : case CALLABLE_TASK_TYPE:
365 : case PROMISE_FULFILL_REACTION_JOB_TASK_TYPE:
366 : case PROMISE_REJECT_REACTION_JOB_TASK_TYPE:
367 : case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE:
368 : case FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE:
369 0 : UNREACHABLE();
370 : }
371 0 : UNREACHABLE();
372 : }
373 :
374 : // Explicit instantiation.
375 : template Type::bitset BitsetType::Lub<MapRef>(const MapRef& map);
376 :
377 0 : Type::bitset BitsetType::Lub(double value) {
378 : DisallowHeapAllocation no_allocation;
379 0 : if (IsMinusZero(value)) return kMinusZero;
380 0 : if (std::isnan(value)) return kNaN;
381 0 : if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
382 : return kOtherNumber;
383 : }
384 :
385 : // Minimum values of plain numeric bitsets.
386 : const BitsetType::Boundary BitsetType::BoundariesArray[] = {
387 : {kOtherNumber, kPlainNumber, -V8_INFINITY},
388 : {kOtherSigned32, kNegative32, kMinInt},
389 : {kNegative31, kNegative31, -0x40000000},
390 : {kUnsigned30, kUnsigned30, 0},
391 : {kOtherUnsigned31, kUnsigned31, 0x40000000},
392 : {kOtherUnsigned32, kUnsigned32, 0x80000000},
393 : {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
394 :
395 : const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
396 :
397 : size_t BitsetType::BoundariesSize() {
398 : // Windows doesn't like arraysize here.
399 : // return arraysize(BoundariesArray);
400 : return 7;
401 : }
402 :
403 12123 : Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
404 : DCHECK_IMPLIES(bits & kOtherOneByteString,
405 : bits & kNonEmptyInternalizedOneByteString);
406 : DCHECK_IMPLIES(bits & kOtherTwoByteString,
407 : bits & kNonEmptyInternalizedTwoByteString);
408 : DisallowHeapAllocation no_allocation;
409 12460 : if (!(bits & kPlainNumber)) return bits; // Shortcut.
410 : const Boundary* boundaries = Boundaries();
411 0 : for (size_t i = 0; i < BoundariesSize(); ++i) {
412 : DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
413 0 : if (bits & boundaries[i].internal) bits |= boundaries[i].external;
414 : }
415 : return bits;
416 : }
417 :
418 0 : Type::bitset BitsetType::Lub(double min, double max) {
419 : DisallowHeapAllocation no_allocation;
420 : int lub = kNone;
421 : const Boundary* mins = Boundaries();
422 :
423 193682868 : for (size_t i = 1; i < BoundariesSize(); ++i) {
424 97028446 : if (min < mins[i].min) {
425 51871149 : lub |= mins[i - 1].internal;
426 51871149 : if (max < mins[i].min) return lub;
427 : }
428 : }
429 9942067 : return lub | mins[BoundariesSize() - 1].internal;
430 : }
431 :
432 14620028 : Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; }
433 :
434 38256674 : Type::bitset BitsetType::Glb(double min, double max) {
435 : DisallowHeapAllocation no_allocation;
436 : int glb = kNone;
437 : const Boundary* mins = Boundaries();
438 :
439 : // If the range does not touch 0, the bound is empty.
440 38256674 : if (max < -1 || min > 0) return glb;
441 :
442 130227519 : for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
443 115410118 : if (min <= mins[i].min) {
444 83170551 : if (max + 1 < mins[i + 1].min) break;
445 70085023 : glb |= mins[i].external;
446 : }
447 : }
448 : // OtherNumber also contains float numbers, so it can never be
449 : // in the greatest lower bound.
450 27902929 : return glb & ~(kOtherNumber);
451 : }
452 :
453 6611722 : double BitsetType::Min(bitset bits) {
454 : DisallowHeapAllocation no_allocation;
455 : DCHECK(Is(bits, kNumber));
456 : DCHECK(!Is(bits, kNaN));
457 : const Boundary* mins = Boundaries();
458 6611722 : bool mz = bits & kMinusZero;
459 24699112 : for (size_t i = 0; i < BoundariesSize(); ++i) {
460 31269718 : if (Is(mins[i].internal, bits)) {
461 6644889 : return mz ? std::min(0.0, mins[i].min) : mins[i].min;
462 : }
463 : }
464 : DCHECK(mz);
465 : return 0;
466 : }
467 :
468 6787048 : double BitsetType::Max(bitset bits) {
469 : DisallowHeapAllocation no_allocation;
470 : DCHECK(Is(bits, kNumber));
471 : DCHECK(!Is(bits, kNaN));
472 : const Boundary* mins = Boundaries();
473 6787048 : bool mz = bits & kMinusZero;
474 6787048 : if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) {
475 : return +V8_INFINITY;
476 : }
477 8792853 : for (size_t i = BoundariesSize() - 1; i-- > 0;) {
478 17553670 : if (Is(mins[i].internal, bits)) {
479 5615454 : return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
480 : }
481 : }
482 : DCHECK(mz);
483 : return 0;
484 : }
485 :
486 : // static
487 1488770 : bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
488 : // Not an integer, not NaN, and not -0.
489 2977540 : return !std::isnan(value) && !RangeType::IsInteger(value) &&
490 1488770 : !IsMinusZero(value);
491 : }
492 :
493 0 : HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
494 : const HeapObjectRef& heap_ref)
495 18180685 : : TypeBase(kHeapConstant), bitset_(bitset), heap_ref_(heap_ref) {}
496 :
497 2025283 : Handle<HeapObject> HeapConstantType::Value() const {
498 23209563 : return heap_ref_.object();
499 : }
500 :
501 : // -----------------------------------------------------------------------------
502 : // Predicates.
503 :
504 15111466 : bool Type::SimplyEquals(Type that) const {
505 : DisallowHeapAllocation no_allocation;
506 15111466 : if (this->IsHeapConstant()) {
507 22791288 : return that.IsHeapConstant() &&
508 10592101 : this->AsHeapConstant()->Value().address() ==
509 10592110 : that.AsHeapConstant()->Value().address();
510 : }
511 2912288 : if (this->IsOtherNumberConstant()) {
512 3647499 : return that.IsOtherNumberConstant() &&
513 : this->AsOtherNumberConstant()->Value() ==
514 : that.AsOtherNumberConstant()->Value();
515 : }
516 336118 : if (this->IsRange()) {
517 672237 : if (that.IsHeapConstant() || that.IsOtherNumberConstant()) return false;
518 : }
519 0 : if (this->IsTuple()) {
520 0 : if (!that.IsTuple()) return false;
521 : const TupleType* this_tuple = this->AsTuple();
522 : const TupleType* that_tuple = that.AsTuple();
523 0 : if (this_tuple->Arity() != that_tuple->Arity()) {
524 : return false;
525 : }
526 0 : for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
527 0 : if (!this_tuple->Element(i).Equals(that_tuple->Element(i))) return false;
528 : }
529 : return true;
530 : }
531 0 : UNREACHABLE();
532 : }
533 :
534 : // Check if [this] <= [that].
535 397563214 : bool Type::SlowIs(Type that) const {
536 : DisallowHeapAllocation no_allocation;
537 :
538 : // Fast bitset cases
539 397563214 : if (that.IsBitset()) {
540 560186669 : return BitsetType::Is(this->BitsetLub(), that.AsBitset());
541 : }
542 :
543 117473454 : if (this->IsBitset()) {
544 65821124 : return BitsetType::Is(this->AsBitset(), that.BitsetGlb());
545 : }
546 :
547 : // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T)
548 84561362 : if (this->IsUnion()) {
549 23545814 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
550 17836487 : if (!this->AsUnion()->Get(i).Is(that)) return false;
551 : }
552 : return true;
553 : }
554 :
555 : // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn)
556 71039716 : if (that.IsUnion()) {
557 48357949 : for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
558 26049905 : if (this->Is(that.AsUnion()->Get(i))) return true;
559 22601306 : if (i > 1 && this->IsRange()) return false; // Shortcut.
560 : }
561 : return false;
562 : }
563 :
564 59210963 : if (that.IsRange()) {
565 64180073 : return (this->IsRange() && Contains(that.AsRange(), this->AsRange()));
566 : }
567 17965351 : if (this->IsRange()) return false;
568 :
569 14734138 : return this->SimplyEquals(that);
570 : }
571 :
572 : // Check if [this] and [that] overlap.
573 21361465 : bool Type::Maybe(Type that) const {
574 : DisallowHeapAllocation no_allocation;
575 :
576 21361465 : if (BitsetType::IsNone(this->BitsetLub() & that.BitsetLub())) return false;
577 :
578 : // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T)
579 10032099 : if (this->IsUnion()) {
580 1128888 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
581 705686 : if (this->AsUnion()->Get(i).Maybe(that)) return true;
582 : }
583 : return false;
584 : }
585 :
586 : // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn)
587 9591701 : if (that.IsUnion()) {
588 863014 : for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
589 448593 : if (this->Maybe(that.AsUnion()->Get(i))) return true;
590 : }
591 : return false;
592 : }
593 :
594 9353803 : if (this->IsBitset() && that.IsBitset()) return true;
595 :
596 4986977 : if (this->IsRange()) {
597 2400639 : if (that.IsRange()) {
598 1261350 : return Overlap(this->AsRange(), that.AsRange());
599 : }
600 1139289 : if (that.IsBitset()) {
601 : bitset number_bits = BitsetType::NumberBits(that.AsBitset());
602 803437 : if (number_bits == BitsetType::kNone) {
603 : return false;
604 : }
605 1606837 : double min = std::max(BitsetType::Min(number_bits), this->Min());
606 1606759 : double max = std::min(BitsetType::Max(number_bits), this->Max());
607 803359 : return min <= max;
608 : }
609 : }
610 2922190 : if (that.IsRange()) {
611 1094490 : return that.Maybe(*this); // This case is handled above.
612 : }
613 :
614 1827700 : if (this->IsBitset() || that.IsBitset()) return true;
615 :
616 375414 : return this->SimplyEquals(that);
617 : }
618 :
619 : // Return the range in [this], or [nullptr].
620 35029434 : Type Type::GetRange() const {
621 : DisallowHeapAllocation no_allocation;
622 35029434 : if (this->IsRange()) return *this;
623 41398308 : if (this->IsUnion() && this->AsUnion()->Get(1).IsRange()) {
624 : return this->AsUnion()->Get(1);
625 : }
626 18760192 : return nullptr;
627 : }
628 :
629 0 : bool UnionType::Wellformed() const {
630 : DisallowHeapAllocation no_allocation;
631 : // This checks the invariants of the union representation:
632 : // 1. There are at least two elements.
633 : // 2. The first element is a bitset, no other element is a bitset.
634 : // 3. At most one element is a range, and it must be the second one.
635 : // 4. No element is itself a union.
636 : // 5. No element (except the bitset) is a subtype of any other.
637 : // 6. If there is a range, then the bitset type does not contain
638 : // plain number bits.
639 : DCHECK_LE(2, this->Length()); // (1)
640 : DCHECK(this->Get(0).IsBitset()); // (2a)
641 :
642 : for (int i = 0; i < this->Length(); ++i) {
643 : if (i != 0) DCHECK(!this->Get(i).IsBitset()); // (2b)
644 : if (i != 1) DCHECK(!this->Get(i).IsRange()); // (3)
645 : DCHECK(!this->Get(i).IsUnion()); // (4)
646 : for (int j = 0; j < this->Length(); ++j) {
647 : if (i != j && i != 0) DCHECK(!this->Get(i).Is(this->Get(j))); // (5)
648 : }
649 : }
650 : DCHECK(!this->Get(1).IsRange() ||
651 : (BitsetType::NumberBits(this->Get(0).AsBitset()) ==
652 : BitsetType::kNone)); // (6)
653 0 : return true;
654 : }
655 :
656 : // -----------------------------------------------------------------------------
657 : // Union and intersection
658 :
659 26429158 : Type Type::Intersect(Type type1, Type type2, Zone* zone) {
660 : // Fast case: bit sets.
661 41827728 : if (type1.IsBitset() && type2.IsBitset()) {
662 14588309 : return NewBitset(type1.AsBitset() & type2.AsBitset());
663 : }
664 :
665 : // Fast case: top or bottom types.
666 23658729 : if (type1.IsNone() || type2.IsAny()) return type1; // Shortcut.
667 11597199 : if (type2.IsNone() || type1.IsAny()) return type2; // Shortcut.
668 :
669 : // Semi-fast case.
670 11515467 : if (type1.Is(type2)) return type1;
671 3697218 : if (type2.Is(type1)) return type2;
672 :
673 : // Slow case: create union.
674 :
675 : // Semantic subtyping check - this is needed for consistency with the
676 : // semi-fast case above.
677 1926161 : if (type1.Is(type2)) {
678 0 : type2 = Any();
679 1926162 : } else if (type2.Is(type1)) {
680 0 : type1 = Any();
681 : }
682 :
683 1926162 : bitset bits = type1.BitsetGlb() & type2.BitsetGlb();
684 1926090 : int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
685 1926090 : int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
686 : int size;
687 1926090 : if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
688 1926090 : if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
689 1926090 : UnionType* result = UnionType::New(size, zone);
690 : size = 0;
691 :
692 : // Deal with bitsets.
693 : result->Set(size++, NewBitset(bits));
694 :
695 1926092 : RangeType::Limits lims = RangeType::Limits::Empty();
696 1926092 : size = IntersectAux(type1, type2, result, size, &lims, zone);
697 :
698 : // If the range is not empty, then insert it into the union and
699 : // remove the number bits from the bitset.
700 1926115 : if (!lims.IsEmpty()) {
701 623628 : size = UpdateRange(Type::Range(lims, zone), result, size, zone);
702 :
703 : // Remove the number bits.
704 : bitset number_bits = BitsetType::NumberBits(bits);
705 623636 : bits &= ~number_bits;
706 : result->Set(0, NewBitset(bits));
707 : }
708 1926113 : return NormalizeUnion(result, size, zone);
709 : }
710 :
711 623638 : int Type::UpdateRange(Type range, UnionType* result, int size, Zone* zone) {
712 623638 : if (size == 1) {
713 620929 : result->Set(size++, range);
714 : } else {
715 : // Make space for the range.
716 2709 : result->Set(size++, result->Get(1));
717 : result->Set(1, range);
718 : }
719 :
720 : // Remove any components that just got subsumed.
721 626459 : for (int i = 2; i < size;) {
722 5642 : if (result->Get(i).Is(range)) {
723 0 : result->Set(i, result->Get(--size));
724 : } else {
725 2821 : ++i;
726 : }
727 : }
728 623638 : return size;
729 : }
730 :
731 304914 : RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
732 : bitset number_bits = BitsetType::NumberBits(bits);
733 :
734 304914 : if (number_bits == BitsetType::kNone) {
735 : return RangeType::Limits::Empty();
736 : }
737 :
738 : return RangeType::Limits(BitsetType::Min(number_bits),
739 304914 : BitsetType::Max(number_bits));
740 : }
741 :
742 304914 : RangeType::Limits Type::IntersectRangeAndBitset(Type range, Type bitset,
743 : Zone* zone) {
744 : RangeType::Limits range_lims(range.AsRange());
745 304914 : RangeType::Limits bitset_lims = ToLimits(bitset.AsBitset(), zone);
746 304909 : return RangeType::Limits::Intersect(range_lims, bitset_lims);
747 : }
748 :
749 3267775 : int Type::IntersectAux(Type lhs, Type rhs, UnionType* result, int size,
750 : RangeType::Limits* lims, Zone* zone) {
751 3267775 : if (lhs.IsUnion()) {
752 2300663 : for (int i = 0, n = lhs.AsUnion()->Length(); i < n; ++i) {
753 956266 : size = IntersectAux(lhs.AsUnion()->Get(i), rhs, result, size, lims, zone);
754 : }
755 : return size;
756 : }
757 2879640 : if (rhs.IsUnion()) {
758 498879 : for (int i = 0, n = rhs.AsUnion()->Length(); i < n; ++i) {
759 199739 : size = IntersectAux(lhs, rhs.AsUnion()->Get(i), result, size, lims, zone);
760 : }
761 : return size;
762 : }
763 :
764 2780245 : if (BitsetType::IsNone(lhs.BitsetLub() & rhs.BitsetLub())) return size;
765 :
766 1009918 : if (lhs.IsRange()) {
767 782524 : if (rhs.IsBitset()) {
768 304915 : RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
769 :
770 304910 : if (!lim.IsEmpty()) {
771 304910 : *lims = RangeType::Limits::Union(lim, *lims);
772 : }
773 : return size;
774 : }
775 477609 : if (rhs.IsRange()) {
776 : RangeType::Limits lim = RangeType::Limits::Intersect(
777 : RangeType::Limits(lhs.AsRange()), RangeType::Limits(rhs.AsRange()));
778 319021 : if (!lim.IsEmpty()) {
779 318823 : *lims = RangeType::Limits::Union(lim, *lims);
780 : }
781 : }
782 : return size;
783 : }
784 227394 : if (rhs.IsRange()) {
785 : // This case is handled symmetrically above.
786 185766 : return IntersectAux(rhs, lhs, result, size, lims, zone);
787 : }
788 41628 : if (lhs.IsBitset() || rhs.IsBitset()) {
789 39700 : return AddToUnion(lhs.IsBitset() ? rhs : lhs, result, size, zone);
790 : }
791 1928 : if (lhs.SimplyEquals(rhs)) {
792 320 : return AddToUnion(lhs, result, size, zone);
793 : }
794 : return size;
795 : }
796 :
797 : // Make sure that we produce a well-formed range and bitset:
798 : // If the range is non-empty, the number bits in the bitset should be
799 : // clear. Moreover, if we have a canonical range (such as Signed32),
800 : // we want to produce a bitset rather than a range.
801 12888041 : Type Type::NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone) {
802 : // Fast path: If the bitset does not mention numbers, we can just keep the
803 : // range.
804 12888041 : bitset number_bits = BitsetType::NumberBits(*bits);
805 12888041 : if (number_bits == 0) {
806 7251755 : return range;
807 : }
808 :
809 : // If the range is semantically contained within the bitset, return None and
810 : // leave the bitset untouched.
811 5636286 : bitset range_lub = range.BitsetLub();
812 11272572 : if (BitsetType::Is(range_lub, *bits)) {
813 : return None();
814 : }
815 :
816 : // Slow path: reconcile the bitset range and the range.
817 4839106 : double bitset_min = BitsetType::Min(number_bits);
818 4839106 : double bitset_max = BitsetType::Max(number_bits);
819 :
820 4839106 : double range_min = range.Min();
821 4839106 : double range_max = range.Max();
822 :
823 : // Remove the number bits from the bitset, they would just confuse us now.
824 : // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
825 : // case we already returned after the subtype check above.
826 4839106 : *bits &= ~number_bits;
827 :
828 4839106 : if (range_min <= bitset_min && range_max >= bitset_max) {
829 : // Bitset is contained within the range, just return the range.
830 4497441 : return range;
831 : }
832 :
833 341665 : if (bitset_min < range_min) {
834 : range_min = bitset_min;
835 : }
836 341665 : if (bitset_max > range_max) {
837 : range_max = bitset_max;
838 : }
839 : return Type::Range(range_min, range_max, zone);
840 : }
841 :
842 7747870 : Type Type::NewConstant(double value, Zone* zone) {
843 7747870 : if (RangeType::IsInteger(value)) {
844 : return Range(value, value, zone);
845 1507069 : } else if (IsMinusZero(value)) {
846 : return Type::MinusZero();
847 1493481 : } else if (std::isnan(value)) {
848 : return Type::NaN();
849 : }
850 :
851 : DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
852 : return OtherNumberConstant(value, zone);
853 : }
854 :
855 11003636 : Type Type::NewConstant(JSHeapBroker* broker, Handle<i::Object> value,
856 : Zone* zone) {
857 11003636 : ObjectRef ref(broker, value);
858 11003657 : if (ref.IsSmi()) {
859 587623 : return NewConstant(static_cast<double>(ref.AsSmi()), zone);
860 : }
861 10416034 : if (ref.IsHeapNumber()) {
862 2444028 : return NewConstant(ref.AsHeapNumber().value(), zone);
863 : }
864 7972002 : if (ref.IsString() && !ref.IsInternalizedString()) {
865 337 : return For(ref.AsString().map());
866 : }
867 15943295 : return HeapConstant(ref.AsHeapObject(), zone);
868 : }
869 :
870 45805300 : Type Type::Union(Type type1, Type type2, Zone* zone) {
871 : // Fast case: bit sets.
872 70067536 : if (type1.IsBitset() && type2.IsBitset()) {
873 15621132 : return NewBitset(type1.AsBitset() | type2.AsBitset());
874 : }
875 :
876 : // Fast case: top or bottom types.
877 60185851 : if (type1.IsAny() || type2.IsNone()) return type1;
878 28754509 : if (type2.IsAny() || type1.IsNone()) return type2;
879 :
880 : // Semi-fast case.
881 26064323 : if (type1.Is(type2)) return type2;
882 24073865 : if (type2.Is(type1)) return type1;
883 :
884 : // Slow case: create union.
885 17316979 : int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
886 17316979 : int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
887 : int size;
888 17316979 : if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
889 17316979 : if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
890 17316979 : UnionType* result = UnionType::New(size, zone);
891 : size = 0;
892 :
893 : // Compute the new bitset.
894 17316929 : bitset new_bitset = type1.BitsetGlb() | type2.BitsetGlb();
895 :
896 : // Deal with ranges.
897 : Type range = None();
898 17316976 : Type range1 = type1.GetRange();
899 17316971 : Type range2 = type2.GetRange();
900 17316991 : if (range1 != nullptr && range2 != nullptr) {
901 : RangeType::Limits lims =
902 : RangeType::Limits::Union(RangeType::Limits(range1.AsRange()),
903 : RangeType::Limits(range2.AsRange()));
904 2994283 : Type union_range = Type::Range(lims, zone);
905 2994283 : range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
906 14322708 : } else if (range1 != nullptr) {
907 5489766 : range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
908 8832942 : } else if (range2 != nullptr) {
909 4404016 : range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
910 : }
911 17316987 : Type bits = NewBitset(new_bitset);
912 : result->Set(size++, bits);
913 17316987 : if (!range.IsNone()) result->Set(size++, range);
914 :
915 17316987 : size = AddToUnion(type1, result, size, zone);
916 17316995 : size = AddToUnion(type2, result, size, zone);
917 17316991 : return NormalizeUnion(result, size, zone);
918 : }
919 :
920 : // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
921 : // Return new size of [result].
922 71020093 : int Type::AddToUnion(Type type, UnionType* result, int size, Zone* zone) {
923 120516849 : if (type.IsBitset() || type.IsRange()) return size;
924 33614554 : if (type.IsUnion()) {
925 85498581 : for (int i = 0, n = type.AsUnion()->Length(); i < n; ++i) {
926 36346344 : size = AddToUnion(type.AsUnion()->Get(i), result, size, zone);
927 : }
928 : return size;
929 : }
930 101545567 : for (int i = 0; i < size; ++i) {
931 41985676 : if (type.Is(result->Get(i))) return size;
932 : }
933 19191311 : result->Set(size++, type);
934 19191311 : return size;
935 : }
936 :
937 19243096 : Type Type::NormalizeUnion(UnionType* unioned, int size, Zone* zone) {
938 : DCHECK_LE(1, size);
939 : DCHECK(unioned->Get(0).IsBitset());
940 : // If the union has just one element, return it.
941 19243096 : if (size == 1) {
942 : return unioned->Get(0);
943 : }
944 : bitset bits = unioned->Get(0).AsBitset();
945 : // If the union only consists of a range, we can get rid of the union.
946 17513956 : if (size == 2 && bits == BitsetType::kNone) {
947 1773793 : if (unioned->Get(1).IsRange()) {
948 : return Type::Range(unioned->Get(1).AsRange()->Min(),
949 : unioned->Get(1).AsRange()->Max(), zone);
950 : }
951 : }
952 : unioned->Shrink(size);
953 : SLOW_DCHECK(unioned->Wellformed());
954 15742680 : return Type(unioned);
955 : }
956 :
957 86212 : int Type::NumConstants() const {
958 : DisallowHeapAllocation no_allocation;
959 170358 : if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
960 : return 1;
961 83020 : } else if (this->IsUnion()) {
962 : int result = 0;
963 44818 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
964 18014 : if (this->AsUnion()->Get(i).IsHeapConstant()) ++result;
965 : }
966 : return result;
967 : } else {
968 : return 0;
969 : }
970 : }
971 :
972 : // -----------------------------------------------------------------------------
973 : // Printing.
974 :
975 141750 : const char* BitsetType::Name(bitset bits) {
976 141750 : switch (bits) {
977 : #define RETURN_NAMED_TYPE(type, value) \
978 : case k##type: \
979 : return #type;
980 0 : PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
981 0 : INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
982 : #undef RETURN_NAMED_TYPE
983 :
984 : default:
985 0 : return nullptr;
986 : }
987 : }
988 :
989 141750 : void BitsetType::Print(std::ostream& os, // NOLINT
990 : bitset bits) {
991 : DisallowHeapAllocation no_allocation;
992 141750 : const char* name = Name(bits);
993 141750 : if (name != nullptr) {
994 141750 : os << name;
995 : return;
996 : }
997 :
998 : // clang-format off
999 : static const bitset named_bitsets[] = {
1000 : #define BITSET_CONSTANT(type, value) k##type,
1001 : INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
1002 : PROPER_BITSET_TYPE_LIST(BITSET_CONSTANT)
1003 : #undef BITSET_CONSTANT
1004 : };
1005 : // clang-format on
1006 :
1007 : bool is_first = true;
1008 0 : os << "(";
1009 0 : for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
1010 0 : bitset subset = named_bitsets[i];
1011 0 : if ((bits & subset) == subset) {
1012 0 : if (!is_first) os << " | ";
1013 : is_first = false;
1014 0 : os << Name(subset);
1015 0 : bits -= subset;
1016 : }
1017 : }
1018 : DCHECK_EQ(0, bits);
1019 0 : os << ")";
1020 : }
1021 :
1022 141874 : void Type::PrintTo(std::ostream& os) const {
1023 : DisallowHeapAllocation no_allocation;
1024 141874 : if (this->IsBitset()) {
1025 141750 : BitsetType::Print(os, this->AsBitset());
1026 124 : } else if (this->IsHeapConstant()) {
1027 152 : os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
1028 48 : } else if (this->IsOtherNumberConstant()) {
1029 : os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
1030 0 : << ")";
1031 48 : } else if (this->IsRange()) {
1032 29 : std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1033 29 : std::streamsize saved_precision = os.precision(0);
1034 : os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1035 29 : << ")";
1036 29 : os.flags(saved_flags);
1037 29 : os.precision(saved_precision);
1038 19 : } else if (this->IsUnion()) {
1039 19 : os << "(";
1040 95 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1041 38 : Type type_i = this->AsUnion()->Get(i);
1042 38 : if (i > 0) os << " | ";
1043 38 : os << type_i;
1044 : }
1045 19 : os << ")";
1046 0 : } else if (this->IsTuple()) {
1047 0 : os << "<";
1048 0 : for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
1049 0 : Type type_i = this->AsTuple()->Element(i);
1050 0 : if (i > 0) os << ", ";
1051 0 : os << type_i;
1052 : }
1053 0 : os << ">";
1054 : } else {
1055 0 : UNREACHABLE();
1056 : }
1057 141874 : }
1058 :
1059 : #ifdef DEBUG
1060 : void Type::Print() const {
1061 : StdoutStream os;
1062 : PrintTo(os);
1063 : os << std::endl;
1064 : }
1065 : void BitsetType::Print(bitset bits) {
1066 : StdoutStream os;
1067 : Print(os, bits);
1068 : os << std::endl;
1069 : }
1070 : #endif
1071 :
1072 6822657 : BitsetType::bitset BitsetType::SignedSmall() {
1073 6822657 : return SmiValuesAre31Bits() ? kSigned31 : kSigned32;
1074 : }
1075 :
1076 230740 : BitsetType::bitset BitsetType::UnsignedSmall() {
1077 230740 : return SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
1078 : }
1079 :
1080 : // static
1081 1371 : Type Type::Tuple(Type first, Type second, Type third, Zone* zone) {
1082 1371 : TupleType* tuple = TupleType::New(3, zone);
1083 : tuple->InitElement(0, first);
1084 : tuple->InitElement(1, second);
1085 : tuple->InitElement(2, third);
1086 1371 : return FromTypeBase(tuple);
1087 : }
1088 :
1089 : // static
1090 0 : Type Type::OtherNumberConstant(double value, Zone* zone) {
1091 1488770 : return FromTypeBase(OtherNumberConstantType::New(value, zone));
1092 : }
1093 :
1094 : // static
1095 10209038 : Type Type::HeapConstant(JSHeapBroker* broker, Handle<i::Object> value,
1096 : Zone* zone) {
1097 : return FromTypeBase(
1098 20418238 : HeapConstantType::New(HeapObjectRef(broker, value), zone));
1099 : }
1100 :
1101 : // static
1102 0 : Type Type::HeapConstant(const HeapObjectRef& value, Zone* zone) {
1103 7971657 : return HeapConstantType::New(value, zone);
1104 : }
1105 :
1106 : // static
1107 8287389 : Type Type::Range(double min, double max, Zone* zone) {
1108 8287384 : return FromTypeBase(RangeType::New(min, max, zone));
1109 : }
1110 :
1111 : // static
1112 0 : Type Type::Range(RangeType::Limits lims, Zone* zone) {
1113 3617921 : return FromTypeBase(RangeType::New(lims, zone));
1114 : }
1115 :
1116 : // static
1117 0 : Type Type::Union(int length, Zone* zone) {
1118 0 : return FromTypeBase(UnionType::New(length, zone));
1119 : }
1120 :
1121 2347758 : const HeapConstantType* Type::AsHeapConstant() const {
1122 : DCHECK(IsKind(TypeBase::kHeapConstant));
1123 2347758 : return static_cast<const HeapConstantType*>(ToTypeBase());
1124 : }
1125 :
1126 57 : const OtherNumberConstantType* Type::AsOtherNumberConstant() const {
1127 : DCHECK(IsKind(TypeBase::kOtherNumberConstant));
1128 57 : return static_cast<const OtherNumberConstantType*>(ToTypeBase());
1129 : }
1130 :
1131 45246 : const RangeType* Type::AsRange() const {
1132 : DCHECK(IsKind(TypeBase::kRange));
1133 45246 : return static_cast<const RangeType*>(ToTypeBase());
1134 : }
1135 :
1136 8226 : const TupleType* Type::AsTuple() const {
1137 : DCHECK(IsKind(TypeBase::kTuple));
1138 8226 : return static_cast<const TupleType*>(ToTypeBase());
1139 : }
1140 :
1141 8790 : const UnionType* Type::AsUnion() const {
1142 : DCHECK(IsKind(TypeBase::kUnion));
1143 8790 : return static_cast<const UnionType*>(ToTypeBase());
1144 : }
1145 :
1146 141712 : std::ostream& operator<<(std::ostream& os, Type type) {
1147 141712 : type.PrintTo(os);
1148 141712 : return os;
1149 : }
1150 :
1151 : } // namespace compiler
1152 : } // namespace internal
1153 120216 : } // namespace v8
|