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 : // NOTE: If code is marked as being a "shortcut", this means that removing
18 : // the code won't affect the semantics of the surrounding function definition.
19 :
20 : // static
21 13727395 : bool Type::IsInteger(i::Object* x) {
22 18840942 : return x->IsNumber() && Type::IsInteger(x->Number());
23 : }
24 :
25 : // -----------------------------------------------------------------------------
26 : // Range-related helper functions.
27 :
28 3382089 : bool RangeType::Limits::IsEmpty() { return this->min > this->max; }
29 :
30 0 : RangeType::Limits RangeType::Limits::Intersect(Limits lhs, Limits rhs) {
31 : DisallowHeapAllocation no_allocation;
32 : Limits result(lhs);
33 3175621 : if (lhs.min < rhs.min) result.min = rhs.min;
34 3175621 : if (lhs.max > rhs.max) result.max = rhs.max;
35 0 : return result;
36 : }
37 :
38 0 : RangeType::Limits RangeType::Limits::Union(Limits lhs, Limits rhs) {
39 : DisallowHeapAllocation no_allocation;
40 3357419 : if (lhs.IsEmpty()) return rhs;
41 3357419 : if (rhs.IsEmpty()) return lhs;
42 : Limits result(lhs);
43 3157769 : if (lhs.min > rhs.min) result.min = rhs.min;
44 3157769 : if (lhs.max < rhs.max) result.max = rhs.max;
45 0 : return result;
46 : }
47 :
48 0 : bool Type::Overlap(RangeType* lhs, RangeType* rhs) {
49 : DisallowHeapAllocation no_allocation;
50 : return !RangeType::Limits::Intersect(RangeType::Limits(lhs),
51 : RangeType::Limits(rhs))
52 2975952 : .IsEmpty();
53 : }
54 :
55 28172249 : bool Type::Contains(RangeType* lhs, RangeType* rhs) {
56 : DisallowHeapAllocation no_allocation;
57 28172249 : return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
58 : }
59 :
60 0 : bool Type::Contains(RangeType* range, i::Object* val) {
61 : DisallowHeapAllocation no_allocation;
62 0 : return IsInteger(val) && range->Min() <= val->Number() &&
63 0 : val->Number() <= range->Max();
64 : }
65 :
66 : // -----------------------------------------------------------------------------
67 : // Min and Max computation.
68 :
69 10973641 : double Type::Min() {
70 : DCHECK(this->Is(Number()));
71 11636516 : if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
72 10310766 : if (this->IsUnion()) {
73 19680 : double min = +V8_INFINITY;
74 66320 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
75 139920 : min = std::min(min, this->AsUnion()->Get(i)->Min());
76 : }
77 19680 : return min;
78 : }
79 10291086 : if (this->IsRange()) return this->AsRange()->Min();
80 11261 : if (this->IsOtherNumberConstant())
81 11261 : return this->AsOtherNumberConstant()->Value();
82 0 : UNREACHABLE();
83 : return 0;
84 : }
85 :
86 11097614 : double Type::Max() {
87 : DCHECK(this->Is(Number()));
88 11933560 : if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
89 10261668 : if (this->IsUnion()) {
90 17107 : double max = -V8_INFINITY;
91 58601 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
92 124482 : max = std::max(max, this->AsUnion()->Get(i)->Max());
93 : }
94 17107 : return max;
95 : }
96 10244561 : if (this->IsRange()) return this->AsRange()->Max();
97 10754 : if (this->IsOtherNumberConstant())
98 10754 : return this->AsOtherNumberConstant()->Value();
99 0 : UNREACHABLE();
100 : return 0;
101 : }
102 :
103 : // -----------------------------------------------------------------------------
104 : // Glb and lub computation.
105 :
106 : // The largest bitset subsumed by this type.
107 92968834 : Type::bitset BitsetType::Glb(Type* type) {
108 : DisallowHeapAllocation no_allocation;
109 : // Fast case.
110 92968834 : if (IsBitset(type)) {
111 27589525 : return type->AsBitset();
112 65379309 : } else if (type->IsUnion()) {
113 : SLOW_DCHECK(type->AsUnion()->Wellformed());
114 40718664 : return type->AsUnion()->Get(0)->BitsetGlb() |
115 40718748 : type->AsUnion()->Get(1)->BitsetGlb(); // Shortcut.
116 45019977 : } else if (type->IsRange()) {
117 : bitset glb =
118 29385393 : BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max());
119 29386073 : return glb;
120 : } else {
121 : return kNone;
122 : }
123 : }
124 :
125 : // The smallest bitset subsuming this type, possibly not a proper one.
126 275784545 : Type::bitset BitsetType::Lub(Type* type) {
127 : DisallowHeapAllocation no_allocation;
128 446056131 : if (IsBitset(type)) return type->AsBitset();
129 105512959 : if (type->IsUnion()) {
130 : // Take the representation from the first element, which is always
131 : // a bitset.
132 15538036 : int bitset = type->AsUnion()->Get(0)->BitsetLub();
133 28362971 : for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
134 : // Other elements only contribute their semantic part.
135 41189286 : bitset |= type->AsUnion()->Get(i)->BitsetLub();
136 : }
137 7768328 : return bitset;
138 : }
139 97743941 : if (type->IsHeapConstant()) return type->AsHeapConstant()->Lub();
140 71284381 : if (type->IsOtherNumberConstant())
141 : return type->AsOtherNumberConstant()->Lub();
142 60325730 : if (type->IsRange()) return type->AsRange()->Lub();
143 3933 : if (type->IsTuple()) return kOtherInternal;
144 0 : UNREACHABLE();
145 : return kNone;
146 : }
147 :
148 9448420 : Type::bitset BitsetType::Lub(i::Map* map) {
149 : DisallowHeapAllocation no_allocation;
150 9448420 : switch (map->instance_type()) {
151 : case STRING_TYPE:
152 : case ONE_BYTE_STRING_TYPE:
153 : case CONS_STRING_TYPE:
154 : case CONS_ONE_BYTE_STRING_TYPE:
155 : case THIN_STRING_TYPE:
156 : case THIN_ONE_BYTE_STRING_TYPE:
157 : case SLICED_STRING_TYPE:
158 : case SLICED_ONE_BYTE_STRING_TYPE:
159 : case EXTERNAL_STRING_TYPE:
160 : case EXTERNAL_ONE_BYTE_STRING_TYPE:
161 : case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
162 : case SHORT_EXTERNAL_STRING_TYPE:
163 : case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
164 : case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
165 : return kOtherString;
166 : case INTERNALIZED_STRING_TYPE:
167 : case ONE_BYTE_INTERNALIZED_STRING_TYPE:
168 : case EXTERNAL_INTERNALIZED_STRING_TYPE:
169 : case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
170 : case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
171 : case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
172 : case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
173 : case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
174 1313541 : return kInternalizedString;
175 : case SYMBOL_TYPE:
176 1721 : return kSymbol;
177 : case ODDBALL_TYPE: {
178 15022462 : Heap* heap = map->GetHeap();
179 5062084 : if (map == heap->undefined_map()) return kUndefined;
180 4225794 : if (map == heap->null_map()) return kNull;
181 4187163 : if (map == heap->boolean_map()) return kBoolean;
182 1547421 : if (map == heap->the_hole_map()) return kHole;
183 : DCHECK(map == heap->uninitialized_map() ||
184 : map == heap->termination_exception_map() ||
185 : map == heap->arguments_marker_map() ||
186 : map == heap->optimized_out_map() ||
187 : map == heap->stale_register_map());
188 559030 : return kOtherInternal;
189 : }
190 : case HEAP_NUMBER_TYPE:
191 0 : return kNumber;
192 : case JS_OBJECT_TYPE:
193 : case JS_ARGUMENTS_TYPE:
194 : case JS_ERROR_TYPE:
195 : case JS_GLOBAL_OBJECT_TYPE:
196 : case JS_GLOBAL_PROXY_TYPE:
197 : case JS_API_OBJECT_TYPE:
198 : case JS_SPECIAL_API_OBJECT_TYPE:
199 1253088 : if (map->is_undetectable()) {
200 : // Currently we assume that every undetectable receiver is also
201 : // callable, which is what we need to support document.all. We
202 : // could add another Type bit to support other use cases in the
203 : // future if necessary.
204 : DCHECK(map->is_callable());
205 : return kOtherUndetectable;
206 : }
207 1252986 : if (map->is_callable()) {
208 : return kOtherCallable;
209 : }
210 1252976 : return kOtherObject;
211 : case JS_ARRAY_TYPE:
212 581889 : return kArray;
213 : case JS_VALUE_TYPE:
214 : case JS_MESSAGE_OBJECT_TYPE:
215 : case JS_DATE_TYPE:
216 : case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
217 : case JS_GENERATOR_OBJECT_TYPE:
218 : case JS_ASYNC_GENERATOR_OBJECT_TYPE:
219 : case JS_MODULE_NAMESPACE_TYPE:
220 : case JS_ARRAY_BUFFER_TYPE:
221 : case JS_REGEXP_TYPE: // TODO(rossberg): there should be a RegExp type.
222 : case JS_TYPED_ARRAY_TYPE:
223 : case JS_DATA_VIEW_TYPE:
224 : case JS_SET_TYPE:
225 : case JS_MAP_TYPE:
226 : case JS_SET_ITERATOR_TYPE:
227 : case JS_MAP_ITERATOR_TYPE:
228 : case JS_STRING_ITERATOR_TYPE:
229 : case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:
230 :
231 : case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
232 : case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
233 : case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
234 : case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
235 : case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
236 : case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
237 : case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
238 : case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
239 : case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
240 : case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
241 : case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
242 : case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
243 : case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
244 : case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
245 : case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
246 : case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
247 : case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
248 : case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
249 : case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
250 : case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
251 : case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
252 : case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
253 : case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
254 : case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
255 : case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
256 : case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
257 : case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
258 : case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
259 : case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
260 : case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
261 : case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
262 : case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
263 : case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
264 : case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
265 : case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
266 :
267 : case JS_WEAK_MAP_TYPE:
268 : case JS_WEAK_SET_TYPE:
269 : case JS_PROMISE_CAPABILITY_TYPE:
270 : case JS_PROMISE_TYPE:
271 : DCHECK(!map->is_callable());
272 : DCHECK(!map->is_undetectable());
273 5086 : return kOtherObject;
274 : case JS_BOUND_FUNCTION_TYPE:
275 : DCHECK(!map->is_undetectable());
276 192 : return kBoundFunction;
277 : case JS_FUNCTION_TYPE:
278 : DCHECK(!map->is_undetectable());
279 625538 : return kFunction;
280 : case JS_PROXY_TYPE:
281 : DCHECK(!map->is_undetectable());
282 1064 : if (map->is_callable()) return kCallableProxy;
283 944 : return kOtherProxy;
284 : case MAP_TYPE:
285 : case ALLOCATION_SITE_TYPE:
286 : case ACCESSOR_INFO_TYPE:
287 : case SHARED_FUNCTION_INFO_TYPE:
288 : case FUNCTION_TEMPLATE_INFO_TYPE:
289 : case ACCESSOR_PAIR_TYPE:
290 : case FIXED_ARRAY_TYPE:
291 : case FIXED_DOUBLE_ARRAY_TYPE:
292 : case BYTE_ARRAY_TYPE:
293 : case BYTECODE_ARRAY_TYPE:
294 : case TRANSITION_ARRAY_TYPE:
295 : case FOREIGN_TYPE:
296 : case SCRIPT_TYPE:
297 : case CODE_TYPE:
298 : case PROPERTY_CELL_TYPE:
299 : case MODULE_TYPE:
300 : case MODULE_INFO_ENTRY_TYPE:
301 604243 : return kOtherInternal;
302 :
303 : // Remaining instance types are unsupported for now. If any of them do
304 : // require bit set types, they should get kOtherInternal.
305 : case MUTABLE_HEAP_NUMBER_TYPE:
306 : case FREE_SPACE_TYPE:
307 : #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
308 : case FIXED_##TYPE##_ARRAY_TYPE:
309 :
310 : TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
311 : #undef FIXED_TYPED_ARRAY_CASE
312 : case FILLER_TYPE:
313 : case ACCESS_CHECK_INFO_TYPE:
314 : case INTERCEPTOR_INFO_TYPE:
315 : case OBJECT_TEMPLATE_INFO_TYPE:
316 : case ALLOCATION_MEMENTO_TYPE:
317 : case ALIASED_ARGUMENTS_ENTRY_TYPE:
318 : case PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE:
319 : case PROMISE_REACTION_JOB_INFO_TYPE:
320 : case DEBUG_INFO_TYPE:
321 : case STACK_FRAME_INFO_TYPE:
322 : case CELL_TYPE:
323 : case WEAK_CELL_TYPE:
324 : case PROTOTYPE_INFO_TYPE:
325 : case TUPLE2_TYPE:
326 : case TUPLE3_TYPE:
327 : case CONTEXT_EXTENSION_TYPE:
328 : case ASYNC_GENERATOR_REQUEST_TYPE:
329 : case PADDING_TYPE_1:
330 : case PADDING_TYPE_2:
331 : case PADDING_TYPE_3:
332 : case PADDING_TYPE_4:
333 0 : UNREACHABLE();
334 : return kNone;
335 : }
336 0 : UNREACHABLE();
337 : return kNone;
338 : }
339 :
340 9432170 : Type::bitset BitsetType::Lub(i::Object* value) {
341 : DisallowHeapAllocation no_allocation;
342 9432180 : if (value->IsNumber()) {
343 1410 : return Lub(value->Number());
344 : }
345 9430770 : return Lub(i::HeapObject::cast(value)->map());
346 : }
347 :
348 1410 : Type::bitset BitsetType::Lub(double value) {
349 : DisallowHeapAllocation no_allocation;
350 1410 : if (i::IsMinusZero(value)) return kMinusZero;
351 1410 : if (std::isnan(value)) return kNaN;
352 2820 : if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
353 : return kOtherNumber;
354 : }
355 :
356 : // Minimum values of plain numeric bitsets.
357 : const BitsetType::Boundary BitsetType::BoundariesArray[] = {
358 : {kOtherNumber, kPlainNumber, -V8_INFINITY},
359 : {kOtherSigned32, kNegative32, kMinInt},
360 : {kNegative31, kNegative31, -0x40000000},
361 : {kUnsigned30, kUnsigned30, 0},
362 : {kOtherUnsigned31, kUnsigned31, 0x40000000},
363 : {kOtherUnsigned32, kUnsigned32, 0x80000000},
364 : {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
365 :
366 : const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; }
367 :
368 : size_t BitsetType::BoundariesSize() {
369 : // Windows doesn't like arraysize here.
370 : // return arraysize(BoundariesArray);
371 : return 7;
372 : }
373 :
374 20001 : Type::bitset BitsetType::ExpandInternals(Type::bitset bits) {
375 : DisallowHeapAllocation no_allocation;
376 20001 : if (!(bits & kPlainNumber)) return bits; // Shortcut.
377 : const Boundary* boundaries = Boundaries();
378 9870 : for (size_t i = 0; i < BoundariesSize(); ++i) {
379 : DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
380 9870 : if (bits & boundaries[i].internal) bits |= boundaries[i].external;
381 : }
382 : return bits;
383 : }
384 :
385 10166752 : Type::bitset BitsetType::Lub(double min, double max) {
386 : DisallowHeapAllocation no_allocation;
387 : int lub = kNone;
388 : const Boundary* mins = Boundaries();
389 :
390 89695977 : for (size_t i = 1; i < BoundariesSize(); ++i) {
391 94999801 : if (min < mins[i].min) {
392 56398445 : lub |= mins[i - 1].internal;
393 56398445 : if (max < mins[i].min) return lub;
394 : }
395 : }
396 5994287 : return lub | mins[BoundariesSize() - 1].internal;
397 : }
398 :
399 11782755 : Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; }
400 :
401 29385359 : Type::bitset BitsetType::Glb(double min, double max) {
402 : DisallowHeapAllocation no_allocation;
403 : int glb = kNone;
404 : const Boundary* mins = Boundaries();
405 :
406 : // If the range does not touch 0, the bound is empty.
407 29385359 : if (max < -1 || min > 0) return glb;
408 :
409 91852250 : for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
410 82319545 : if (min <= mins[i].min) {
411 70785422 : if (max + 1 < mins[i + 1].min) break;
412 60499496 : glb |= mins[i].external;
413 : }
414 : }
415 : // OtherNumber also contains float numbers, so it can never be
416 : // in the greatest lower bound.
417 19818631 : return glb & ~(kOtherNumber);
418 : }
419 :
420 7274804 : double BitsetType::Min(bitset bits) {
421 : DisallowHeapAllocation no_allocation;
422 : DCHECK(Is(bits, kNumber));
423 : const Boundary* mins = Boundaries();
424 7274804 : bool mz = bits & kMinusZero;
425 15319041 : for (size_t i = 0; i < BoundariesSize(); ++i) {
426 30596272 : if (Is(mins[i].internal, bits)) {
427 7339206 : return mz ? std::min(0.0, mins[i].min) : mins[i].min;
428 : }
429 : }
430 20905 : if (mz) return 0;
431 7804 : return std::numeric_limits<double>::quiet_NaN();
432 : }
433 :
434 7447587 : double BitsetType::Max(bitset bits) {
435 : DisallowHeapAllocation no_allocation;
436 : DCHECK(Is(bits, kNumber));
437 : const Boundary* mins = Boundaries();
438 7447587 : bool mz = bits & kMinusZero;
439 7447587 : if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) {
440 : return +V8_INFINITY;
441 : }
442 13155730 : for (size_t i = BoundariesSize() - 1; i-- > 0;) {
443 26274732 : if (Is(mins[i].internal, bits)) {
444 6473162 : return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1;
445 : }
446 : }
447 18364 : if (mz) return 0;
448 7814 : return std::numeric_limits<double>::quiet_NaN();
449 : }
450 :
451 : // static
452 1720863 : bool OtherNumberConstantType::IsOtherNumberConstant(double value) {
453 : // Not an integer, not NaN, and not -0.
454 5162589 : return !std::isnan(value) && !Type::IsInteger(value) &&
455 1720863 : !i::IsMinusZero(value);
456 : }
457 :
458 : // static
459 0 : bool OtherNumberConstantType::IsOtherNumberConstant(Object* value) {
460 0 : return value->IsHeapNumber() &&
461 0 : IsOtherNumberConstant(HeapNumber::cast(value)->value());
462 : }
463 :
464 3980614 : HeapConstantType::HeapConstantType(BitsetType::bitset bitset,
465 : i::Handle<i::HeapObject> object)
466 9429868 : : TypeBase(kHeapConstant), bitset_(bitset), object_(object) {
467 : DCHECK(!object->IsHeapNumber());
468 : DCHECK_IMPLIES(object->IsString(), object->IsInternalizedString());
469 3980614 : }
470 :
471 : // -----------------------------------------------------------------------------
472 : // Predicates.
473 :
474 9784633 : bool Type::SimplyEquals(Type* that) {
475 : DisallowHeapAllocation no_allocation;
476 9784633 : if (this->IsHeapConstant()) {
477 6674236 : return that->IsHeapConstant() &&
478 : this->AsHeapConstant()->Value().address() ==
479 6674236 : that->AsHeapConstant()->Value().address();
480 : }
481 3110397 : if (this->IsOtherNumberConstant()) {
482 4220277 : return that->IsOtherNumberConstant() &&
483 1273442 : this->AsOtherNumberConstant()->Value() ==
484 4220277 : that->AsOtherNumberConstant()->Value();
485 : }
486 163562 : if (this->IsRange()) {
487 326897 : if (that->IsHeapConstant() || that->IsOtherNumberConstant()) return false;
488 : }
489 114 : if (this->IsTuple()) {
490 114 : if (!that->IsTuple()) return false;
491 : TupleType* this_tuple = this->AsTuple();
492 : TupleType* that_tuple = that->AsTuple();
493 114 : if (this_tuple->Arity() != that_tuple->Arity()) {
494 : return false;
495 : }
496 342 : for (int i = 0, n = this_tuple->Arity(); i < n; ++i) {
497 342 : if (!this_tuple->Element(i)->Equals(that_tuple->Element(i))) return false;
498 : }
499 : return true;
500 : }
501 0 : UNREACHABLE();
502 : return false;
503 : }
504 :
505 : // Check if [this] <= [that].
506 264511890 : bool Type::SlowIs(Type* that) {
507 : DisallowHeapAllocation no_allocation;
508 :
509 : // Fast bitset cases
510 264511890 : if (that->IsBitset()) {
511 179835765 : return BitsetType::Is(this->BitsetLub(), that->AsBitset());
512 : }
513 :
514 84670131 : if (this->IsBitset()) {
515 23435983 : return BitsetType::Is(this->AsBitset(), that->BitsetGlb());
516 : }
517 :
518 : // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T)
519 61234267 : if (this->IsUnion()) {
520 13581077 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
521 26303612 : if (!this->AsUnion()->Get(i)->Is(that)) return false;
522 : }
523 : return true;
524 : }
525 :
526 : // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn)
527 51174735 : if (that->IsUnion()) {
528 23567724 : for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
529 40482512 : if (this->Is(that->AsUnion()->Get(i))) return true;
530 18515432 : if (i > 1 && this->IsRange()) return false; // Shortcut.
531 : }
532 : return false;
533 : }
534 :
535 41999534 : if (that->IsRange()) {
536 45181874 : return (this->IsRange() && Contains(that->AsRange(), this->AsRange()));
537 : }
538 12888619 : if (this->IsRange()) return false;
539 :
540 9573052 : return this->SimplyEquals(that);
541 : }
542 :
543 : // Check if [this] and [that] overlap.
544 13141731 : bool Type::Maybe(Type* that) {
545 : DisallowHeapAllocation no_allocation;
546 :
547 13941600 : if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()))
548 : return false;
549 :
550 : // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T)
551 8440132 : if (this->IsUnion()) {
552 218169 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
553 383620 : if (this->AsUnion()->Get(i)->Maybe(that)) return true;
554 : }
555 : return false;
556 : }
557 :
558 : // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn)
559 8323927 : if (that->IsUnion()) {
560 258856 : for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
561 396128 : if (this->Maybe(that->AsUnion()->Get(i))) return true;
562 : }
563 : return false;
564 : }
565 :
566 8209413 : if (this->IsBitset() && that->IsBitset()) return true;
567 :
568 5105018 : if (this->IsRange()) {
569 3912912 : if (that->IsRange()) {
570 2975952 : return Overlap(this->AsRange(), that->AsRange());
571 : }
572 936960 : if (that->IsBitset()) {
573 : bitset number_bits = BitsetType::NumberBits(that->AsBitset());
574 773585 : if (number_bits == BitsetType::kNone) {
575 : return false;
576 : }
577 1547177 : double min = std::max(BitsetType::Min(number_bits), this->Min());
578 1547172 : double max = std::min(BitsetType::Max(number_bits), this->Max());
579 773582 : return min <= max;
580 : }
581 : }
582 1355481 : if (that->IsRange()) {
583 : return that->Maybe(this); // This case is handled above.
584 : }
585 :
586 552418 : if (this->IsBitset() || that->IsBitset()) return true;
587 :
588 210598 : return this->SimplyEquals(that);
589 : }
590 :
591 : // Return the range in [this], or [NULL].
592 28437983 : Type* Type::GetRange() {
593 : DisallowHeapAllocation no_allocation;
594 28437983 : if (this->IsRange()) return this;
595 32127610 : if (this->IsUnion() && this->AsUnion()->Get(1)->IsRange()) {
596 15448732 : return this->AsUnion()->Get(1);
597 : }
598 : return NULL;
599 : }
600 :
601 0 : bool UnionType::Wellformed() {
602 : DisallowHeapAllocation no_allocation;
603 : // This checks the invariants of the union representation:
604 : // 1. There are at least two elements.
605 : // 2. The first element is a bitset, no other element is a bitset.
606 : // 3. At most one element is a range, and it must be the second one.
607 : // 4. No element is itself a union.
608 : // 5. No element (except the bitset) is a subtype of any other.
609 : // 6. If there is a range, then the bitset type does not contain
610 : // plain number bits.
611 : DCHECK(this->Length() >= 2); // (1)
612 : DCHECK(this->Get(0)->IsBitset()); // (2a)
613 :
614 : for (int i = 0; i < this->Length(); ++i) {
615 : if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2b)
616 : if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3)
617 : DCHECK(!this->Get(i)->IsUnion()); // (4)
618 : for (int j = 0; j < this->Length(); ++j) {
619 : if (i != j && i != 0) DCHECK(!this->Get(i)->Is(this->Get(j))); // (5)
620 : }
621 : }
622 : DCHECK(!this->Get(1)->IsRange() ||
623 : (BitsetType::NumberBits(this->Get(0)->AsBitset()) ==
624 : BitsetType::kNone)); // (6)
625 0 : return true;
626 : }
627 :
628 : // -----------------------------------------------------------------------------
629 : // Union and intersection
630 :
631 : static bool AddIsSafe(int x, int y) {
632 28774589 : return x >= 0 ? y <= std::numeric_limits<int>::max() - x
633 57549178 : : y >= std::numeric_limits<int>::min() - x;
634 : }
635 :
636 20284924 : Type* Type::Intersect(Type* type1, Type* type2, Zone* zone) {
637 : // Fast case: bit sets.
638 35467283 : if (type1->IsBitset() && type2->IsBitset()) {
639 29098636 : return BitsetType::New(type1->AsBitset() & type2->AsBitset());
640 : }
641 :
642 : // Fast case: top or bottom types.
643 5735606 : if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut.
644 5560965 : if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut.
645 :
646 : // Semi-fast case.
647 5427723 : if (type1->Is(type2)) return type1;
648 1533975 : if (type2->Is(type1)) return type2;
649 :
650 : // Slow case: create union.
651 :
652 : // Semantic subtyping check - this is needed for consistency with the
653 : // semi-fast case above.
654 406140 : if (type1->Is(type2)) {
655 : type2 = Any();
656 406140 : } else if (type2->Is(type1)) {
657 : type1 = Any();
658 : }
659 :
660 406139 : bitset bits = type1->BitsetGlb() & type2->BitsetGlb();
661 406139 : int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
662 406139 : int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
663 406139 : if (!AddIsSafe(size1, size2)) return Any();
664 406138 : int size = size1 + size2;
665 406138 : if (!AddIsSafe(size, 2)) return Any();
666 406140 : size += 2;
667 406140 : Type* result_type = UnionType::New(size, zone);
668 : UnionType* result = result_type->AsUnion();
669 : size = 0;
670 :
671 : // Deal with bitsets.
672 605780 : result->Set(size++, BitsetType::New(bits));
673 :
674 406140 : RangeType::Limits lims = RangeType::Limits::Empty();
675 406140 : size = IntersectAux(type1, type2, result, size, &lims, zone);
676 :
677 : // If the range is not empty, then insert it into the union and
678 : // remove the number bits from the bitset.
679 406137 : if (!lims.IsEmpty()) {
680 199642 : size = UpdateRange(RangeType::New(lims, zone), result, size, zone);
681 :
682 : // Remove the number bits.
683 : bitset number_bits = BitsetType::NumberBits(bits);
684 199640 : bits &= ~number_bits;
685 : result->Set(0, BitsetType::New(bits));
686 : }
687 406135 : return NormalizeUnion(result_type, size, zone);
688 : }
689 :
690 199640 : int Type::UpdateRange(Type* range, UnionType* result, int size, Zone* zone) {
691 199640 : if (size == 1) {
692 200214 : result->Set(size++, range);
693 : } else {
694 : // Make space for the range.
695 225 : result->Set(size++, result->Get(1));
696 : result->Set(1, range);
697 : }
698 :
699 : // Remove any components that just got subsumed.
700 199989 : for (int i = 2; i < size;) {
701 349 : if (result->Get(i)->Is(range)) {
702 0 : result->Set(i, result->Get(--size));
703 : } else {
704 349 : ++i;
705 : }
706 : }
707 199640 : return size;
708 : }
709 :
710 137479 : RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) {
711 : bitset number_bits = BitsetType::NumberBits(bits);
712 :
713 137479 : if (number_bits == BitsetType::kNone) {
714 : return RangeType::Limits::Empty();
715 : }
716 :
717 : return RangeType::Limits(BitsetType::Min(number_bits),
718 137479 : BitsetType::Max(number_bits));
719 : }
720 :
721 137481 : RangeType::Limits Type::IntersectRangeAndBitset(Type* range, Type* bitset,
722 : Zone* zone) {
723 : RangeType::Limits range_lims(range->AsRange());
724 137481 : RangeType::Limits bitset_lims = ToLimits(bitset->AsBitset(), zone);
725 137481 : return RangeType::Limits::Intersect(range_lims, bitset_lims);
726 : }
727 :
728 636511 : int Type::IntersectAux(Type* lhs, Type* rhs, UnionType* result, int size,
729 : RangeType::Limits* lims, Zone* zone) {
730 681309 : if (lhs->IsUnion()) {
731 324535 : for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
732 : size =
733 460680 : IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, lims, zone);
734 : }
735 : return size;
736 : }
737 587116 : if (rhs->IsUnion()) {
738 66 : for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
739 : size =
740 92 : IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone);
741 : }
742 : return size;
743 : }
744 :
745 587098 : if (!BitsetType::IsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) {
746 : return size;
747 : }
748 :
749 290999 : if (lhs->IsRange()) {
750 239853 : if (rhs->IsBitset()) {
751 137482 : RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone);
752 :
753 137481 : if (!lim.IsEmpty()) {
754 137481 : *lims = RangeType::Limits::Union(lim, *lims);
755 : }
756 : return size;
757 : }
758 102371 : if (rhs->IsRange()) {
759 : RangeType::Limits lim = RangeType::Limits::Intersect(
760 : RangeType::Limits(lhs->AsRange()), RangeType::Limits(rhs->AsRange()));
761 62188 : if (!lim.IsEmpty()) {
762 62169 : *lims = RangeType::Limits::Union(lim, *lims);
763 : }
764 : }
765 102371 : return size;
766 : }
767 51146 : if (rhs->IsRange()) {
768 : // This case is handled symmetrically above.
769 : return IntersectAux(rhs, lhs, result, size, lims, zone);
770 : }
771 6348 : if (lhs->IsBitset() || rhs->IsBitset()) {
772 5370 : return AddToUnion(lhs->IsBitset() ? rhs : lhs, result, size, zone);
773 : }
774 978 : if (lhs->SimplyEquals(rhs)) {
775 2 : return AddToUnion(lhs, result, size, zone);
776 : }
777 : return size;
778 : }
779 :
780 : // Make sure that we produce a well-formed range and bitset:
781 : // If the range is non-empty, the number bits in the bitset should be
782 : // clear. Moreover, if we have a canonical range (such as Signed32),
783 : // we want to produce a bitset rather than a range.
784 10672051 : Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) {
785 : // Fast path: If the bitset does not mention numbers, we can just keep the
786 : // range.
787 10672051 : bitset number_bits = BitsetType::NumberBits(*bits);
788 10672051 : if (number_bits == 0) {
789 : return range;
790 : }
791 :
792 : // If the range is semantically contained within the bitset, return None and
793 : // leave the bitset untouched.
794 : bitset range_lub = range->BitsetLub();
795 13219176 : if (BitsetType::Is(range_lub, *bits)) {
796 : return None();
797 : }
798 :
799 : // Slow path: reconcile the bitset range and the range.
800 5700994 : double bitset_min = BitsetType::Min(number_bits);
801 5700994 : double bitset_max = BitsetType::Max(number_bits);
802 :
803 5700994 : double range_min = range->Min();
804 5700994 : double range_max = range->Max();
805 :
806 : // Remove the number bits from the bitset, they would just confuse us now.
807 : // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
808 : // case we already returned after the subtype check above.
809 5700994 : *bits &= ~number_bits;
810 :
811 5700994 : if (range_min <= bitset_min && range_max >= bitset_max) {
812 : // Bitset is contained within the range, just return the range.
813 : return range;
814 : }
815 :
816 484176 : if (bitset_min < range_min) {
817 : range_min = bitset_min;
818 : }
819 484176 : if (bitset_max > range_max) {
820 : range_max = bitset_max;
821 : }
822 484176 : return RangeType::New(range_min, range_max, zone);
823 : }
824 :
825 4592951 : Type* Type::NewConstant(double value, Zone* zone) {
826 4592951 : if (IsInteger(value)) {
827 2853064 : return Range(value, value, zone);
828 1739887 : } else if (i::IsMinusZero(value)) {
829 : return Type::MinusZero();
830 1726852 : } else if (std::isnan(value)) {
831 : return Type::NaN();
832 : }
833 :
834 : DCHECK(OtherNumberConstantType::IsOtherNumberConstant(value));
835 1720863 : return OtherNumberConstant(value, zone);
836 : }
837 :
838 10565650 : Type* Type::NewConstant(i::Handle<i::Object> value, Zone* zone) {
839 10565650 : if (IsInteger(*value)) {
840 : double v = value->Number();
841 3406292 : return Range(v, v, zone);
842 7159371 : } else if (value->IsHeapNumber()) {
843 1707250 : return NewConstant(value->Number(), zone);
844 5954004 : } else if (value->IsString() && !value->IsInternalizedString()) {
845 : return Type::OtherString();
846 : }
847 5449254 : return HeapConstant(i::Handle<i::HeapObject>::cast(value), zone);
848 : }
849 :
850 35632825 : Type* Type::Union(Type* type1, Type* type2, Zone* zone) {
851 : // Fast case: bit sets.
852 53540203 : if (type1->IsBitset() && type2->IsBitset()) {
853 19643264 : return BitsetType::New(type1->AsBitset() | type2->AsBitset());
854 : }
855 :
856 : // Fast case: top or bottom types.
857 25811193 : if (type1->IsAny() || type2->IsNone()) return type1;
858 25146542 : if (type2->IsAny() || type1->IsNone()) return type2;
859 :
860 : // Semi-fast case.
861 21710450 : if (type1->Is(type2)) return type2;
862 20043493 : if (type2->Is(type1)) return type1;
863 :
864 : // Slow case: create union.
865 13981156 : int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
866 13981156 : int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
867 13981156 : if (!AddIsSafe(size1, size2)) return Any();
868 13981156 : int size = size1 + size2;
869 13981156 : if (!AddIsSafe(size, 2)) return Any();
870 13981156 : size += 2;
871 13981156 : Type* result_type = UnionType::New(size, zone);
872 : UnionType* result = result_type->AsUnion();
873 : size = 0;
874 :
875 : // Compute the new bitset.
876 13981153 : bitset new_bitset = type1->BitsetGlb() | type2->BitsetGlb();
877 :
878 : // Deal with ranges.
879 : Type* range = None();
880 13981153 : Type* range1 = type1->GetRange();
881 13981152 : Type* range2 = type2->GetRange();
882 13981158 : if (range1 != NULL && range2 != NULL) {
883 : RangeType::Limits lims =
884 : RangeType::Limits::Union(RangeType::Limits(range1->AsRange()),
885 3157769 : RangeType::Limits(range2->AsRange()));
886 3157769 : Type* union_range = RangeType::New(lims, zone);
887 3157769 : range = NormalizeRangeAndBitset(union_range, &new_bitset, zone);
888 10823389 : } else if (range1 != NULL) {
889 5005190 : range = NormalizeRangeAndBitset(range1, &new_bitset, zone);
890 5818199 : } else if (range2 != NULL) {
891 2509100 : range = NormalizeRangeAndBitset(range2, &new_bitset, zone);
892 : }
893 13981151 : Type* bits = BitsetType::New(new_bitset);
894 23744608 : result->Set(size++, bits);
895 13981151 : if (!range->IsNone()) result->Set(size++, range);
896 :
897 13981151 : size = AddToUnion(type1, result, size, zone);
898 13981156 : size = AddToUnion(type2, result, size, zone);
899 13981151 : return NormalizeUnion(result_type, size, zone);
900 : }
901 :
902 : // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
903 : // Return new size of [result].
904 57085074 : int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) {
905 97037047 : if (type->IsBitset() || type->IsRange()) return size;
906 26122172 : if (type->IsUnion()) {
907 39375703 : for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
908 58234850 : size = AddToUnion(type->AsUnion()->Get(i), result, size, zone);
909 : }
910 : return size;
911 : }
912 29491415 : for (int i = 0; i < size; ++i) {
913 76693836 : if (type->Is(result->Get(i))) return size;
914 : }
915 14016767 : result->Set(size++, type);
916 14016767 : return size;
917 : }
918 :
919 14387287 : Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) {
920 : UnionType* unioned = union_type->AsUnion();
921 : DCHECK(size >= 1);
922 : DCHECK(unioned->Get(0)->IsBitset());
923 : // If the union has just one element, return it.
924 14387287 : if (size == 1) {
925 1467900 : return unioned->Get(0);
926 : }
927 : bitset bits = unioned->Get(0)->AsBitset();
928 : // If the union only consists of a range, we can get rid of the union.
929 13653337 : if (size == 2 && bits == BitsetType::kNone) {
930 1196811 : if (unioned->Get(1)->IsRange()) {
931 : return RangeType::New(unioned->Get(1)->AsRange()->Min(),
932 2393129 : unioned->Get(1)->AsRange()->Max(), zone);
933 : }
934 : }
935 : unioned->Shrink(size);
936 : SLOW_DCHECK(unioned->Wellformed());
937 12456770 : return union_type;
938 : }
939 :
940 73228 : int Type::NumConstants() {
941 : DisallowHeapAllocation no_allocation;
942 145118 : if (this->IsHeapConstant() || this->IsOtherNumberConstant()) {
943 : return 1;
944 71086 : } else if (this->IsUnion()) {
945 : int result = 0;
946 10222 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
947 13812 : if (this->AsUnion()->Get(i)->IsHeapConstant()) ++result;
948 : }
949 : return result;
950 : } else {
951 : return 0;
952 : }
953 : }
954 :
955 : // -----------------------------------------------------------------------------
956 : // Printing.
957 :
958 117852 : const char* BitsetType::Name(bitset bits) {
959 117852 : switch (bits) {
960 : #define RETURN_NAMED_TYPE(type, value) \
961 : case k##type: \
962 : return #type;
963 0 : PROPER_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
964 0 : INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_TYPE)
965 : #undef RETURN_NAMED_TYPE
966 :
967 : default:
968 0 : return NULL;
969 : }
970 : }
971 :
972 117852 : void BitsetType::Print(std::ostream& os, // NOLINT
973 : bitset bits) {
974 : DisallowHeapAllocation no_allocation;
975 117852 : const char* name = Name(bits);
976 117852 : if (name != NULL) {
977 117852 : os << name;
978 117852 : return;
979 : }
980 :
981 : // clang-format off
982 : static const bitset named_bitsets[] = {
983 : #define BITSET_CONSTANT(type, value) k##type,
984 : INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
985 : PROPER_BITSET_TYPE_LIST(BITSET_CONSTANT)
986 : #undef BITSET_CONSTANT
987 : };
988 : // clang-format on
989 :
990 : bool is_first = true;
991 0 : os << "(";
992 0 : for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) {
993 0 : bitset subset = named_bitsets[i];
994 0 : if ((bits & subset) == subset) {
995 0 : if (!is_first) os << " | ";
996 : is_first = false;
997 0 : os << Name(subset);
998 0 : bits -= subset;
999 : }
1000 : }
1001 : DCHECK(bits == 0);
1002 0 : os << ")";
1003 : }
1004 :
1005 117852 : void Type::PrintTo(std::ostream& os) {
1006 : DisallowHeapAllocation no_allocation;
1007 117852 : if (this->IsBitset()) {
1008 117852 : BitsetType::Print(os, this->AsBitset());
1009 0 : } else if (this->IsHeapConstant()) {
1010 0 : os << "HeapConstant(" << Brief(*this->AsHeapConstant()->Value()) << ")";
1011 0 : } else if (this->IsOtherNumberConstant()) {
1012 0 : os << "OtherNumberConstant(" << this->AsOtherNumberConstant()->Value()
1013 0 : << ")";
1014 0 : } else if (this->IsRange()) {
1015 0 : std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
1016 : std::streamsize saved_precision = os.precision(0);
1017 0 : os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max()
1018 0 : << ")";
1019 0 : os.flags(saved_flags);
1020 : os.precision(saved_precision);
1021 0 : } else if (this->IsUnion()) {
1022 0 : os << "(";
1023 0 : for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
1024 0 : Type* type_i = this->AsUnion()->Get(i);
1025 0 : if (i > 0) os << " | ";
1026 0 : type_i->PrintTo(os);
1027 : }
1028 0 : os << ")";
1029 0 : } else if (this->IsTuple()) {
1030 0 : os << "<";
1031 0 : for (int i = 0, n = this->AsTuple()->Arity(); i < n; ++i) {
1032 : Type* type_i = this->AsTuple()->Element(i);
1033 0 : if (i > 0) os << ", ";
1034 0 : type_i->PrintTo(os);
1035 : }
1036 0 : os << ">";
1037 : } else {
1038 0 : UNREACHABLE();
1039 : }
1040 117852 : }
1041 :
1042 : #ifdef DEBUG
1043 : void Type::Print() {
1044 : OFStream os(stdout);
1045 : PrintTo(os);
1046 : os << std::endl;
1047 : }
1048 : void BitsetType::Print(bitset bits) {
1049 : OFStream os(stdout);
1050 : Print(os, bits);
1051 : os << std::endl;
1052 : }
1053 : #endif
1054 :
1055 2253618 : BitsetType::bitset BitsetType::SignedSmall() {
1056 2253618 : return i::SmiValuesAre31Bits() ? kSigned31 : kSigned32;
1057 : }
1058 :
1059 73457 : BitsetType::bitset BitsetType::UnsignedSmall() {
1060 73457 : return i::SmiValuesAre31Bits() ? kUnsigned30 : kUnsigned31;
1061 : }
1062 :
1063 : } // namespace compiler
1064 : } // namespace internal
1065 : } // namespace v8
|