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

Side by Side Diff: src/types.cc

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

Powered by Google App Engine
This is Rietveld 408576698