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 3188410 : 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 1896862 : if (lhs.min < rhs.min) result.min = rhs.min;
26 1896862 : 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 3958490 : if (lhs.IsEmpty()) return rhs;
33 3958490 : if (rhs.IsEmpty()) return lhs;
34 : Limits result(lhs);
35 3317346 : if (lhs.min > rhs.min) result.min = rhs.min;
36 3317346 : 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 1255504 : .IsEmpty();
45 : }
46 :
47 0 : bool Type::Contains(const RangeType* lhs, const RangeType* rhs) {
48 : DisallowHeapAllocation no_allocation;
49 23512707 : return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
50 : }
51 :
52 : // -----------------------------------------------------------------------------
53 : // Min and Max computation.
54 :
55 13349801 : double Type::Min() const {
56 : DCHECK(this->Is(Number()));
57 : DCHECK(!this->Is(NaN()));
58 13931746 : if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
59 12767856 : if (this->IsUnion()) {
60 49372 : double min = +V8_INFINITY;
61 205880 : for (int i = 1, n = AsUnion()->Length(); i < n; ++i) {
62 156508 : min = std::min(min, AsUnion()->Get(i).Min());
63 : }
64 49372 : Type bitset = AsUnion()->Get(0);
65 68259 : if (!bitset.Is(NaN())) min = std::min(min, bitset.Min());
66 49372 : return min;
67 : }
68 25397548 : if (this->IsRange()) return this->AsRange()->Min();
69 : DCHECK(this->IsOtherNumberConstant());
70 39420 : return this->AsOtherNumberConstant()->Value();
71 : }
72 :
73 13560424 : double Type::Max() const {
74 : DCHECK(this->Is(Number()));
75 : DCHECK(!this->Is(NaN()));
76 14325283 : if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
77 12795565 : if (this->IsUnion()) {
78 44898 : double max = -V8_INFINITY;
79 192458 : for (int i = 1, n = this->AsUnion()->Length(); i < n; ++i) {
80 147561 : max = std::max(max, this->AsUnion()->Get(i).Max());
81 : }
82 44897 : Type bitset = this->AsUnion()->Get(0);
83 59295 : if (!bitset.Is(NaN())) max = std::max(max, bitset.Max());
84 44896 : return max;
85 : }
86 25465798 : if (this->IsRange()) return this->AsRange()->Max();
87 : DCHECK(this->IsOtherNumberConstant());
88 35536 : return this->AsOtherNumberConstant()->Value();
89 : }
90 :
91 : // -----------------------------------------------------------------------------
92 : // Glb and lub computation.
93 :
94 : // The largest bitset subsumed by this type.
95 130214046 : Type::bitset Type::BitsetGlb() const {
96 : DisallowHeapAllocation no_allocation;
97 : // Fast case.
98 130214046 : if (IsBitset()) {
99 38411209 : return AsBitset();
100 91802837 : } else if (IsUnion()) {
101 : SLOW_DCHECK(AsUnion()->Wellformed());
102 55267270 : return AsUnion()->Get(0).BitsetGlb() |
103 27633690 : AsUnion()->Get(1).BitsetGlb(); // Shortcut.
104 64169421 : } else if (IsRange()) {
105 41282682 : bitset glb = BitsetType::Glb(AsRange()->Min(), AsRange()->Max());
106 41283870 : return glb;
107 : } else {
108 : return BitsetType::kNone;
109 : }
110 : }
111 :
112 : // The smallest bitset subsuming this type, possibly not a proper one.
113 371978365 : Type::bitset Type::BitsetLub() const {
114 : DisallowHeapAllocation no_allocation;
115 612565723 : if (IsBitset()) return AsBitset();
116 131391007 : if (IsUnion()) {
117 : // Take the representation from the first element, which is always
118 : // a bitset.
119 10893376 : int bitset = AsUnion()->Get(0).BitsetLub();
120 71271294 : for (int i = 0, n = AsUnion()->Length(); i < n; ++i) {
121 : // Other elements only contribute their semantic part.
122 30191240 : bitset |= AsUnion()->Get(i).BitsetLub();
123 : }
124 10894607 : return bitset;
125 : }
126 159185064 : if (IsHeapConstant()) return AsHeapConstant()->Lub();
127 81810198 : if (IsOtherNumberConstant()) {
128 : return AsOtherNumberConstant()->Lub();
129 : }
130 138711786 : if (IsRange()) return AsRange()->Lub();
131 4158 : 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 18435917 : Type::bitset BitsetType::Lub(const MapRefLike& map) {
139 18435917 : 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 331 : return kNonEmptyOneByteString;
156 : case EXTERNAL_INTERNALIZED_STRING_TYPE:
157 : case UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE:
158 : case INTERNALIZED_STRING_TYPE:
159 4219 : 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 3130858 : return kNonEmptyInternalizedOneByteString;
164 : case SYMBOL_TYPE:
165 599 : return kSymbol;
166 : case BIGINT_TYPE:
167 2385 : return kBigInt;
168 : case ODDBALL_TYPE:
169 10681594 : switch (map.oddball_type()) {
170 : case OddballType::kNone:
171 : break;
172 : case OddballType::kHole:
173 : return kHole;
174 : case OddballType::kBoolean:
175 6623761 : return kBoolean;
176 : case OddballType::kNull:
177 32572 : return kNull;
178 : case OddballType::kUndefined:
179 965496 : return kUndefined;
180 : case OddballType::kUninitialized:
181 : case OddballType::kOther:
182 : // TODO(neis): We should add a kOtherOddball type.
183 1470070 : 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 1154209 : 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 1154143 : if (map.is_callable()) {
204 : return kOtherCallable;
205 : }
206 1154143 : return kOtherObject;
207 : case JS_ARRAY_TYPE:
208 561868 : 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 4240 : return kOtherObject;
260 : case JS_BOUND_FUNCTION_TYPE:
261 : DCHECK(!map.is_undetectable());
262 163 : return kBoundFunction;
263 : case JS_FUNCTION_TYPE:
264 : DCHECK(!map.is_undetectable());
265 550957 : return kFunction;
266 : case JS_PROXY_TYPE:
267 : DCHECK(!map.is_undetectable());
268 394 : 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 CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
301 : case FEEDBACK_VECTOR_TYPE:
302 : case PROPERTY_ARRAY_TYPE:
303 : case FOREIGN_TYPE:
304 : case SCOPE_INFO_TYPE:
305 : case SCRIPT_CONTEXT_TABLE_TYPE:
306 : case AWAIT_CONTEXT_TYPE:
307 : case BLOCK_CONTEXT_TYPE:
308 : case CATCH_CONTEXT_TYPE:
309 : case DEBUG_EVALUATE_CONTEXT_TYPE:
310 : case EVAL_CONTEXT_TYPE:
311 : case FUNCTION_CONTEXT_TYPE:
312 : case MODULE_CONTEXT_TYPE:
313 : case NATIVE_CONTEXT_TYPE:
314 : case SCRIPT_CONTEXT_TYPE:
315 : case WITH_CONTEXT_TYPE:
316 : case SCRIPT_TYPE:
317 : case CODE_TYPE:
318 : case PROPERTY_CELL_TYPE:
319 : case MODULE_TYPE:
320 : case MODULE_INFO_ENTRY_TYPE:
321 : case CELL_TYPE:
322 : case PREPARSE_DATA_TYPE:
323 : case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
324 : case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
325 938739 : return kOtherInternal;
326 :
327 : // Remaining instance types are unsupported for now. If any of them do
328 : // require bit set types, they should get kOtherInternal.
329 : case MUTABLE_HEAP_NUMBER_TYPE:
330 : case FREE_SPACE_TYPE:
331 : #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
332 : case FIXED_##TYPE##_ARRAY_TYPE:
333 :
334 : TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
335 : #undef FIXED_TYPED_ARRAY_CASE
336 : case FILLER_TYPE:
337 : case ACCESS_CHECK_INFO_TYPE:
338 : case ASM_WASM_DATA_TYPE:
339 : case CALL_HANDLER_INFO_TYPE:
340 : case INTERCEPTOR_INFO_TYPE:
341 : case OBJECT_TEMPLATE_INFO_TYPE:
342 : case ALLOCATION_MEMENTO_TYPE:
343 : case ALIASED_ARGUMENTS_ENTRY_TYPE:
344 : case PROMISE_CAPABILITY_TYPE:
345 : case PROMISE_REACTION_TYPE:
346 : case CLASS_POSITIONS_TYPE:
347 : case DEBUG_INFO_TYPE:
348 : case STACK_FRAME_INFO_TYPE:
349 : case STACK_TRACE_FRAME_TYPE:
350 : case SMALL_ORDERED_HASH_MAP_TYPE:
351 : case SMALL_ORDERED_HASH_SET_TYPE:
352 : case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
353 : case PROTOTYPE_INFO_TYPE:
354 : case INTERPRETER_DATA_TYPE:
355 : case TUPLE2_TYPE:
356 : case TUPLE3_TYPE:
357 : case ENUM_CACHE_TYPE:
358 : case WASM_DEBUG_INFO_TYPE:
359 : case WASM_EXCEPTION_TAG_TYPE:
360 : case WASM_EXPORTED_FUNCTION_DATA_TYPE:
361 : case LOAD_HANDLER_TYPE:
362 : case STORE_HANDLER_TYPE:
363 : case ASYNC_GENERATOR_REQUEST_TYPE:
364 : case CODE_DATA_CONTAINER_TYPE:
365 : case CALLBACK_TASK_TYPE:
366 : case CALLABLE_TASK_TYPE:
367 : case PROMISE_FULFILL_REACTION_JOB_TASK_TYPE:
368 : case PROMISE_REJECT_REACTION_JOB_TASK_TYPE:
369 : case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE:
370 : case FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE:
371 0 : UNREACHABLE();
372 : }
373 0 : UNREACHABLE();
374 : }
375 :
376 : // Explicit instantiation.
377 : template Type::bitset BitsetType::Lub<MapRef>(const MapRef& map);
378 :
379 0 : Type::bitset BitsetType::Lub(double value) {
380 : DisallowHeapAllocation no_allocation;
381 0 : if (IsMinusZero(value)) return kMinusZero;
382 0 : if (std::isnan(value)) return kNaN;
383 0 : if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
384 : return kOtherNumber;
385 : }
386 :
387 : // Minimum values of plain numeric bitsets.
388 : const BitsetType::Boundary BitsetType::BoundariesArray[] = {
389 : {kOtherNumber, kPlainNumber, -V8_INFINITY},
390 : {kOtherSigned32, kNegative32, kMinInt},
391 : {kNegative31, kNegative31, -0x40000000},
392 : {kUnsigned30, kUnsigned30, 0},
393 : {kOtherUnsigned31, kUnsigned31, 0x40000000},
394 : {kOtherUnsigned32, kUnsigned32, 0x80000000},
395 : {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
396 :
397 : const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
398 :
399 : size_t BitsetType::BoundariesSize() {
400 : // Windows doesn't like arraysize here.
401 : // return arraysize(BoundariesArray);
402 : return 7;
403 : }
404 :
405 12257 : Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
406 : DCHECK_IMPLIES(bits & kOtherOneByteString,
407 : bits & kNonEmptyInternalizedOneByteString);
408 : DCHECK_IMPLIES(bits & kOtherTwoByteString,
409 : bits & kNonEmptyInternalizedTwoByteString);
410 : DisallowHeapAllocation no_allocation;
411 12596 : if (!(bits & kPlainNumber)) return bits; // Shortcut.
412 : const Boundary* boundaries = Boundaries();
413 0 : for (size_t i = 0; i < BoundariesSize(); ++i) {
414 : DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
415 0 : if (bits & boundaries[i].internal) bits |= boundaries[i].external;
416 : }
417 : return bits;
418 : }
419 :
420 0 : Type::bitset BitsetType::Lub(double min, double max) {
421 : DisallowHeapAllocation no_allocation;
422 : int lub = kNone;
423 : const Boundary* mins = Boundaries();
424 :
425 191948617 : for (size_t i = 1; i < BoundariesSize(); ++i) {
426 97685520 : if (min < mins[i].min) {
427 57152311 : lub |= mins[i - 1].internal;
428 57152311 : if (max < mins[i].min) return lub;
429 : }
430 : }
431 8986347 : return lub | mins[BoundariesSize() - 1].internal;
432 : }
433 :
434 15637032 : Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; }
435 :
436 41282133 : Type::bitset BitsetType::Glb(double min, double max) {
437 : DisallowHeapAllocation no_allocation;
438 : int glb = kNone;
439 : const Boundary* mins = Boundaries();
440 :
441 : // If the range does not touch 0, the bound is empty.
442 41282133 : if (max < -1 || min > 0) return glb;
443 :
444 137683501 : for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
445 122614350 : if (min <= mins[i].min) {
446 92102088 : if (max + 1 < mins[i + 1].min) break;
447 77227304 : glb |= mins[i].external;
448 : }
449 : }
450 : // OtherNumber also contains float numbers, so it can never be
451 : // in the greatest lower bound.
452 29943935 : return glb & ~(kOtherNumber);
453 : }
454 :
455 7164393 : double BitsetType::Min(bitset bits) {
456 : DisallowHeapAllocation no_allocation;
457 : DCHECK(Is(bits, kNumber));
458 : DCHECK(!Is(bits, kNaN));
459 : const Boundary* mins = Boundaries();
460 7164393 : bool mz = bits & kMinusZero;
461 24188615 : for (size_t i = 0; i < BoundariesSize(); ++i) {
462 31312686 : if (Is(mins[i].internal, bits)) {
463 7197274 : return mz ? std::min(0.0, mins[i].min) : mins[i].min;
464 : }
465 : }
466 : DCHECK(mz);
467 : return 0;
468 : }
469 :
470 7346555 : double BitsetType::Max(bitset bits) {
471 : DisallowHeapAllocation no_allocation;
472 : DCHECK(Is(bits, kNumber));
473 : DCHECK(!Is(bits, kNaN));
474 : const Boundary* mins = Boundaries();
475 7346555 : bool mz = bits & kMinusZero;
476 7346555 : if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) {
477 : return +V8_INFINITY;
478 : }
479 10742405 : for (size_t i = BoundariesSize() - 1; i-- > 0;) {
480 21453346 : if (Is(mins[i].internal, bits)) {
481 6175546 : return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
482 : }
483 : }
484 : DCHECK(mz);
485 : return 0;
486 : }
487 :
488 : // static
489 1640802 : bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
490 : // Not an integer, not NaN, and not -0.
491 3281604 : return !std::isnan(value) && !RangeType::IsInteger(value) &&
492 1640802 : !IsMinusZero(value);
493 : }
494 :
495 0 : HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
496 : const HeapObjectRef& heap_ref)
497 18423310 : : TypeBase(kHeapConstant), bitset_(bitset), heap_ref_(heap_ref) {}
498 :
499 2047977 : Handle<HeapObject> HeapConstantType::Value() const {
500 23745135 : return heap_ref_.object();
501 : }
502 :
503 : // -----------------------------------------------------------------------------
504 : // Predicates.
505 :
506 15708147 : bool Type::SimplyEquals(Type that) const {
507 : DisallowHeapAllocation no_allocation;
508 15708147 : if (this->IsHeapConstant()) {
509 23416051 : return that.IsHeapConstant() &&
510 10848539 : this->AsHeapConstant()->Value().address() ==
511 10848536 : that.AsHeapConstant()->Value().address();
512 : }
513 3140632 : if (this->IsOtherNumberConstant()) {
514 3964980 : return that.IsOtherNumberConstant() &&
515 : this->AsOtherNumberConstant()->Value() ==
516 : that.AsOtherNumberConstant()->Value();
517 : }
518 330806 : if (this->IsRange()) {
519 661617 : if (that.IsHeapConstant() || that.IsOtherNumberConstant()) return false;
520 : }
521 0 : if (this->IsTuple()) {
522 0 : if (!that.IsTuple()) return false;
523 : const TupleType* this_tuple = this->AsTuple();
524 : const TupleType* that_tuple = that.AsTuple();
525 0 : if (this_tuple->Arity() != that_tuple->Arity()) {
526 : return false;
527 : }
528 0 : for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
529 0 : if (!this_tuple->Element(i).Equals(that_tuple->Element(i))) return false;
530 : }
531 : return true;
532 : }
533 0 : UNREACHABLE();
534 : }
535 :
536 : // Check if [this] <= [that].
537 399554280 : bool Type::SlowIs(Type that) const {
538 : DisallowHeapAllocation no_allocation;
539 :
540 : // Fast bitset cases
541 399554280 : if (that.IsBitset()) {
542 553598175 : return BitsetType::Is(this->BitsetLub(), that.AsBitset());
543 : }
544 :
545 122758623 : if (this->IsBitset()) {
546 68430697 : return BitsetType::Is(this->AsBitset(), that.BitsetGlb());
547 : }
548 :
549 : // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T)
550 88542923 : if (this->IsUnion()) {
551 24987812 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
552 18958354 : if (!this->AsUnion()->Get(i).Is(that)) return false;
553 : }
554 : return true;
555 : }
556 :
557 : // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn)
558 74158923 : if (that.IsUnion()) {
559 51272487 : for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
560 27611581 : if (this->Is(that.AsUnion()->Get(i))) return true;
561 24149374 : if (i > 1 && this->IsRange()) return false; // Shortcut.
562 : }
563 : return false;
564 : }
565 :
566 61672668 : if (that.IsRange()) {
567 66304404 : return (this->IsRange() && Contains(that.AsRange(), this->AsRange()));
568 : }
569 18880971 : if (this->IsRange()) return false;
570 :
571 15336148 : return this->SimplyEquals(that);
572 : }
573 :
574 : // Check if [this] and [that] overlap.
575 21066917 : bool Type::Maybe(Type that) const {
576 : DisallowHeapAllocation no_allocation;
577 :
578 21066917 : if (BitsetType::IsNone(this->BitsetLub() & that.BitsetLub())) return false;
579 :
580 : // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T)
581 9898234 : if (this->IsUnion()) {
582 1113718 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
583 693043 : if (this->AsUnion()->Get(i).Maybe(that)) return true;
584 : }
585 : return false;
586 : }
587 :
588 : // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn)
589 9469254 : if (that.IsUnion()) {
590 811769 : for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
591 416159 : if (this->Maybe(that.AsUnion()->Get(i))) return true;
592 : }
593 : return false;
594 : }
595 :
596 9249241 : if (this->IsBitset() && that.IsBitset()) return true;
597 :
598 4935306 : if (this->IsRange()) {
599 2375160 : if (that.IsRange()) {
600 1255504 : return Overlap(this->AsRange(), that.AsRange());
601 : }
602 1119656 : if (that.IsBitset()) {
603 : bitset number_bits = BitsetType::NumberBits(that.AsBitset());
604 789322 : if (number_bits == BitsetType::kNone) {
605 : return false;
606 : }
607 1578536 : double min = std::max(BitsetType::Min(number_bits), this->Min());
608 1578323 : double max = std::min(BitsetType::Max(number_bits), this->Max());
609 789113 : return min <= max;
610 : }
611 : }
612 2890480 : if (that.IsRange()) {
613 1073272 : return that.Maybe(*this); // This case is handled above.
614 : }
615 :
616 1817208 : if (this->IsBitset() || that.IsBitset()) return true;
617 :
618 369788 : return this->SimplyEquals(that);
619 : }
620 :
621 : // Return the range in [this], or [nullptr].
622 37215725 : Type Type::GetRange() const {
623 : DisallowHeapAllocation no_allocation;
624 37215725 : if (this->IsRange()) return *this;
625 43833042 : if (this->IsUnion() && this->AsUnion()->Get(1).IsRange()) {
626 : return this->AsUnion()->Get(1);
627 : }
628 19629615 : return nullptr;
629 : }
630 :
631 0 : bool UnionType::Wellformed() const {
632 : DisallowHeapAllocation no_allocation;
633 : // This checks the invariants of the union representation:
634 : // 1. There are at least two elements.
635 : // 2. The first element is a bitset, no other element is a bitset.
636 : // 3. At most one element is a range, and it must be the second one.
637 : // 4. No element is itself a union.
638 : // 5. No element (except the bitset) is a subtype of any other.
639 : // 6. If there is a range, then the bitset type does not contain
640 : // plain number bits.
641 : DCHECK_LE(2, this->Length()); // (1)
642 : DCHECK(this->Get(0).IsBitset()); // (2a)
643 :
644 : for (int i = 0; i < this->Length(); ++i) {
645 : if (i != 0) DCHECK(!this->Get(i).IsBitset()); // (2b)
646 : if (i != 1) DCHECK(!this->Get(i).IsRange()); // (3)
647 : DCHECK(!this->Get(i).IsUnion()); // (4)
648 : for (int j = 0; j < this->Length(); ++j) {
649 : if (i != j && i != 0) DCHECK(!this->Get(i).Is(this->Get(j))); // (5)
650 : }
651 : }
652 : DCHECK(!this->Get(1).IsRange() ||
653 : (BitsetType::NumberBits(this->Get(0).AsBitset()) ==
654 : BitsetType::kNone)); // (6)
655 0 : return true;
656 : }
657 :
658 : // -----------------------------------------------------------------------------
659 : // Union and intersection
660 :
661 27309883 : Type Type::Intersect(Type type1, Type type2, Zone* zone) {
662 : // Fast case: bit sets.
663 43688385 : if (type1.IsBitset() && type2.IsBitset()) {
664 15584645 : return NewBitset(type1.AsBitset() & type2.AsBitset());
665 : }
666 :
667 : // Fast case: top or bottom types.
668 23426152 : if (type1.IsNone() || type2.IsAny()) return type1; // Shortcut.
669 11491030 : if (type2.IsNone() || type1.IsAny()) return type2; // Shortcut.
670 :
671 : // Semi-fast case.
672 11401316 : if (type1.Is(type2)) return type1;
673 3672896 : if (type2.Is(type1)) return type2;
674 :
675 : // Slow case: create union.
676 :
677 : // Semantic subtyping check - this is needed for consistency with the
678 : // semi-fast case above.
679 1932966 : if (type1.Is(type2)) {
680 0 : type2 = Any();
681 1932975 : } else if (type2.Is(type1)) {
682 0 : type1 = Any();
683 : }
684 :
685 1932975 : bitset bits = type1.BitsetGlb() & type2.BitsetGlb();
686 1932932 : int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
687 1932932 : int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
688 : int size;
689 1932932 : if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
690 1932932 : if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
691 1932932 : UnionType* result = UnionType::New(size, zone);
692 : size = 0;
693 :
694 : // Deal with bitsets.
695 : result->Set(size++, NewBitset(bits));
696 :
697 1932909 : RangeType::Limits lims = RangeType::Limits::Empty();
698 1932909 : size = IntersectAux(type1, type2, result, size, &lims, zone);
699 :
700 : // If the range is not empty, then insert it into the union and
701 : // remove the number bits from the bitset.
702 1932906 : if (!lims.IsEmpty()) {
703 641025 : size = UpdateRange(Type::Range(lims, zone), result, size, zone);
704 :
705 : // Remove the number bits.
706 : bitset number_bits = BitsetType::NumberBits(bits);
707 641057 : bits &= ~number_bits;
708 : result->Set(0, NewBitset(bits));
709 : }
710 1932931 : return NormalizeUnion(result, size, zone);
711 : }
712 :
713 641055 : int Type::UpdateRange(Type range, UnionType* result, int size, Zone* zone) {
714 641055 : if (size == 1) {
715 628382 : result->Set(size++, range);
716 : } else {
717 : // Make space for the range.
718 12673 : result->Set(size++, result->Get(1));
719 : result->Set(1, range);
720 : }
721 :
722 : // Remove any components that just got subsumed.
723 654264 : for (int i = 2; i < size;) {
724 26418 : if (result->Get(i).Is(range)) {
725 0 : result->Set(i, result->Get(--size));
726 : } else {
727 13209 : ++i;
728 : }
729 : }
730 641055 : return size;
731 : }
732 :
733 323096 : RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
734 : bitset number_bits = BitsetType::NumberBits(bits);
735 :
736 323096 : if (number_bits == BitsetType::kNone) {
737 : return RangeType::Limits::Empty();
738 : }
739 :
740 : return RangeType::Limits(BitsetType::Min(number_bits),
741 323096 : BitsetType::Max(number_bits));
742 : }
743 :
744 323094 : RangeType::Limits Type::IntersectRangeAndBitset(Type range, Type bitset,
745 : Zone* zone) {
746 : RangeType::Limits range_lims(range.AsRange());
747 323094 : RangeType::Limits bitset_lims = ToLimits(bitset.AsBitset(), zone);
748 323094 : return RangeType::Limits::Intersect(range_lims, bitset_lims);
749 : }
750 :
751 3359216 : int Type::IntersectAux(Type lhs, Type rhs, UnionType* result, int size,
752 : RangeType::Limits* lims, Zone* zone) {
753 3359216 : if (lhs.IsUnion()) {
754 2361242 : for (int i = 0, n = lhs.AsUnion()->Length(); i < n; ++i) {
755 984748 : size = IntersectAux(lhs.AsUnion()->Get(i), rhs, result, size, lims, zone);
756 : }
757 : return size;
758 : }
759 2967410 : if (rhs.IsUnion()) {
760 606070 : for (int i = 0, n = rhs.AsUnion()->Length(); i < n; ++i) {
761 247257 : size = IntersectAux(lhs, rhs.AsUnion()->Get(i), result, size, lims, zone);
762 : }
763 : return size;
764 : }
765 :
766 2855848 : if (BitsetType::IsNone(lhs.BitsetLub() & rhs.BitsetLub())) return size;
767 :
768 1048996 : if (lhs.IsRange()) {
769 801225 : if (rhs.IsBitset()) {
770 323094 : RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
771 :
772 323093 : if (!lim.IsEmpty()) {
773 323093 : *lims = RangeType::Limits::Union(lim, *lims);
774 : }
775 : return size;
776 : }
777 478131 : if (rhs.IsRange()) {
778 : RangeType::Limits lim = RangeType::Limits::Intersect(
779 : RangeType::Limits(lhs.AsRange()), RangeType::Limits(rhs.AsRange()));
780 318264 : if (!lim.IsEmpty()) {
781 318051 : *lims = RangeType::Limits::Union(lim, *lims);
782 : }
783 : }
784 : return size;
785 : }
786 247771 : if (rhs.IsRange()) {
787 : // This case is handled symmetrically above.
788 194543 : return IntersectAux(rhs, lhs, result, size, lims, zone);
789 : }
790 53228 : if (lhs.IsBitset() || rhs.IsBitset()) {
791 51032 : return AddToUnion(lhs.IsBitset() ? rhs : lhs, result, size, zone);
792 : }
793 2196 : if (lhs.SimplyEquals(rhs)) {
794 588 : return AddToUnion(lhs, result, size, zone);
795 : }
796 : return size;
797 : }
798 :
799 : // Make sure that we produce a well-formed range and bitset:
800 : // If the range is non-empty, the number bits in the bitset should be
801 : // clear. Moreover, if we have a canonical range (such as Signed32),
802 : // we want to produce a bitset rather than a range.
803 13883557 : Type Type::NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone) {
804 : // Fast path: If the bitset does not mention numbers, we can just keep the
805 : // range.
806 13883557 : bitset number_bits = BitsetType::NumberBits(*bits);
807 13883557 : if (number_bits == 0) {
808 7502339 : return range;
809 : }
810 :
811 : // If the range is semantically contained within the bitset, return None and
812 : // leave the bitset untouched.
813 6381218 : bitset range_lub = range.BitsetLub();
814 12762436 : if (BitsetType::Is(range_lub, *bits)) {
815 : return None();
816 : }
817 :
818 : // Slow path: reconcile the bitset range and the range.
819 5470954 : double bitset_min = BitsetType::Min(number_bits);
820 5470954 : double bitset_max = BitsetType::Max(number_bits);
821 :
822 5470954 : double range_min = range.Min();
823 5470954 : double range_max = range.Max();
824 :
825 : // Remove the number bits from the bitset, they would just confuse us now.
826 : // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
827 : // case we already returned after the subtype check above.
828 5470954 : *bits &= ~number_bits;
829 :
830 5470954 : if (range_min <= bitset_min && range_max >= bitset_max) {
831 : // Bitset is contained within the range, just return the range.
832 5075514 : return range;
833 : }
834 :
835 395440 : if (bitset_min < range_min) {
836 : range_min = bitset_min;
837 : }
838 395440 : if (bitset_max > range_max) {
839 : range_max = bitset_max;
840 : }
841 : return Type::Range(range_min, range_max, zone);
842 : }
843 :
844 7917854 : Type Type::NewConstant(double value, Zone* zone) {
845 7917854 : if (RangeType::IsInteger(value)) {
846 : return Range(value, value, zone);
847 1659221 : } else if (IsMinusZero(value)) {
848 : return Type::MinusZero();
849 1645838 : } else if (std::isnan(value)) {
850 : return Type::NaN();
851 : }
852 :
853 : DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
854 : return OtherNumberConstant(value, zone);
855 : }
856 :
857 11570179 : Type Type::NewConstant(JSHeapBroker* broker, Handle<i::Object> value,
858 : Zone* zone) {
859 11570179 : ObjectRef ref(broker, value);
860 11570174 : if (ref.IsSmi()) {
861 642303 : return NewConstant(static_cast<double>(ref.AsSmi()), zone);
862 : }
863 10927871 : if (ref.IsHeapNumber()) {
864 2718620 : return NewConstant(ref.AsHeapNumber().value(), zone);
865 : }
866 8209248 : if (ref.IsString() && !ref.IsInternalizedString()) {
867 339 : return For(ref.AsString().map());
868 : }
869 16417805 : return HeapConstant(ref.AsHeapObject(), zone);
870 : }
871 :
872 48177781 : Type Type::Union(Type type1, Type type2, Zone* zone) {
873 : // Fast case: bit sets.
874 73375040 : if (type1.IsBitset() && type2.IsBitset()) {
875 15981864 : return NewBitset(type1.AsBitset() | type2.AsBitset());
876 : }
877 :
878 : // Fast case: top or bottom types.
879 64225940 : if (type1.IsAny() || type2.IsNone()) return type1;
880 30774910 : if (type2.IsAny() || type1.IsNone()) return type2;
881 :
882 : // Semi-fast case.
883 27740311 : if (type1.Is(type2)) return type2;
884 25702196 : if (type2.Is(type1)) return type1;
885 :
886 : // Slow case: create union.
887 18411038 : int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
888 18411038 : int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
889 : int size;
890 18411038 : if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
891 18411038 : if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
892 18411038 : UnionType* result = UnionType::New(size, zone);
893 : size = 0;
894 :
895 : // Compute the new bitset.
896 18411030 : bitset new_bitset = type1.BitsetGlb() | type2.BitsetGlb();
897 :
898 : // Deal with ranges.
899 : Type range = None();
900 18411022 : Type range1 = type1.GetRange();
901 18411023 : Type range2 = type2.GetRange();
902 18411053 : if (range1 != nullptr && range2 != nullptr) {
903 : RangeType::Limits lims =
904 : RangeType::Limits::Union(RangeType::Limits(range1.AsRange()),
905 : RangeType::Limits(range2.AsRange()));
906 3317347 : Type union_range = Type::Range(lims, zone);
907 3317347 : range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
908 15093707 : } else if (range1 != nullptr) {
909 5906573 : range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
910 9187134 : } else if (range2 != nullptr) {
911 4659652 : range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
912 : }
913 18411053 : Type bits = NewBitset(new_bitset);
914 : result->Set(size++, bits);
915 18411053 : if (!range.IsNone()) result->Set(size++, range);
916 :
917 18411053 : size = AddToUnion(type1, result, size, zone);
918 18411035 : size = AddToUnion(type2, result, size, zone);
919 18411043 : return NormalizeUnion(result, size, zone);
920 : }
921 :
922 : // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
923 : // Return new size of [result].
924 75631863 : int Type::AddToUnion(Type type, UnionType* result, int size, Zone* zone) {
925 128403843 : if (type.IsBitset() || type.IsRange()) return size;
926 35571170 : if (type.IsUnion()) {
927 91184702 : for (int i = 0, n = type.AsUnion()->Length(); i < n; ++i) {
928 38758362 : size = AddToUnion(type.AsUnion()->Get(i), result, size, zone);
929 : }
930 : return size;
931 : }
932 106718748 : for (int i = 0; i < size; ++i) {
933 44178478 : if (type.Is(result->Get(i))) return size;
934 : }
935 20132474 : result->Set(size++, type);
936 20132474 : return size;
937 : }
938 :
939 20343977 : Type Type::NormalizeUnion(UnionType* unioned, int size, Zone* zone) {
940 : DCHECK_LE(1, size);
941 : DCHECK(unioned->Get(0).IsBitset());
942 : // If the union has just one element, return it.
943 20343977 : if (size == 1) {
944 : return unioned->Get(0);
945 : }
946 : bitset bits = unioned->Get(0).AsBitset();
947 : // If the union only consists of a range, we can get rid of the union.
948 18563804 : if (size == 2 && bits == BitsetType::kNone) {
949 1848314 : if (unioned->Get(1).IsRange()) {
950 : return Type::Range(unioned->Get(1).AsRange()->Min(),
951 : unioned->Get(1).AsRange()->Max(), zone);
952 : }
953 : }
954 : unioned->Shrink(size);
955 : SLOW_DCHECK(unioned->Wellformed());
956 16716659 : return Type(unioned);
957 : }
958 :
959 86394 : int Type::NumConstants() const {
960 : DisallowHeapAllocation no_allocation;
961 171534 : if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
962 : return 1;
963 84002 : } else if (this->IsUnion()) {
964 : int result = 0;
965 39956 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
966 16462 : if (this->AsUnion()->Get(i).IsHeapConstant()) ++result;
967 : }
968 : return result;
969 : } else {
970 : return 0;
971 : }
972 : }
973 :
974 : // -----------------------------------------------------------------------------
975 : // Printing.
976 :
977 142389 : const char* BitsetType::Name(bitset bits) {
978 142389 : switch (bits) {
979 : #define RETURN_NAMED_TYPE(type, value) \
980 : case k##type: \
981 : return #type;
982 0 : PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
983 0 : INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
984 : #undef RETURN_NAMED_TYPE
985 :
986 : default:
987 0 : return nullptr;
988 : }
989 : }
990 :
991 142389 : void BitsetType::Print(std::ostream& os, // NOLINT
992 : bitset bits) {
993 : DisallowHeapAllocation no_allocation;
994 142389 : const char* name = Name(bits);
995 142389 : if (name != nullptr) {
996 142389 : os << name;
997 : return;
998 : }
999 :
1000 : // clang-format off
1001 : static const bitset named_bitsets[] = {
1002 : #define BITSET_CONSTANT(type, value) k##type,
1003 : INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
1004 : PROPER_BITSET_TYPE_LIST(BITSET_CONSTANT)
1005 : #undef BITSET_CONSTANT
1006 : };
1007 : // clang-format on
1008 :
1009 : bool is_first = true;
1010 0 : os << "(";
1011 0 : for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
1012 0 : bitset subset = named_bitsets[i];
1013 0 : if ((bits & subset) == subset) {
1014 0 : if (!is_first) os << " | ";
1015 : is_first = false;
1016 0 : os << Name(subset);
1017 0 : bits -= subset;
1018 : }
1019 : }
1020 : DCHECK_EQ(0, bits);
1021 0 : os << ")";
1022 : }
1023 :
1024 142517 : void Type::PrintTo(std::ostream& os) const {
1025 : DisallowHeapAllocation no_allocation;
1026 142517 : if (this->IsBitset()) {
1027 142389 : BitsetType::Print(os, this->AsBitset());
1028 128 : } else if (this->IsHeapConstant()) {
1029 160 : os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
1030 48 : } else if (this->IsOtherNumberConstant()) {
1031 : os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
1032 0 : << ")";
1033 48 : } else if (this->IsRange()) {
1034 29 : std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1035 29 : std::streamsize saved_precision = os.precision(0);
1036 : os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1037 29 : << ")";
1038 29 : os.flags(saved_flags);
1039 29 : os.precision(saved_precision);
1040 19 : } else if (this->IsUnion()) {
1041 19 : os << "(";
1042 95 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1043 38 : Type type_i = this->AsUnion()->Get(i);
1044 38 : if (i > 0) os << " | ";
1045 38 : os << type_i;
1046 : }
1047 19 : os << ")";
1048 0 : } else if (this->IsTuple()) {
1049 0 : os << "<";
1050 0 : for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
1051 0 : Type type_i = this->AsTuple()->Element(i);
1052 0 : if (i > 0) os << ", ";
1053 0 : os << type_i;
1054 : }
1055 0 : os << ">";
1056 : } else {
1057 0 : UNREACHABLE();
1058 : }
1059 142517 : }
1060 :
1061 : #ifdef DEBUG
1062 : void Type::Print() const {
1063 : StdoutStream os;
1064 : PrintTo(os);
1065 : os << std::endl;
1066 : }
1067 : void BitsetType::Print(bitset bits) {
1068 : StdoutStream os;
1069 : Print(os, bits);
1070 : os << std::endl;
1071 : }
1072 : #endif
1073 :
1074 6829747 : BitsetType::bitset BitsetType::SignedSmall() {
1075 6829747 : return SmiValuesAre31Bits() ? kSigned31 : kSigned32;
1076 : }
1077 :
1078 231946 : BitsetType::bitset BitsetType::UnsignedSmall() {
1079 231946 : return SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
1080 : }
1081 :
1082 : // static
1083 1386 : Type Type::Tuple(Type first, Type second, Type third, Zone* zone) {
1084 1386 : TupleType* tuple = TupleType::New(3, zone);
1085 : tuple->InitElement(0, first);
1086 : tuple->InitElement(1, second);
1087 : tuple->InitElement(2, third);
1088 1386 : return FromTypeBase(tuple);
1089 : }
1090 :
1091 : // static
1092 0 : Type Type::OtherNumberConstant(double value, Zone* zone) {
1093 1640802 : return FromTypeBase(OtherNumberConstantType::New(value, zone));
1094 : }
1095 :
1096 : // static
1097 10214432 : Type Type::HeapConstant(JSHeapBroker* broker, Handle<i::Object> value,
1098 : Zone* zone) {
1099 : return FromTypeBase(
1100 20428890 : HeapConstantType::New(HeapObjectRef(broker, value), zone));
1101 : }
1102 :
1103 : // static
1104 0 : Type Type::HeapConstant(const HeapObjectRef& value, Zone* zone) {
1105 8208894 : return HeapConstantType::New(value, zone);
1106 : }
1107 :
1108 : // static
1109 8936689 : Type Type::Range(double min, double max, Zone* zone) {
1110 8936695 : return FromTypeBase(RangeType::New(min, max, zone));
1111 : }
1112 :
1113 : // static
1114 0 : Type Type::Range(RangeType::Limits lims, Zone* zone) {
1115 3958378 : return FromTypeBase(RangeType::New(lims, zone));
1116 : }
1117 :
1118 : // static
1119 0 : Type Type::Union(int length, Zone* zone) {
1120 0 : return FromTypeBase(UnionType::New(length, zone));
1121 : }
1122 :
1123 2384088 : const HeapConstantType* Type::AsHeapConstant() const {
1124 : DCHECK(IsKind(TypeBase::kHeapConstant));
1125 2384088 : return static_cast<const HeapConstantType*>(ToTypeBase());
1126 : }
1127 :
1128 57 : const OtherNumberConstantType* Type::AsOtherNumberConstant() const {
1129 : DCHECK(IsKind(TypeBase::kOtherNumberConstant));
1130 57 : return static_cast<const OtherNumberConstantType*>(ToTypeBase());
1131 : }
1132 :
1133 45250 : const RangeType* Type::AsRange() const {
1134 : DCHECK(IsKind(TypeBase::kRange));
1135 45250 : return static_cast<const RangeType*>(ToTypeBase());
1136 : }
1137 :
1138 8316 : const TupleType* Type::AsTuple() const {
1139 : DCHECK(IsKind(TypeBase::kTuple));
1140 8316 : return static_cast<const TupleType*>(ToTypeBase());
1141 : }
1142 :
1143 7032 : const UnionType* Type::AsUnion() const {
1144 : DCHECK(IsKind(TypeBase::kUnion));
1145 7032 : return static_cast<const UnionType*>(ToTypeBase());
1146 : }
1147 :
1148 142345 : std::ostream& operator<<(std::ostream& os, Type type) {
1149 142345 : type.PrintTo(os);
1150 142345 : return os;
1151 : }
1152 :
1153 : } // namespace compiler
1154 : } // namespace internal
1155 121996 : } // namespace v8
|