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

Side by Side Diff: src/types.h

Issue 133683002: Retry "Templatise type representation" after making clang happy (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 11 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/type-info.cc ('k') | src/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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 V(NumberOrString, kNumber | kString) \ 124 V(NumberOrString, kNumber | kString) \
125 V(Object, kUndetectable | kArray | kFunction | \ 125 V(Object, kUndetectable | kArray | kFunction | \
126 kRegExp | kOtherObject) \ 126 kRegExp | kOtherObject) \
127 V(Receiver, kObject | kProxy) \ 127 V(Receiver, kObject | kProxy) \
128 V(Allocated, kDouble | kName | kReceiver) \ 128 V(Allocated, kDouble | kName | kReceiver) \
129 V(Any, kOddball | kNumber | kAllocated | kInternal) \ 129 V(Any, kOddball | kNumber | kAllocated | kInternal) \
130 V(NonNumber, kAny - kNumber) \ 130 V(NonNumber, kAny - kNumber) \
131 V(Detectable, kAllocated - kUndetectable) 131 V(Detectable, kAllocated - kUndetectable)
132 132
133 133
134 class Type : public Object { 134 // struct Config {
135 // typedef Base;
136 // typedef Unioned;
137 // typedef Region;
138 // template<class> struct Handle { typedef type; } // No template typedefs...
139 // static Handle<Type>::type handle(Type* type); // !is_bitset(type)
140 // static bool is_bitset(Type* type);
141 // static bool is_class(Type* type);
142 // static bool is_constant(Type* type);
143 // static bool is_union(Type* type);
144 // static int as_bitset(Type* type);
145 // static i::Handle<i::Map> as_class(Type* type);
146 // static i::Handle<i::Object> as_constant(Type* type);
147 // static Handle<Unioned>::type as_union(Type* type);
148 // static Type* from_bitset(int bitset);
149 // static Handle<Type>::type from_bitset(int bitset, Region* region);
150 // static Handle<Type>::type from_class(i::Handle<i::Map> map, Region* region)
151 // static Handle<Type>::type from_constant(
152 // i::Handle<i::Object> value, Region* region);
153 // static Handle<Type>::type from_union(Handle<Unioned>::T unioned);
154 // static Handle<Unioned>::type union_create(int size, Region* region);
155 // static Handle<Type>::type union_get(Handle<Unioned>::T unioned, int i);
156 // }
157 template<class Config>
158 class TypeImpl : public Config::Base {
135 public: 159 public:
136 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ 160 typedef typename Config::template Handle<TypeImpl>::type TypeHandle;
137 static Type* type() { return from_bitset(k##type); } 161 typedef typename Config::Region Region;
162
163 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \
164 static TypeImpl* type() { return Config::from_bitset(k##type); } \
165 static TypeHandle type(Region* region) { \
166 return Config::from_bitset(k##type, region); \
167 }
138 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) 168 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR)
139 #undef DEFINE_TYPE_CONSTRUCTOR 169 #undef DEFINE_TYPE_CONSTRUCTOR
140 170
141 static Type* Class(Handle<i::Map> map) { return from_handle(map); } 171 static TypeHandle Class(i::Handle<i::Map> map, Region* region) {
142 static Type* Constant(Handle<i::HeapObject> value) { 172 return Config::from_class(map, region);
143 return Constant(value, value->GetIsolate());
144 } 173 }
145 static Type* Constant(Handle<i::Object> value, Isolate* isolate) { 174 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) {
146 return from_handle(isolate->factory()->NewBox(value)); 175 return Config::from_constant(value, region);
147 } 176 }
148 177
149 static Type* Union(Handle<Type> type1, Handle<Type> type2); 178 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
150 static Type* Intersect(Handle<Type> type1, Handle<Type> type2); 179 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
151 static Type* Optional(Handle<Type> type); // type \/ Undefined
152 180
153 static Type* Of(Handle<i::Object> value) { 181 static TypeHandle Of(i::Handle<i::Object> value, Region* region) {
154 return from_bitset(LubBitset(*value)); 182 return Config::from_bitset(LubBitset(*value), region);
155 } 183 }
156 184
157 bool Is(Type* that) { return this == that || SlowIs(that); } 185 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); }
158 bool Is(Handle<Type> that) { return this->Is(*that); } 186 bool Is(TypeHandle that) { return this->Is(*that); }
159 bool Maybe(Type* that); 187 bool Maybe(TypeImpl* that);
160 bool Maybe(Handle<Type> that) { return this->Maybe(*that); } 188 bool Maybe(TypeHandle that) { return this->Maybe(*that); }
161 189
162 // State-dependent versions of Of and Is that consider subtyping between 190 // State-dependent versions of Of and Is that consider subtyping between
163 // a constant and its map class. 191 // a constant and its map class.
164 static Type* OfCurrently(Handle<i::Object> value); 192 static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region);
165 bool IsCurrently(Type* that); 193 bool IsCurrently(TypeImpl* that);
166 bool IsCurrently(Handle<Type> that) { return this->IsCurrently(*that); } 194 bool IsCurrently(TypeHandle that) { return this->IsCurrently(*that); }
167 195
168 bool IsClass() { return is_class(); } 196 bool IsClass() { return Config::is_class(this); }
169 bool IsConstant() { return is_constant(); } 197 bool IsConstant() { return Config::is_constant(this); }
170 Handle<i::Map> AsClass() { return as_class(); } 198 i::Handle<i::Map> AsClass() { return Config::as_class(this); }
171 Handle<i::Object> AsConstant() { return as_constant(); } 199 i::Handle<i::Object> AsConstant() { return Config::as_constant(this); }
172 200
173 int NumClasses(); 201 int NumClasses();
174 int NumConstants(); 202 int NumConstants();
175 203
176 template<class T> 204 template<class T>
177 class Iterator { 205 class Iterator {
178 public: 206 public:
179 bool Done() const { return index_ < 0; } 207 bool Done() const { return index_ < 0; }
180 Handle<T> Current(); 208 i::Handle<T> Current();
181 void Advance(); 209 void Advance();
182 210
183 private: 211 private:
184 friend class Type; 212 template<class> friend class TypeImpl;
185 213
186 Iterator() : index_(-1) {} 214 Iterator() : index_(-1) {}
187 explicit Iterator(Handle<Type> type) : type_(type), index_(-1) { 215 explicit Iterator(TypeHandle type) : type_(type), index_(-1) {
188 Advance(); 216 Advance();
189 } 217 }
190 218
191 inline bool matches(Handle<Type> type); 219 inline bool matches(TypeHandle type);
192 inline Handle<Type> get_type(); 220 inline TypeHandle get_type();
193 221
194 Handle<Type> type_; 222 TypeHandle type_;
195 int index_; 223 int index_;
196 }; 224 };
197 225
198 Iterator<i::Map> Classes() { 226 Iterator<i::Map> Classes() {
199 if (this->is_bitset()) return Iterator<i::Map>(); 227 if (this->IsBitset()) return Iterator<i::Map>();
200 return Iterator<i::Map>(this->handle()); 228 return Iterator<i::Map>(Config::handle(this));
201 } 229 }
202 Iterator<i::Object> Constants() { 230 Iterator<i::Object> Constants() {
203 if (this->is_bitset()) return Iterator<i::Object>(); 231 if (this->IsBitset()) return Iterator<i::Object>();
204 return Iterator<i::Object>(this->handle()); 232 return Iterator<i::Object>(Config::handle(this));
205 } 233 }
206 234
207 static Type* cast(i::Object* object) { 235 static TypeImpl* cast(i::Object* object) {
208 Type* t = static_cast<Type*>(object); 236 TypeImpl* t = static_cast<TypeImpl*>(object);
209 ASSERT(t->is_bitset() || t->is_class() || 237 ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion());
210 t->is_constant() || t->is_union());
211 return t; 238 return t;
212 } 239 }
213 240
214 #ifdef OBJECT_PRINT 241 #ifdef OBJECT_PRINT
215 void TypePrint(); 242 void TypePrint();
216 void TypePrint(FILE* out); 243 void TypePrint(FILE* out);
217 #endif 244 #endif
218 245
219 private: 246 private:
247 template<class> friend class Iterator;
248
220 // A union is a fixed array containing types. Invariants: 249 // A union is a fixed array containing types. Invariants:
221 // - its length is at least 2 250 // - its length is at least 2
222 // - at most one field is a bitset, and it must go into index 0 251 // - at most one field is a bitset, and it must go into index 0
223 // - no field is a union 252 // - no field is a union
224 typedef FixedArray Unioned; 253 typedef typename Config::Unioned Unioned;
254 typedef typename Config::template Handle<Unioned>::type UnionedHandle;
225 255
226 enum { 256 enum {
227 #define DECLARE_TYPE(type, value) k##type = (value), 257 #define DECLARE_TYPE(type, value) k##type = (value),
228 BITSET_TYPE_LIST(DECLARE_TYPE) 258 BITSET_TYPE_LIST(DECLARE_TYPE)
229 #undef DECLARE_TYPE 259 #undef DECLARE_TYPE
230 kUnusedEOL = 0 260 kUnusedEOL = 0
231 }; 261 };
232 262
233 bool is_none() { return this == None(); } 263 bool IsNone() { return this == None(); }
234 bool is_bitset() { return this->IsSmi(); } 264 bool IsAny() { return this == Any(); }
235 bool is_class() { return this->IsMap(); } 265 bool IsBitset() { return Config::is_bitset(this); }
236 bool is_constant() { return this->IsBox(); } 266 bool IsUnion() { return Config::is_union(this); }
237 bool is_union() { return this->IsFixedArray(); } 267 int AsBitset() { return Config::as_bitset(this); }
268 UnionedHandle AsUnion() { return Config::as_union(this); }
238 269
239 bool SlowIs(Type* that); 270 bool SlowIs(TypeImpl* that);
240
241 int as_bitset() { return Smi::cast(this)->value(); }
242 Handle<i::Map> as_class() { return Handle<i::Map>::cast(handle()); }
243 Handle<i::Object> as_constant() {
244 Handle<i::Box> box = Handle<i::Box>::cast(handle());
245 return i::handle(box->value(), box->GetIsolate());
246 }
247 Handle<Unioned> as_union() { return Handle<Unioned>::cast(handle()); }
248
249 Handle<Type> handle() { return handle_via_isolate_of(this); }
250 Handle<Type> handle_via_isolate_of(Type* type) {
251 ASSERT(type->IsHeapObject());
252 return i::handle(this, i::HeapObject::cast(type)->GetIsolate());
253 }
254
255 static Type* from_bitset(int bitset) {
256 return static_cast<Type*>(i::Object::cast(i::Smi::FromInt(bitset)));
257 }
258 static Type* from_handle(Handle<i::HeapObject> handle) {
259 return static_cast<Type*>(i::Object::cast(*handle));
260 }
261
262 static Handle<Type> union_get(Handle<Unioned> unioned, int i) {
263 Type* type = static_cast<Type*>(unioned->get(i));
264 ASSERT(!type->is_union());
265 return type->handle_via_isolate_of(from_handle(unioned));
266 }
267 271
268 int LubBitset(); // least upper bound that's a bitset 272 int LubBitset(); // least upper bound that's a bitset
269 int GlbBitset(); // greatest lower bound that's a bitset 273 int GlbBitset(); // greatest lower bound that's a bitset
270 274
271 static int LubBitset(i::Object* value); 275 static int LubBitset(i::Object* value);
272 static int LubBitset(i::Map* map); 276 static int LubBitset(i::Map* map);
273 277
274 bool InUnion(Handle<Unioned> unioned, int current_size); 278 bool InUnion(UnionedHandle unioned, int current_size);
275 int ExtendUnion(Handle<Unioned> unioned, int current_size); 279 int ExtendUnion(UnionedHandle unioned, int current_size);
276 int ExtendIntersection( 280 int ExtendIntersection(
277 Handle<Unioned> unioned, Handle<Type> type, int current_size); 281 UnionedHandle unioned, TypeHandle type, int current_size);
278 282
279 static const char* bitset_name(int bitset); 283 static const char* bitset_name(int bitset);
280 }; 284 };
281 285
282 286
287 struct HeapTypeConfig {
288 typedef TypeImpl<HeapTypeConfig> Type;
289 typedef i::Object Base;
290 typedef i::FixedArray Unioned;
291 typedef i::Isolate Region;
292 template<class T> struct Handle { typedef i::Handle<T> type; };
293
294 static i::Handle<Type> handle(Type* type) {
295 return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
296 }
297
298 static bool is_bitset(Type* type) { return type->IsSmi(); }
299 static bool is_class(Type* type) { return type->IsMap(); }
300 static bool is_constant(Type* type) { return type->IsBox(); }
301 static bool is_union(Type* type) { return type->IsFixedArray(); }
302
303 static int as_bitset(Type* type) {
304 return Smi::cast(type)->value();
305 }
306 static i::Handle<i::Map> as_class(Type* type) {
307 return i::handle(i::Map::cast(type));
308 }
309 static i::Handle<i::Object> as_constant(Type* type) {
310 i::Box* box = i::Box::cast(type);
311 return i::handle(box->value(), box->GetIsolate());
312 }
313 static i::Handle<Unioned> as_union(Type* type) {
314 return i::handle(i::FixedArray::cast(type));
315 }
316
317 static Type* from_bitset(int bitset) {
318 return Type::cast(i::Smi::FromInt(bitset));
319 }
320 static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) {
321 return i::handle(from_bitset(bitset), isolate);
322 }
323 static i::Handle<Type> from_class(i::Handle<i::Map> map, Isolate* isolate) {
324 return i::Handle<Type>::cast(i::Handle<Object>::cast(map));
325 }
326 static i::Handle<Type> from_constant(
327 i::Handle<i::Object> value, Isolate* isolate) {
328 ASSERT(isolate || value->IsHeapObject());
329 if (!isolate) isolate = i::HeapObject::cast(*value)->GetIsolate();
330 i::Handle<Box> box = isolate->factory()->NewBox(value);
331 return i::Handle<Type>::cast(i::Handle<Object>::cast(box));
332 }
333 static i::Handle<Type> from_union(i::Handle<Unioned> unioned) {
334 return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned));
335 }
336
337 static i::Handle<Unioned> union_create(int size, Isolate* isolate) {
338 return isolate->factory()->NewFixedArray(size);
339 }
340 static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) {
341 Type* type = static_cast<Type*>(unioned->get(i));
342 ASSERT(!is_union(type));
343 return i::handle(type, unioned->GetIsolate());
344 }
345 };
346
347 typedef TypeImpl<HeapTypeConfig> Type;
348
349
283 // A simple struct to represent a pair of lower/upper type bounds. 350 // A simple struct to represent a pair of lower/upper type bounds.
284 struct Bounds { 351 template<class Config>
285 Handle<Type> lower; 352 struct BoundsImpl {
286 Handle<Type> upper; 353 typedef TypeImpl<Config> Type;
354 typedef typename Type::TypeHandle TypeHandle;
355 typedef typename Type::Region Region;
287 356
288 Bounds() {} 357 TypeHandle lower;
289 Bounds(Handle<Type> l, Handle<Type> u) : lower(l), upper(u) { 358 TypeHandle upper;
290 ASSERT(lower->Is(upper)); 359
291 } 360 BoundsImpl() {}
292 Bounds(Type* l, Type* u, Isolate* isl) : lower(l, isl), upper(u, isl) { 361 explicit BoundsImpl(TypeHandle t) : lower(t), upper(t) {}
293 ASSERT(lower->Is(upper)); 362 BoundsImpl(TypeHandle l, TypeHandle u) : lower(l), upper(u) {
294 }
295 explicit Bounds(Handle<Type> t) : lower(t), upper(t) {
296 ASSERT(lower->Is(upper));
297 }
298 Bounds(Type* t, Isolate* isl) : lower(t, isl), upper(t, isl) {
299 ASSERT(lower->Is(upper)); 363 ASSERT(lower->Is(upper));
300 } 364 }
301 365
302 // Unrestricted bounds. 366 // Unrestricted bounds.
303 static Bounds Unbounded(Isolate* isl) { 367 static BoundsImpl Unbounded(Region* region) {
304 return Bounds(Type::None(), Type::Any(), isl); 368 return BoundsImpl(Type::None(region), Type::Any(region));
305 } 369 }
306 370
307 // Meet: both b1 and b2 are known to hold. 371 // Meet: both b1 and b2 are known to hold.
308 static Bounds Both(Bounds b1, Bounds b2, Isolate* isl) { 372 static BoundsImpl Both(BoundsImpl b1, BoundsImpl b2, Region* region) {
309 Handle<Type> lower(Type::Union(b1.lower, b2.lower), isl); 373 TypeHandle lower = Type::Union(b1.lower, b2.lower, region);
310 Handle<Type> upper(Type::Intersect(b1.upper, b2.upper), isl); 374 TypeHandle upper = Type::Intersect(b1.upper, b2.upper, region);
311 // Lower bounds are considered approximate, correct as necessary. 375 // Lower bounds are considered approximate, correct as necessary.
312 lower = handle(Type::Intersect(lower, upper), isl); 376 lower = Type::Intersect(lower, upper, region);
313 return Bounds(lower, upper); 377 return BoundsImpl(lower, upper);
314 } 378 }
315 379
316 // Join: either b1 or b2 is known to hold. 380 // Join: either b1 or b2 is known to hold.
317 static Bounds Either(Bounds b1, Bounds b2, Isolate* isl) { 381 static BoundsImpl Either(BoundsImpl b1, BoundsImpl b2, Region* region) {
318 return Bounds( 382 TypeHandle lower = Type::Intersect(b1.lower, b2.lower, region);
319 handle(Type::Intersect(b1.lower, b2.lower), isl), 383 TypeHandle upper = Type::Union(b1.upper, b2.upper, region);
320 handle(Type::Union(b1.upper, b2.upper), isl)); 384 return BoundsImpl(lower, upper);
321 } 385 }
322 386
323 static Bounds NarrowLower(Bounds b, Handle<Type> t, Isolate* isl) { 387 static BoundsImpl NarrowLower(BoundsImpl b, TypeHandle t, Region* region) {
324 // Lower bounds are considered approximate, correct as necessary. 388 // Lower bounds are considered approximate, correct as necessary.
325 t = handle(Type::Intersect(t, b.upper), isl); 389 t = Type::Intersect(t, b.upper, region);
326 return Bounds(handle(Type::Union(b.lower, t), isl), b.upper); 390 TypeHandle lower = Type::Union(b.lower, t, region);
391 return BoundsImpl(lower, b.upper);
327 } 392 }
328 static Bounds NarrowUpper(Bounds b, Handle<Type> t, Isolate* isl) { 393 static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) {
329 return Bounds( 394 TypeHandle lower = Type::Intersect(b.lower, t, region);
330 handle(Type::Intersect(b.lower, t), isl), 395 TypeHandle upper = Type::Intersect(b.upper, t, region);
331 handle(Type::Intersect(b.upper, t), isl)); 396 return BoundsImpl(lower, upper);
332 } 397 }
333 }; 398 };
334 399
400 typedef BoundsImpl<HeapTypeConfig> Bounds;
401
402
335 } } // namespace v8::internal 403 } } // namespace v8::internal
336 404
337 #endif // V8_TYPES_H_ 405 #endif // V8_TYPES_H_
OLDNEW
« no previous file with comments | « src/type-info.cc ('k') | src/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698