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

Side by Side Diff: src/types.h

Issue 186743002: Types: cache lub bitset to avoid heap access (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment Created 6 years, 9 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 | « no previous file | 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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; // kNone, which causes recomputation.
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
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_
OLDNEW
« no previous file with comments | « no previous file | src/types.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698