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 3071437 : 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 1889240 : if (lhs.min < rhs.min) result.min = rhs.min;
26 1889240 : 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 3891264 : if (lhs.IsEmpty()) return rhs;
33 3891273 : if (rhs.IsEmpty()) return lhs;
34 : Limits result(lhs);
35 3258573 : if (lhs.min > rhs.min) result.min = rhs.min;
36 3258573 : 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 1256336 : .IsEmpty();
45 : }
46 :
47 0 : bool Type::Contains(const RangeType* lhs, const RangeType* rhs) {
48 : DisallowHeapAllocation no_allocation;
49 23487461 : return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
50 : }
51 :
52 : // -----------------------------------------------------------------------------
53 : // Min and Max computation.
54 :
55 13382892 : double Type::Min() const {
56 : DCHECK(this->Is(Number()));
57 : DCHECK(!this->Is(NaN()));
58 13965791 : if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
59 12799993 : if (this->IsUnion()) {
60 49784 : double min = +V8_INFINITY;
61 207952 : for (int i = 1, n = AsUnion()->Length(); i < n; ++i) {
62 158169 : min = std::min(min, AsUnion()->Get(i).Min());
63 : }
64 49783 : Type bitset = AsUnion()->Get(0);
65 68664 : if (!bitset.Is(NaN())) min = std::min(min, bitset.Min());
66 49781 : return min;
67 : }
68 25460789 : if (this->IsRange()) return this->AsRange()->Min();
69 : DCHECK(this->IsOtherNumberConstant());
70 39629 : return this->AsOtherNumberConstant()->Value();
71 : }
72 :
73 13648223 : double Type::Max() const {
74 : DCHECK(this->Is(Number()));
75 : DCHECK(!this->Is(NaN()));
76 14416177 : if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
77 12880269 : if (this->IsUnion()) {
78 45309 : double max = -V8_INFINITY;
79 194535 : for (int i = 1, n = this->AsUnion()->Length(); i < n; ++i) {
80 149224 : max = std::max(max, this->AsUnion()->Get(i).Max());
81 : }
82 45311 : Type bitset = this->AsUnion()->Get(0);
83 59710 : if (!bitset.Is(NaN())) max = std::max(max, bitset.Max());
84 45311 : return max;
85 : }
86 25634095 : if (this->IsRange()) return this->AsRange()->Max();
87 : DCHECK(this->IsOtherNumberConstant());
88 35825 : return this->AsOtherNumberConstant()->Value();
89 : }
90 :
91 : // -----------------------------------------------------------------------------
92 : // Glb and lub computation.
93 :
94 : // The largest bitset subsumed by this type.
95 134709164 : Type::bitset Type::BitsetGlb() const {
96 : DisallowHeapAllocation no_allocation;
97 : // Fast case.
98 134709164 : if (IsBitset()) {
99 40264595 : return AsBitset();
100 94444569 : } else if (IsUnion()) {
101 : SLOW_DCHECK(AsUnion()->Wellformed());
102 57169127 : return AsUnion()->Get(0).BitsetGlb() |
103 28584648 : AsUnion()->Get(1).BitsetGlb(); // Shortcut.
104 65860304 : } else if (IsRange()) {
105 40749855 : bitset glb = BitsetType::Glb(AsRange()->Min(), AsRange()->Max());
106 40750161 : return glb;
107 : } else {
108 : return BitsetType::kNone;
109 : }
110 : }
111 :
112 : // The smallest bitset subsuming this type, possibly not a proper one.
113 374728549 : Type::bitset Type::BitsetLub() const {
114 : DisallowHeapAllocation no_allocation;
115 616001755 : if (IsBitset()) return AsBitset();
116 133455343 : if (IsUnion()) {
117 : // Take the representation from the first element, which is always
118 : // a bitset.
119 11439379 : int bitset = AsUnion()->Get(0).BitsetLub();
120 74212769 : for (int i = 0, n = AsUnion()->Length(); i < n; ++i) {
121 : // Other elements only contribute their semantic part.
122 31388139 : bitset |= AsUnion()->Get(i).BitsetLub();
123 : }
124 11439632 : return bitset;
125 : }
126 162417634 : if (IsHeapConstant()) return AsHeapConstant()->Lub();
127 81614294 : if (IsOtherNumberConstant()) {
128 : return AsOtherNumberConstant()->Lub();
129 : }
130 138320292 : if (IsRange()) return AsRange()->Lub();
131 4140 : 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 19002070 : Type::bitset BitsetType::Lub(const MapRefLike& map) {
139 19002070 : switch (map.instance_type()) {
140 : case CONS_STRING_TYPE:
141 : case CONS_ONE_BYTE_STRING_TYPE:
142 : case THIN_STRING_TYPE:
143 : case THIN_ONE_BYTE_STRING_TYPE:
144 : case SLICED_STRING_TYPE:
145 : case SLICED_ONE_BYTE_STRING_TYPE:
146 : case EXTERNAL_STRING_TYPE:
147 : case EXTERNAL_ONE_BYTE_STRING_TYPE:
148 : case UNCACHED_EXTERNAL_STRING_TYPE:
149 : case UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE:
150 : case STRING_TYPE:
151 : case ONE_BYTE_STRING_TYPE:
152 : return kString;
153 : case EXTERNAL_INTERNALIZED_STRING_TYPE:
154 : case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
155 : case UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE:
156 : case UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
157 : case INTERNALIZED_STRING_TYPE:
158 : case ONE_BYTE_INTERNALIZED_STRING_TYPE:
159 5023109 : return kInternalizedString;
160 : case SYMBOL_TYPE:
161 598 : return kSymbol;
162 : case BIGINT_TYPE:
163 2385 : return kBigInt;
164 : case ODDBALL_TYPE:
165 10705200 : switch (map.oddball_type()) {
166 : case OddballType::kNone:
167 : break;
168 : case OddballType::kHole:
169 : return kHole;
170 : case OddballType::kBoolean:
171 6628392 : return kBoolean;
172 : case OddballType::kNull:
173 32594 : return kNull;
174 : case OddballType::kUndefined:
175 966152 : return kUndefined;
176 : case OddballType::kUninitialized:
177 : case OddballType::kOther:
178 : // TODO(neis): We should add a kOtherOddball type.
179 1487286 : return kOtherInternal;
180 : }
181 0 : UNREACHABLE();
182 : case HEAP_NUMBER_TYPE:
183 0 : return kNumber;
184 : case JS_OBJECT_TYPE:
185 : case JS_ARGUMENTS_TYPE:
186 : case JS_ERROR_TYPE:
187 : case JS_GLOBAL_OBJECT_TYPE:
188 : case JS_GLOBAL_PROXY_TYPE:
189 : case JS_API_OBJECT_TYPE:
190 : case JS_SPECIAL_API_OBJECT_TYPE:
191 1208275 : if (map.is_undetectable()) {
192 : // Currently we assume that every undetectable receiver is also
193 : // callable, which is what we need to support document.all. We
194 : // could add another Type bit to support other use cases in the
195 : // future if necessary.
196 : DCHECK(map.is_callable());
197 : return kOtherUndetectable;
198 : }
199 1208209 : if (map.is_callable()) {
200 : return kOtherCallable;
201 : }
202 1208209 : return kOtherObject;
203 : case JS_ARRAY_TYPE:
204 566690 : return kArray;
205 : case JS_VALUE_TYPE:
206 : case JS_MESSAGE_OBJECT_TYPE:
207 : case JS_DATE_TYPE:
208 : #ifdef V8_INTL_SUPPORT
209 : case JS_INTL_V8_BREAK_ITERATOR_TYPE:
210 : case JS_INTL_COLLATOR_TYPE:
211 : case JS_INTL_DATE_TIME_FORMAT_TYPE:
212 : case JS_INTL_LIST_FORMAT_TYPE:
213 : case JS_INTL_LOCALE_TYPE:
214 : case JS_INTL_NUMBER_FORMAT_TYPE:
215 : case JS_INTL_PLURAL_RULES_TYPE:
216 : case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
217 : case JS_INTL_SEGMENT_ITERATOR_TYPE:
218 : case JS_INTL_SEGMENTER_TYPE:
219 : #endif // V8_INTL_SUPPORT
220 : case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
221 : case JS_GENERATOR_OBJECT_TYPE:
222 : case JS_ASYNC_FUNCTION_OBJECT_TYPE:
223 : case JS_ASYNC_GENERATOR_OBJECT_TYPE:
224 : case JS_MODULE_NAMESPACE_TYPE:
225 : case JS_ARRAY_BUFFER_TYPE:
226 : case JS_ARRAY_ITERATOR_TYPE:
227 : case JS_REGEXP_TYPE: // TODO(rossberg): there should be a RegExp type.
228 : case JS_REGEXP_STRING_ITERATOR_TYPE:
229 : case JS_TYPED_ARRAY_TYPE:
230 : case JS_DATA_VIEW_TYPE:
231 : case JS_SET_TYPE:
232 : case JS_MAP_TYPE:
233 : case JS_SET_KEY_VALUE_ITERATOR_TYPE:
234 : case JS_SET_VALUE_ITERATOR_TYPE:
235 : case JS_MAP_KEY_ITERATOR_TYPE:
236 : case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
237 : case JS_MAP_VALUE_ITERATOR_TYPE:
238 : case JS_STRING_ITERATOR_TYPE:
239 : case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
240 : case JS_FINALIZATION_GROUP_TYPE:
241 : case JS_FINALIZATION_GROUP_CLEANUP_ITERATOR_TYPE:
242 : case JS_WEAK_MAP_TYPE:
243 : case JS_WEAK_REF_TYPE:
244 : case JS_WEAK_SET_TYPE:
245 : case JS_PROMISE_TYPE:
246 : case WASM_EXCEPTION_TYPE:
247 : case WASM_GLOBAL_TYPE:
248 : case WASM_INSTANCE_TYPE:
249 : case WASM_MEMORY_TYPE:
250 : case WASM_MODULE_TYPE:
251 : case WASM_TABLE_TYPE:
252 : case WEAK_CELL_TYPE:
253 : DCHECK(!map.is_callable());
254 : DCHECK(!map.is_undetectable());
255 4228 : return kOtherObject;
256 : case JS_BOUND_FUNCTION_TYPE:
257 : DCHECK(!map.is_undetectable());
258 164 : return kBoundFunction;
259 : case JS_FUNCTION_TYPE:
260 : DCHECK(!map.is_undetectable());
261 551088 : return kFunction;
262 : case JS_PROXY_TYPE:
263 : DCHECK(!map.is_undetectable());
264 394 : if (map.is_callable()) return kCallableProxy;
265 190 : return kOtherProxy;
266 : case MAP_TYPE:
267 : case ALLOCATION_SITE_TYPE:
268 : case ACCESSOR_INFO_TYPE:
269 : case SHARED_FUNCTION_INFO_TYPE:
270 : case FUNCTION_TEMPLATE_INFO_TYPE:
271 : case FUNCTION_TEMPLATE_RARE_DATA_TYPE:
272 : case ACCESSOR_PAIR_TYPE:
273 : case EMBEDDER_DATA_ARRAY_TYPE:
274 : case FIXED_ARRAY_TYPE:
275 : case HASH_TABLE_TYPE:
276 : case ORDERED_HASH_MAP_TYPE:
277 : case ORDERED_HASH_SET_TYPE:
278 : case ORDERED_NAME_DICTIONARY_TYPE:
279 : case NAME_DICTIONARY_TYPE:
280 : case GLOBAL_DICTIONARY_TYPE:
281 : case NUMBER_DICTIONARY_TYPE:
282 : case SIMPLE_NUMBER_DICTIONARY_TYPE:
283 : case STRING_TABLE_TYPE:
284 : case EPHEMERON_HASH_TABLE_TYPE:
285 : case WEAK_FIXED_ARRAY_TYPE:
286 : case WEAK_ARRAY_LIST_TYPE:
287 : case FIXED_DOUBLE_ARRAY_TYPE:
288 : case FEEDBACK_METADATA_TYPE:
289 : case BYTE_ARRAY_TYPE:
290 : case BYTECODE_ARRAY_TYPE:
291 : case OBJECT_BOILERPLATE_DESCRIPTION_TYPE:
292 : case ARRAY_BOILERPLATE_DESCRIPTION_TYPE:
293 : case DESCRIPTOR_ARRAY_TYPE:
294 : case TRANSITION_ARRAY_TYPE:
295 : case FEEDBACK_CELL_TYPE:
296 : case CLOSURE_FEEDBACK_CELL_ARRAY_TYPE:
297 : case FEEDBACK_VECTOR_TYPE:
298 : case PROPERTY_ARRAY_TYPE:
299 : case FOREIGN_TYPE:
300 : case SCOPE_INFO_TYPE:
301 : case SCRIPT_CONTEXT_TABLE_TYPE:
302 : case AWAIT_CONTEXT_TYPE:
303 : case BLOCK_CONTEXT_TYPE:
304 : case CATCH_CONTEXT_TYPE:
305 : case DEBUG_EVALUATE_CONTEXT_TYPE:
306 : case EVAL_CONTEXT_TYPE:
307 : case FUNCTION_CONTEXT_TYPE:
308 : case MODULE_CONTEXT_TYPE:
309 : case NATIVE_CONTEXT_TYPE:
310 : case SCRIPT_CONTEXT_TYPE:
311 : case WITH_CONTEXT_TYPE:
312 : case SCRIPT_TYPE:
313 : case CODE_TYPE:
314 : case PROPERTY_CELL_TYPE:
315 : case MODULE_TYPE:
316 : case MODULE_INFO_ENTRY_TYPE:
317 : case CELL_TYPE:
318 : case PREPARSE_DATA_TYPE:
319 : case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE:
320 : case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE:
321 939366 : return kOtherInternal;
322 :
323 : // Remaining instance types are unsupported for now. If any of them do
324 : // require bit set types, they should get kOtherInternal.
325 : case MUTABLE_HEAP_NUMBER_TYPE:
326 : case FREE_SPACE_TYPE:
327 : #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
328 : case FIXED_##TYPE##_ARRAY_TYPE:
329 :
330 : TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
331 : #undef FIXED_TYPED_ARRAY_CASE
332 : case FILLER_TYPE:
333 : case ACCESS_CHECK_INFO_TYPE:
334 : case ASM_WASM_DATA_TYPE:
335 : case CALL_HANDLER_INFO_TYPE:
336 : case INTERCEPTOR_INFO_TYPE:
337 : case OBJECT_TEMPLATE_INFO_TYPE:
338 : case ALLOCATION_MEMENTO_TYPE:
339 : case ALIASED_ARGUMENTS_ENTRY_TYPE:
340 : case PROMISE_CAPABILITY_TYPE:
341 : case PROMISE_REACTION_TYPE:
342 : case CLASS_POSITIONS_TYPE:
343 : case DEBUG_INFO_TYPE:
344 : case STACK_FRAME_INFO_TYPE:
345 : case STACK_TRACE_FRAME_TYPE:
346 : case SMALL_ORDERED_HASH_MAP_TYPE:
347 : case SMALL_ORDERED_HASH_SET_TYPE:
348 : case SMALL_ORDERED_NAME_DICTIONARY_TYPE:
349 : case PROTOTYPE_INFO_TYPE:
350 : case INTERPRETER_DATA_TYPE:
351 : case TUPLE2_TYPE:
352 : case TUPLE3_TYPE:
353 : case ENUM_CACHE_TYPE:
354 : case WASM_DEBUG_INFO_TYPE:
355 : case WASM_EXCEPTION_TAG_TYPE:
356 : case WASM_EXPORTED_FUNCTION_DATA_TYPE:
357 : case LOAD_HANDLER_TYPE:
358 : case STORE_HANDLER_TYPE:
359 : case ASYNC_GENERATOR_REQUEST_TYPE:
360 : case CODE_DATA_CONTAINER_TYPE:
361 : case CALLBACK_TASK_TYPE:
362 : case CALLABLE_TASK_TYPE:
363 : case PROMISE_FULFILL_REACTION_JOB_TASK_TYPE:
364 : case PROMISE_REJECT_REACTION_JOB_TASK_TYPE:
365 : case PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE:
366 : case FINALIZATION_GROUP_CLEANUP_JOB_TASK_TYPE:
367 0 : UNREACHABLE();
368 : }
369 0 : UNREACHABLE();
370 : }
371 :
372 : // Explicit instantiation.
373 : template Type::bitset BitsetType::Lub<MapRef>(const MapRef& map);
374 :
375 0 : Type::bitset BitsetType::Lub(double value) {
376 : DisallowHeapAllocation no_allocation;
377 0 : if (IsMinusZero(value)) return kMinusZero;
378 0 : if (std::isnan(value)) return kNaN;
379 0 : if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
380 : return kOtherNumber;
381 : }
382 :
383 : // Minimum values of plain numeric bitsets.
384 : const BitsetType::Boundary BitsetType::BoundariesArray[] = {
385 : {kOtherNumber, kPlainNumber, -V8_INFINITY},
386 : {kOtherSigned32, kNegative32, kMinInt},
387 : {kNegative31, kNegative31, -0x40000000},
388 : {kUnsigned30, kUnsigned30, 0},
389 : {kOtherUnsigned31, kUnsigned31, 0x40000000},
390 : {kOtherUnsigned32, kUnsigned32, 0x80000000},
391 : {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
392 :
393 : const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
394 :
395 : size_t BitsetType::BoundariesSize() {
396 : // Windows doesn't like arraysize here.
397 : // return arraysize(BoundariesArray);
398 : return 7;
399 : }
400 :
401 12193 : Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
402 : DCHECK_IMPLIES(bits & kOtherString, (bits & kString) == kString);
403 : DisallowHeapAllocation no_allocation;
404 12193 : if (!(bits & kPlainNumber)) return bits; // Shortcut.
405 : const Boundary* boundaries = Boundaries();
406 0 : for (size_t i = 0; i < BoundariesSize(); ++i) {
407 : DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
408 0 : if (bits & boundaries[i].internal) bits |= boundaries[i].external;
409 : }
410 : return bits;
411 : }
412 :
413 0 : Type::bitset BitsetType::Lub(double min, double max) {
414 : DisallowHeapAllocation no_allocation;
415 : int lub = kNone;
416 : const Boundary* mins = Boundaries();
417 :
418 200224170 : for (size_t i = 1; i < BoundariesSize(); ++i) {
419 101255457 : if (min < mins[i].min) {
420 58094964 : lub |= mins[i - 1].internal;
421 58094964 : if (max < mins[i].min) return lub;
422 : }
423 : }
424 9685138 : return lub | mins[BoundariesSize() - 1].internal;
425 : }
426 :
427 15550330 : Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; }
428 :
429 40748757 : Type::bitset BitsetType::Glb(double min, double max) {
430 : DisallowHeapAllocation no_allocation;
431 : int glb = kNone;
432 : const Boundary* mins = Boundaries();
433 :
434 : // If the range does not touch 0, the bound is empty.
435 40748757 : if (max < -1 || min > 0) return glb;
436 :
437 137158700 : for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
438 122217117 : if (min <= mins[i].min) {
439 92335600 : if (max + 1 < mins[i + 1].min) break;
440 77292454 : glb |= mins[i].external;
441 : }
442 : }
443 : // OtherNumber also contains float numbers, so it can never be
444 : // in the greatest lower bound.
445 29984729 : return glb & ~(kOtherNumber);
446 : }
447 :
448 7246832 : double BitsetType::Min(bitset bits) {
449 : DisallowHeapAllocation no_allocation;
450 : DCHECK(Is(bits, kNumber));
451 : DCHECK(!Is(bits, kNaN));
452 : const Boundary* mins = Boundaries();
453 7246832 : bool mz = bits & kMinusZero;
454 24187290 : for (size_t i = 0; i < BoundariesSize(); ++i) {
455 31393918 : if (Is(mins[i].internal, bits)) {
456 7279525 : return mz ? std::min(0.0, mins[i].min) : mins[i].min;
457 : }
458 : }
459 : DCHECK(mz);
460 : return 0;
461 : }
462 :
463 7431192 : double BitsetType::Max(bitset bits) {
464 : DisallowHeapAllocation no_allocation;
465 : DCHECK(Is(bits, kNumber));
466 : DCHECK(!Is(bits, kNaN));
467 : const Boundary* mins = Boundaries();
468 7431192 : bool mz = bits & kMinusZero;
469 7431192 : if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) {
470 : return +V8_INFINITY;
471 : }
472 11096361 : for (size_t i = BoundariesSize() - 1; i-- > 0;) {
473 22161236 : if (Is(mins[i].internal, bits)) {
474 6257492 : return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
475 : }
476 : }
477 : DCHECK(mz);
478 : return 0;
479 : }
480 :
481 : // static
482 1735499 : bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
483 : // Not an integer, not NaN, and not -0.
484 3470998 : return !std::isnan(value) && !RangeType::IsInteger(value) &&
485 1735499 : !IsMinusZero(value);
486 : }
487 :
488 0 : HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
489 : const HeapObjectRef& heap_ref)
490 18989865 : : TypeBase(kHeapConstant), bitset_(bitset), heap_ref_(heap_ref) {}
491 :
492 2058440 : Handle<HeapObject> HeapConstantType::Value() const {
493 23548633 : return heap_ref_.object();
494 : }
495 :
496 : // -----------------------------------------------------------------------------
497 : // Predicates.
498 :
499 15370008 : bool Type::SimplyEquals(Type that) const {
500 : DisallowHeapAllocation no_allocation;
501 15370008 : if (this->IsHeapConstant()) {
502 23059225 : return that.IsHeapConstant() &&
503 10745056 : this->AsHeapConstant()->Value().address() ==
504 10745051 : that.AsHeapConstant()->Value().address();
505 : }
506 3055834 : if (this->IsOtherNumberConstant()) {
507 3864590 : return that.IsOtherNumberConstant() &&
508 : this->AsOtherNumberConstant()->Value() ==
509 : that.AsOtherNumberConstant()->Value();
510 : }
511 332911 : if (this->IsRange()) {
512 665837 : if (that.IsHeapConstant() || that.IsOtherNumberConstant()) return false;
513 : }
514 0 : if (this->IsTuple()) {
515 0 : if (!that.IsTuple()) return false;
516 : const TupleType* this_tuple = this->AsTuple();
517 : const TupleType* that_tuple = that.AsTuple();
518 0 : if (this_tuple->Arity() != that_tuple->Arity()) {
519 : return false;
520 : }
521 0 : for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
522 0 : if (!this_tuple->Element(i).Equals(that_tuple->Element(i))) return false;
523 : }
524 : return true;
525 : }
526 0 : UNREACHABLE();
527 : }
528 :
529 : // Check if [this] <= [that].
530 401148133 : bool Type::SlowIs(Type that) const {
531 : DisallowHeapAllocation no_allocation;
532 :
533 : // Fast bitset cases
534 401148133 : if (that.IsBitset()) {
535 555878324 : return BitsetType::Is(this->BitsetLub(), that.AsBitset());
536 : }
537 :
538 123205442 : if (this->IsBitset()) {
539 70180619 : return BitsetType::Is(this->AsBitset(), that.BitsetGlb());
540 : }
541 :
542 : // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T)
543 88114439 : if (this->IsUnion()) {
544 25075521 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
545 18983863 : if (!this->AsUnion()->Get(i).Is(that)) return false;
546 : }
547 : return true;
548 : }
549 :
550 : // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn)
551 73761096 : if (that.IsUnion()) {
552 51727988 : for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
553 27836601 : if (this->Is(that.AsUnion()->Get(i))) return true;
554 24250685 : if (i > 1 && this->IsRange()) return false; // Shortcut.
555 : }
556 : return false;
557 : }
558 :
559 61104962 : if (that.IsRange()) {
560 65995191 : return (this->IsRange() && Contains(that.AsRange(), this->AsRange()));
561 : }
562 18597232 : if (this->IsRange()) return false;
563 :
564 14997115 : return this->SimplyEquals(that);
565 : }
566 :
567 : // Check if [this] and [that] overlap.
568 21109242 : bool Type::Maybe(Type that) const {
569 : DisallowHeapAllocation no_allocation;
570 :
571 21109242 : if (BitsetType::IsNone(this->BitsetLub() & that.BitsetLub())) return false;
572 :
573 : // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T)
574 9926905 : if (this->IsUnion()) {
575 1120914 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
576 696641 : if (this->AsUnion()->Get(i).Maybe(that)) return true;
577 : }
578 : return false;
579 : }
580 :
581 : // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn)
582 9496383 : if (that.IsUnion()) {
583 810188 : for (int i = 0, n = that.AsUnion()->Length(); i < n; ++i) {
584 : if (this->Maybe(that.AsUnion()->Get(i))) return true;
585 : }
586 : return false;
587 : }
588 :
589 9277099 : if (this->IsBitset() && that.IsBitset()) return true;
590 :
591 4950620 : if (this->IsRange()) {
592 2381302 : if (that.IsRange()) {
593 1256336 : return Overlap(this->AsRange(), that.AsRange());
594 : }
595 1124966 : if (that.IsBitset()) {
596 : bitset number_bits = BitsetType::NumberBits(that.AsBitset());
597 792523 : if (number_bits == BitsetType::kNone) {
598 : return false;
599 : }
600 1584983 : double min = std::max(BitsetType::Min(number_bits), this->Min());
601 1584877 : double max = std::min(BitsetType::Max(number_bits), this->Max());
602 792417 : return min <= max;
603 : }
604 : }
605 2901761 : if (that.IsRange()) {
606 1079563 : return that.Maybe(*this); // This case is handled above.
607 : }
608 :
609 1822198 : if (this->IsBitset() || that.IsBitset()) return true;
610 :
611 371069 : return this->SimplyEquals(that);
612 : }
613 :
614 : // Return the range in [this], or [nullptr].
615 39178505 : Type Type::GetRange() const {
616 : DisallowHeapAllocation no_allocation;
617 39178505 : if (this->IsRange()) return *this;
618 46211926 : if (this->IsUnion() && this->AsUnion()->Get(1).IsRange()) {
619 : return this->AsUnion()->Get(1);
620 : }
621 21721139 : return nullptr;
622 : }
623 :
624 0 : bool UnionType::Wellformed() const {
625 : DisallowHeapAllocation no_allocation;
626 : // This checks the invariants of the union representation:
627 : // 1. There are at least two elements.
628 : // 2. The first element is a bitset, no other element is a bitset.
629 : // 3. At most one element is a range, and it must be the second one.
630 : // 4. No element is itself a union.
631 : // 5. No element (except the bitset) is a subtype of any other.
632 : // 6. If there is a range, then the bitset type does not contain
633 : // plain number bits.
634 : DCHECK_LE(2, this->Length()); // (1)
635 : DCHECK(this->Get(0).IsBitset()); // (2a)
636 :
637 : for (int i = 0; i < this->Length(); ++i) {
638 : if (i != 0) DCHECK(!this->Get(i).IsBitset()); // (2b)
639 : if (i != 1) DCHECK(!this->Get(i).IsRange()); // (3)
640 : DCHECK(!this->Get(i).IsUnion()); // (4)
641 : for (int j = 0; j < this->Length(); ++j) {
642 : if (i != j && i != 0) DCHECK(!this->Get(i).Is(this->Get(j))); // (5)
643 : }
644 : }
645 : DCHECK(!this->Get(1).IsRange() ||
646 : (BitsetType::NumberBits(this->Get(0).AsBitset()) ==
647 : BitsetType::kNone)); // (6)
648 0 : return true;
649 : }
650 :
651 : // -----------------------------------------------------------------------------
652 : // Union and intersection
653 :
654 27381185 : Type Type::Intersect(Type type1, Type type2, Zone* zone) {
655 : // Fast case: bit sets.
656 43986137 : if (type1.IsBitset() && type2.IsBitset()) {
657 15901685 : return NewBitset(type1.AsBitset() & type2.AsBitset());
658 : }
659 :
660 : // Fast case: top or bottom types.
661 22941083 : if (type1.IsNone() || type2.IsAny()) return type1; // Shortcut.
662 11251221 : if (type2.IsNone() || type1.IsAny()) return type2; // Shortcut.
663 :
664 : // Semi-fast case.
665 11167531 : if (type1.Is(type2)) return type1;
666 3512543 : if (type2.Is(type1)) return type2;
667 :
668 : // Slow case: create union.
669 :
670 : // Semantic subtyping check - this is needed for consistency with the
671 : // semi-fast case above.
672 1815114 : if (type1.Is(type2)) {
673 0 : type2 = Any();
674 1815133 : } else if (type2.Is(type1)) {
675 0 : type1 = Any();
676 : }
677 :
678 1815133 : bitset bits = type1.BitsetGlb() & type2.BitsetGlb();
679 1815084 : int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
680 1815084 : int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
681 : int size;
682 1815084 : if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
683 1815084 : if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
684 1815084 : UnionType* result = UnionType::New(size, zone);
685 : size = 0;
686 :
687 : // Deal with bitsets.
688 : result->Set(size++, NewBitset(bits));
689 :
690 1815070 : RangeType::Limits lims = RangeType::Limits::Empty();
691 1815070 : size = IntersectAux(type1, type2, result, size, &lims, zone);
692 :
693 : // If the range is not empty, then insert it into the union and
694 : // remove the number bits from the bitset.
695 1815101 : if (!lims.IsEmpty()) {
696 632588 : size = UpdateRange(Type::Range(lims, zone), result, size, zone);
697 :
698 : // Remove the number bits.
699 : bitset number_bits = BitsetType::NumberBits(bits);
700 632593 : bits &= ~number_bits;
701 : result->Set(0, NewBitset(bits));
702 : }
703 1815097 : return NormalizeUnion(result, size, zone);
704 : }
705 :
706 632591 : int Type::UpdateRange(Type range, UnionType* result, int size, Zone* zone) {
707 632591 : if (size == 1) {
708 621933 : result->Set(size++, range);
709 : } else {
710 : // Make space for the range.
711 10658 : result->Set(size++, result->Get(1));
712 : result->Set(1, range);
713 : }
714 :
715 : // Remove any components that just got subsumed.
716 647533 : for (int i = 2; i < size;) {
717 29885 : if (result->Get(i).Is(range)) {
718 0 : result->Set(i, result->Get(--size));
719 : } else {
720 14942 : ++i;
721 : }
722 : }
723 632590 : return size;
724 : }
725 :
726 313472 : RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
727 : bitset number_bits = BitsetType::NumberBits(bits);
728 :
729 313472 : if (number_bits == BitsetType::kNone) {
730 : return RangeType::Limits::Empty();
731 : }
732 :
733 : return RangeType::Limits(BitsetType::Min(number_bits),
734 313472 : BitsetType::Max(number_bits));
735 : }
736 :
737 313470 : RangeType::Limits Type::IntersectRangeAndBitset(Type range, Type bitset,
738 : Zone* zone) {
739 : RangeType::Limits range_lims(range.AsRange());
740 313470 : RangeType::Limits bitset_lims = ToLimits(bitset.AsBitset(), zone);
741 313479 : return RangeType::Limits::Intersect(range_lims, bitset_lims);
742 : }
743 :
744 3192944 : int Type::IntersectAux(Type lhs, Type rhs, UnionType* result, int size,
745 : RangeType::Limits* lims, Zone* zone) {
746 3192944 : if (lhs.IsUnion()) {
747 2313660 : for (int i = 0, n = lhs.AsUnion()->Length(); i < n; ++i) {
748 964546 : size = IntersectAux(lhs.AsUnion()->Get(i), rhs, result, size, lims, zone);
749 : }
750 : return size;
751 : }
752 2808370 : if (rhs.IsUnion()) {
753 552339 : for (int i = 0, n = rhs.AsUnion()->Length(); i < n; ++i) {
754 224505 : size = IntersectAux(lhs, rhs.AsUnion()->Get(i), result, size, lims, zone);
755 : }
756 : return size;
757 : }
758 :
759 2705033 : if (BitsetType::IsNone(lhs.BitsetLub() & rhs.BitsetLub())) return size;
760 :
761 1032443 : if (lhs.IsRange()) {
762 791551 : if (rhs.IsBitset()) {
763 313479 : RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
764 :
765 313479 : if (!lim.IsEmpty()) {
766 313473 : *lims = RangeType::Limits::Union(lim, *lims);
767 : }
768 : return size;
769 : }
770 478072 : if (rhs.IsRange()) {
771 : RangeType::Limits lim = RangeType::Limits::Intersect(
772 : RangeType::Limits(lhs.AsRange()), RangeType::Limits(rhs.AsRange()));
773 319425 : if (!lim.IsEmpty()) {
774 319218 : *lims = RangeType::Limits::Union(lim, *lims);
775 : }
776 : }
777 : return size;
778 : }
779 240892 : if (rhs.IsRange()) {
780 : // This case is handled symmetrically above.
781 188972 : return IntersectAux(rhs, lhs, result, size, lims, zone);
782 : }
783 51920 : if (lhs.IsBitset() || rhs.IsBitset()) {
784 50088 : return AddToUnion(lhs.IsBitset() ? rhs : lhs, result, size, zone);
785 : }
786 1832 : if (lhs.SimplyEquals(rhs)) {
787 572 : return AddToUnion(lhs, result, size, zone);
788 : }
789 : return size;
790 : }
791 :
792 : // Make sure that we produce a well-formed range and bitset:
793 : // If the range is non-empty, the number bits in the bitset should be
794 : // clear. Moreover, if we have a canonical range (such as Signed32),
795 : // we want to produce a bitset rather than a range.
796 13811742 : Type Type::NormalizeRangeAndBitset(Type range, bitset* bits, Zone* zone) {
797 : // Fast path: If the bitset does not mention numbers, we can just keep the
798 : // range.
799 13811742 : bitset number_bits = BitsetType::NumberBits(*bits);
800 13811742 : if (number_bits == 0) {
801 7314362 : return range;
802 : }
803 :
804 : // If the range is semantically contained within the bitset, return None and
805 : // leave the bitset untouched.
806 6497380 : bitset range_lub = range.BitsetLub();
807 12994760 : if (BitsetType::Is(range_lub, *bits)) {
808 : return None();
809 : }
810 :
811 : // Slow path: reconcile the bitset range and the range.
812 5558868 : double bitset_min = BitsetType::Min(number_bits);
813 5558868 : double bitset_max = BitsetType::Max(number_bits);
814 :
815 5558868 : double range_min = range.Min();
816 5558868 : double range_max = range.Max();
817 :
818 : // Remove the number bits from the bitset, they would just confuse us now.
819 : // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
820 : // case we already returned after the subtype check above.
821 5558868 : *bits &= ~number_bits;
822 :
823 5558868 : if (range_min <= bitset_min && range_max >= bitset_max) {
824 : // Bitset is contained within the range, just return the range.
825 5117790 : return range;
826 : }
827 :
828 441078 : if (bitset_min < range_min) {
829 : range_min = bitset_min;
830 : }
831 441078 : if (bitset_max > range_max) {
832 : range_max = bitset_max;
833 : }
834 : return Type::Range(range_min, range_max, zone);
835 : }
836 :
837 8076304 : Type Type::NewConstant(double value, Zone* zone) {
838 8076304 : if (RangeType::IsInteger(value)) {
839 : return Range(value, value, zone);
840 1754032 : } else if (IsMinusZero(value)) {
841 : return Type::MinusZero();
842 1740526 : } else if (std::isnan(value)) {
843 : return Type::NaN();
844 : }
845 :
846 : DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
847 : return OtherNumberConstant(value, zone);
848 : }
849 :
850 11803275 : Type Type::NewConstant(JSHeapBroker* broker, Handle<i::Object> value,
851 : Zone* zone) {
852 11803275 : ObjectRef ref(broker, value);
853 11803283 : if (ref.IsSmi()) {
854 669120 : return NewConstant(static_cast<double>(ref.AsSmi()), zone);
855 : }
856 11134160 : if (ref.IsHeapNumber()) {
857 2846145 : return NewConstant(ref.AsHeapNumber().value(), zone);
858 : }
859 8288004 : if (ref.IsString() && !ref.IsInternalizedString()) {
860 : return Type::String();
861 : }
862 16575311 : return HeapConstant(ref.AsHeapObject(), zone);
863 : }
864 :
865 48954504 : Type Type::Union(Type type1, Type type2, Zone* zone) {
866 : // Fast case: bit sets.
867 74648298 : if (type1.IsBitset() && type2.IsBitset()) {
868 15213511 : return NewBitset(type1.AsBitset() | type2.AsBitset());
869 : }
870 :
871 : // Fast case: top or bottom types.
872 67292976 : if (type1.IsAny() || type2.IsNone()) return type1;
873 32287270 : if (type2.IsAny() || type1.IsNone()) return type2;
874 :
875 : // Semi-fast case.
876 29148713 : if (type1.Is(type2)) return type2;
877 27063882 : if (type2.Is(type1)) return type1;
878 :
879 : // Slow case: create union.
880 19391520 : int size1 = type1.IsUnion() ? type1.AsUnion()->Length() : 1;
881 19391520 : int size2 = type2.IsUnion() ? type2.AsUnion()->Length() : 1;
882 : int size;
883 19391520 : if (base::bits::SignedAddOverflow32(size1, size2, &size)) return Any();
884 19391520 : if (base::bits::SignedAddOverflow32(size, 2, &size)) return Any();
885 19391520 : UnionType* result = UnionType::New(size, zone);
886 : size = 0;
887 :
888 : // Compute the new bitset.
889 19391486 : bitset new_bitset = type1.BitsetGlb() | type2.BitsetGlb();
890 :
891 : // Deal with ranges.
892 : Type range = None();
893 19391507 : Type range1 = type1.GetRange();
894 19391502 : Type range2 = type2.GetRange();
895 19391541 : if (range1 != nullptr && range2 != nullptr) {
896 : RangeType::Limits lims =
897 : RangeType::Limits::Union(RangeType::Limits(range1.AsRange()),
898 : RangeType::Limits(range2.AsRange()));
899 3258573 : Type union_range = Type::Range(lims, zone);
900 3258573 : range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
901 16132968 : } else if (range1 != nullptr) {
902 5951618 : range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
903 10181350 : } else if (range2 != nullptr) {
904 4601573 : range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
905 : }
906 19391543 : Type bits = NewBitset(new_bitset);
907 : result->Set(size++, bits);
908 19391543 : if (!range.IsNone()) result->Set(size++, range);
909 :
910 19391543 : size = AddToUnion(type1, result, size, zone);
911 19391497 : size = AddToUnion(type2, result, size, zone);
912 19391515 : return NormalizeUnion(result, size, zone);
913 : }
914 :
915 : // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
916 : // Return new size of [result].
917 78148423 : int Type::AddToUnion(Type type, UnionType* result, int size, Zone* zone) {
918 132011418 : if (type.IsBitset() || type.IsRange()) return size;
919 36792820 : if (type.IsUnion()) {
920 92712002 : for (int i = 0, n = type.AsUnion()->Length(); i < n; ++i) {
921 39314998 : size = AddToUnion(type.AsUnion()->Get(i), result, size, zone);
922 : }
923 : return size;
924 : }
925 107884478 : for (int i = 0; i < size; ++i) {
926 44360648 : if (type.Is(result->Get(i))) return size;
927 : }
928 20936926 : result->Set(size++, type);
929 20936926 : return size;
930 : }
931 :
932 21206610 : Type Type::NormalizeUnion(UnionType* unioned, int size, Zone* zone) {
933 : DCHECK_LE(1, size);
934 : DCHECK(unioned->Get(0).IsBitset());
935 : // If the union has just one element, return it.
936 21206610 : if (size == 1) {
937 : return unioned->Get(0);
938 : }
939 : bitset bits = unioned->Get(0).AsBitset();
940 : // If the union only consists of a range, we can get rid of the union.
941 19490443 : if (size == 2 && bits == BitsetType::kNone) {
942 1861505 : if (unioned->Get(1).IsRange()) {
943 : return Type::Range(unioned->Get(1).AsRange()->Min(),
944 : unioned->Get(1).AsRange()->Max(), zone);
945 : }
946 : }
947 : unioned->Shrink(size);
948 : SLOW_DCHECK(unioned->Wellformed());
949 17629694 : return Type(unioned);
950 : }
951 :
952 76992 : int Type::NumConstants() const {
953 : DisallowHeapAllocation no_allocation;
954 152422 : if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
955 : return 1;
956 74614 : } else if (this->IsUnion()) {
957 : int result = 0;
958 30884 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
959 12938 : if (this->AsUnion()->Get(i).IsHeapConstant()) ++result;
960 : }
961 : return result;
962 : } else {
963 : return 0;
964 : }
965 : }
966 :
967 : // -----------------------------------------------------------------------------
968 : // Printing.
969 :
970 142159 : const char* BitsetType::Name(bitset bits) {
971 142159 : switch (bits) {
972 : #define RETURN_NAMED_TYPE(type, value) \
973 : case k##type: \
974 : return #type;
975 0 : PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
976 0 : INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
977 : #undef RETURN_NAMED_TYPE
978 :
979 : default:
980 0 : return nullptr;
981 : }
982 : }
983 :
984 142159 : void BitsetType::Print(std::ostream& os, // NOLINT
985 : bitset bits) {
986 : DisallowHeapAllocation no_allocation;
987 142159 : const char* name = Name(bits);
988 142159 : if (name != nullptr) {
989 142159 : os << name;
990 : return;
991 : }
992 :
993 : // clang-format off
994 : static const bitset named_bitsets[] = {
995 : #define BITSET_CONSTANT(type, value) k##type,
996 : INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
997 : PROPER_BITSET_TYPE_LIST(BITSET_CONSTANT)
998 : #undef BITSET_CONSTANT
999 : };
1000 : // clang-format on
1001 :
1002 : bool is_first = true;
1003 0 : os << "(";
1004 0 : for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
1005 0 : bitset subset = named_bitsets[i];
1006 0 : if ((bits & subset) == subset) {
1007 0 : if (!is_first) os << " | ";
1008 : is_first = false;
1009 0 : os << Name(subset);
1010 0 : bits -= subset;
1011 : }
1012 : }
1013 : DCHECK_EQ(0, bits);
1014 0 : os << ")";
1015 : }
1016 :
1017 142287 : void Type::PrintTo(std::ostream& os) const {
1018 : DisallowHeapAllocation no_allocation;
1019 142287 : if (this->IsBitset()) {
1020 142159 : BitsetType::Print(os, this->AsBitset());
1021 128 : } else if (this->IsHeapConstant()) {
1022 160 : os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
1023 48 : } else if (this->IsOtherNumberConstant()) {
1024 : os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
1025 0 : << ")";
1026 48 : } else if (this->IsRange()) {
1027 29 : std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1028 29 : std::streamsize saved_precision = os.precision(0);
1029 : os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1030 29 : << ")";
1031 29 : os.flags(saved_flags);
1032 29 : os.precision(saved_precision);
1033 19 : } else if (this->IsUnion()) {
1034 19 : os << "(";
1035 95 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1036 38 : Type type_i = this->AsUnion()->Get(i);
1037 38 : if (i > 0) os << " | ";
1038 38 : os << type_i;
1039 : }
1040 19 : os << ")";
1041 0 : } else if (this->IsTuple()) {
1042 0 : os << "<";
1043 0 : for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
1044 0 : Type type_i = this->AsTuple()->Element(i);
1045 0 : if (i > 0) os << ", ";
1046 0 : os << type_i;
1047 : }
1048 0 : os << ">";
1049 : } else {
1050 0 : UNREACHABLE();
1051 : }
1052 142287 : }
1053 :
1054 : #ifdef DEBUG
1055 : void Type::Print() const {
1056 : StdoutStream os;
1057 : PrintTo(os);
1058 : os << std::endl;
1059 : }
1060 : void BitsetType::Print(bitset bits) {
1061 : StdoutStream os;
1062 : Print(os, bits);
1063 : os << std::endl;
1064 : }
1065 : #endif
1066 :
1067 6849139 : BitsetType::bitset BitsetType::SignedSmall() {
1068 6849139 : return SmiValuesAre31Bits() ? kSigned31 : kSigned32;
1069 : }
1070 :
1071 233082 : BitsetType::bitset BitsetType::UnsignedSmall() {
1072 233082 : return SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
1073 : }
1074 :
1075 : // static
1076 1380 : Type Type::Tuple(Type first, Type second, Type third, Zone* zone) {
1077 1380 : TupleType* tuple = TupleType::New(3, zone);
1078 : tuple->InitElement(0, first);
1079 : tuple->InitElement(1, second);
1080 : tuple->InitElement(2, third);
1081 1380 : return FromTypeBase(tuple);
1082 : }
1083 :
1084 : // static
1085 0 : Type Type::OtherNumberConstant(double value, Zone* zone) {
1086 1735499 : return FromTypeBase(OtherNumberConstantType::New(value, zone));
1087 : }
1088 :
1089 : // static
1090 10702212 : Type Type::HeapConstant(JSHeapBroker* broker, Handle<i::Object> value,
1091 : Zone* zone) {
1092 : return FromTypeBase(
1093 21404498 : HeapConstantType::New(HeapObjectRef(broker, value), zone));
1094 : }
1095 :
1096 : // static
1097 0 : Type Type::HeapConstant(const HeapObjectRef& value, Zone* zone) {
1098 8287656 : return HeapConstantType::New(value, zone);
1099 : }
1100 :
1101 : // static
1102 9143049 : Type Type::Range(double min, double max, Zone* zone) {
1103 9143055 : return FromTypeBase(RangeType::New(min, max, zone));
1104 : }
1105 :
1106 : // static
1107 0 : Type Type::Range(RangeType::Limits lims, Zone* zone) {
1108 3891170 : return FromTypeBase(RangeType::New(lims, zone));
1109 : }
1110 :
1111 : // static
1112 0 : Type Type::Union(int length, Zone* zone) {
1113 0 : return FromTypeBase(UnionType::New(length, zone));
1114 : }
1115 :
1116 2394255 : const HeapConstantType* Type::AsHeapConstant() const {
1117 : DCHECK(IsKind(TypeBase::kHeapConstant));
1118 2394255 : return static_cast<const HeapConstantType*>(ToTypeBase());
1119 : }
1120 :
1121 57 : const OtherNumberConstantType* Type::AsOtherNumberConstant() const {
1122 : DCHECK(IsKind(TypeBase::kOtherNumberConstant));
1123 57 : return static_cast<const OtherNumberConstantType*>(ToTypeBase());
1124 : }
1125 :
1126 45246 : const RangeType* Type::AsRange() const {
1127 : DCHECK(IsKind(TypeBase::kRange));
1128 45246 : return static_cast<const RangeType*>(ToTypeBase());
1129 : }
1130 :
1131 8280 : const TupleType* Type::AsTuple() const {
1132 : DCHECK(IsKind(TypeBase::kTuple));
1133 8280 : return static_cast<const TupleType*>(ToTypeBase());
1134 : }
1135 :
1136 5008 : const UnionType* Type::AsUnion() const {
1137 : DCHECK(IsKind(TypeBase::kUnion));
1138 5008 : return static_cast<const UnionType*>(ToTypeBase());
1139 : }
1140 :
1141 142115 : std::ostream& operator<<(std::ostream& os, Type type) {
1142 142115 : type.PrintTo(os);
1143 142115 : return os;
1144 : }
1145 :
1146 : } // namespace compiler
1147 : } // namespace internal
1148 122036 : } // namespace v8
|