OLD | NEW |
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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 // struct Config { | 134 // struct Config { |
135 // typedef Base; | 135 // typedef Base; |
136 // typedef Unioned; | 136 // typedef Unioned; |
137 // typedef Region; | 137 // typedef Region; |
138 // template<class> struct Handle { typedef type; } // No template typedefs... | 138 // template<class> struct Handle { typedef type; } // No template typedefs... |
139 // static Handle<Type>::type handle(Type* type); // !is_bitset(type) | 139 // static Handle<Type>::type handle(Type* type); // !is_bitset(type) |
140 // static bool is_bitset(Type*); | 140 // static bool is_bitset(Type* type); |
141 // static bool is_class(Type*); | 141 // static bool is_class(Type* type); |
142 // static bool is_constant(Type*); | 142 // static bool is_constant(Type* type); |
143 // static bool is_union(Type*); | 143 // static bool is_union(Type* type); |
144 // static int as_bitset(Type*); | 144 // static int as_bitset(Type* type); |
145 // static i::Handle<i::Map> as_class(Type*); | 145 // static i::Handle<i::Map> as_class(Type* type); |
146 // static i::Handle<i::Object> as_constant(Type*); | 146 // static i::Handle<i::Object> as_constant(Type* type); |
147 // static Handle<Unioned>::type as_union(Type*); | 147 // static Handle<Unioned>::type as_union(Type* type); |
148 // static Type* from_bitset(int bitset); | 148 // static Type* from_bitset(int bitset); |
149 // static Handle<Type>::type from_bitset(int bitset, Region*); | 149 // static Handle<Type>::type from_bitset(int bitset, Region* region); |
150 // static Handle<Type>::type from_class(i::Handle<i::Map>, Region*) | 150 // static Handle<Type>::type from_class(i::Handle<i::Map> map, Region* region) |
151 // static Handle<Type>::type from_constant(i::Handle<i::Object>, Region*); | 151 // static Handle<Type>::type from_constant( |
152 // static Handle<Type>::type from_union(Handle<Unioned>::type); | 152 // i::Handle<i::Object> value, Region* region); |
153 // static Handle<Unioned>::type union_create(int size, Region*); | 153 // static Handle<Type>::type from_union(Handle<Unioned>::T unioned); |
154 // static void union_shrink(Handle<Unioned>::type, int size); | 154 // static Handle<Unioned>::type union_create(int size, Region* region); |
155 // static Handle<Type>::type union_get(Handle<Unioned>::type, int); | 155 // static Handle<Type>::type union_get(Handle<Unioned>::T unioned, int i); |
156 // static void union_set(Handle<Unioned>::type, int, Handle<Type>::type); | |
157 // static int union_length(Handle<Unioned>::type); | |
158 // } | 156 // } |
159 template<class Config> | 157 template<class Config> |
160 class TypeImpl : public Config::Base { | 158 class TypeImpl : public Config::Base { |
161 public: | 159 public: |
162 typedef typename Config::template Handle<TypeImpl>::type TypeHandle; | 160 typedef typename Config::template Handle<TypeImpl>::type TypeHandle; |
163 typedef typename Config::Region Region; | 161 typedef typename Config::Region Region; |
164 | 162 |
165 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 163 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ |
166 static TypeImpl* type() { return Config::from_bitset(k##type); } \ | 164 static TypeImpl* type() { return Config::from_bitset(k##type); } \ |
167 static TypeHandle type(Region* region) { \ | 165 static TypeHandle type(Region* region) { \ |
(...skipping 10 matching lines...) Expand all Loading... |
178 } | 176 } |
179 | 177 |
180 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); | 178 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); |
181 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); | 179 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); |
182 | 180 |
183 static TypeHandle Of(i::Handle<i::Object> value, Region* region) { | 181 static TypeHandle Of(i::Handle<i::Object> value, Region* region) { |
184 return Config::from_bitset(LubBitset(*value), region); | 182 return Config::from_bitset(LubBitset(*value), region); |
185 } | 183 } |
186 | 184 |
187 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } | 185 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } |
188 template<class TypeHandle> | |
189 bool Is(TypeHandle that) { return this->Is(*that); } | 186 bool Is(TypeHandle that) { return this->Is(*that); } |
190 bool Maybe(TypeImpl* that); | 187 bool Maybe(TypeImpl* that); |
191 template<class TypeHandle> | |
192 bool Maybe(TypeHandle that) { return this->Maybe(*that); } | 188 bool Maybe(TypeHandle that) { return this->Maybe(*that); } |
193 | 189 |
194 // State-dependent versions of Of and Is that consider subtyping between | 190 // State-dependent versions of Of and Is that consider subtyping between |
195 // a constant and its map class. | 191 // a constant and its map class. |
196 static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region); | 192 static TypeHandle OfCurrently(i::Handle<i::Object> value, Region* region); |
197 bool IsCurrently(TypeImpl* that); | 193 bool IsCurrently(TypeImpl* that); |
198 template<class TypeHandle> | |
199 bool IsCurrently(TypeHandle that) { return this->IsCurrently(*that); } | 194 bool IsCurrently(TypeHandle that) { return this->IsCurrently(*that); } |
200 | 195 |
201 bool IsClass() { return Config::is_class(this); } | 196 bool IsClass() { return Config::is_class(this); } |
202 bool IsConstant() { return Config::is_constant(this); } | 197 bool IsConstant() { return Config::is_constant(this); } |
203 i::Handle<i::Map> AsClass() { return Config::as_class(this); } | 198 i::Handle<i::Map> AsClass() { return Config::as_class(this); } |
204 i::Handle<i::Object> AsConstant() { return Config::as_constant(this); } | 199 i::Handle<i::Object> AsConstant() { return Config::as_constant(this); } |
205 | 200 |
206 int NumClasses(); | 201 int NumClasses(); |
207 int NumConstants(); | 202 int NumConstants(); |
208 | 203 |
(...skipping 21 matching lines...) Expand all Loading... |
230 | 225 |
231 Iterator<i::Map> Classes() { | 226 Iterator<i::Map> Classes() { |
232 if (this->IsBitset()) return Iterator<i::Map>(); | 227 if (this->IsBitset()) return Iterator<i::Map>(); |
233 return Iterator<i::Map>(Config::handle(this)); | 228 return Iterator<i::Map>(Config::handle(this)); |
234 } | 229 } |
235 Iterator<i::Object> Constants() { | 230 Iterator<i::Object> Constants() { |
236 if (this->IsBitset()) return Iterator<i::Object>(); | 231 if (this->IsBitset()) return Iterator<i::Object>(); |
237 return Iterator<i::Object>(Config::handle(this)); | 232 return Iterator<i::Object>(Config::handle(this)); |
238 } | 233 } |
239 | 234 |
240 static TypeImpl* cast(typename Config::Base* object) { | 235 static TypeImpl* cast(i::Object* object) { |
241 TypeImpl* t = static_cast<TypeImpl*>(object); | 236 TypeImpl* t = static_cast<TypeImpl*>(object); |
242 ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion()); | 237 ASSERT(t->IsBitset() || t->IsClass() || t->IsConstant() || t->IsUnion()); |
243 return t; | 238 return t; |
244 } | 239 } |
245 | 240 |
246 #ifdef OBJECT_PRINT | 241 #ifdef OBJECT_PRINT |
247 void TypePrint(); | 242 void TypePrint(); |
248 void TypePrint(FILE* out); | 243 void TypePrint(FILE* out); |
249 #endif | 244 #endif |
250 | 245 |
(...skipping 23 matching lines...) Expand all Loading... |
274 | 269 |
275 bool SlowIs(TypeImpl* that); | 270 bool SlowIs(TypeImpl* that); |
276 | 271 |
277 int LubBitset(); // least upper bound that's a bitset | 272 int LubBitset(); // least upper bound that's a bitset |
278 int GlbBitset(); // greatest lower bound that's a bitset | 273 int GlbBitset(); // greatest lower bound that's a bitset |
279 | 274 |
280 static int LubBitset(i::Object* value); | 275 static int LubBitset(i::Object* value); |
281 static int LubBitset(i::Map* map); | 276 static int LubBitset(i::Map* map); |
282 | 277 |
283 bool InUnion(UnionedHandle unioned, int current_size); | 278 bool InUnion(UnionedHandle unioned, int current_size); |
284 static int ExtendUnion( | 279 int ExtendUnion(UnionedHandle unioned, int current_size); |
285 UnionedHandle unioned, TypeHandle t, int current_size); | 280 int ExtendIntersection( |
286 static int ExtendIntersection( | 281 UnionedHandle unioned, TypeHandle type, int current_size); |
287 UnionedHandle unioned, TypeHandle t, TypeHandle other, int current_size); | |
288 | 282 |
289 #ifdef OBJECT_PRINT | 283 #ifdef OBJECT_PRINT |
290 static const char* bitset_name(int bitset); | 284 static const char* bitset_name(int bitset); |
291 #endif | 285 #endif |
292 }; | 286 }; |
293 | 287 |
294 | 288 |
295 // Zone-allocated types are either (odd) integers to represent bitsets, or | |
296 // (even) pointers to zone lists for everything else. The first slot of every | |
297 // list is an explicit tag value to distinguish representation. | |
298 struct ZoneTypeConfig { | |
299 private: | |
300 typedef i::ZoneList<void*> Tagged; | |
301 | |
302 enum Tag { | |
303 kClassTag, | |
304 kConstantTag, | |
305 kUnionTag | |
306 }; | |
307 | |
308 static Tagged* tagged_create(Tag tag, int size, Zone* zone) { | |
309 Tagged* tagged = new(zone) Tagged(size + 1, zone); | |
310 tagged->Add(reinterpret_cast<void*>(tag), zone); | |
311 tagged->AddBlock(NULL, size, zone); | |
312 return tagged; | |
313 } | |
314 static void tagged_shrink(Tagged* tagged, int size) { | |
315 tagged->Rewind(size + 1); | |
316 } | |
317 static Tag tagged_tag(Tagged* tagged) { | |
318 return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0))); | |
319 } | |
320 template<class T> | |
321 static T tagged_get(Tagged* tagged, int i) { | |
322 return reinterpret_cast<T>(tagged->at(i + 1)); | |
323 } | |
324 template<class T> | |
325 static void tagged_set(Tagged* tagged, int i, T value) { | |
326 tagged->at(i + 1) = reinterpret_cast<T>(value); | |
327 } | |
328 static int tagged_length(Tagged* tagged) { | |
329 return tagged->length() - 1; | |
330 } | |
331 | |
332 public: | |
333 typedef TypeImpl<ZoneTypeConfig> Type; | |
334 class Base {}; | |
335 typedef i::ZoneList<Type*> Unioned; | |
336 typedef i::Zone Region; | |
337 template<class T> struct Handle { typedef T* type; }; | |
338 | |
339 static Type* handle(Type* type) { return type; } | |
340 | |
341 static bool is(Type* type, Tag tag) { | |
342 return is_tagged(type) && tagged_tag(as_tagged(type)) == tag; | |
343 } | |
344 | |
345 static bool is_bitset(Type* type) { | |
346 return reinterpret_cast<intptr_t>(type) & 1; | |
347 } | |
348 static bool is_tagged(Type* type) { return !is_bitset(type); } | |
349 static bool is_class(Type* type) { return is(type, kClassTag); } | |
350 static bool is_constant(Type* type) { return is(type, kConstantTag); } | |
351 static bool is_union(Type* type) { return is(type, kUnionTag); } | |
352 static bool tagged_is_union(Tagged* tagged) { | |
353 return is(from_tagged(tagged), kUnionTag); | |
354 } | |
355 | |
356 static int as_bitset(Type* type) { | |
357 ASSERT(is_bitset(type)); | |
358 return reinterpret_cast<intptr_t>(type) >> 1; | |
359 } | |
360 static Tagged* as_tagged(Type* type) { | |
361 ASSERT(is_tagged(type)); | |
362 return reinterpret_cast<Tagged*>(type); | |
363 } | |
364 static i::Handle<i::Map> as_class(Type* type) { | |
365 ASSERT(is_class(type)); | |
366 return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 0)); | |
367 } | |
368 static i::Handle<i::Object> as_constant(Type* type) { | |
369 ASSERT(is_constant(type)); | |
370 return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 0)); | |
371 } | |
372 static Unioned* as_union(Type* type) { | |
373 ASSERT(is_union(type)); | |
374 return tagged_as_union(as_tagged(type)); | |
375 } | |
376 static Unioned* tagged_as_union(Tagged* tagged) { | |
377 ASSERT(tagged_is_union(tagged)); | |
378 return reinterpret_cast<Unioned*>(tagged); | |
379 } | |
380 | |
381 static Type* from_bitset(int bitset) { | |
382 return reinterpret_cast<Type*>((bitset << 1) | 1); | |
383 } | |
384 static Type* from_bitset(int bitset, Zone* Zone) { | |
385 return from_bitset(bitset); | |
386 } | |
387 static Type* from_tagged(Tagged* tagged) { | |
388 return reinterpret_cast<Type*>(tagged); | |
389 } | |
390 static Type* from_class(i::Handle<i::Map> map, Zone* zone) { | |
391 Tagged* tagged = tagged_create(kClassTag, 1, zone); | |
392 tagged_set(tagged, 0, map.location()); | |
393 return from_tagged(tagged); | |
394 } | |
395 static Type* from_constant(i::Handle<i::Object> value, Zone* zone) { | |
396 Tagged* tagged = tagged_create(kConstantTag, 1, zone); | |
397 tagged_set(tagged, 0, value.location()); | |
398 return from_tagged(tagged); | |
399 } | |
400 static Type* from_union(Unioned* unioned) { | |
401 return from_tagged(tagged_from_union(unioned)); | |
402 } | |
403 static Tagged* tagged_from_union(Unioned* unioned) { | |
404 return reinterpret_cast<Tagged*>(unioned); | |
405 } | |
406 | |
407 static Unioned* union_create(int size, Zone* zone) { | |
408 return tagged_as_union(tagged_create(kUnionTag, size, zone)); | |
409 } | |
410 static void union_shrink(Unioned* unioned, int size) { | |
411 tagged_shrink(tagged_from_union(unioned), size); | |
412 } | |
413 static Type* union_get(Unioned* unioned, int i) { | |
414 Type* type = tagged_get<Type*>(tagged_from_union(unioned), i); | |
415 ASSERT(!is_union(type)); | |
416 return type; | |
417 } | |
418 static void union_set(Unioned* unioned, int i, Type* type) { | |
419 ASSERT(!is_union(type)); | |
420 tagged_set(tagged_from_union(unioned), i, type); | |
421 } | |
422 static int union_length(Unioned* unioned) { | |
423 return tagged_length(tagged_from_union(unioned)); | |
424 } | |
425 }; | |
426 | |
427 | |
428 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for | |
429 // constants, or fixed arrays for unions. | |
430 struct HeapTypeConfig { | 289 struct HeapTypeConfig { |
431 typedef TypeImpl<HeapTypeConfig> Type; | 290 typedef TypeImpl<HeapTypeConfig> Type; |
432 typedef i::Object Base; | 291 typedef i::Object Base; |
433 typedef i::FixedArray Unioned; | 292 typedef i::FixedArray Unioned; |
434 typedef i::Isolate Region; | 293 typedef i::Isolate Region; |
435 template<class T> struct Handle { typedef i::Handle<T> type; }; | 294 template<class T> struct Handle { typedef i::Handle<T> type; }; |
436 | 295 |
437 static i::Handle<Type> handle(Type* type) { | 296 static i::Handle<Type> handle(Type* type) { |
438 return i::handle(type, i::HeapObject::cast(type)->GetIsolate()); | 297 return i::handle(type, i::HeapObject::cast(type)->GetIsolate()); |
439 } | 298 } |
(...skipping 21 matching lines...) Expand all Loading... |
461 return Type::cast(i::Smi::FromInt(bitset)); | 320 return Type::cast(i::Smi::FromInt(bitset)); |
462 } | 321 } |
463 static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) { | 322 static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) { |
464 return i::handle(from_bitset(bitset), isolate); | 323 return i::handle(from_bitset(bitset), isolate); |
465 } | 324 } |
466 static i::Handle<Type> from_class(i::Handle<i::Map> map, Isolate* isolate) { | 325 static i::Handle<Type> from_class(i::Handle<i::Map> map, Isolate* isolate) { |
467 return i::Handle<Type>::cast(i::Handle<Object>::cast(map)); | 326 return i::Handle<Type>::cast(i::Handle<Object>::cast(map)); |
468 } | 327 } |
469 static i::Handle<Type> from_constant( | 328 static i::Handle<Type> from_constant( |
470 i::Handle<i::Object> value, Isolate* isolate) { | 329 i::Handle<i::Object> value, Isolate* isolate) { |
| 330 ASSERT(isolate || value->IsHeapObject()); |
| 331 if (!isolate) isolate = i::HeapObject::cast(*value)->GetIsolate(); |
471 i::Handle<Box> box = isolate->factory()->NewBox(value); | 332 i::Handle<Box> box = isolate->factory()->NewBox(value); |
472 return i::Handle<Type>::cast(i::Handle<Object>::cast(box)); | 333 return i::Handle<Type>::cast(i::Handle<Object>::cast(box)); |
473 } | 334 } |
474 static i::Handle<Type> from_union(i::Handle<Unioned> unioned) { | 335 static i::Handle<Type> from_union(i::Handle<Unioned> unioned) { |
475 return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned)); | 336 return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned)); |
476 } | 337 } |
477 | 338 |
478 static i::Handle<Unioned> union_create(int size, Isolate* isolate) { | 339 static i::Handle<Unioned> union_create(int size, Isolate* isolate) { |
479 return isolate->factory()->NewFixedArray(size); | 340 return isolate->factory()->NewFixedArray(size); |
480 } | 341 } |
481 static void union_shrink(i::Handle<Unioned> unioned, int size) { | |
482 unioned->Shrink(size); | |
483 } | |
484 static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) { | 342 static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) { |
485 Type* type = static_cast<Type*>(unioned->get(i)); | 343 Type* type = static_cast<Type*>(unioned->get(i)); |
486 ASSERT(!is_union(type)); | 344 ASSERT(!is_union(type)); |
487 return i::handle(type, unioned->GetIsolate()); | 345 return i::handle(type, unioned->GetIsolate()); |
488 } | 346 } |
489 static void union_set( | |
490 i::Handle<Unioned> unioned, int i, i::Handle<Type> type) { | |
491 ASSERT(!is_union(*type)); | |
492 unioned->set(i, *type); | |
493 } | |
494 static int union_length(i::Handle<Unioned> unioned) { | |
495 return unioned->length(); | |
496 } | |
497 }; | 347 }; |
498 | 348 |
499 typedef TypeImpl<ZoneTypeConfig> ZoneType; | |
500 typedef TypeImpl<HeapTypeConfig> Type; | 349 typedef TypeImpl<HeapTypeConfig> Type; |
501 | 350 |
502 | 351 |
503 // A simple struct to represent a pair of lower/upper type bounds. | 352 // A simple struct to represent a pair of lower/upper type bounds. |
504 template<class Config> | 353 template<class Config> |
505 struct BoundsImpl { | 354 struct BoundsImpl { |
506 typedef TypeImpl<Config> Type; | 355 typedef TypeImpl<Config> Type; |
507 typedef typename Type::TypeHandle TypeHandle; | 356 typedef typename Type::TypeHandle TypeHandle; |
508 typedef typename Type::Region Region; | 357 typedef typename Type::Region Region; |
509 | 358 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 TypeHandle lower = Type::Union(b.lower, t, region); | 392 TypeHandle lower = Type::Union(b.lower, t, region); |
544 return BoundsImpl(lower, b.upper); | 393 return BoundsImpl(lower, b.upper); |
545 } | 394 } |
546 static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) { | 395 static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) { |
547 TypeHandle lower = Type::Intersect(b.lower, t, region); | 396 TypeHandle lower = Type::Intersect(b.lower, t, region); |
548 TypeHandle upper = Type::Intersect(b.upper, t, region); | 397 TypeHandle upper = Type::Intersect(b.upper, t, region); |
549 return BoundsImpl(lower, upper); | 398 return BoundsImpl(lower, upper); |
550 } | 399 } |
551 }; | 400 }; |
552 | 401 |
553 typedef BoundsImpl<ZoneTypeConfig> ZoneBounds; | |
554 typedef BoundsImpl<HeapTypeConfig> Bounds; | 402 typedef BoundsImpl<HeapTypeConfig> Bounds; |
555 | 403 |
556 | 404 |
557 } } // namespace v8::internal | 405 } } // namespace v8::internal |
558 | 406 |
559 #endif // V8_TYPES_H_ | 407 #endif // V8_TYPES_H_ |
OLD | NEW |