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 3121865 : 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 1887449 : if (lhs.min < rhs.min) result.min = rhs.min;
26 1887449 : 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 4279713 : if (lhs.IsEmpty()) return rhs;
33 4279714 : if (rhs.IsEmpty()) return lhs;
34 : Limits result(lhs);
35 3651476 : if (lhs.min > rhs.min) result.min = rhs.min;
36 3651476 : 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 1258995 : .IsEmpty();
45 : }
46 :
47 0 : bool Type::Contains(const RangeType* lhs, const RangeType* rhs) {
48 : DisallowHeapAllocation no_allocation;
49 24288764 : return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
50 : }
51 :
52 : // -----------------------------------------------------------------------------
53 : // Min and Max computation.
54 :
55 14189736 : double Type::Min() const {
56 : DCHECK(this->Is(Number()));
57 : DCHECK(!this->Is(NaN()));
58 14774900 : if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
59 13604572 : if (this->IsUnion()) {
60 49360 : double min = +V8_INFINITY;
61 205836 : for (int i = 1, n = AsUnion()->Length(); i < n; ++i) {
62 156476 : min = std::min(min, AsUnion()->Get(i).Min());
63 : }
64 49360 : Type bitset = AsUnion()->Get(0);
65 68243 : if (!bitset.Is(NaN())) min = std::min(min, bitset.Min());
66 49360 : return min;
67 : }
68 27070894 : if (this->IsRange()) return this->AsRange()->Min();
69 : DCHECK(this->IsOtherNumberConstant());
70 39530 : return this->AsOtherNumberConstant()->Value();
71 : }
72 :
73 14400328 : double Type::Max() const {
74 : DCHECK(this->Is(Number()));
75 : DCHECK(!this->Is(NaN()));
76 15168688 : if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
77 13631968 : if (this->IsUnion()) {
78 44885 : double max = -V8_INFINITY;
79 192409 : for (int i = 1, n = this->AsUnion()->Length(); i < n; ++i) {
80 147525 : max = std::max(max, this->AsUnion()->Get(i).Max());
81 : }
82 44884 : Type bitset = this->AsUnion()->Get(0);
83 59278 : if (!bitset.Is(NaN())) max = std::max(max, bitset.Max());
84 44884 : return max;
85 : }
86 27138574 : if (this->IsRange()) return this->AsRange()->Max();
87 : DCHECK(this->IsOtherNumberConstant());
88 35592 : return this->AsOtherNumberConstant()->Value();
89 : }
90 :
91 : // -----------------------------------------------------------------------------
92 : // Glb and lub computation.
93 :
94 : // The largest bitset subsumed by this type.
95 137818760 : Type::bitset Type::BitsetGlb() const {
96 : DisallowHeapAllocation no_allocation;
97 : // Fast case.
98 137818760 : if (IsBitset()) {
99 40728263 : return AsBitset();
100 97090497 : } else if (IsUnion()) {
101 : SLOW_DCHECK(AsUnion()->Wellformed());
102 58916905 : return AsUnion()->Get(0).BitsetGlb() |
103 29458581 : AsUnion()->Get(1).BitsetGlb(); // Shortcut.
104 67631987 : } else if (IsRange()) {
105 43560494 : bitset glb = BitsetType::Glb(AsRange()->Min(), AsRange()->Max());
106 43560512 : return glb;
107 : } else {
108 : return BitsetType::kNone;
109 : }
110 : }
111 :
112 : // The smallest bitset subsuming this type, possibly not a proper one.
113 379390142 : Type::bitset Type::BitsetLub() const {
114 : DisallowHeapAllocation no_allocation;
115 622713383 : if (IsBitset()) return AsBitset();
116 136066901 : if (IsUnion()) {
117 : // Take the representation from the first element, which is always
118 : // a bitset.
119 11311432 : int bitset = AsUnion()->Get(0).BitsetLub();
120 74033281 : for (int i = 0, n = AsUnion()->Length(); i < n; ++i) {
121 : // Other elements only contribute their semantic part.
122 31361967 : bitset |= AsUnion()->Get(i).BitsetLub();
123 : }
124 11315194 : return bitset;
125 : }
126 165045495 : if (IsHeapConstant()) return AsHeapConstant()->Lub();
127 84465443 : if (IsOtherNumberConstant()) {
128 : return AsOtherNumberConstant()->Lub();
129 : }
130 142148599 : if (IsRange()) return AsRange()->Lub();
131 4143 : 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 18735487 : Type::bitset BitsetType::Lub(const MapRefLike& map) {
139 18735487 : 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 4215 : 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 3131633 : return kNonEmptyInternalizedOneByteString;
164 : case SYMBOL_TYPE:
165 604 : return kSymbol;
166 : case BIGINT_TYPE:
167 2385 : return kBigInt;
168 : case ODDBALL_TYPE:
169 10758969 : switch (map.oddball_type()) {
170 : case OddballType::kNone:
171 : break;
172 : case OddballType::kHole:
173 : return kHole;
174 : case OddballType::kBoolean:
175 6625141 : return kBoolean;
176 : case OddballType::kNull:
177 32658 : return kNull;
178 : case OddballType::kUndefined:
179 965667 : return kUndefined;
180 : case OddballType::kUninitialized:
181 : case OddballType::kOther:
182 : // TODO(neis): We should add a kOtherOddball type.
183 1545495 : 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 1299702 : 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 1299636 : if (map.is_callable()) {
204 : return kOtherCallable;
205 : }
206 1299636 : return kOtherObject;
207 : case JS_ARRAY_TYPE:
208 633689 : 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 4434 : return kOtherObject;
260 : case JS_BOUND_FUNCTION_TYPE:
261 : DCHECK(!map.is_undetectable());
262 162 : return kBoundFunction;
263 : case JS_FUNCTION_TYPE:
264 : DCHECK(!map.is_undetectable());
265 551319 : 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 942021 : 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 WASM_DEBUG_INFO_TYPE:
358 : case WASM_EXCEPTION_TAG_TYPE:
359 : case WASM_EXPORTED_FUNCTION_DATA_TYPE:
360 : case LOAD_HANDLER_TYPE:
361 : case STORE_HANDLER_TYPE:
362 : case ASYNC_GENERATOR_REQUEST_TYPE:
363 : case CODE_DATA_CONTAINER_TYPE:
364 : case CALLBACK_TASK_TYPE:
365 : case CALLABLE_TASK_TYPE:
366 : case PROMISE_FULFILL_REACTION_JOB_TASK_TYPE:
367 : case PROMISE_REJECT_REACTION_JOB_TASK_TYPE:
368 : case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE:
369 : case FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE:
370 0 : UNREACHABLE();
371 : }
372 0 : UNREACHABLE();
373 : }
374 :
375 : // Explicit instantiation.
376 : template Type::bitset BitsetType::Lub<MapRef>(const MapRef& map);
377 :
378 0 : Type::bitset BitsetType::Lub(double value) {
379 : DisallowHeapAllocation no_allocation;
380 0 : if (IsMinusZero(value)) return kMinusZero;
381 0 : if (std::isnan(value)) return kNaN;
382 0 : if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
383 : return kOtherNumber;
384 : }
385 :
386 : // Minimum values of plain numeric bitsets.
387 : const BitsetType::Boundary BitsetType::BoundariesArray[] = {
388 : {kOtherNumber, kPlainNumber, -V8_INFINITY},
389 : {kOtherSigned32, kNegative32, kMinInt},
390 : {kNegative31, kNegative31, -0x40000000},
391 : {kUnsigned30, kUnsigned30, 0},
392 : {kOtherUnsigned31, kUnsigned31, 0x40000000},
393 : {kOtherUnsigned32, kUnsigned32, 0x80000000},
394 : {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
395 :
396 : const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
397 :
398 : size_t BitsetType::BoundariesSize() {
399 : // Windows doesn't like arraysize here.
400 : // return arraysize(BoundariesArray);
401 : return 7;
402 : }
403 :
404 12456 : Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
405 : DCHECK_IMPLIES(bits & kOtherOneByteString,
406 : bits & kNonEmptyInternalizedOneByteString);
407 : DCHECK_IMPLIES(bits & kOtherTwoByteString,
408 : bits & kNonEmptyInternalizedTwoByteString);
409 : DisallowHeapAllocation no_allocation;
410 12794 : if (!(bits & kPlainNumber)) return bits; // Shortcut.
411 : const Boundary* boundaries = Boundaries();
412 0 : for (size_t i = 0; i < BoundariesSize(); ++i) {
413 : DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
414 0 : if (bits & boundaries[i].internal) bits |= boundaries[i].external;
415 : }
416 : return bits;
417 : }
418 :
419 0 : Type::bitset BitsetType::Lub(double min, double max) {
420 : DisallowHeapAllocation no_allocation;
421 : int lub = kNone;
422 : const Boundary* mins = Boundaries();
423 :
424 216144400 : for (size_t i = 1; i < BoundariesSize(); ++i) {
425 108657026 : if (min < mins[i].min) {
426 61946947 : lub |= mins[i - 1].internal;
427 61946947 : if (max < mins[i].min) return lub;
428 : }
429 : }
430 10835297 : return lub | mins[BoundariesSize() - 1].internal;
431 : }
432 :
433 16679745 : Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; }
434 :
435 43559988 : Type::bitset BitsetType::Glb(double min, double max) {
436 : DisallowHeapAllocation no_allocation;
437 : int glb = kNone;
438 : const Boundary* mins = Boundaries();
439 :
440 : // If the range does not touch 0, the bound is empty.
441 43559988 : if (max < -1 || min > 0) return glb;
442 :
443 146842625 : for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
444 130320341 : if (min <= mins[i].min) {
445 98778987 : if (max + 1 < mins[i + 1].min) break;
446 83649815 : glb |= mins[i].external;
447 : }
448 : }
449 : // OtherNumber also contains float numbers, so it can never be
450 : // in the greatest lower bound.
451 31651456 : return glb & ~(kOtherNumber);
452 : }
453 :
454 7977116 : double BitsetType::Min(bitset bits) {
455 : DisallowHeapAllocation no_allocation;
456 : DCHECK(Is(bits, kNumber));
457 : DCHECK(!Is(bits, kNaN));
458 : const Boundary* mins = Boundaries();
459 7977116 : bool mz = bits & kMinusZero;
460 27604668 : for (size_t i = 0; i < BoundariesSize(); ++i) {
461 35541524 : if (Is(mins[i].internal, bits)) {
462 8009582 : return mz ? std::min(0.0, mins[i].min) : mins[i].min;
463 : }
464 : }
465 : DCHECK(mz);
466 : return 0;
467 : }
468 :
469 8159627 : double BitsetType::Max(bitset bits) {
470 : DisallowHeapAllocation no_allocation;
471 : DCHECK(Is(bits, kNumber));
472 : DCHECK(!Is(bits, kNaN));
473 : const Boundary* mins = Boundaries();
474 8159627 : bool mz = bits & kMinusZero;
475 8159627 : if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) {
476 : return +V8_INFINITY;
477 : }
478 12017124 : for (size_t i = BoundariesSize() - 1; i-- > 0;) {
479 24002752 : if (Is(mins[i].internal, bits)) {
480 6994995 : return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
481 : }
482 : }
483 : DCHECK(mz);
484 : return 0;
485 : }
486 :
487 : // static
488 1886576 : bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
489 : // Not an integer, not NaN, and not -0.
490 3773152 : return !std::isnan(value) && !RangeType::IsInteger(value) &&
491 1886576 : !IsMinusZero(value);
492 : }
493 :
494 0 : HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
495 : const HeapObjectRef& heap_ref)
496 18722675 : : TypeBase(kHeapConstant), bitset_(bitset), heap_ref_(heap_ref) {}
497 :
498 2056532 : Handle<HeapObject> HeapConstantType::Value() const {
499 24499147 : return heap_ref_.object();
500 : }
501 :
502 : // -----------------------------------------------------------------------------
503 : // Predicates.
504 :
505 16655904 : bool Type::SimplyEquals(Type that) const {
506 : DisallowHeapAllocation no_allocation;
507 16655904 : if (this->IsHeapConstant()) {
508 24404658 : return that.IsHeapConstant() &&
509 11221265 : this->AsHeapConstant()->Value().address() ==
510 11221262 : that.AsHeapConstant()->Value().address();
511 : }
512 3472508 : if (this->IsOtherNumberConstant()) {
513 4483496 : return that.IsOtherNumberConstant() &&
514 : this->AsOtherNumberConstant()->Value() ==
515 : that.AsOtherNumberConstant()->Value();
516 : }
517 330502 : if (this->IsRange()) {
518 661011 : if (that.IsHeapConstant() || that.IsOtherNumberConstant()) return false;
519 : }
520 0 : if (this->IsTuple()) {
521 0 : if (!that.IsTuple()) return false;
522 : const TupleType* this_tuple = this->AsTuple();
523 : const TupleType* that_tuple = that.AsTuple();
524 0 : if (this_tuple->Arity() != that_tuple->Arity()) {
525 : return false;
526 : }
527 0 : for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
528 0 : if (!this_tuple->Element(i).Equals(that_tuple->Element(i))) return false;
529 : }
530 : return true;
531 : }
532 0 : UNREACHABLE();
533 : }
534 :
535 : // Check if [this] <= [that].
536 411466419 : bool Type::SlowIs(Type that) const {
537 : DisallowHeapAllocation no_allocation;
538 :
539 : // Fast bitset cases
540 411466419 : if (that.IsBitset()) {
541 563563916 : return BitsetType::Is(this->BitsetLub(), that.AsBitset());
542 : }
543 :
544 129692618 : if (this->IsBitset()) {
545 71404749 : return BitsetType::Is(this->AsBitset(), that.BitsetGlb());
546 : }
547 :
548 : // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T)
549 93988830 : if (this->IsUnion()) {
550 26981262 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
551 20447902 : if (!this->AsUnion()->Get(i).Is(that)) return false;
552 : }
553 : return true;
554 : }
555 :
556 : // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn)
557 78506156 : if (that.IsUnion()) {
558 54958308 : for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
559 29617643 : if (this->Is(that.AsUnion()->Get(i))) return true;
560 26063748 : if (i > 1 && this->IsRange()) return false; // Shortcut.
561 : }
562 : return false;
563 : }
564 :
565 65133156 : if (that.IsRange()) {
566 69212468 : return (this->IsRange() && Contains(that.AsRange(), this->AsRange()));
567 : }
568 20209452 : if (this->IsRange()) return false;
569 :
570 16284500 : return this->SimplyEquals(that);
571 : }
572 :
573 : // Check if [this] and [that] overlap.
574 21095412 : bool Type::Maybe(Type that) const {
575 : DisallowHeapAllocation no_allocation;
576 :
577 21095412 : if (BitsetType::IsNone(this->BitsetLub() & that.BitsetLub())) return false;
578 :
579 : // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T)
580 9910122 : if (this->IsUnion()) {
581 1112490 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
582 692248 : if (this->AsUnion()->Get(i).Maybe(that)) return true;
583 : }
584 : return false;
585 : }
586 :
587 : // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn)
588 9481642 : if (that.IsUnion()) {
589 818682 : for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
590 419390 : if (this->Maybe(that.AsUnion()->Get(i))) return true;
591 : }
592 : return false;
593 : }
594 :
595 9260280 : if (this->IsBitset() && that.IsBitset()) return true;
596 :
597 4934252 : if (this->IsRange()) {
598 2376034 : if (that.IsRange()) {
599 1258995 : return Overlap(this->AsRange(), that.AsRange());
600 : }
601 1117039 : if (that.IsBitset()) {
602 : bitset number_bits = BitsetType::NumberBits(that.AsBitset());
603 786926 : if (number_bits == BitsetType::kNone) {
604 : return false;
605 : }
606 1573755 : double min = std::max(BitsetType::Min(number_bits), this->Min());
607 1573616 : double max = std::min(BitsetType::Max(number_bits), this->Max());
608 786791 : return min <= max;
609 : }
610 : }
611 2888331 : if (that.IsRange()) {
612 1071524 : return that.Maybe(*this); // This case is handled above.
613 : }
614 :
615 1816807 : if (this->IsBitset() || that.IsBitset()) return true;
616 :
617 369467 : return this->SimplyEquals(that);
618 : }
619 :
620 : // Return the range in [this], or [nullptr].
621 39823597 : Type Type::GetRange() const {
622 : DisallowHeapAllocation no_allocation;
623 39823597 : if (this->IsRange()) return *this;
624 46929046 : if (this->IsUnion() && this->AsUnion()->Get(1).IsRange()) {
625 : return this->AsUnion()->Get(1);
626 : }
627 20832129 : return nullptr;
628 : }
629 :
630 0 : bool UnionType::Wellformed() const {
631 : DisallowHeapAllocation no_allocation;
632 : // This checks the invariants of the union representation:
633 : // 1. There are at least two elements.
634 : // 2. The first element is a bitset, no other element is a bitset.
635 : // 3. At most one element is a range, and it must be the second one.
636 : // 4. No element is itself a union.
637 : // 5. No element (except the bitset) is a subtype of any other.
638 : // 6. If there is a range, then the bitset type does not contain
639 : // plain number bits.
640 : DCHECK_LE(2, this->Length()); // (1)
641 : DCHECK(this->Get(0).IsBitset()); // (2a)
642 :
643 : for (int i = 0; i < this->Length(); ++i) {
644 : if (i != 0) DCHECK(!this->Get(i).IsBitset()); // (2b)
645 : if (i != 1) DCHECK(!this->Get(i).IsRange()); // (3)
646 : DCHECK(!this->Get(i).IsUnion()); // (4)
647 : for (int j = 0; j < this->Length(); ++j) {
648 : if (i != j && i != 0) DCHECK(!this->Get(i).Is(this->Get(j))); // (5)
649 : }
650 : }
651 : DCHECK(!this->Get(1).IsRange() ||
652 : (BitsetType::NumberBits(this->Get(0).AsBitset()) ==
653 : BitsetType::kNone)); // (6)
654 0 : return true;
655 : }
656 :
657 : // -----------------------------------------------------------------------------
658 : // Union and intersection
659 :
660 28726196 : Type Type::Intersect(Type type1, Type type2, Zone* zone) {
661 : // Fast case: bit sets.
662 46592270 : if (type1.IsBitset() && type2.IsBitset()) {
663 17135135 : return NewBitset(type1.AsBitset() & type2.AsBitset());
664 : }
665 :
666 : // Fast case: top or bottom types.
667 23162785 : if (type1.IsNone() || type2.IsAny()) return type1; // Shortcut.
668 11365157 : if (type2.IsNone() || type1.IsAny()) return type2; // Shortcut.
669 :
670 : // Semi-fast case.
671 11284724 : if (type1.Is(type2)) return type1;
672 3575795 : if (type2.Is(type1)) return type2;
673 :
674 : // Slow case: create union.
675 :
676 : // Semantic subtyping check - this is needed for consistency with the
677 : // semi-fast case above.
678 1862897 : if (type1.Is(type2)) {
679 0 : type2 = Any();
680 1862900 : } else if (type2.Is(type1)) {
681 0 : type1 = Any();
682 : }
683 :
684 1862900 : bitset bits = type1.BitsetGlb() & type2.BitsetGlb();
685 1862847 : int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
686 1862847 : int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
687 : int size;
688 1862847 : if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
689 1862847 : if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
690 1862847 : UnionType* result = UnionType::New(size, zone);
691 : size = 0;
692 :
693 : // Deal with bitsets.
694 : result->Set(size++, NewBitset(bits));
695 :
696 1862827 : RangeType::Limits lims = RangeType::Limits::Empty();
697 1862827 : size = IntersectAux(type1, type2, result, size, &lims, zone);
698 :
699 : // If the range is not empty, then insert it into the union and
700 : // remove the number bits from the bitset.
701 1862870 : if (!lims.IsEmpty()) {
702 628108 : size = UpdateRange(Type::Range(lims, zone), result, size, zone);
703 :
704 : // Remove the number bits.
705 : bitset number_bits = BitsetType::NumberBits(bits);
706 628123 : bits &= ~number_bits;
707 : result->Set(0, NewBitset(bits));
708 : }
709 1862867 : return NormalizeUnion(result, size, zone);
710 : }
711 :
712 628125 : int Type::UpdateRange(Type range, UnionType* result, int size, Zone* zone) {
713 628125 : if (size == 1) {
714 620364 : result->Set(size++, range);
715 : } else {
716 : // Make space for the range.
717 7761 : result->Set(size++, result->Get(1));
718 : result->Set(1, range);
719 : }
720 :
721 : // Remove any components that just got subsumed.
722 636529 : for (int i = 2; i < size;) {
723 16808 : if (result->Get(i).Is(range)) {
724 0 : result->Set(i, result->Get(--size));
725 : } else {
726 8404 : ++i;
727 : }
728 : }
729 628125 : return size;
730 : }
731 :
732 309617 : RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
733 : bitset number_bits = BitsetType::NumberBits(bits);
734 :
735 309617 : if (number_bits == BitsetType::kNone) {
736 : return RangeType::Limits::Empty();
737 : }
738 :
739 : return RangeType::Limits(BitsetType::Min(number_bits),
740 309617 : BitsetType::Max(number_bits));
741 : }
742 :
743 309616 : RangeType::Limits Type::IntersectRangeAndBitset(Type range, Type bitset,
744 : Zone* zone) {
745 : RangeType::Limits range_lims(range.AsRange());
746 309616 : RangeType::Limits bitset_lims = ToLimits(bitset.AsBitset(), zone);
747 309615 : return RangeType::Limits::Intersect(range_lims, bitset_lims);
748 : }
749 :
750 3271801 : int Type::IntersectAux(Type lhs, Type rhs, UnionType* result, int size,
751 : RangeType::Limits* lims, Zone* zone) {
752 3271801 : if (lhs.IsUnion()) {
753 2353232 : for (int i = 0, n = lhs.AsUnion()->Length(); i < n; ++i) {
754 981034 : size = IntersectAux(lhs.AsUnion()->Get(i), rhs, result, size, lims, zone);
755 : }
756 : return size;
757 : }
758 2880687 : if (rhs.IsUnion()) {
759 591784 : for (int i = 0, n = rhs.AsUnion()->Length(); i < n; ++i) {
760 240872 : size = IntersectAux(lhs, rhs.AsUnion()->Get(i), result, size, lims, zone);
761 : }
762 : return size;
763 : }
764 :
765 2770643 : if (BitsetType::IsNone(lhs.BitsetLub() & rhs.BitsetLub())) return size;
766 :
767 1031338 : if (lhs.IsRange()) {
768 787523 : if (rhs.IsBitset()) {
769 309621 : RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
770 :
771 309615 : if (!lim.IsEmpty()) {
772 309614 : *lims = RangeType::Limits::Union(lim, *lims);
773 : }
774 : return size;
775 : }
776 477902 : if (rhs.IsRange()) {
777 : RangeType::Limits lim = RangeType::Limits::Intersect(
778 : RangeType::Limits(lhs.AsRange()), RangeType::Limits(rhs.AsRange()));
779 318839 : if (!lim.IsEmpty()) {
780 318623 : *lims = RangeType::Limits::Union(lim, *lims);
781 : }
782 : }
783 : return size;
784 : }
785 243815 : if (rhs.IsRange()) {
786 : // This case is handled symmetrically above.
787 187178 : return IntersectAux(rhs, lhs, result, size, lims, zone);
788 : }
789 56637 : if (lhs.IsBitset() || rhs.IsBitset()) {
790 54709 : return AddToUnion(lhs.IsBitset() ? rhs : lhs, result, size, zone);
791 : }
792 1928 : if (lhs.SimplyEquals(rhs)) {
793 588 : return AddToUnion(lhs, result, size, zone);
794 : }
795 : return size;
796 : }
797 :
798 : // Make sure that we produce a well-formed range and bitset:
799 : // If the range is non-empty, the number bits in the bitset should be
800 : // clear. Moreover, if we have a canonical range (such as Signed32),
801 : // we want to produce a bitset rather than a range.
802 14955079 : Type Type::NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone) {
803 : // Fast path: If the bitset does not mention numbers, we can just keep the
804 : // range.
805 14955079 : bitset number_bits = BitsetType::NumberBits(*bits);
806 14955079 : if (number_bits == 0) {
807 7640803 : return range;
808 : }
809 :
810 : // If the range is semantically contained within the bitset, return None and
811 : // leave the bitset untouched.
812 7314276 : bitset range_lub = range.BitsetLub();
813 14628552 : if (BitsetType::Is(range_lub, *bits)) {
814 : return None();
815 : }
816 :
817 : // Slow path: reconcile the bitset range and the range.
818 6296207 : double bitset_min = BitsetType::Min(number_bits);
819 6296207 : double bitset_max = BitsetType::Max(number_bits);
820 :
821 6296207 : double range_min = range.Min();
822 6296207 : double range_max = range.Max();
823 :
824 : // Remove the number bits from the bitset, they would just confuse us now.
825 : // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
826 : // case we already returned after the subtype check above.
827 6296207 : *bits &= ~number_bits;
828 :
829 6296207 : if (range_min <= bitset_min && range_max >= bitset_max) {
830 : // Bitset is contained within the range, just return the range.
831 5844986 : return range;
832 : }
833 :
834 451221 : if (bitset_min < range_min) {
835 : range_min = bitset_min;
836 : }
837 451221 : if (bitset_max > range_max) {
838 : range_max = bitset_max;
839 : }
840 : return Type::Range(range_min, range_max, zone);
841 : }
842 :
843 8400358 : Type Type::NewConstant(double value, Zone* zone) {
844 8400358 : if (RangeType::IsInteger(value)) {
845 : return Range(value, value, zone);
846 1904990 : } else if (IsMinusZero(value)) {
847 : return Type::MinusZero();
848 1891596 : } else if (std::isnan(value)) {
849 : return Type::NaN();
850 : }
851 :
852 : DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
853 : return OtherNumberConstant(value, zone);
854 : }
855 :
856 12347836 : Type Type::NewConstant(JSHeapBroker* broker, Handle<i::Object> value,
857 : Zone* zone) {
858 12347836 : ObjectRef ref(broker, value);
859 12347840 : if (ref.IsSmi()) {
860 723075 : return NewConstant(static_cast<double>(ref.AsSmi()), zone);
861 : }
862 11624765 : if (ref.IsHeapNumber()) {
863 3117972 : return NewConstant(ref.AsHeapNumber().value(), zone);
864 : }
865 8506784 : if (ref.IsString() && !ref.IsInternalizedString()) {
866 338 : return For(ref.AsString().map());
867 : }
868 17012871 : return HeapConstant(ref.AsHeapObject(), zone);
869 : }
870 :
871 51182036 : Type Type::Union(Type type1, Type type2, Zone* zone) {
872 : // Fast case: bit sets.
873 77602423 : if (type1.IsBitset() && type2.IsBitset()) {
874 16527967 : return NewBitset(type1.AsBitset() | type2.AsBitset());
875 : }
876 :
877 : // Fast case: top or bottom types.
878 69103852 : if (type1.IsAny() || type2.IsNone()) return type1;
879 33159744 : if (type2.IsAny() || type1.IsNone()) return type2;
880 :
881 : // Semi-fast case.
882 29748152 : if (type1.Is(type2)) return type2;
883 27634548 : if (type2.Is(type1)) return type1;
884 :
885 : // Slow case: create union.
886 19715141 : int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
887 19715141 : int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
888 : int size;
889 19715141 : if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
890 19715141 : if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
891 19715141 : UnionType* result = UnionType::New(size, zone);
892 : size = 0;
893 :
894 : // Compute the new bitset.
895 19715119 : bitset new_bitset = type1.BitsetGlb() | type2.BitsetGlb();
896 :
897 : // Deal with ranges.
898 : Type range = None();
899 19715110 : Type range1 = type1.GetRange();
900 19715107 : Type range2 = type2.GetRange();
901 19715145 : if (range1 != nullptr && range2 != nullptr) {
902 : RangeType::Limits lims =
903 : RangeType::Limits::Union(RangeType::Limits(range1.AsRange()),
904 : RangeType::Limits(range2.AsRange()));
905 3651478 : Type union_range = Type::Range(lims, zone);
906 3651478 : range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
907 16063669 : } else if (range1 != nullptr) {
908 6477558 : range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
909 9586111 : } else if (range2 != nullptr) {
910 4826062 : range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
911 : }
912 19715146 : Type bits = NewBitset(new_bitset);
913 : result->Set(size++, bits);
914 19715146 : if (!range.IsNone()) result->Set(size++, range);
915 :
916 19715146 : size = AddToUnion(type1, result, size, zone);
917 19715117 : size = AddToUnion(type2, result, size, zone);
918 19715136 : return NormalizeUnion(result, size, zone);
919 : }
920 :
921 : // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
922 : // Return new size of [result].
923 81395011 : int Type::AddToUnion(Type type, UnionType* result, int size, Zone* zone) {
924 138299102 : if (type.IsBitset() || type.IsRange()) return size;
925 38297694 : if (type.IsUnion()) {
926 98560277 : for (int i = 0, n = type.AsUnion()->Length(); i < n; ++i) {
927 41909698 : size = AddToUnion(type.AsUnion()->Get(i), result, size, zone);
928 : }
929 : return size;
930 : }
931 114529635 : for (int i = 0; i < size; ++i) {
932 47520467 : if (type.Is(result->Get(i))) return size;
933 : }
934 21522747 : result->Set(size++, type);
935 21522747 : return size;
936 : }
937 :
938 21578000 : Type Type::NormalizeUnion(UnionType* unioned, int size, Zone* zone) {
939 : DCHECK_LE(1, size);
940 : DCHECK(unioned->Get(0).IsBitset());
941 : // If the union has just one element, return it.
942 21578000 : if (size == 1) {
943 : return unioned->Get(0);
944 : }
945 : bitset bits = unioned->Get(0).AsBitset();
946 : // If the union only consists of a range, we can get rid of the union.
947 19790095 : if (size == 2 && bits == BitsetType::kNone) {
948 1918188 : if (unioned->Get(1).IsRange()) {
949 : return Type::Range(unioned->Get(1).AsRange()->Min(),
950 : unioned->Get(1).AsRange()->Max(), zone);
951 : }
952 : }
953 : unioned->Shrink(size);
954 : SLOW_DCHECK(unioned->Wellformed());
955 17873348 : return Type(unioned);
956 : }
957 :
958 87176 : int Type::NumConstants() const {
959 : DisallowHeapAllocation no_allocation;
960 172972 : if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
961 : return 1;
962 84926 : } else if (this->IsUnion()) {
963 : int result = 0;
964 29092 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
965 11934 : if (this->AsUnion()->Get(i).IsHeapConstant()) ++result;
966 : }
967 : return result;
968 : } else {
969 : return 0;
970 : }
971 : }
972 :
973 : // -----------------------------------------------------------------------------
974 : // Printing.
975 :
976 142389 : const char* BitsetType::Name(bitset bits) {
977 142389 : switch (bits) {
978 : #define RETURN_NAMED_TYPE(type, value) \
979 : case k##type: \
980 : return #type;
981 0 : PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
982 0 : INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
983 : #undef RETURN_NAMED_TYPE
984 :
985 : default:
986 0 : return nullptr;
987 : }
988 : }
989 :
990 142389 : void BitsetType::Print(std::ostream& os, // NOLINT
991 : bitset bits) {
992 : DisallowHeapAllocation no_allocation;
993 142389 : const char* name = Name(bits);
994 142389 : if (name != nullptr) {
995 142389 : os << name;
996 : return;
997 : }
998 :
999 : // clang-format off
1000 : static const bitset named_bitsets[] = {
1001 : #define BITSET_CONSTANT(type, value) k##type,
1002 : INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
1003 : PROPER_BITSET_TYPE_LIST(BITSET_CONSTANT)
1004 : #undef BITSET_CONSTANT
1005 : };
1006 : // clang-format on
1007 :
1008 : bool is_first = true;
1009 0 : os << "(";
1010 0 : for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
1011 0 : bitset subset = named_bitsets[i];
1012 0 : if ((bits & subset) == subset) {
1013 0 : if (!is_first) os << " | ";
1014 : is_first = false;
1015 0 : os << Name(subset);
1016 0 : bits -= subset;
1017 : }
1018 : }
1019 : DCHECK_EQ(0, bits);
1020 0 : os << ")";
1021 : }
1022 :
1023 142517 : void Type::PrintTo(std::ostream& os) const {
1024 : DisallowHeapAllocation no_allocation;
1025 142517 : if (this->IsBitset()) {
1026 142389 : BitsetType::Print(os, this->AsBitset());
1027 128 : } else if (this->IsHeapConstant()) {
1028 160 : os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
1029 48 : } else if (this->IsOtherNumberConstant()) {
1030 : os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
1031 0 : << ")";
1032 48 : } else if (this->IsRange()) {
1033 29 : std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1034 29 : std::streamsize saved_precision = os.precision(0);
1035 : os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1036 29 : << ")";
1037 29 : os.flags(saved_flags);
1038 29 : os.precision(saved_precision);
1039 19 : } else if (this->IsUnion()) {
1040 19 : os << "(";
1041 95 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1042 38 : Type type_i = this->AsUnion()->Get(i);
1043 38 : if (i > 0) os << " | ";
1044 38 : os << type_i;
1045 : }
1046 19 : os << ")";
1047 0 : } else if (this->IsTuple()) {
1048 0 : os << "<";
1049 0 : for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
1050 0 : Type type_i = this->AsTuple()->Element(i);
1051 0 : if (i > 0) os << ", ";
1052 0 : os << type_i;
1053 : }
1054 0 : os << ">";
1055 : } else {
1056 0 : UNREACHABLE();
1057 : }
1058 142517 : }
1059 :
1060 : #ifdef DEBUG
1061 : void Type::Print() const {
1062 : StdoutStream os;
1063 : PrintTo(os);
1064 : os << std::endl;
1065 : }
1066 : void BitsetType::Print(bitset bits) {
1067 : StdoutStream os;
1068 : Print(os, bits);
1069 : os << std::endl;
1070 : }
1071 : #endif
1072 :
1073 6850163 : BitsetType::bitset BitsetType::SignedSmall() {
1074 6850163 : return SmiValuesAre31Bits() ? kSigned31 : kSigned32;
1075 : }
1076 :
1077 231870 : BitsetType::bitset BitsetType::UnsignedSmall() {
1078 231870 : return SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
1079 : }
1080 :
1081 : // static
1082 1381 : Type Type::Tuple(Type first, Type second, Type third, Zone* zone) {
1083 1381 : TupleType* tuple = TupleType::New(3, zone);
1084 : tuple->InitElement(0, first);
1085 : tuple->InitElement(1, second);
1086 : tuple->InitElement(2, third);
1087 1381 : return FromTypeBase(tuple);
1088 : }
1089 :
1090 : // static
1091 0 : Type Type::OtherNumberConstant(double value, Zone* zone) {
1092 1886576 : return FromTypeBase(OtherNumberConstantType::New(value, zone));
1093 : }
1094 :
1095 : // static
1096 10216281 : Type Type::HeapConstant(JSHeapBroker* broker, Handle<i::Object> value,
1097 : Zone* zone) {
1098 : return FromTypeBase(
1099 20432609 : HeapConstantType::New(HeapObjectRef(broker, value), zone));
1100 : }
1101 :
1102 : // static
1103 0 : Type Type::HeapConstant(const HeapObjectRef& value, Zone* zone) {
1104 8506433 : return HeapConstantType::New(value, zone);
1105 : }
1106 :
1107 : // static
1108 9698447 : Type Type::Range(double min, double max, Zone* zone) {
1109 9698465 : return FromTypeBase(RangeType::New(min, max, zone));
1110 : }
1111 :
1112 : // static
1113 0 : Type Type::Range(RangeType::Limits lims, Zone* zone) {
1114 4279602 : return FromTypeBase(RangeType::New(lims, zone));
1115 : }
1116 :
1117 : // static
1118 0 : Type Type::Union(int length, Zone* zone) {
1119 0 : return FromTypeBase(UnionType::New(length, zone));
1120 : }
1121 :
1122 2394893 : const HeapConstantType* Type::AsHeapConstant() const {
1123 : DCHECK(IsKind(TypeBase::kHeapConstant));
1124 2394893 : return static_cast<const HeapConstantType*>(ToTypeBase());
1125 : }
1126 :
1127 57 : const OtherNumberConstantType* Type::AsOtherNumberConstant() const {
1128 : DCHECK(IsKind(TypeBase::kOtherNumberConstant));
1129 57 : return static_cast<const OtherNumberConstantType*>(ToTypeBase());
1130 : }
1131 :
1132 45247 : const RangeType* Type::AsRange() const {
1133 : DCHECK(IsKind(TypeBase::kRange));
1134 45247 : return static_cast<const RangeType*>(ToTypeBase());
1135 : }
1136 :
1137 8286 : const TupleType* Type::AsTuple() const {
1138 : DCHECK(IsKind(TypeBase::kTuple));
1139 8286 : return static_cast<const TupleType*>(ToTypeBase());
1140 : }
1141 :
1142 5224 : const UnionType* Type::AsUnion() const {
1143 : DCHECK(IsKind(TypeBase::kUnion));
1144 5224 : return static_cast<const UnionType*>(ToTypeBase());
1145 : }
1146 :
1147 142345 : std::ostream& operator<<(std::ostream& os, Type type) {
1148 142345 : type.PrintTo(os);
1149 142345 : return os;
1150 : }
1151 :
1152 : } // namespace compiler
1153 : } // namespace internal
1154 122004 : } // namespace v8
|