OLD | NEW |
| (Empty) |
1 // Copyright 2010 the V8 project authors. All rights reserved. | |
2 // Redistribution and use in source and binary forms, with or without | |
3 // modification, are permitted provided that the following conditions are | |
4 // met: | |
5 // | |
6 // * Redistributions of source code must retain the above copyright | |
7 // notice, this list of conditions and the following disclaimer. | |
8 // * Redistributions in binary form must reproduce the above | |
9 // copyright notice, this list of conditions and the following | |
10 // disclaimer in the documentation and/or other materials provided | |
11 // with the distribution. | |
12 // * Neither the name of Google Inc. nor the names of its | |
13 // contributors may be used to endorse or promote products derived | |
14 // from this software without specific prior written permission. | |
15 // | |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | |
28 #ifndef V8_NUMBER_INFO_H_ | |
29 #define V8_NUMBER_INFO_H_ | |
30 | |
31 #include "globals.h" | |
32 | |
33 namespace v8 { | |
34 namespace internal { | |
35 | |
36 // Unknown | |
37 // | | |
38 // PrimitiveType | |
39 // | \--------| | |
40 // Number String | |
41 // / | | | |
42 // Double Integer32 | | |
43 // | | / | |
44 // | Smi / | |
45 // | / / | |
46 // Uninitialized. | |
47 | |
48 class NumberInfo { | |
49 public: | |
50 NumberInfo() { } | |
51 | |
52 static inline NumberInfo Unknown(); | |
53 // We know it's a primitive type. | |
54 static inline NumberInfo Primitive(); | |
55 // We know it's a number of some sort. | |
56 static inline NumberInfo Number(); | |
57 // We know it's signed or unsigned 32 bit integer. | |
58 static inline NumberInfo Integer32(); | |
59 // We know it's a Smi. | |
60 static inline NumberInfo Smi(); | |
61 // We know it's a heap number. | |
62 static inline NumberInfo Double(); | |
63 // We know it's a string. | |
64 static inline NumberInfo String(); | |
65 // We haven't started collecting info yet. | |
66 static inline NumberInfo Uninitialized(); | |
67 | |
68 // Return compact representation. Very sensitive to enum values below! | |
69 // Compacting drops information about primtive types and strings types. | |
70 // We use the compact representation when we only care about number types. | |
71 int ThreeBitRepresentation() { | |
72 ASSERT(type_ != kUninitializedType); | |
73 int answer = type_ & 0xf; | |
74 answer = answer > 6 ? answer - 2 : answer; | |
75 ASSERT(answer >= 0); | |
76 ASSERT(answer <= 7); | |
77 return answer; | |
78 } | |
79 | |
80 // Decode compact representation. Very sensitive to enum values below! | |
81 static NumberInfo ExpandedRepresentation(int three_bit_representation) { | |
82 Type t = static_cast<Type>(three_bit_representation >= 6 ? | |
83 three_bit_representation + 2 : | |
84 three_bit_representation); | |
85 t = (t == kUnknownType) ? t : static_cast<Type>(t | kPrimitiveType); | |
86 ASSERT(t == kUnknownType || | |
87 t == kNumberType || | |
88 t == kInteger32Type || | |
89 t == kSmiType || | |
90 t == kDoubleType); | |
91 return NumberInfo(t); | |
92 } | |
93 | |
94 int ToInt() { | |
95 return type_; | |
96 } | |
97 | |
98 static NumberInfo FromInt(int bit_representation) { | |
99 Type t = static_cast<Type>(bit_representation); | |
100 ASSERT(t == kUnknownType || | |
101 t == kPrimitiveType || | |
102 t == kNumberType || | |
103 t == kInteger32Type || | |
104 t == kSmiType || | |
105 t == kDoubleType || | |
106 t == kStringType); | |
107 return NumberInfo(t); | |
108 } | |
109 | |
110 // Return the weakest (least precise) common type. | |
111 static NumberInfo Combine(NumberInfo a, NumberInfo b) { | |
112 return NumberInfo(static_cast<Type>(a.type_ & b.type_)); | |
113 } | |
114 | |
115 | |
116 // Integer32 is an integer that can be represented as either a signed | |
117 // 32-bit integer or as an unsigned 32-bit integer. It has to be | |
118 // in the range [-2^31, 2^32 - 1]. We also have to check for negative 0 | |
119 // as it is not an Integer32. | |
120 static inline bool IsInt32Double(double value) { | |
121 const DoubleRepresentation minus_zero(-0.0); | |
122 DoubleRepresentation rep(value); | |
123 if (rep.bits == minus_zero.bits) return false; | |
124 if (value >= kMinInt && value <= kMaxUInt32) { | |
125 if (value <= kMaxInt && value == static_cast<int32_t>(value)) { | |
126 return true; | |
127 } | |
128 if (value == static_cast<uint32_t>(value)) return true; | |
129 } | |
130 return false; | |
131 } | |
132 | |
133 static inline NumberInfo TypeFromValue(Handle<Object> value); | |
134 | |
135 inline bool IsUnknown() { | |
136 return type_ == kUnknownType; | |
137 } | |
138 | |
139 inline bool IsNumber() { | |
140 ASSERT(type_ != kUninitializedType); | |
141 return ((type_ & kNumberType) == kNumberType); | |
142 } | |
143 | |
144 inline bool IsSmi() { | |
145 ASSERT(type_ != kUninitializedType); | |
146 return ((type_ & kSmiType) == kSmiType); | |
147 } | |
148 | |
149 inline bool IsInteger32() { | |
150 ASSERT(type_ != kUninitializedType); | |
151 return ((type_ & kInteger32Type) == kInteger32Type); | |
152 } | |
153 | |
154 inline bool IsDouble() { | |
155 ASSERT(type_ != kUninitializedType); | |
156 return ((type_ & kDoubleType) == kDoubleType); | |
157 } | |
158 | |
159 inline bool IsUninitialized() { | |
160 return type_ == kUninitializedType; | |
161 } | |
162 | |
163 const char* ToString() { | |
164 switch (type_) { | |
165 case kUnknownType: return "UnknownType"; | |
166 case kPrimitiveType: return "PrimitiveType"; | |
167 case kNumberType: return "NumberType"; | |
168 case kInteger32Type: return "Integer32Type"; | |
169 case kSmiType: return "SmiType"; | |
170 case kDoubleType: return "DoubleType"; | |
171 case kStringType: return "StringType"; | |
172 case kUninitializedType: | |
173 UNREACHABLE(); | |
174 return "UninitializedType"; | |
175 } | |
176 UNREACHABLE(); | |
177 return "Unreachable code"; | |
178 } | |
179 | |
180 private: | |
181 // We use 6 bits to represent the types. | |
182 enum Type { | |
183 kUnknownType = 0, // 000000 | |
184 kPrimitiveType = 0x10, // 010000 | |
185 kNumberType = 0x11, // 010001 | |
186 kInteger32Type = 0x13, // 010011 | |
187 kSmiType = 0x17, // 010111 | |
188 kDoubleType = 0x19, // 011001 | |
189 kStringType = 0x30, // 110000 | |
190 kUninitializedType = 0x3f // 111111 | |
191 }; | |
192 explicit inline NumberInfo(Type t) : type_(t) { } | |
193 | |
194 Type type_; | |
195 }; | |
196 | |
197 | |
198 NumberInfo NumberInfo::Unknown() { | |
199 return NumberInfo(kUnknownType); | |
200 } | |
201 | |
202 | |
203 NumberInfo NumberInfo::Primitive() { | |
204 return NumberInfo(kPrimitiveType); | |
205 } | |
206 | |
207 | |
208 NumberInfo NumberInfo::Number() { | |
209 return NumberInfo(kNumberType); | |
210 } | |
211 | |
212 | |
213 NumberInfo NumberInfo::Integer32() { | |
214 return NumberInfo(kInteger32Type); | |
215 } | |
216 | |
217 | |
218 NumberInfo NumberInfo::Smi() { | |
219 return NumberInfo(kSmiType); | |
220 } | |
221 | |
222 | |
223 NumberInfo NumberInfo::Double() { | |
224 return NumberInfo(kDoubleType); | |
225 } | |
226 | |
227 | |
228 NumberInfo NumberInfo::String() { | |
229 return NumberInfo(kStringType); | |
230 } | |
231 | |
232 | |
233 NumberInfo NumberInfo::Uninitialized() { | |
234 return NumberInfo(kUninitializedType); | |
235 } | |
236 | |
237 } } // namespace v8::internal | |
238 | |
239 #endif // V8_NUMBER_INFO_H_ | |
OLD | NEW |