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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 // (e.g., via T->Maybe(Number())). | 80 // (e.g., via T->Maybe(Number())). |
81 // | 81 // |
82 // There is no functionality to discover whether a type is a leaf in the | 82 // There is no functionality to discover whether a type is a leaf in the |
83 // lattice. That is intentional. It should always be possible to refine the | 83 // lattice. That is intentional. It should always be possible to refine the |
84 // lattice (e.g., splitting up number types further) without invalidating any | 84 // lattice (e.g., splitting up number types further) without invalidating any |
85 // existing assumptions or tests. | 85 // existing assumptions or tests. |
86 // | 86 // |
87 // Consequently, do not use pointer equality for type tests, always use Is! | 87 // Consequently, do not use pointer equality for type tests, always use Is! |
88 // | 88 // |
89 // Internally, all 'primitive' types, and their unions, are represented as | 89 // Internally, all 'primitive' types, and their unions, are represented as |
90 // bitsets via smis. Class is a heap pointer to the respective map. Only | 90 // bitsets. Class is a heap pointer to the respective map. Only Constant's, or |
91 // Constant's, or unions containing Class'es or Constant's, require allocation. | 91 // unions containing Class'es or Constant's, currently require allocation. |
92 // Note that the bitset representation is closed under both Union and Intersect. | 92 // Note that the bitset representation is closed under both Union and Intersect. |
93 // | 93 // |
94 // The type representation is heap-allocated, so cannot (currently) be used in | 94 // There are two type representations, using different allocation: |
95 // a concurrent compilation context. | 95 // |
96 // - class Type (zone-allocated, for compiler and concurrent compilation) | |
97 // - class HeapType (heap-allocated, for persistent types) | |
98 // | |
99 // Both provide the same API, and the Convert method can be used to interconvert | |
100 // them. For zone types, no query method touches the heap, only constructors do. | |
96 | 101 |
97 | 102 |
98 #define BITSET_TYPE_LIST(V) \ | 103 #define BITSET_TYPE_LIST(V) \ |
99 V(None, 0) \ | 104 V(None, 0) \ |
100 V(Null, 1 << 0) \ | 105 V(Null, 1 << 0) \ |
101 V(Undefined, 1 << 1) \ | 106 V(Undefined, 1 << 1) \ |
102 V(Boolean, 1 << 2) \ | 107 V(Boolean, 1 << 2) \ |
103 V(Smi, 1 << 3) \ | 108 V(Smi, 1 << 3) \ |
104 V(OtherSigned32, 1 << 4) \ | 109 V(OtherSigned32, 1 << 4) \ |
105 V(Unsigned32, 1 << 5) \ | 110 V(Unsigned32, 1 << 5) \ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
140 // static bool is_bitset(Type*); | 145 // static bool is_bitset(Type*); |
141 // static bool is_class(Type*); | 146 // static bool is_class(Type*); |
142 // static bool is_constant(Type*); | 147 // static bool is_constant(Type*); |
143 // static bool is_union(Type*); | 148 // static bool is_union(Type*); |
144 // static int as_bitset(Type*); | 149 // static int as_bitset(Type*); |
145 // static i::Handle<i::Map> as_class(Type*); | 150 // static i::Handle<i::Map> as_class(Type*); |
146 // static i::Handle<i::Object> as_constant(Type*); | 151 // static i::Handle<i::Object> as_constant(Type*); |
147 // static Handle<Unioned>::type as_union(Type*); | 152 // static Handle<Unioned>::type as_union(Type*); |
148 // static Type* from_bitset(int bitset); | 153 // static Type* from_bitset(int bitset); |
149 // static Handle<Type>::type from_bitset(int bitset, Region*); | 154 // static Handle<Type>::type from_bitset(int bitset, Region*); |
150 // static Handle<Type>::type from_class(i::Handle<i::Map>, Region*) | 155 // static Handle<Type>::type from_class(i::Handle<Map>, int lub, Region*); |
151 // static Handle<Type>::type from_constant(i::Handle<i::Object>, Region*); | 156 // static Handle<Type>::type from_constant(i::Handle<Object>, int, Region*); |
152 // static Handle<Type>::type from_union(Handle<Unioned>::type); | 157 // static Handle<Type>::type from_union(Handle<Unioned>::type); |
153 // static Handle<Unioned>::type union_create(int size, Region*); | 158 // static Handle<Unioned>::type union_create(int size, Region*); |
154 // static void union_shrink(Handle<Unioned>::type, int size); | 159 // static void union_shrink(Handle<Unioned>::type, int size); |
155 // static Handle<Type>::type union_get(Handle<Unioned>::type, int); | 160 // static Handle<Type>::type union_get(Handle<Unioned>::type, int); |
156 // static void union_set(Handle<Unioned>::type, int, Handle<Type>::type); | 161 // static void union_set(Handle<Unioned>::type, int, Handle<Type>::type); |
157 // static int union_length(Handle<Unioned>::type); | 162 // static int union_length(Handle<Unioned>::type); |
163 // static int lub_bitset(Type*); | |
158 // } | 164 // } |
159 template<class Config> | 165 template<class Config> |
160 class TypeImpl : public Config::Base { | 166 class TypeImpl : public Config::Base { |
161 public: | 167 public: |
162 typedef typename Config::template Handle<TypeImpl>::type TypeHandle; | 168 typedef typename Config::template Handle<TypeImpl>::type TypeHandle; |
163 typedef typename Config::Region Region; | 169 typedef typename Config::Region Region; |
164 | 170 |
165 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ | 171 #define DEFINE_TYPE_CONSTRUCTOR(type, value) \ |
166 static TypeImpl* type() { return Config::from_bitset(k##type); } \ | 172 static TypeImpl* type() { return Config::from_bitset(k##type); } \ |
167 static TypeHandle type(Region* region) { \ | 173 static TypeHandle type(Region* region) { \ |
168 return Config::from_bitset(k##type, region); \ | 174 return Config::from_bitset(k##type, region); \ |
169 } | 175 } |
170 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) | 176 BITSET_TYPE_LIST(DEFINE_TYPE_CONSTRUCTOR) |
171 #undef DEFINE_TYPE_CONSTRUCTOR | 177 #undef DEFINE_TYPE_CONSTRUCTOR |
172 | 178 |
173 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { | 179 static TypeHandle Class(i::Handle<i::Map> map, Region* region) { |
174 return Config::from_class(map, region); | 180 return Config::from_class(map, LubBitset(*map), region); |
175 } | 181 } |
176 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { | 182 static TypeHandle Constant(i::Handle<i::Object> value, Region* region) { |
177 return Config::from_constant(value, region); | 183 return Config::from_constant(value, LubBitset(*value), region); |
178 } | 184 } |
179 | 185 |
180 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); | 186 static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg); |
181 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); | 187 static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg); |
182 | 188 |
183 static TypeHandle Of(i::Handle<i::Object> value, Region* region) { | 189 static TypeHandle Of(i::Handle<i::Object> value, Region* region) { |
184 return Config::from_bitset(LubBitset(*value), region); | 190 return Config::from_bitset(LubBitset(*value), region); |
185 } | 191 } |
186 | 192 |
187 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } | 193 bool Is(TypeImpl* that) { return this == that || this->SlowIs(that); } |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 } | 334 } |
329 static Tag tagged_tag(Tagged* tagged) { | 335 static Tag tagged_tag(Tagged* tagged) { |
330 return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0))); | 336 return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0))); |
331 } | 337 } |
332 template<class T> | 338 template<class T> |
333 static T tagged_get(Tagged* tagged, int i) { | 339 static T tagged_get(Tagged* tagged, int i) { |
334 return reinterpret_cast<T>(tagged->at(i + 1)); | 340 return reinterpret_cast<T>(tagged->at(i + 1)); |
335 } | 341 } |
336 template<class T> | 342 template<class T> |
337 static void tagged_set(Tagged* tagged, int i, T value) { | 343 static void tagged_set(Tagged* tagged, int i, T value) { |
338 tagged->at(i + 1) = reinterpret_cast<T>(value); | 344 tagged->at(i + 1) = reinterpret_cast<void*>(value); |
339 } | 345 } |
340 static int tagged_length(Tagged* tagged) { | 346 static int tagged_length(Tagged* tagged) { |
341 return tagged->length() - 1; | 347 return tagged->length() - 1; |
342 } | 348 } |
343 | 349 |
344 public: | 350 public: |
345 typedef TypeImpl<ZoneTypeConfig> Type; | 351 typedef TypeImpl<ZoneTypeConfig> Type; |
346 class Base {}; | 352 class Base {}; |
347 typedef i::ZoneList<Type*> Unioned; | 353 typedef i::ZoneList<Type*> Unioned; |
348 typedef i::Zone Region; | 354 typedef i::Zone Region; |
(...skipping 19 matching lines...) Expand all Loading... | |
368 static int as_bitset(Type* type) { | 374 static int as_bitset(Type* type) { |
369 ASSERT(is_bitset(type)); | 375 ASSERT(is_bitset(type)); |
370 return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1); | 376 return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1); |
371 } | 377 } |
372 static Tagged* as_tagged(Type* type) { | 378 static Tagged* as_tagged(Type* type) { |
373 ASSERT(is_tagged(type)); | 379 ASSERT(is_tagged(type)); |
374 return reinterpret_cast<Tagged*>(type); | 380 return reinterpret_cast<Tagged*>(type); |
375 } | 381 } |
376 static i::Handle<i::Map> as_class(Type* type) { | 382 static i::Handle<i::Map> as_class(Type* type) { |
377 ASSERT(is_class(type)); | 383 ASSERT(is_class(type)); |
378 return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 0)); | 384 return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 1)); |
379 } | 385 } |
380 static i::Handle<i::Object> as_constant(Type* type) { | 386 static i::Handle<i::Object> as_constant(Type* type) { |
381 ASSERT(is_constant(type)); | 387 ASSERT(is_constant(type)); |
382 return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 0)); | 388 return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 1)); |
383 } | 389 } |
384 static Unioned* as_union(Type* type) { | 390 static Unioned* as_union(Type* type) { |
385 ASSERT(is_union(type)); | 391 ASSERT(is_union(type)); |
386 return tagged_as_union(as_tagged(type)); | 392 return tagged_as_union(as_tagged(type)); |
387 } | 393 } |
388 static Unioned* tagged_as_union(Tagged* tagged) { | 394 static Unioned* tagged_as_union(Tagged* tagged) { |
389 ASSERT(tagged_is_union(tagged)); | 395 ASSERT(tagged_is_union(tagged)); |
390 return reinterpret_cast<Unioned*>(tagged); | 396 return reinterpret_cast<Unioned*>(tagged); |
391 } | 397 } |
392 | 398 |
393 static Type* from_bitset(int bitset) { | 399 static Type* from_bitset(int bitset) { |
394 return reinterpret_cast<Type*>((bitset << 1) | 1); | 400 return reinterpret_cast<Type*>((bitset << 1) | 1); |
395 } | 401 } |
396 static Type* from_bitset(int bitset, Zone* Zone) { | 402 static Type* from_bitset(int bitset, Zone* Zone) { |
397 return from_bitset(bitset); | 403 return from_bitset(bitset); |
398 } | 404 } |
399 static Type* from_tagged(Tagged* tagged) { | 405 static Type* from_tagged(Tagged* tagged) { |
400 return reinterpret_cast<Type*>(tagged); | 406 return reinterpret_cast<Type*>(tagged); |
401 } | 407 } |
402 static Type* from_class(i::Handle<i::Map> map, Zone* zone) { | 408 static Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone) { |
403 Tagged* tagged = tagged_create(kClassTag, 1, zone); | 409 Tagged* tagged = tagged_create(kClassTag, 2, zone); |
404 tagged_set(tagged, 0, map.location()); | 410 tagged_set(tagged, 0, lub); |
411 tagged_set(tagged, 1, map.location()); | |
405 return from_tagged(tagged); | 412 return from_tagged(tagged); |
406 } | 413 } |
407 static Type* from_constant(i::Handle<i::Object> value, Zone* zone) { | 414 static Type* from_constant(i::Handle<i::Object> value, int lub, Zone* zone) { |
408 Tagged* tagged = tagged_create(kConstantTag, 1, zone); | 415 Tagged* tagged = tagged_create(kConstantTag, 2, zone); |
409 tagged_set(tagged, 0, value.location()); | 416 tagged_set(tagged, 0, lub); |
417 tagged_set(tagged, 1, value.location()); | |
410 return from_tagged(tagged); | 418 return from_tagged(tagged); |
411 } | 419 } |
412 static Type* from_union(Unioned* unioned) { | 420 static Type* from_union(Unioned* unioned) { |
413 return from_tagged(tagged_from_union(unioned)); | 421 return from_tagged(tagged_from_union(unioned)); |
414 } | 422 } |
415 static Tagged* tagged_from_union(Unioned* unioned) { | 423 static Tagged* tagged_from_union(Unioned* unioned) { |
416 return reinterpret_cast<Tagged*>(unioned); | 424 return reinterpret_cast<Tagged*>(unioned); |
417 } | 425 } |
418 | 426 |
419 static Unioned* union_create(int size, Zone* zone) { | 427 static Unioned* union_create(int size, Zone* zone) { |
420 return tagged_as_union(tagged_create(kUnionTag, size, zone)); | 428 return tagged_as_union(tagged_create(kUnionTag, size, zone)); |
421 } | 429 } |
422 static void union_shrink(Unioned* unioned, int size) { | 430 static void union_shrink(Unioned* unioned, int size) { |
423 tagged_shrink(tagged_from_union(unioned), size); | 431 tagged_shrink(tagged_from_union(unioned), size); |
424 } | 432 } |
425 static Type* union_get(Unioned* unioned, int i) { | 433 static Type* union_get(Unioned* unioned, int i) { |
426 Type* type = tagged_get<Type*>(tagged_from_union(unioned), i); | 434 Type* type = tagged_get<Type*>(tagged_from_union(unioned), i); |
427 ASSERT(!is_union(type)); | 435 ASSERT(!is_union(type)); |
428 return type; | 436 return type; |
429 } | 437 } |
430 static void union_set(Unioned* unioned, int i, Type* type) { | 438 static void union_set(Unioned* unioned, int i, Type* type) { |
431 ASSERT(!is_union(type)); | 439 ASSERT(!is_union(type)); |
432 tagged_set(tagged_from_union(unioned), i, type); | 440 tagged_set(tagged_from_union(unioned), i, type); |
433 } | 441 } |
434 static int union_length(Unioned* unioned) { | 442 static int union_length(Unioned* unioned) { |
435 return tagged_length(tagged_from_union(unioned)); | 443 return tagged_length(tagged_from_union(unioned)); |
436 } | 444 } |
445 static int lub_bitset(Type* type) { | |
446 ASSERT(is_class(type) || is_constant(type)); | |
447 return tagged_get<int>(as_tagged(type), 0); | |
448 } | |
437 }; | 449 }; |
438 | 450 |
439 | 451 |
440 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for | 452 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for |
441 // constants, or fixed arrays for unions. | 453 // constants, or fixed arrays for unions. |
442 struct HeapTypeConfig { | 454 struct HeapTypeConfig { |
443 typedef TypeImpl<HeapTypeConfig> Type; | 455 typedef TypeImpl<HeapTypeConfig> Type; |
444 typedef i::Object Base; | 456 typedef i::Object Base; |
445 typedef i::FixedArray Unioned; | 457 typedef i::FixedArray Unioned; |
446 typedef i::Isolate Region; | 458 typedef i::Isolate Region; |
(...skipping 21 matching lines...) Expand all Loading... | |
468 static i::Handle<Unioned> as_union(Type* type) { | 480 static i::Handle<Unioned> as_union(Type* type) { |
469 return i::handle(i::FixedArray::cast(type)); | 481 return i::handle(i::FixedArray::cast(type)); |
470 } | 482 } |
471 | 483 |
472 static Type* from_bitset(int bitset) { | 484 static Type* from_bitset(int bitset) { |
473 return Type::cast(i::Smi::FromInt(bitset)); | 485 return Type::cast(i::Smi::FromInt(bitset)); |
474 } | 486 } |
475 static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) { | 487 static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) { |
476 return i::handle(from_bitset(bitset), isolate); | 488 return i::handle(from_bitset(bitset), isolate); |
477 } | 489 } |
478 static i::Handle<Type> from_class(i::Handle<i::Map> map, Isolate* isolate) { | 490 static i::Handle<Type> from_class( |
491 i::Handle<i::Map> map, int lub, Isolate* isolate) { | |
479 return i::Handle<Type>::cast(i::Handle<Object>::cast(map)); | 492 return i::Handle<Type>::cast(i::Handle<Object>::cast(map)); |
480 } | 493 } |
481 static i::Handle<Type> from_constant( | 494 static i::Handle<Type> from_constant( |
482 i::Handle<i::Object> value, Isolate* isolate) { | 495 i::Handle<i::Object> value, int lub, Isolate* isolate) { |
483 i::Handle<Box> box = isolate->factory()->NewBox(value); | 496 i::Handle<Box> box = isolate->factory()->NewBox(value); |
484 return i::Handle<Type>::cast(i::Handle<Object>::cast(box)); | 497 return i::Handle<Type>::cast(i::Handle<Object>::cast(box)); |
485 } | 498 } |
486 static i::Handle<Type> from_union(i::Handle<Unioned> unioned) { | 499 static i::Handle<Type> from_union(i::Handle<Unioned> unioned) { |
487 return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned)); | 500 return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned)); |
488 } | 501 } |
489 | 502 |
490 static i::Handle<Unioned> union_create(int size, Isolate* isolate) { | 503 static i::Handle<Unioned> union_create(int size, Isolate* isolate) { |
491 return isolate->factory()->NewFixedArray(size); | 504 return isolate->factory()->NewFixedArray(size); |
492 } | 505 } |
493 static void union_shrink(i::Handle<Unioned> unioned, int size) { | 506 static void union_shrink(i::Handle<Unioned> unioned, int size) { |
494 unioned->Shrink(size); | 507 unioned->Shrink(size); |
495 } | 508 } |
496 static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) { | 509 static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) { |
497 Type* type = static_cast<Type*>(unioned->get(i)); | 510 Type* type = static_cast<Type*>(unioned->get(i)); |
498 ASSERT(!is_union(type)); | 511 ASSERT(!is_union(type)); |
499 return i::handle(type, unioned->GetIsolate()); | 512 return i::handle(type, unioned->GetIsolate()); |
500 } | 513 } |
501 static void union_set( | 514 static void union_set( |
502 i::Handle<Unioned> unioned, int i, i::Handle<Type> type) { | 515 i::Handle<Unioned> unioned, int i, i::Handle<Type> type) { |
503 ASSERT(!is_union(*type)); | 516 ASSERT(!is_union(*type)); |
504 unioned->set(i, *type); | 517 unioned->set(i, *type); |
505 } | 518 } |
506 static int union_length(i::Handle<Unioned> unioned) { | 519 static int union_length(i::Handle<Unioned> unioned) { |
507 return unioned->length(); | 520 return unioned->length(); |
508 } | 521 } |
522 static int lub_bitset(Type* type) { | |
523 return 0; | |
Toon Verwaest
2014/03/10 12:52:18
I presume this is because of the "bitset ? bitset
rossberg
2014/03/11 10:11:39
Done.
| |
524 } | |
509 }; | 525 }; |
510 | 526 |
511 typedef TypeImpl<ZoneTypeConfig> Type; | 527 typedef TypeImpl<ZoneTypeConfig> Type; |
512 typedef TypeImpl<HeapTypeConfig> HeapType; | 528 typedef TypeImpl<HeapTypeConfig> HeapType; |
513 | 529 |
514 | 530 |
515 // A simple struct to represent a pair of lower/upper type bounds. | 531 // A simple struct to represent a pair of lower/upper type bounds. |
516 template<class Config> | 532 template<class Config> |
517 struct BoundsImpl { | 533 struct BoundsImpl { |
518 typedef TypeImpl<Config> Type; | 534 typedef TypeImpl<Config> Type; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 581 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
566 } | 582 } |
567 }; | 583 }; |
568 | 584 |
569 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 585 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
570 | 586 |
571 | 587 |
572 } } // namespace v8::internal | 588 } } // namespace v8::internal |
573 | 589 |
574 #endif // V8_TYPES_H_ | 590 #endif // V8_TYPES_H_ |
OLD | NEW |