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

Side by Side Diff: src/types.cc

Issue 437393005: Extend some operations to range types. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
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 "src/types.h" 5 #include "src/types.h"
6 6
7 #include "src/ostreams.h" 7 #include "src/ostreams.h"
8 #include "src/types-inl.h" 8 #include "src/types-inl.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 12
13
14 // -----------------------------------------------------------------------------
15 // Range-related custom order on numbers.
16 // We want -0 to be less than +0.
17
18 static bool le(double x, double y) {
19 return x <= y && copysign(1, x) <= copysign(1, y);
20 }
21
22
23 static bool eq(double x, double y) {
24 return le(x, y) && le(y, x);
25 }
26
27
13 // ----------------------------------------------------------------------------- 28 // -----------------------------------------------------------------------------
14 // Glb and lub computation. 29 // Glb and lub computation.
15 30
16 // The largest bitset subsumed by this type. 31 // The largest bitset subsumed by this type.
17 template<class Config> 32 template<class Config>
18 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { 33 int TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
19 DisallowHeapAllocation no_allocation; 34 DisallowHeapAllocation no_allocation;
20 if (type->IsBitset()) { 35 if (type->IsBitset()) {
21 return type->AsBitset(); 36 return type->AsBitset();
22 } else if (type->IsUnion()) { 37 } else if (type->IsUnion()) {
(...skipping 18 matching lines...) Expand all
41 for (int i = 0; i < unioned->Length(); ++i) { 56 for (int i = 0; i < unioned->Length(); ++i) {
42 bitset |= unioned->Get(i)->BitsetLub(); 57 bitset |= unioned->Get(i)->BitsetLub();
43 } 58 }
44 return bitset; 59 return bitset;
45 } else if (type->IsClass()) { 60 } else if (type->IsClass()) {
46 // Little hack to avoid the need for a region for handlification here... 61 // Little hack to avoid the need for a region for handlification here...
47 return Config::is_class(type) ? Lub(*Config::as_class(type)) : 62 return Config::is_class(type) ? Lub(*Config::as_class(type)) :
48 type->AsClass()->Bound(NULL)->AsBitset(); 63 type->AsClass()->Bound(NULL)->AsBitset();
49 } else if (type->IsConstant()) { 64 } else if (type->IsConstant()) {
50 return type->AsConstant()->Bound()->AsBitset(); 65 return type->AsConstant()->Bound()->AsBitset();
66 } else if (type->IsRange()) {
67 return type->AsRange()->Bound()->AsBitset();
51 } else if (type->IsContext()) { 68 } else if (type->IsContext()) {
52 return type->AsContext()->Bound()->AsBitset(); 69 return type->AsContext()->Bound()->AsBitset();
53 } else if (type->IsArray()) { 70 } else if (type->IsArray()) {
54 return type->AsArray()->Bound()->AsBitset(); 71 return type->AsArray()->Bound()->AsBitset();
55 } else if (type->IsFunction()) { 72 } else if (type->IsFunction()) {
56 return type->AsFunction()->Bound()->AsBitset(); 73 return type->AsFunction()->Bound()->AsBitset();
57 } else { 74 } else {
58 UNREACHABLE(); 75 UNREACHABLE();
59 return kNone; 76 return kNone;
60 } 77 }
(...skipping 10 matching lines...) Expand all
71 UnionHandle unioned = handle(type->AsUnion()); 88 UnionHandle unioned = handle(type->AsUnion());
72 int bitset = kNone; 89 int bitset = kNone;
73 for (int i = 0; i < unioned->Length(); ++i) { 90 for (int i = 0; i < unioned->Length(); ++i) {
74 bitset |= unioned->Get(i)->InherentBitsetLub(); 91 bitset |= unioned->Get(i)->InherentBitsetLub();
75 } 92 }
76 return bitset; 93 return bitset;
77 } else if (type->IsClass()) { 94 } else if (type->IsClass()) {
78 return Lub(*type->AsClass()->Map()); 95 return Lub(*type->AsClass()->Map());
79 } else if (type->IsConstant()) { 96 } else if (type->IsConstant()) {
80 return Lub(*type->AsConstant()->Value()); 97 return Lub(*type->AsConstant()->Value());
98 } else if (type->IsRange()) {
99 return Lub(type->AsRange()->Min(), type->AsRange()->Max());
81 } else if (type->IsContext()) { 100 } else if (type->IsContext()) {
82 return kInternal & kTaggedPtr; 101 return kInternal & kTaggedPtr;
83 } else if (type->IsArray()) { 102 } else if (type->IsArray()) {
84 return kArray; 103 return kArray;
85 } else if (type->IsFunction()) { 104 } else if (type->IsFunction()) {
86 return kFunction; 105 return kFunction;
87 } else { 106 } else {
88 UNREACHABLE(); 107 UNREACHABLE();
89 return kNone; 108 return kNone;
90 } 109 }
(...skipping 15 matching lines...) Expand all
106 DisallowHeapAllocation no_allocation; 125 DisallowHeapAllocation no_allocation;
107 if (i::IsMinusZero(value)) return kMinusZero; 126 if (i::IsMinusZero(value)) return kMinusZero;
108 if (std::isnan(value)) return kNaN; 127 if (std::isnan(value)) return kNaN;
109 if (IsUint32Double(value)) return Lub(FastD2UI(value)); 128 if (IsUint32Double(value)) return Lub(FastD2UI(value));
110 if (IsInt32Double(value)) return Lub(FastD2I(value)); 129 if (IsInt32Double(value)) return Lub(FastD2I(value));
111 return kOtherNumber; 130 return kOtherNumber;
112 } 131 }
113 132
114 133
115 template<class Config> 134 template<class Config>
135 int TypeImpl<Config>::BitsetType::Lub(double min, double max) {
136 DCHECK(le(min, max));
137 DisallowHeapAllocation no_allocation;
rossberg 2014/08/06 13:27:31 Nit: put this first
138 if (eq(min, max)) {
rossberg 2014/08/06 13:27:31 Style nit: same line: if (eq(min, max)) return
139 return BitsetType::Lub(min); // Singleton range.
140 }
141 int bitset = BitsetType::kNumber ^ SEMANTIC(BitsetType::kNaN);
142 if (le(0, min) || max < 0)
rossberg 2014/08/06 13:27:31 Style nit: same line
143 bitset ^= SEMANTIC(BitsetType::kMinusZero);
144 return bitset;
145 // TODO(neis): Could refine this further by doing more checks on min/max.
146 }
147
148
149 template<class Config>
116 int TypeImpl<Config>::BitsetType::Lub(int32_t value) { 150 int TypeImpl<Config>::BitsetType::Lub(int32_t value) {
117 if (value >= 0x40000000) { 151 if (value >= 0x40000000) {
118 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall; 152 return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall;
119 } 153 }
120 if (value >= 0) return kUnsignedSmall; 154 if (value >= 0) return kUnsignedSmall;
121 if (value >= -0x40000000) return kOtherSignedSmall; 155 if (value >= -0x40000000) return kOtherSignedSmall;
122 return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall; 156 return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall;
123 } 157 }
124 158
125 159
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 && *this->AsClass()->Map() == *that->AsClass()->Map() 283 && *this->AsClass()->Map() == *that->AsClass()->Map()
250 && ((Config::is_class(that) && Config::is_class(this)) || 284 && ((Config::is_class(that) && Config::is_class(this)) ||
251 BitsetType::New(this->BitsetLub())->Is( 285 BitsetType::New(this->BitsetLub())->Is(
252 BitsetType::New(that->BitsetLub()))); 286 BitsetType::New(that->BitsetLub())));
253 } 287 }
254 if (that->IsConstant()) { 288 if (that->IsConstant()) {
255 return this->IsConstant() 289 return this->IsConstant()
256 && *this->AsConstant()->Value() == *that->AsConstant()->Value() 290 && *this->AsConstant()->Value() == *that->AsConstant()->Value()
257 && this->AsConstant()->Bound()->Is(that->AsConstant()->Bound()); 291 && this->AsConstant()->Bound()->Is(that->AsConstant()->Bound());
258 } 292 }
293 if (that->IsRange()) {
294 return this->IsRange()
295 && this->AsRange()->Bound()->Is(that->AsRange()->Bound())
296 && le(that->AsRange()->Min(), this->AsRange()->Min())
297 && le(this->AsRange()->Max(), that->AsRange()->Max());
298 }
259 if (that->IsContext()) { 299 if (that->IsContext()) {
260 return this->IsContext() 300 return this->IsContext()
261 && this->AsContext()->Outer()->Equals(that->AsContext()->Outer()); 301 && this->AsContext()->Outer()->Equals(that->AsContext()->Outer());
262 } 302 }
263 if (that->IsArray()) { 303 if (that->IsArray()) {
264 return this->IsArray() 304 return this->IsArray()
265 && this->AsArray()->Element()->Equals(that->AsArray()->Element()); 305 && this->AsArray()->Element()->Equals(that->AsArray()->Element());
266 } 306 }
267 if (that->IsFunction()) { 307 if (that->IsFunction()) {
268 // We currently do not allow for any variance here, in order to keep 308 // We currently do not allow for any variance here, in order to keep
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 } 421 }
382 422
383 return false; 423 return false;
384 } 424 }
385 425
386 426
387 // Check if value is contained in (inhabits) type. 427 // Check if value is contained in (inhabits) type.
388 template<class Config> 428 template<class Config>
389 bool TypeImpl<Config>::Contains(i::Object* value) { 429 bool TypeImpl<Config>::Contains(i::Object* value) {
390 DisallowHeapAllocation no_allocation; 430 DisallowHeapAllocation no_allocation;
431 if (this->IsRange()) {
432 return value->IsNumber() &&
433 le(this->AsRange()->Min(), value->Number()) &&
434 le(value->Number(), this->AsRange()->Max()) &&
435 BitsetType::Is(BitsetType::Lub(value), this->BitsetLub());
436 }
391 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) { 437 for (Iterator<i::Object> it = this->Constants(); !it.Done(); it.Advance()) {
392 if (*it.Current() == value) return true; 438 if (*it.Current() == value) return true;
393 } 439 }
394 return BitsetType::New(BitsetType::Lub(value))->Is(this); 440 return BitsetType::New(BitsetType::Lub(value))->Is(this);
395 } 441 }
396 442
397 443
398 template<class Config> 444 template<class Config>
399 bool TypeImpl<Config>::UnionType::Wellformed() { 445 bool TypeImpl<Config>::UnionType::Wellformed() {
400 DCHECK(this->Length() >= 2); 446 DCHECK(this->Length() >= 2);
(...skipping 12 matching lines...) Expand all
413 // Union and intersection 459 // Union and intersection
414 460
415 template<class Config> 461 template<class Config>
416 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound( 462 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Rebound(
417 int bitset, Region* region) { 463 int bitset, Region* region) {
418 TypeHandle bound = BitsetType::New(bitset, region); 464 TypeHandle bound = BitsetType::New(bitset, region);
419 if (this->IsClass()) { 465 if (this->IsClass()) {
420 return ClassType::New(this->AsClass()->Map(), bound, region); 466 return ClassType::New(this->AsClass()->Map(), bound, region);
421 } else if (this->IsConstant()) { 467 } else if (this->IsConstant()) {
422 return ConstantType::New(this->AsConstant()->Value(), bound, region); 468 return ConstantType::New(this->AsConstant()->Value(), bound, region);
469 } else if (this->IsRange()) {
470 return RangeType::New(
471 this->AsRange()->Min(), this->AsRange()->Max(), bound, region);
423 } else if (this->IsContext()) { 472 } else if (this->IsContext()) {
424 return ContextType::New(this->AsContext()->Outer(), bound, region); 473 return ContextType::New(this->AsContext()->Outer(), bound, region);
425 } else if (this->IsArray()) { 474 } else if (this->IsArray()) {
426 return ArrayType::New(this->AsArray()->Element(), bound, region); 475 return ArrayType::New(this->AsArray()->Element(), bound, region);
427 } else if (this->IsFunction()) { 476 } else if (this->IsFunction()) {
428 FunctionType* function = this->AsFunction(); 477 FunctionType* function = this->AsFunction();
429 int arity = function->Arity(); 478 int arity = function->Arity();
430 FunctionHandle type = FunctionType::New( 479 FunctionHandle type = FunctionType::New(
431 function->Result(), function->Receiver(), bound, arity, region); 480 function->Result(), function->Receiver(), bound, arity, region);
432 for (int i = 0; i < arity; ++i) { 481 for (int i = 0; i < arity; ++i) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 if (type->IsUnion()) { 550 if (type->IsUnion()) {
502 UnionHandle unioned = handle(type->AsUnion()); 551 UnionHandle unioned = handle(type->AsUnion());
503 for (int i = 0; i < unioned->Length(); ++i) { 552 for (int i = 0; i < unioned->Length(); ++i) {
504 TypeHandle type_i = unioned->Get(i); 553 TypeHandle type_i = unioned->Get(i);
505 DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0)))); 554 DCHECK(i == 0 || !(type_i->IsBitset() || type_i->Is(unioned->Get(0))));
506 if (!type_i->IsBitset()) { 555 if (!type_i->IsBitset()) {
507 size = ExtendUnion(result, size, type_i, other, is_intersect, region); 556 size = ExtendUnion(result, size, type_i, other, is_intersect, region);
508 } 557 }
509 } 558 }
510 } else if (!type->IsBitset()) { 559 } else if (!type->IsBitset()) {
511 DCHECK(type->IsClass() || type->IsConstant() || 560 DCHECK(type->IsClass() || type->IsConstant() || type->IsRange() ||
512 type->IsArray() || type->IsFunction() || type->IsContext()); 561 type->IsContext() || type->IsArray() || type->IsFunction());
513 int inherent_bound = type->InherentBitsetLub(); 562 int inherent_bound = type->InherentBitsetLub();
514 int old_bound = type->BitsetLub(); 563 int old_bound = type->BitsetLub();
515 int other_bound = type->BoundBy(other->unhandle()) & inherent_bound; 564 int other_bound = type->BoundBy(other->unhandle()) & inherent_bound;
516 int new_bound = 565 int new_bound =
517 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound); 566 is_intersect ? (old_bound & other_bound) : (old_bound | other_bound);
518 if (new_bound != BitsetType::kNone) { 567 if (new_bound != BitsetType::kNone) {
519 int i = type->IndexInUnion(new_bound, result, size); 568 int i = type->IndexInUnion(new_bound, result, size);
520 if (i == -1) { 569 if (i == -1) {
521 i = size++; 570 i = size++;
522 } else if (result->Get(i)->IsBitset()) { 571 } else if (result->Get(i)->IsBitset()) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 if (type->IsBitset()) { 796 if (type->IsBitset()) {
748 return BitsetType::New(type->AsBitset(), region); 797 return BitsetType::New(type->AsBitset(), region);
749 } else if (type->IsClass()) { 798 } else if (type->IsClass()) {
750 return ClassType::New( 799 return ClassType::New(
751 type->AsClass()->Map(), 800 type->AsClass()->Map(),
752 BitsetType::New(type->BitsetLub(), region), region); 801 BitsetType::New(type->BitsetLub(), region), region);
753 } else if (type->IsConstant()) { 802 } else if (type->IsConstant()) {
754 return ConstantType::New( 803 return ConstantType::New(
755 type->AsConstant()->Value(), 804 type->AsConstant()->Value(),
756 Convert<OtherType>(type->AsConstant()->Bound(), region), region); 805 Convert<OtherType>(type->AsConstant()->Bound(), region), region);
806 } else if (type->IsRange()) {
807 return RangeType::New(
808 type->AsRange()->Min(), type->AsRange()->Max(),
809 Convert<OtherType>(type->AsRange()->Bound(), region), region);
757 } else if (type->IsContext()) { 810 } else if (type->IsContext()) {
758 TypeHandle outer = Convert<OtherType>(type->AsContext()->Outer(), region); 811 TypeHandle outer = Convert<OtherType>(type->AsContext()->Outer(), region);
759 return ContextType::New(outer, region); 812 return ContextType::New(outer, region);
760 } else if (type->IsUnion()) { 813 } else if (type->IsUnion()) {
761 int length = type->AsUnion()->Length(); 814 int length = type->AsUnion()->Length();
762 UnionHandle unioned = UnionType::New(length, region); 815 UnionHandle unioned = UnionType::New(length, region);
763 for (int i = 0; i < length; ++i) { 816 for (int i = 0; i < length; ++i) {
764 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region)); 817 unioned->Set(i, Convert<OtherType>(type->AsUnion()->Get(i), region));
765 } 818 }
766 return unioned; 819 return unioned;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; 970 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
918 971
919 template TypeImpl<ZoneTypeConfig>::TypeHandle 972 template TypeImpl<ZoneTypeConfig>::TypeHandle
920 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( 973 TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
921 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); 974 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
922 template TypeImpl<HeapTypeConfig>::TypeHandle 975 template TypeImpl<HeapTypeConfig>::TypeHandle
923 TypeImpl<HeapTypeConfig>::Convert<Type>( 976 TypeImpl<HeapTypeConfig>::Convert<Type>(
924 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); 977 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
925 978
926 } } // namespace v8::internal 979 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/types.h ('k') | test/cctest/test-types.cc » ('j') | test/cctest/test-types.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698