Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: src/types.cc

Issue 1343933002: Fix type Intersection and Maybe (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/types.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <iomanip> 5 #include <iomanip>
6 6
7 #include "src/types.h" 7 #include "src/types.h"
8 8
9 #include "src/ostreams.h" 9 #include "src/ostreams.h"
10 #include "src/types-inl.h" 10 #include "src/types-inl.h"
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } else if (type->IsRange()) { 145 } else if (type->IsRange()) {
146 bitset glb = SEMANTIC( 146 bitset glb = SEMANTIC(
147 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); 147 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max()));
148 return glb | REPRESENTATION(type->BitsetLub()); 148 return glb | REPRESENTATION(type->BitsetLub());
149 } else { 149 } else {
150 return type->Representation(); 150 return type->Representation();
151 } 151 }
152 } 152 }
153 153
154 154
155 // The smallest bitset subsuming this type. 155 // The smallest bitset subsuming this type, possibly not a proper one.
156 template<class Config> 156 template<class Config>
157 typename TypeImpl<Config>::bitset 157 typename TypeImpl<Config>::bitset
158 TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { 158 TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
159 DisallowHeapAllocation no_allocation; 159 DisallowHeapAllocation no_allocation;
160 if (type->IsBitset()) return type->AsBitset(); 160 if (type->IsBitset()) return type->AsBitset();
161 if (type->IsUnion()) { 161 if (type->IsUnion()) {
162 // Take the representation from the first element, which is always 162 // Take the representation from the first element, which is always
163 // a bitset. 163 // a bitset.
164 int bitset = type->AsUnion()->Get(0)->BitsetLub(); 164 int bitset = type->AsUnion()->Get(0)->BitsetLub();
165 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { 165 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
166 // Other elements only contribute their semantic part. 166 // Other elements only contribute their semantic part.
167 bitset |= SEMANTIC(type->AsUnion()->Get(i)->BitsetLub()); 167 bitset |= SEMANTIC(type->AsUnion()->Get(i)->BitsetLub());
168 } 168 }
169 return bitset; 169 return bitset;
170 } 170 }
171 if (type->IsClass()) { 171 if (type->IsClass()) return type->AsClass()->Lub();
172 // Little hack to avoid the need for a region for handlification here... 172 if (type->IsConstant()) return type->AsConstant()->Lub();
173 return Config::is_class(type) ? Lub(*Config::as_class(type)) : 173 if (type->IsRange()) return type->AsRange()->Lub();
174 type->AsClass()->Bound(NULL)->AsBitset();
175 }
176 if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset();
177 if (type->IsRange()) return type->AsRange()->Bound();
178 if (type->IsContext()) return kInternal & kTaggedPointer; 174 if (type->IsContext()) return kInternal & kTaggedPointer;
179 if (type->IsArray()) return kOtherObject; 175 if (type->IsArray()) return kOtherObject;
180 if (type->IsFunction()) return kOtherObject; // TODO(rossberg): kFunction 176 if (type->IsFunction()) return kOtherObject; // TODO(rossberg): kFunction
181 UNREACHABLE(); 177 UNREACHABLE();
182 return kNone; 178 return kNone;
183 } 179 }
184 180
185 181
186 template<class Config> 182 template<class Config>
187 typename TypeImpl<Config>::bitset 183 typename TypeImpl<Config>::bitset
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 } 330 }
335 331
336 332
337 template<class Config> 333 template<class Config>
338 typename TypeImpl<Config>::bitset 334 typename TypeImpl<Config>::bitset
339 TypeImpl<Config>::BitsetType::Lub(double value) { 335 TypeImpl<Config>::BitsetType::Lub(double value) {
340 DisallowHeapAllocation no_allocation; 336 DisallowHeapAllocation no_allocation;
341 if (i::IsMinusZero(value)) return kMinusZero; 337 if (i::IsMinusZero(value)) return kMinusZero;
342 if (std::isnan(value)) return kNaN; 338 if (std::isnan(value)) return kNaN;
343 if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value); 339 if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
344 return kPlainNumber; 340 return kOtherNumber;
345 } 341 }
346 342
347 343
348 // Minimum values of regular numeric bitsets. 344 // Minimum values of plain numeric bitsets.
349 template <class Config> 345 template <class Config>
350 const typename TypeImpl<Config>::BitsetType::Boundary 346 const typename TypeImpl<Config>::BitsetType::Boundary
351 TypeImpl<Config>::BitsetType::BoundariesArray[] = { 347 TypeImpl<Config>::BitsetType::BoundariesArray[] = {
352 {kPlainNumber, -V8_INFINITY}, 348 {kOtherNumber, kPlainNumber, -V8_INFINITY},
353 {kNegative32, kMinInt}, 349 {kOtherSigned32, kNegative32, kMinInt},
354 {kNegative31, -0x40000000}, 350 {kNegative31, kNegative31, -0x40000000},
355 {kUnsigned30, 0}, 351 {kUnsigned30, kUnsigned30, 0},
356 {kUnsigned31, 0x40000000}, 352 {kOtherUnsigned31, kUnsigned31, 0x40000000},
357 {kUnsigned32, 0x80000000}, 353 {kOtherUnsigned32, kUnsigned32, 0x80000000},
358 {kPlainNumber, static_cast<double>(kMaxUInt32) + 1} 354 {kOtherNumber, kPlainNumber, static_cast<double>(kMaxUInt32) + 1}};
359 };
360 355
361 356
362 template <class Config> 357 template <class Config>
363 const typename TypeImpl<Config>::BitsetType::Boundary* 358 const typename TypeImpl<Config>::BitsetType::Boundary*
364 TypeImpl<Config>::BitsetType::Boundaries() { 359 TypeImpl<Config>::BitsetType::Boundaries() {
365 return BoundariesArray; 360 return BoundariesArray;
366 } 361 }
367 362
368 363
369 template <class Config> 364 template <class Config>
370 size_t TypeImpl<Config>::BitsetType::BoundariesSize() { 365 size_t TypeImpl<Config>::BitsetType::BoundariesSize() {
371 // Windows doesn't like arraysize here. 366 // Windows doesn't like arraysize here.
372 // return arraysize(BoundariesArray); 367 // return arraysize(BoundariesArray);
373 return 7; 368 return 7;
374 } 369 }
375 370
376 371
372 template <class Config>
373 typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::ExpandInternals(
374 typename TypeImpl<Config>::bitset bits) {
375 DisallowHeapAllocation no_allocation;
376 if (!(bits & SEMANTIC(kPlainNumber))) return bits; // Shortcut.
377 const Boundary* boundaries = Boundaries();
378 for (size_t i = 0; i < BoundariesSize(); ++i) {
379 DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external));
380 if (bits & SEMANTIC(boundaries[i].internal))
381 bits |= SEMANTIC(boundaries[i].external);
382 }
383 return bits;
384 }
385
386
377 template<class Config> 387 template<class Config>
378 typename TypeImpl<Config>::bitset 388 typename TypeImpl<Config>::bitset
379 TypeImpl<Config>::BitsetType::Lub(double min, double max) { 389 TypeImpl<Config>::BitsetType::Lub(double min, double max) {
380 DisallowHeapAllocation no_allocation; 390 DisallowHeapAllocation no_allocation;
381 int lub = kNone; 391 int lub = kNone;
382 const Boundary* mins = Boundaries(); 392 const Boundary* mins = Boundaries();
383 393
384 // Make sure the min-max range touches 0, so we are guaranteed no holes
385 // in unions of valid bitsets.
386 if (max < -1) max = -1;
387 if (min > 0) min = 0;
388
389 for (size_t i = 1; i < BoundariesSize(); ++i) { 394 for (size_t i = 1; i < BoundariesSize(); ++i) {
390 if (min < mins[i].min) { 395 if (min < mins[i].min) {
391 lub |= mins[i-1].bits; 396 lub |= mins[i-1].internal;
392 if (max < mins[i].min) return lub; 397 if (max < mins[i].min) return lub;
393 } 398 }
394 } 399 }
395 return lub |= mins[BoundariesSize() - 1].bits; 400 return lub | mins[BoundariesSize() - 1].internal;
396 } 401 }
397 402
398 403
399 template <class Config> 404 template <class Config>
400 typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::NumberBits( 405 typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::NumberBits(
401 bitset bits) { 406 bitset bits) {
402 return SEMANTIC(bits & kPlainNumber); 407 return SEMANTIC(bits & kPlainNumber);
403 } 408 }
404 409
405 410
406 template <class Config> 411 template <class Config>
407 void TypeImpl<Config>::BitsetType::CheckNumberBits(bitset bits) {
408 // Check that the bitset does not contain any holes in number ranges.
409 bitset number_bits = NumberBits(bits);
410 if (number_bits != 0) {
411 bitset lub = SEMANTIC(Lub(Min(number_bits), Max(number_bits)));
412 CHECK(lub == number_bits);
413 }
414 }
415
416 template <class Config>
417 typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::Glb( 412 typename TypeImpl<Config>::bitset TypeImpl<Config>::BitsetType::Glb(
418 double min, double max) { 413 double min, double max) {
419 DisallowHeapAllocation no_allocation; 414 DisallowHeapAllocation no_allocation;
420 int glb = kNone; 415 int glb = kNone;
421 const Boundary* mins = Boundaries(); 416 const Boundary* mins = Boundaries();
422 417
423 // If the range does not touch 0, the bound is empty. 418 // If the range does not touch 0, the bound is empty.
424 if (max < -1 || min > 0) return glb; 419 if (max < -1 || min > 0) return glb;
425 420
426 for (size_t i = 1; i + 1 < BoundariesSize(); ++i) { 421 for (size_t i = 1; i + 1 < BoundariesSize(); ++i) {
427 if (min <= mins[i].min) { 422 if (min <= mins[i].min) {
428 if (max + 1 < mins[i + 1].min) break; 423 if (max + 1 < mins[i + 1].min) break;
429 glb |= mins[i].bits; 424 glb |= mins[i].external;
430 } 425 }
431 } 426 }
432 // OtherNumber also contains float numbers, so it can never be 427 // OtherNumber also contains float numbers, so it can never be
433 // in the greatest lower bound. (There is also the small trouble 428 // in the greatest lower bound.
434 // of kOtherNumber having a range hole, which we can conveniently
435 // ignore here.)
436 return glb & ~(SEMANTIC(kOtherNumber)); 429 return glb & ~(SEMANTIC(kOtherNumber));
437 } 430 }
438 431
439 432
440 template <class Config> 433 template <class Config>
441 double TypeImpl<Config>::BitsetType::Min(bitset bits) { 434 double TypeImpl<Config>::BitsetType::Min(bitset bits) {
442 DisallowHeapAllocation no_allocation; 435 DisallowHeapAllocation no_allocation;
443 DCHECK(Is(SEMANTIC(bits), kNumber)); 436 DCHECK(Is(SEMANTIC(bits), kNumber));
444 const Boundary* mins = Boundaries(); 437 const Boundary* mins = Boundaries();
445 bool mz = SEMANTIC(bits & kMinusZero); 438 bool mz = SEMANTIC(bits & kMinusZero);
446 for (size_t i = 0; i < BoundariesSize(); ++i) { 439 for (size_t i = 0; i < BoundariesSize(); ++i) {
447 if (Is(SEMANTIC(mins[i].bits), bits)) { 440 if (Is(SEMANTIC(mins[i].internal), bits)) {
448 return mz ? std::min(0.0, mins[i].min) : mins[i].min; 441 return mz ? std::min(0.0, mins[i].min) : mins[i].min;
449 } 442 }
450 } 443 }
451 if (mz) return 0; 444 if (mz) return 0;
452 return std::numeric_limits<double>::quiet_NaN(); 445 return std::numeric_limits<double>::quiet_NaN();
453 } 446 }
454 447
455 448
456 template<class Config> 449 template<class Config>
457 double TypeImpl<Config>::BitsetType::Max(bitset bits) { 450 double TypeImpl<Config>::BitsetType::Max(bitset bits) {
458 DisallowHeapAllocation no_allocation; 451 DisallowHeapAllocation no_allocation;
459 DCHECK(Is(SEMANTIC(bits), kNumber)); 452 DCHECK(Is(SEMANTIC(bits), kNumber));
460 const Boundary* mins = Boundaries(); 453 const Boundary* mins = Boundaries();
461 bool mz = SEMANTIC(bits & kMinusZero); 454 bool mz = SEMANTIC(bits & kMinusZero);
462 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].bits), bits)) { 455 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].internal), bits)) {
463 return +V8_INFINITY; 456 return +V8_INFINITY;
464 } 457 }
465 for (size_t i = BoundariesSize() - 1; i-- > 0;) { 458 for (size_t i = BoundariesSize() - 1; i-- > 0;) {
466 if (Is(SEMANTIC(mins[i].bits), bits)) { 459 if (Is(SEMANTIC(mins[i].internal), bits)) {
467 return mz ? 460 return mz ?
468 std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1; 461 std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1;
469 } 462 }
470 } 463 }
471 if (mz) return 0; 464 if (mz) return 0;
472 return std::numeric_limits<double>::quiet_NaN(); 465 return std::numeric_limits<double>::quiet_NaN();
473 } 466 }
474 467
475 468
476 // ----------------------------------------------------------------------------- 469 // -----------------------------------------------------------------------------
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 // Fast path: If the bitset does not mention numbers, we can just keep the 930 // Fast path: If the bitset does not mention numbers, we can just keep the
938 // range. 931 // range.
939 bitset number_bits = BitsetType::NumberBits(*bits); 932 bitset number_bits = BitsetType::NumberBits(*bits);
940 if (number_bits == 0) { 933 if (number_bits == 0) {
941 return range; 934 return range;
942 } 935 }
943 936
944 // If the range is semantically contained within the bitset, return None and 937 // If the range is semantically contained within the bitset, return None and
945 // leave the bitset untouched. 938 // leave the bitset untouched.
946 bitset range_lub = SEMANTIC(range->BitsetLub()); 939 bitset range_lub = SEMANTIC(range->BitsetLub());
947 if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) { 940 if (BitsetType::Is(range_lub, *bits)) {
948 return None(region); 941 return None(region);
949 } 942 }
950 943
951 // Slow path: reconcile the bitset range and the range. 944 // Slow path: reconcile the bitset range and the range.
952 double bitset_min = BitsetType::Min(number_bits); 945 double bitset_min = BitsetType::Min(number_bits);
953 double bitset_max = BitsetType::Max(number_bits); 946 double bitset_max = BitsetType::Max(number_bits);
954 947
955 double range_min = range->Min(); 948 double range_min = range->Min();
956 double range_max = range->Max(); 949 double range_max = range->Max();
957 950
958 // Remove the number bits from the bitset, they would just confuse us now. 951 // Remove the number bits from the bitset, they would just confuse us now.
952 // NOTE: bits contains OtherNumber iff bits contains PlainNumber, in which
953 // case we already returned after the subtype check above.
959 *bits &= ~number_bits; 954 *bits &= ~number_bits;
960 955
961 if (range_min <= bitset_min && range_max >= bitset_max) { 956 if (range_min <= bitset_min && range_max >= bitset_max) {
962 // Bitset is contained within the range, just return the range. 957 // Bitset is contained within the range, just return the range.
963 return range; 958 return range;
964 } 959 }
965 960
966 if (bitset_min < range_min) { 961 if (bitset_min < range_min) {
967 range_min = bitset_min; 962 range_min = bitset_min;
968 } 963 }
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 1395
1401 template TypeImpl<ZoneTypeConfig>::TypeHandle 1396 template TypeImpl<ZoneTypeConfig>::TypeHandle
1402 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( 1397 TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
1403 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); 1398 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
1404 template TypeImpl<HeapTypeConfig>::TypeHandle 1399 template TypeImpl<HeapTypeConfig>::TypeHandle
1405 TypeImpl<HeapTypeConfig>::Convert<Type>( 1400 TypeImpl<HeapTypeConfig>::Convert<Type>(
1406 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); 1401 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
1407 1402
1408 } // namespace internal 1403 } // namespace internal
1409 } // namespace v8 1404 } // namespace v8
OLDNEW
« no previous file with comments | « src/types.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698