OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 namespace v8 { | 31 namespace v8 { |
32 namespace internal { | 32 namespace internal { |
33 | 33 |
34 // Unknown | 34 // Unknown |
35 // | | 35 // | |
36 // PrimitiveType | 36 // PrimitiveType |
37 // | \--------| | 37 // | \--------| |
38 // Number String | 38 // Number String |
39 // / | | | 39 // / | | |
40 // HeapNumber Integer32 | | 40 // Double Integer32 | |
41 // | | / | 41 // | | / |
42 // | Smi / | 42 // | Smi / |
43 // | / / | 43 // | / / |
44 // Uninitialized. | 44 // Uninitialized. |
45 | 45 |
46 class NumberInfo { | 46 class NumberInfo { |
47 public: | 47 public: |
48 NumberInfo() { } | 48 NumberInfo() { } |
49 | 49 |
50 static inline NumberInfo Unknown(); | 50 static inline NumberInfo Unknown(); |
51 // We know it's a primitive type. | 51 // We know it's a primitive type. |
52 static inline NumberInfo Primitive(); | 52 static inline NumberInfo Primitive(); |
53 // We know it's a number of some sort. | 53 // We know it's a number of some sort. |
54 static inline NumberInfo Number(); | 54 static inline NumberInfo Number(); |
55 // We know it's signed or unsigned 32 bit integer. | 55 // We know it's signed or unsigned 32 bit integer. |
56 static inline NumberInfo Integer32(); | 56 static inline NumberInfo Integer32(); |
57 // We know it's a Smi. | 57 // We know it's a Smi. |
58 static inline NumberInfo Smi(); | 58 static inline NumberInfo Smi(); |
59 // We know it's a heap number. | 59 // We know it's a heap number. |
60 static inline NumberInfo HeapNumber(); | 60 static inline NumberInfo Double(); |
61 // We know it's a string. | 61 // We know it's a string. |
62 static inline NumberInfo String(); | 62 static inline NumberInfo String(); |
63 // We haven't started collecting info yet. | 63 // We haven't started collecting info yet. |
64 static inline NumberInfo Uninitialized(); | 64 static inline NumberInfo Uninitialized(); |
65 | 65 |
66 // Return compact representation. Very sensitive to enum values below! | 66 // Return compact representation. Very sensitive to enum values below! |
67 // Compacting drops information about primtive types and strings types. | 67 // Compacting drops information about primtive types and strings types. |
68 // We use the compact representation when we only care about number types. | 68 // We use the compact representation when we only care about number types. |
69 int ThreeBitRepresentation() { | 69 int ThreeBitRepresentation() { |
70 ASSERT(type_ != kUninitializedType); | 70 ASSERT(type_ != kUninitializedType); |
71 int answer = type_ & 0xf; | 71 int answer = type_ & 0xf; |
72 answer = answer > 6 ? answer - 2 : answer; | 72 answer = answer > 6 ? answer - 2 : answer; |
73 ASSERT(answer >= 0); | 73 ASSERT(answer >= 0); |
74 ASSERT(answer <= 7); | 74 ASSERT(answer <= 7); |
75 return answer; | 75 return answer; |
76 } | 76 } |
77 | 77 |
78 // Decode compact representation. Very sensitive to enum values below! | 78 // Decode compact representation. Very sensitive to enum values below! |
79 static NumberInfo ExpandedRepresentation(int three_bit_representation) { | 79 static NumberInfo ExpandedRepresentation(int three_bit_representation) { |
80 Type t = static_cast<Type>(three_bit_representation >= 6 ? | 80 Type t = static_cast<Type>(three_bit_representation >= 6 ? |
81 three_bit_representation + 2 : | 81 three_bit_representation + 2 : |
82 three_bit_representation); | 82 three_bit_representation); |
83 t = (t == kUnknownType) ? t : static_cast<Type>(t | kPrimitiveType); | 83 t = (t == kUnknownType) ? t : static_cast<Type>(t | kPrimitiveType); |
84 ASSERT(t == kUnknownType || | 84 ASSERT(t == kUnknownType || |
85 t == kNumberType || | 85 t == kNumberType || |
86 t == kInteger32Type || | 86 t == kInteger32Type || |
87 t == kSmiType || | 87 t == kSmiType || |
88 t == kHeapNumberType); | 88 t == kDoubleType); |
89 return NumberInfo(t); | 89 return NumberInfo(t); |
90 } | 90 } |
91 | 91 |
92 int ToInt() { | 92 int ToInt() { |
93 return type_; | 93 return type_; |
94 } | 94 } |
95 | 95 |
96 static NumberInfo FromInt(int bit_representation) { | 96 static NumberInfo FromInt(int bit_representation) { |
97 Type t = static_cast<Type>(bit_representation); | 97 Type t = static_cast<Type>(bit_representation); |
98 ASSERT(t == kUnknownType || | 98 ASSERT(t == kUnknownType || |
99 t == kPrimitiveType || | 99 t == kPrimitiveType || |
100 t == kNumberType || | 100 t == kNumberType || |
101 t == kInteger32Type || | 101 t == kInteger32Type || |
102 t == kSmiType || | 102 t == kSmiType || |
103 t == kHeapNumberType || | 103 t == kDoubleType || |
104 t == kStringType); | 104 t == kStringType); |
105 return NumberInfo(t); | 105 return NumberInfo(t); |
106 } | 106 } |
107 | 107 |
108 // Return the weakest (least precise) common type. | 108 // Return the weakest (least precise) common type. |
109 static NumberInfo Combine(NumberInfo a, NumberInfo b) { | 109 static NumberInfo Combine(NumberInfo a, NumberInfo b) { |
110 return NumberInfo(static_cast<Type>(a.type_ & b.type_)); | 110 return NumberInfo(static_cast<Type>(a.type_ & b.type_)); |
111 } | 111 } |
112 | 112 |
| 113 |
| 114 // Integer32 is an integer that can be represented as either a signed |
| 115 // 32-bit integer or as an unsigned 32-bit integer. It has to be |
| 116 // in the range [-2^31, 2^32 - 1]. |
| 117 static inline bool IsInt32Double(double value) { |
| 118 if (value >= -0x80000000 && value <= 0xffffffffu) { |
| 119 if (value <= 0x7fffffff && value == static_cast<int32_t>(value)) { |
| 120 return true; |
| 121 } |
| 122 if (value == static_cast<uint32_t>(value)) return true; |
| 123 } |
| 124 return false; |
| 125 } |
| 126 |
| 127 static inline NumberInfo TypeFromValue(Handle<Object> value); |
| 128 |
113 inline bool IsUnknown() { | 129 inline bool IsUnknown() { |
114 return type_ == kUnknownType; | 130 return type_ == kUnknownType; |
115 } | 131 } |
116 | 132 |
117 inline bool IsNumber() { | 133 inline bool IsNumber() { |
118 ASSERT(type_ != kUninitializedType); | 134 ASSERT(type_ != kUninitializedType); |
119 return ((type_ & kNumberType) == kNumberType); | 135 return ((type_ & kNumberType) == kNumberType); |
120 } | 136 } |
121 | 137 |
122 inline bool IsSmi() { | 138 inline bool IsSmi() { |
123 ASSERT(type_ != kUninitializedType); | 139 ASSERT(type_ != kUninitializedType); |
124 return ((type_ & kSmiType) == kSmiType); | 140 return ((type_ & kSmiType) == kSmiType); |
125 } | 141 } |
126 | 142 |
127 inline bool IsInteger32() { | 143 inline bool IsInteger32() { |
128 ASSERT(type_ != kUninitializedType); | 144 ASSERT(type_ != kUninitializedType); |
129 return ((type_ & kInteger32Type) == kInteger32Type); | 145 return ((type_ & kInteger32Type) == kInteger32Type); |
130 } | 146 } |
131 | 147 |
132 inline bool IsHeapNumber() { | 148 inline bool IsDouble() { |
133 ASSERT(type_ != kUninitializedType); | 149 ASSERT(type_ != kUninitializedType); |
134 return ((type_ & kHeapNumberType) == kHeapNumberType); | 150 return ((type_ & kDoubleType) == kDoubleType); |
135 } | 151 } |
136 | 152 |
137 inline bool IsUninitialized() { | 153 inline bool IsUninitialized() { |
138 return type_ == kUninitializedType; | 154 return type_ == kUninitializedType; |
139 } | 155 } |
140 | 156 |
141 const char* ToString() { | 157 const char* ToString() { |
142 switch (type_) { | 158 switch (type_) { |
143 case kUnknownType: return "UnknownType"; | 159 case kUnknownType: return "UnknownType"; |
144 case kPrimitiveType: return "PrimitiveType"; | 160 case kPrimitiveType: return "PrimitiveType"; |
145 case kNumberType: return "NumberType"; | 161 case kNumberType: return "NumberType"; |
146 case kInteger32Type: return "Integer32Type"; | 162 case kInteger32Type: return "Integer32Type"; |
147 case kSmiType: return "SmiType"; | 163 case kSmiType: return "SmiType"; |
148 case kHeapNumberType: return "HeapNumberType"; | 164 case kDoubleType: return "DoubleType"; |
149 case kStringType: return "StringType"; | 165 case kStringType: return "StringType"; |
150 case kUninitializedType: | 166 case kUninitializedType: |
151 UNREACHABLE(); | 167 UNREACHABLE(); |
152 return "UninitializedType"; | 168 return "UninitializedType"; |
153 } | 169 } |
154 UNREACHABLE(); | 170 UNREACHABLE(); |
155 return "Unreachable code"; | 171 return "Unreachable code"; |
156 } | 172 } |
157 | 173 |
158 private: | 174 private: |
159 // We use 6 bits to represent the types. | 175 // We use 6 bits to represent the types. |
160 enum Type { | 176 enum Type { |
161 kUnknownType = 0, // 000000 | 177 kUnknownType = 0, // 000000 |
162 kPrimitiveType = 0x10, // 010000 | 178 kPrimitiveType = 0x10, // 010000 |
163 kNumberType = 0x11, // 010001 | 179 kNumberType = 0x11, // 010001 |
164 kInteger32Type = 0x13, // 010011 | 180 kInteger32Type = 0x13, // 010011 |
165 kSmiType = 0x17, // 010111 | 181 kSmiType = 0x17, // 010111 |
166 kHeapNumberType = 0x19, // 011001 | 182 kDoubleType = 0x19, // 011001 |
167 kStringType = 0x30, // 110000 | 183 kStringType = 0x30, // 110000 |
168 kUninitializedType = 0x3f // 111111 | 184 kUninitializedType = 0x3f // 111111 |
169 }; | 185 }; |
170 explicit inline NumberInfo(Type t) : type_(t) { } | 186 explicit inline NumberInfo(Type t) : type_(t) { } |
171 | 187 |
172 Type type_; | 188 Type type_; |
173 }; | 189 }; |
174 | 190 |
175 | 191 |
176 NumberInfo NumberInfo::Unknown() { | 192 NumberInfo NumberInfo::Unknown() { |
(...skipping 14 matching lines...) Expand all Loading... |
191 NumberInfo NumberInfo::Integer32() { | 207 NumberInfo NumberInfo::Integer32() { |
192 return NumberInfo(kInteger32Type); | 208 return NumberInfo(kInteger32Type); |
193 } | 209 } |
194 | 210 |
195 | 211 |
196 NumberInfo NumberInfo::Smi() { | 212 NumberInfo NumberInfo::Smi() { |
197 return NumberInfo(kSmiType); | 213 return NumberInfo(kSmiType); |
198 } | 214 } |
199 | 215 |
200 | 216 |
201 NumberInfo NumberInfo::HeapNumber() { | 217 NumberInfo NumberInfo::Double() { |
202 return NumberInfo(kHeapNumberType); | 218 return NumberInfo(kDoubleType); |
203 } | 219 } |
204 | 220 |
205 | 221 |
206 NumberInfo NumberInfo::String() { | 222 NumberInfo NumberInfo::String() { |
207 return NumberInfo(kStringType); | 223 return NumberInfo(kStringType); |
208 } | 224 } |
209 | 225 |
210 | 226 |
211 NumberInfo NumberInfo::Uninitialized() { | 227 NumberInfo NumberInfo::Uninitialized() { |
212 return NumberInfo(kUninitializedType); | 228 return NumberInfo(kUninitializedType); |
213 } | 229 } |
214 | 230 |
215 } } // namespace v8::internal | 231 } } // namespace v8::internal |
216 | 232 |
217 #endif // V8_NUMBER_INFO_H_ | 233 #endif // V8_NUMBER_INFO_H_ |
OLD | NEW |