| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // modification, are permitted provided that the following conditions are | 3 // found in the LICENSE file. |
| 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 | 4 |
| 28 #ifndef V8_TYPES_H_ | 5 #ifndef V8_TYPES_H_ |
| 29 #define V8_TYPES_H_ | 6 #define V8_TYPES_H_ |
| 30 | 7 |
| 31 #include "v8.h" | 8 #include "handles.h" |
| 32 | |
| 33 #include "objects.h" | |
| 34 | 9 |
| 35 namespace v8 { | 10 namespace v8 { |
| 36 namespace internal { | 11 namespace internal { |
| 37 | 12 |
| 38 | |
| 39 // A simple type system for compiler-internal use. It is based entirely on | 13 // A simple type system for compiler-internal use. It is based entirely on |
| 40 // union types, and all subtyping hence amounts to set inclusion. Besides the | 14 // union types, and all subtyping hence amounts to set inclusion. Besides the |
| 41 // obvious primitive types and some predefined unions, the type language also | 15 // obvious primitive types and some predefined unions, the type language also |
| 42 // can express class types (a.k.a. specific maps) and singleton types (i.e., | 16 // can express class types (a.k.a. specific maps) and singleton types (i.e., |
| 43 // concrete constants). | 17 // concrete constants). |
| 44 // | 18 // |
| 45 // Types consist of two dimensions: semantic (value range) and representation. | 19 // Types consist of two dimensions: semantic (value range) and representation. |
| 46 // Both are related through subtyping. | 20 // Both are related through subtyping. |
| 47 // | 21 // |
| 48 // The following equations and inequations hold for the semantic axis: | 22 // The following equations and inequations hold for the semantic axis: |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 struct ZoneTypeConfig { | 349 struct ZoneTypeConfig { |
| 376 private: | 350 private: |
| 377 typedef i::ZoneList<void*> Tagged; | 351 typedef i::ZoneList<void*> Tagged; |
| 378 | 352 |
| 379 enum Tag { | 353 enum Tag { |
| 380 kClassTag, | 354 kClassTag, |
| 381 kConstantTag, | 355 kConstantTag, |
| 382 kUnionTag | 356 kUnionTag |
| 383 }; | 357 }; |
| 384 | 358 |
| 385 static Tagged* tagged_create(Tag tag, int size, Zone* zone) { | 359 static inline Tagged* tagged_create(Tag tag, int size, Zone* zone); |
| 386 Tagged* tagged = new(zone) Tagged(size + 1, zone); | 360 static inline void tagged_shrink(Tagged* tagged, int size); |
| 387 tagged->Add(reinterpret_cast<void*>(tag), zone); | 361 static inline Tag tagged_tag(Tagged* tagged); |
| 388 tagged->AddBlock(NULL, size, zone); | |
| 389 return tagged; | |
| 390 } | |
| 391 static void tagged_shrink(Tagged* tagged, int size) { | |
| 392 tagged->Rewind(size + 1); | |
| 393 } | |
| 394 static Tag tagged_tag(Tagged* tagged) { | |
| 395 return static_cast<Tag>(reinterpret_cast<intptr_t>(tagged->at(0))); | |
| 396 } | |
| 397 template<class T> | 362 template<class T> |
| 398 static T tagged_get(Tagged* tagged, int i) { | 363 static inline T tagged_get(Tagged* tagged, int i); |
| 399 return reinterpret_cast<T>(tagged->at(i + 1)); | |
| 400 } | |
| 401 template<class T> | 364 template<class T> |
| 402 static void tagged_set(Tagged* tagged, int i, T value) { | 365 static inline void tagged_set(Tagged* tagged, int i, T value); |
| 403 tagged->at(i + 1) = reinterpret_cast<void*>(value); | 366 static inline int tagged_length(Tagged* tagged); |
| 404 } | |
| 405 static int tagged_length(Tagged* tagged) { | |
| 406 return tagged->length() - 1; | |
| 407 } | |
| 408 | 367 |
| 409 public: | 368 public: |
| 410 typedef TypeImpl<ZoneTypeConfig> Type; | 369 typedef TypeImpl<ZoneTypeConfig> Type; |
| 411 class Base {}; | 370 class Base {}; |
| 412 typedef i::ZoneList<Type*> Unioned; | 371 typedef i::ZoneList<Type*> Unioned; |
| 413 typedef i::Zone Region; | 372 typedef i::Zone Region; |
| 414 template<class T> struct Handle { typedef T* type; }; | 373 template<class T> struct Handle { typedef T* type; }; |
| 415 | 374 |
| 416 static Type* handle(Type* type) { return type; } | 375 static inline Type* handle(Type* type); |
| 417 | 376 static inline bool is(Type* type, Tag tag); |
| 418 static bool is(Type* type, Tag tag) { | 377 static inline bool is_bitset(Type* type); |
| 419 return is_tagged(type) && tagged_tag(as_tagged(type)) == tag; | 378 static inline bool is_tagged(Type* type); |
| 420 } | 379 static inline bool is_class(Type* type); |
| 421 | 380 static inline bool is_constant(Type* type); |
| 422 static bool is_bitset(Type* type) { | 381 static inline bool is_union(Type* type); |
| 423 return reinterpret_cast<intptr_t>(type) & 1; | 382 static inline bool tagged_is_union(Tagged* tagged); |
| 424 } | 383 static inline int as_bitset(Type* type); |
| 425 static bool is_tagged(Type* type) { return !is_bitset(type); } | 384 static inline Tagged* as_tagged(Type* type); |
| 426 static bool is_class(Type* type) { return is(type, kClassTag); } | 385 static inline i::Handle<i::Map> as_class(Type* type); |
| 427 static bool is_constant(Type* type) { return is(type, kConstantTag); } | 386 static inline i::Handle<i::Object> as_constant(Type* type); |
| 428 static bool is_union(Type* type) { return is(type, kUnionTag); } | 387 static inline Unioned* as_union(Type* type); |
| 429 static bool tagged_is_union(Tagged* tagged) { | 388 static inline Unioned* tagged_as_union(Tagged* tagged); |
| 430 return is(from_tagged(tagged), kUnionTag); | 389 static inline Type* from_bitset(int bitset); |
| 431 } | 390 static inline Type* from_bitset(int bitset, Zone* zone); |
| 432 | 391 static inline Type* from_tagged(Tagged* tagged); |
| 433 static int as_bitset(Type* type) { | 392 static inline Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone); |
| 434 ASSERT(is_bitset(type)); | 393 static inline Type* from_constant( |
| 435 return static_cast<int>(reinterpret_cast<intptr_t>(type) >> 1); | 394 i::Handle<i::Object> value, int lub, Zone* zone); |
| 436 } | 395 static inline Type* from_union(Unioned* unioned); |
| 437 static Tagged* as_tagged(Type* type) { | 396 static inline Tagged* tagged_from_union(Unioned* unioned); |
| 438 ASSERT(is_tagged(type)); | 397 static inline Unioned* union_create(int size, Zone* zone); |
| 439 return reinterpret_cast<Tagged*>(type); | 398 static inline void union_shrink(Unioned* unioned, int size); |
| 440 } | 399 static inline Type* union_get(Unioned* unioned, int i); |
| 441 static i::Handle<i::Map> as_class(Type* type) { | 400 static inline void union_set(Unioned* unioned, int i, Type* type); |
| 442 ASSERT(is_class(type)); | 401 static inline int union_length(Unioned* unioned); |
| 443 return i::Handle<i::Map>(tagged_get<i::Map**>(as_tagged(type), 1)); | 402 static inline int lub_bitset(Type* type); |
| 444 } | |
| 445 static i::Handle<i::Object> as_constant(Type* type) { | |
| 446 ASSERT(is_constant(type)); | |
| 447 return i::Handle<i::Object>(tagged_get<i::Object**>(as_tagged(type), 1)); | |
| 448 } | |
| 449 static Unioned* as_union(Type* type) { | |
| 450 ASSERT(is_union(type)); | |
| 451 return tagged_as_union(as_tagged(type)); | |
| 452 } | |
| 453 static Unioned* tagged_as_union(Tagged* tagged) { | |
| 454 ASSERT(tagged_is_union(tagged)); | |
| 455 return reinterpret_cast<Unioned*>(tagged); | |
| 456 } | |
| 457 | |
| 458 static Type* from_bitset(int bitset) { | |
| 459 return reinterpret_cast<Type*>((bitset << 1) | 1); | |
| 460 } | |
| 461 static Type* from_bitset(int bitset, Zone* Zone) { | |
| 462 return from_bitset(bitset); | |
| 463 } | |
| 464 static Type* from_tagged(Tagged* tagged) { | |
| 465 return reinterpret_cast<Type*>(tagged); | |
| 466 } | |
| 467 static Type* from_class(i::Handle<i::Map> map, int lub, Zone* zone) { | |
| 468 Tagged* tagged = tagged_create(kClassTag, 2, zone); | |
| 469 tagged_set(tagged, 0, lub); | |
| 470 tagged_set(tagged, 1, map.location()); | |
| 471 return from_tagged(tagged); | |
| 472 } | |
| 473 static Type* from_constant(i::Handle<i::Object> value, int lub, Zone* zone) { | |
| 474 Tagged* tagged = tagged_create(kConstantTag, 2, zone); | |
| 475 tagged_set(tagged, 0, lub); | |
| 476 tagged_set(tagged, 1, value.location()); | |
| 477 return from_tagged(tagged); | |
| 478 } | |
| 479 static Type* from_union(Unioned* unioned) { | |
| 480 return from_tagged(tagged_from_union(unioned)); | |
| 481 } | |
| 482 static Tagged* tagged_from_union(Unioned* unioned) { | |
| 483 return reinterpret_cast<Tagged*>(unioned); | |
| 484 } | |
| 485 | |
| 486 static Unioned* union_create(int size, Zone* zone) { | |
| 487 return tagged_as_union(tagged_create(kUnionTag, size, zone)); | |
| 488 } | |
| 489 static void union_shrink(Unioned* unioned, int size) { | |
| 490 tagged_shrink(tagged_from_union(unioned), size); | |
| 491 } | |
| 492 static Type* union_get(Unioned* unioned, int i) { | |
| 493 Type* type = tagged_get<Type*>(tagged_from_union(unioned), i); | |
| 494 ASSERT(!is_union(type)); | |
| 495 return type; | |
| 496 } | |
| 497 static void union_set(Unioned* unioned, int i, Type* type) { | |
| 498 ASSERT(!is_union(type)); | |
| 499 tagged_set(tagged_from_union(unioned), i, type); | |
| 500 } | |
| 501 static int union_length(Unioned* unioned) { | |
| 502 return tagged_length(tagged_from_union(unioned)); | |
| 503 } | |
| 504 static int lub_bitset(Type* type) { | |
| 505 ASSERT(is_class(type) || is_constant(type)); | |
| 506 return static_cast<int>(tagged_get<intptr_t>(as_tagged(type), 0)); | |
| 507 } | |
| 508 }; | 403 }; |
| 509 | 404 |
| 510 | 405 |
| 511 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for | 406 // Heap-allocated types are either smis for bitsets, maps for classes, boxes for |
| 512 // constants, or fixed arrays for unions. | 407 // constants, or fixed arrays for unions. |
| 513 struct HeapTypeConfig { | 408 struct HeapTypeConfig { |
| 514 typedef TypeImpl<HeapTypeConfig> Type; | 409 typedef TypeImpl<HeapTypeConfig> Type; |
| 515 typedef i::Object Base; | 410 typedef i::Object Base; |
| 516 typedef i::FixedArray Unioned; | 411 typedef i::FixedArray Unioned; |
| 517 typedef i::Isolate Region; | 412 typedef i::Isolate Region; |
| 518 template<class T> struct Handle { typedef i::Handle<T> type; }; | 413 template<class T> struct Handle { typedef i::Handle<T> type; }; |
| 519 | 414 |
| 520 static i::Handle<Type> handle(Type* type) { | 415 static inline i::Handle<Type> handle(Type* type); |
| 521 return i::handle(type, i::HeapObject::cast(type)->GetIsolate()); | 416 static inline bool is_bitset(Type* type); |
| 522 } | 417 static inline bool is_class(Type* type); |
| 523 | 418 static inline bool is_constant(Type* type); |
| 524 static bool is_bitset(Type* type) { return type->IsSmi(); } | 419 static inline bool is_union(Type* type); |
| 525 static bool is_class(Type* type) { return type->IsMap(); } | 420 static inline int as_bitset(Type* type); |
| 526 static bool is_constant(Type* type) { return type->IsBox(); } | 421 static inline i::Handle<i::Map> as_class(Type* type); |
| 527 static bool is_union(Type* type) { return type->IsFixedArray(); } | 422 static inline i::Handle<i::Object> as_constant(Type* type); |
| 528 | 423 static inline i::Handle<Unioned> as_union(Type* type); |
| 529 static int as_bitset(Type* type) { | 424 static inline Type* from_bitset(int bitset); |
| 530 return Smi::cast(type)->value(); | 425 static inline i::Handle<Type> from_bitset(int bitset, Isolate* isolate); |
| 531 } | 426 static inline i::Handle<Type> from_class( |
| 532 static i::Handle<i::Map> as_class(Type* type) { | 427 i::Handle<i::Map> map, int lub, Isolate* isolate); |
| 533 return i::handle(i::Map::cast(type)); | 428 static inline i::Handle<Type> from_constant( |
| 534 } | 429 i::Handle<i::Object> value, int lub, Isolate* isolate); |
| 535 static i::Handle<i::Object> as_constant(Type* type) { | 430 static inline i::Handle<Type> from_union(i::Handle<Unioned> unioned); |
| 536 i::Box* box = i::Box::cast(type); | 431 static inline i::Handle<Unioned> union_create(int size, Isolate* isolate); |
| 537 return i::handle(box->value(), box->GetIsolate()); | 432 static inline void union_shrink(i::Handle<Unioned> unioned, int size); |
| 538 } | 433 static inline i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i); |
| 539 static i::Handle<Unioned> as_union(Type* type) { | 434 static inline void union_set( |
| 540 return i::handle(i::FixedArray::cast(type)); | 435 i::Handle<Unioned> unioned, int i, i::Handle<Type> type); |
| 541 } | 436 static inline int union_length(i::Handle<Unioned> unioned); |
| 542 | 437 static inline int lub_bitset(Type* type); |
| 543 static Type* from_bitset(int bitset) { | |
| 544 return Type::cast(i::Smi::FromInt(bitset)); | |
| 545 } | |
| 546 static i::Handle<Type> from_bitset(int bitset, Isolate* isolate) { | |
| 547 return i::handle(from_bitset(bitset), isolate); | |
| 548 } | |
| 549 static i::Handle<Type> from_class( | |
| 550 i::Handle<i::Map> map, int lub, Isolate* isolate) { | |
| 551 return i::Handle<Type>::cast(i::Handle<Object>::cast(map)); | |
| 552 } | |
| 553 static i::Handle<Type> from_constant( | |
| 554 i::Handle<i::Object> value, int lub, Isolate* isolate) { | |
| 555 i::Handle<Box> box = isolate->factory()->NewBox(value); | |
| 556 return i::Handle<Type>::cast(i::Handle<Object>::cast(box)); | |
| 557 } | |
| 558 static i::Handle<Type> from_union(i::Handle<Unioned> unioned) { | |
| 559 return i::Handle<Type>::cast(i::Handle<Object>::cast(unioned)); | |
| 560 } | |
| 561 | |
| 562 static i::Handle<Unioned> union_create(int size, Isolate* isolate) { | |
| 563 return isolate->factory()->NewFixedArray(size); | |
| 564 } | |
| 565 static void union_shrink(i::Handle<Unioned> unioned, int size) { | |
| 566 unioned->Shrink(size); | |
| 567 } | |
| 568 static i::Handle<Type> union_get(i::Handle<Unioned> unioned, int i) { | |
| 569 Type* type = static_cast<Type*>(unioned->get(i)); | |
| 570 ASSERT(!is_union(type)); | |
| 571 return i::handle(type, unioned->GetIsolate()); | |
| 572 } | |
| 573 static void union_set( | |
| 574 i::Handle<Unioned> unioned, int i, i::Handle<Type> type) { | |
| 575 ASSERT(!is_union(*type)); | |
| 576 unioned->set(i, *type); | |
| 577 } | |
| 578 static int union_length(i::Handle<Unioned> unioned) { | |
| 579 return unioned->length(); | |
| 580 } | |
| 581 static int lub_bitset(Type* type) { | |
| 582 return 0; // kNone, which causes recomputation. | |
| 583 } | |
| 584 }; | 438 }; |
| 585 | 439 |
| 586 typedef TypeImpl<ZoneTypeConfig> Type; | 440 typedef TypeImpl<ZoneTypeConfig> Type; |
| 587 typedef TypeImpl<HeapTypeConfig> HeapType; | 441 typedef TypeImpl<HeapTypeConfig> HeapType; |
| 588 | 442 |
| 589 | 443 |
| 590 // A simple struct to represent a pair of lower/upper type bounds. | 444 // A simple struct to represent a pair of lower/upper type bounds. |
| 591 template<class Config> | 445 template<class Config> |
| 592 struct BoundsImpl { | 446 struct BoundsImpl { |
| 593 typedef TypeImpl<Config> Type; | 447 typedef TypeImpl<Config> Type; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 return BoundsImpl(lower, upper); | 490 return BoundsImpl(lower, upper); |
| 637 } | 491 } |
| 638 | 492 |
| 639 bool Narrows(BoundsImpl that) { | 493 bool Narrows(BoundsImpl that) { |
| 640 return that.lower->Is(this->lower) && this->upper->Is(that.upper); | 494 return that.lower->Is(this->lower) && this->upper->Is(that.upper); |
| 641 } | 495 } |
| 642 }; | 496 }; |
| 643 | 497 |
| 644 typedef BoundsImpl<ZoneTypeConfig> Bounds; | 498 typedef BoundsImpl<ZoneTypeConfig> Bounds; |
| 645 | 499 |
| 646 | |
| 647 } } // namespace v8::internal | 500 } } // namespace v8::internal |
| 648 | 501 |
| 649 #endif // V8_TYPES_H_ | 502 #endif // V8_TYPES_H_ |
| OLD | NEW |