| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 23 matching lines...) Expand all Loading... |
| 34 | 34 |
| 35 #ifndef V8_OBJECTS_INL_H_ | 35 #ifndef V8_OBJECTS_INL_H_ |
| 36 #define V8_OBJECTS_INL_H_ | 36 #define V8_OBJECTS_INL_H_ |
| 37 | 37 |
| 38 #include "elements.h" | 38 #include "elements.h" |
| 39 #include "objects.h" | 39 #include "objects.h" |
| 40 #include "contexts.h" | 40 #include "contexts.h" |
| 41 #include "conversions-inl.h" | 41 #include "conversions-inl.h" |
| 42 #include "heap.h" | 42 #include "heap.h" |
| 43 #include "isolate.h" | 43 #include "isolate.h" |
| 44 #include "heap-inl.h" |
| 44 #include "property.h" | 45 #include "property.h" |
| 45 #include "spaces.h" | 46 #include "spaces.h" |
| 46 #include "store-buffer.h" | 47 #include "store-buffer.h" |
| 47 #include "v8memory.h" | 48 #include "v8memory.h" |
| 48 #include "factory.h" | 49 #include "factory.h" |
| 49 #include "incremental-marking.h" | 50 #include "incremental-marking.h" |
| 50 #include "transitions-inl.h" | 51 #include "transitions-inl.h" |
| 51 #include "objects-visiting.h" | 52 #include "objects-visiting.h" |
| 52 | 53 |
| 53 namespace v8 { | 54 namespace v8 { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 79 } | 80 } |
| 80 | 81 |
| 81 | 82 |
| 82 #define CAST_ACCESSOR(type) \ | 83 #define CAST_ACCESSOR(type) \ |
| 83 type* type::cast(Object* object) { \ | 84 type* type::cast(Object* object) { \ |
| 84 SLOW_ASSERT(object->Is##type()); \ | 85 SLOW_ASSERT(object->Is##type()); \ |
| 85 return reinterpret_cast<type*>(object); \ | 86 return reinterpret_cast<type*>(object); \ |
| 86 } | 87 } |
| 87 | 88 |
| 88 | 89 |
| 90 #define FIXED_TYPED_ARRAY_CAST_ACCESSOR(type) \ |
| 91 template<> \ |
| 92 type* type::cast(Object* object) { \ |
| 93 SLOW_ASSERT(object->Is##type()); \ |
| 94 return reinterpret_cast<type*>(object); \ |
| 95 } |
| 96 |
| 89 #define INT_ACCESSORS(holder, name, offset) \ | 97 #define INT_ACCESSORS(holder, name, offset) \ |
| 90 int holder::name() { return READ_INT_FIELD(this, offset); } \ | 98 int holder::name() { return READ_INT_FIELD(this, offset); } \ |
| 91 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } | 99 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } |
| 92 | 100 |
| 93 | 101 |
| 94 #define ACCESSORS(holder, name, type, offset) \ | 102 #define ACCESSORS(holder, name, type, offset) \ |
| 95 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ | 103 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \ |
| 96 void holder::set_##name(type* value, WriteBarrierMode mode) { \ | 104 void holder::set_##name(type* value, WriteBarrierMode mode) { \ |
| 97 WRITE_FIELD(this, offset, value); \ | 105 WRITE_FIELD(this, offset, value); \ |
| 98 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \ | 106 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \ |
| (...skipping 28 matching lines...) Expand all Loading... |
| 127 #define BOOL_ACCESSORS(holder, field, name, offset) \ | 135 #define BOOL_ACCESSORS(holder, field, name, offset) \ |
| 128 bool holder::name() { \ | 136 bool holder::name() { \ |
| 129 return BooleanBit::get(field(), offset); \ | 137 return BooleanBit::get(field(), offset); \ |
| 130 } \ | 138 } \ |
| 131 void holder::set_##name(bool value) { \ | 139 void holder::set_##name(bool value) { \ |
| 132 set_##field(BooleanBit::set(field(), offset, value)); \ | 140 set_##field(BooleanBit::set(field(), offset, value)); \ |
| 133 } | 141 } |
| 134 | 142 |
| 135 | 143 |
| 136 bool Object::IsFixedArrayBase() { | 144 bool Object::IsFixedArrayBase() { |
| 137 return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray(); | 145 return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray() || |
| 146 IsFixedTypedArrayBase() || IsExternalArray(); |
| 138 } | 147 } |
| 139 | 148 |
| 140 | 149 |
| 141 // External objects are not extensible, so the map check is enough. | 150 // External objects are not extensible, so the map check is enough. |
| 142 bool Object::IsExternal() { | 151 bool Object::IsExternal() { |
| 143 return Object::IsHeapObject() && | 152 return Object::IsHeapObject() && |
| 144 HeapObject::cast(this)->map() == | 153 HeapObject::cast(this)->map() == |
| 145 HeapObject::cast(this)->GetHeap()->external_map(); | 154 HeapObject::cast(this)->GetHeap()->external_map(); |
| 146 } | 155 } |
| 147 | 156 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 | 264 |
| 256 | 265 |
| 257 bool Object::IsExternalTwoByteString() { | 266 bool Object::IsExternalTwoByteString() { |
| 258 if (!IsString()) return false; | 267 if (!IsString()) return false; |
| 259 return StringShape(String::cast(this)).IsExternal() && | 268 return StringShape(String::cast(this)).IsExternal() && |
| 260 String::cast(this)->IsTwoByteRepresentation(); | 269 String::cast(this)->IsTwoByteRepresentation(); |
| 261 } | 270 } |
| 262 | 271 |
| 263 bool Object::HasValidElements() { | 272 bool Object::HasValidElements() { |
| 264 // Dictionary is covered under FixedArray. | 273 // Dictionary is covered under FixedArray. |
| 265 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray(); | 274 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray() || |
| 275 IsFixedTypedArrayBase(); |
| 266 } | 276 } |
| 267 | 277 |
| 268 | 278 |
| 269 MaybeObject* Object::AllocateNewStorageFor(Heap* heap, | 279 MaybeObject* Object::AllocateNewStorageFor(Heap* heap, |
| 270 Representation representation) { | 280 Representation representation) { |
| 271 if (FLAG_track_fields && representation.IsSmi() && IsUninitialized()) { | 281 if (FLAG_track_fields && representation.IsSmi() && IsUninitialized()) { |
| 272 return Smi::FromInt(0); | 282 return Smi::FromInt(0); |
| 273 } | 283 } |
| 274 if (!FLAG_track_double_fields) return this; | 284 if (!FLAG_track_double_fields) return this; |
| 275 if (!representation.IsDouble()) return this; | 285 if (!representation.IsDouble()) return this; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 uc32 FlatStringReader::Get(int index) { | 452 uc32 FlatStringReader::Get(int index) { |
| 443 ASSERT(0 <= index && index <= length_); | 453 ASSERT(0 <= index && index <= length_); |
| 444 if (is_ascii_) { | 454 if (is_ascii_) { |
| 445 return static_cast<const byte*>(start_)[index]; | 455 return static_cast<const byte*>(start_)[index]; |
| 446 } else { | 456 } else { |
| 447 return static_cast<const uc16*>(start_)[index]; | 457 return static_cast<const uc16*>(start_)[index]; |
| 448 } | 458 } |
| 449 } | 459 } |
| 450 | 460 |
| 451 | 461 |
| 462 template <typename Char> |
| 463 class SequentialStringKey : public HashTableKey { |
| 464 public: |
| 465 explicit SequentialStringKey(Vector<const Char> string, uint32_t seed) |
| 466 : string_(string), hash_field_(0), seed_(seed) { } |
| 467 |
| 468 virtual uint32_t Hash() { |
| 469 hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(), |
| 470 string_.length(), |
| 471 seed_); |
| 472 |
| 473 uint32_t result = hash_field_ >> String::kHashShift; |
| 474 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 475 return result; |
| 476 } |
| 477 |
| 478 |
| 479 virtual uint32_t HashForObject(Object* other) { |
| 480 return String::cast(other)->Hash(); |
| 481 } |
| 482 |
| 483 Vector<const Char> string_; |
| 484 uint32_t hash_field_; |
| 485 uint32_t seed_; |
| 486 }; |
| 487 |
| 488 |
| 489 class OneByteStringKey : public SequentialStringKey<uint8_t> { |
| 490 public: |
| 491 OneByteStringKey(Vector<const uint8_t> str, uint32_t seed) |
| 492 : SequentialStringKey<uint8_t>(str, seed) { } |
| 493 |
| 494 virtual bool IsMatch(Object* string) { |
| 495 return String::cast(string)->IsOneByteEqualTo(string_); |
| 496 } |
| 497 |
| 498 virtual MaybeObject* AsObject(Heap* heap); |
| 499 }; |
| 500 |
| 501 |
| 502 class SubStringOneByteStringKey : public HashTableKey { |
| 503 public: |
| 504 explicit SubStringOneByteStringKey(Handle<SeqOneByteString> string, |
| 505 int from, |
| 506 int length) |
| 507 : string_(string), from_(from), length_(length) { } |
| 508 |
| 509 virtual uint32_t Hash() { |
| 510 ASSERT(length_ >= 0); |
| 511 ASSERT(from_ + length_ <= string_->length()); |
| 512 uint8_t* chars = string_->GetChars() + from_; |
| 513 hash_field_ = StringHasher::HashSequentialString( |
| 514 chars, length_, string_->GetHeap()->HashSeed()); |
| 515 uint32_t result = hash_field_ >> String::kHashShift; |
| 516 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 517 return result; |
| 518 } |
| 519 |
| 520 |
| 521 virtual uint32_t HashForObject(Object* other) { |
| 522 return String::cast(other)->Hash(); |
| 523 } |
| 524 |
| 525 virtual bool IsMatch(Object* string) { |
| 526 Vector<const uint8_t> chars(string_->GetChars() + from_, length_); |
| 527 return String::cast(string)->IsOneByteEqualTo(chars); |
| 528 } |
| 529 |
| 530 virtual MaybeObject* AsObject(Heap* heap); |
| 531 |
| 532 private: |
| 533 Handle<SeqOneByteString> string_; |
| 534 int from_; |
| 535 int length_; |
| 536 uint32_t hash_field_; |
| 537 }; |
| 538 |
| 539 |
| 540 class TwoByteStringKey : public SequentialStringKey<uc16> { |
| 541 public: |
| 542 explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed) |
| 543 : SequentialStringKey<uc16>(str, seed) { } |
| 544 |
| 545 virtual bool IsMatch(Object* string) { |
| 546 return String::cast(string)->IsTwoByteEqualTo(string_); |
| 547 } |
| 548 |
| 549 virtual MaybeObject* AsObject(Heap* heap); |
| 550 }; |
| 551 |
| 552 |
| 553 // Utf8StringKey carries a vector of chars as key. |
| 554 class Utf8StringKey : public HashTableKey { |
| 555 public: |
| 556 explicit Utf8StringKey(Vector<const char> string, uint32_t seed) |
| 557 : string_(string), hash_field_(0), seed_(seed) { } |
| 558 |
| 559 virtual bool IsMatch(Object* string) { |
| 560 return String::cast(string)->IsUtf8EqualTo(string_); |
| 561 } |
| 562 |
| 563 virtual uint32_t Hash() { |
| 564 if (hash_field_ != 0) return hash_field_ >> String::kHashShift; |
| 565 hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_); |
| 566 uint32_t result = hash_field_ >> String::kHashShift; |
| 567 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 568 return result; |
| 569 } |
| 570 |
| 571 virtual uint32_t HashForObject(Object* other) { |
| 572 return String::cast(other)->Hash(); |
| 573 } |
| 574 |
| 575 virtual MaybeObject* AsObject(Heap* heap) { |
| 576 if (hash_field_ == 0) Hash(); |
| 577 return heap->AllocateInternalizedStringFromUtf8(string_, |
| 578 chars_, |
| 579 hash_field_); |
| 580 } |
| 581 |
| 582 Vector<const char> string_; |
| 583 uint32_t hash_field_; |
| 584 int chars_; // Caches the number of characters when computing the hash code. |
| 585 uint32_t seed_; |
| 586 }; |
| 587 |
| 588 |
| 452 bool Object::IsNumber() { | 589 bool Object::IsNumber() { |
| 453 return IsSmi() || IsHeapNumber(); | 590 return IsSmi() || IsHeapNumber(); |
| 454 } | 591 } |
| 455 | 592 |
| 456 | 593 |
| 457 TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE) | 594 TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE) |
| 458 TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE) | 595 TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE) |
| 459 | 596 |
| 460 | 597 |
| 461 bool Object::IsFiller() { | 598 bool Object::IsFiller() { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 481 TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE) | 618 TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE) |
| 482 TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE) | 619 TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE) |
| 483 TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE) | 620 TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE) |
| 484 TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE) | 621 TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE) |
| 485 TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE) | 622 TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE) |
| 486 TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE) | 623 TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE) |
| 487 TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE) | 624 TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE) |
| 488 TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE) | 625 TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE) |
| 489 | 626 |
| 490 | 627 |
| 628 bool Object::IsFixedTypedArrayBase() { |
| 629 if (!Object::IsHeapObject()) return false; |
| 630 |
| 631 InstanceType instance_type = |
| 632 HeapObject::cast(this)->map()->instance_type(); |
| 633 return (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE && |
| 634 instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE); |
| 635 } |
| 636 |
| 637 |
| 638 TYPE_CHECKER(FixedUint8Array, FIXED_UINT8_ARRAY_TYPE) |
| 639 TYPE_CHECKER(FixedInt8Array, FIXED_INT8_ARRAY_TYPE) |
| 640 TYPE_CHECKER(FixedUint16Array, FIXED_UINT16_ARRAY_TYPE) |
| 641 TYPE_CHECKER(FixedInt16Array, FIXED_INT16_ARRAY_TYPE) |
| 642 TYPE_CHECKER(FixedUint32Array, FIXED_UINT32_ARRAY_TYPE) |
| 643 TYPE_CHECKER(FixedInt32Array, FIXED_INT32_ARRAY_TYPE) |
| 644 TYPE_CHECKER(FixedFloat32Array, FIXED_FLOAT32_ARRAY_TYPE) |
| 645 TYPE_CHECKER(FixedFloat64Array, FIXED_FLOAT64_ARRAY_TYPE) |
| 646 TYPE_CHECKER(FixedUint8ClampedArray, FIXED_UINT8_CLAMPED_ARRAY_TYPE) |
| 647 |
| 648 |
| 491 bool MaybeObject::IsFailure() { | 649 bool MaybeObject::IsFailure() { |
| 492 return HAS_FAILURE_TAG(this); | 650 return HAS_FAILURE_TAG(this); |
| 493 } | 651 } |
| 494 | 652 |
| 495 | 653 |
| 496 bool MaybeObject::IsRetryAfterGC() { | 654 bool MaybeObject::IsRetryAfterGC() { |
| 497 return HAS_FAILURE_TAG(this) | 655 return HAS_FAILURE_TAG(this) |
| 498 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC; | 656 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC; |
| 499 } | 657 } |
| 500 | 658 |
| (...skipping 1447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 IsTrue() || | 2106 IsTrue() || |
| 1949 IsFalse() || | 2107 IsFalse() || |
| 1950 IsNull())) { | 2108 IsNull())) { |
| 1951 FATAL("API call returned invalid object"); | 2109 FATAL("API call returned invalid object"); |
| 1952 } | 2110 } |
| 1953 #endif // ENABLE_EXTRA_CHECKS | 2111 #endif // ENABLE_EXTRA_CHECKS |
| 1954 } | 2112 } |
| 1955 | 2113 |
| 1956 | 2114 |
| 1957 FixedArrayBase* FixedArrayBase::cast(Object* object) { | 2115 FixedArrayBase* FixedArrayBase::cast(Object* object) { |
| 1958 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray() || | 2116 ASSERT(object->IsFixedArrayBase()); |
| 1959 object->IsConstantPoolArray()); | |
| 1960 return reinterpret_cast<FixedArrayBase*>(object); | 2117 return reinterpret_cast<FixedArrayBase*>(object); |
| 1961 } | 2118 } |
| 1962 | 2119 |
| 1963 | 2120 |
| 1964 Object* FixedArray::get(int index) { | 2121 Object* FixedArray::get(int index) { |
| 1965 SLOW_ASSERT(index >= 0 && index < this->length()); | 2122 SLOW_ASSERT(index >= 0 && index < this->length()); |
| 1966 return READ_FIELD(this, kHeaderSize + index * kPointerSize); | 2123 return READ_FIELD(this, kHeaderSize + index * kPointerSize); |
| 1967 } | 2124 } |
| 1968 | 2125 |
| 1969 | 2126 |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2628 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask)); | 2785 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask)); |
| 2629 } | 2786 } |
| 2630 | 2787 |
| 2631 | 2788 |
| 2632 // ------------------------------------ | 2789 // ------------------------------------ |
| 2633 // Cast operations | 2790 // Cast operations |
| 2634 | 2791 |
| 2635 | 2792 |
| 2636 CAST_ACCESSOR(FixedArray) | 2793 CAST_ACCESSOR(FixedArray) |
| 2637 CAST_ACCESSOR(FixedDoubleArray) | 2794 CAST_ACCESSOR(FixedDoubleArray) |
| 2795 CAST_ACCESSOR(FixedTypedArrayBase) |
| 2638 CAST_ACCESSOR(ConstantPoolArray) | 2796 CAST_ACCESSOR(ConstantPoolArray) |
| 2639 CAST_ACCESSOR(DescriptorArray) | 2797 CAST_ACCESSOR(DescriptorArray) |
| 2640 CAST_ACCESSOR(DeoptimizationInputData) | 2798 CAST_ACCESSOR(DeoptimizationInputData) |
| 2641 CAST_ACCESSOR(DeoptimizationOutputData) | 2799 CAST_ACCESSOR(DeoptimizationOutputData) |
| 2642 CAST_ACCESSOR(DependentCode) | 2800 CAST_ACCESSOR(DependentCode) |
| 2643 CAST_ACCESSOR(TypeFeedbackCells) | 2801 CAST_ACCESSOR(TypeFeedbackCells) |
| 2644 CAST_ACCESSOR(StringTable) | 2802 CAST_ACCESSOR(StringTable) |
| 2645 CAST_ACCESSOR(JSFunctionResultCache) | 2803 CAST_ACCESSOR(JSFunctionResultCache) |
| 2646 CAST_ACCESSOR(NormalizedMapCache) | 2804 CAST_ACCESSOR(NormalizedMapCache) |
| 2647 CAST_ACCESSOR(ScopeInfo) | 2805 CAST_ACCESSOR(ScopeInfo) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2697 CAST_ACCESSOR(ExternalShortArray) | 2855 CAST_ACCESSOR(ExternalShortArray) |
| 2698 CAST_ACCESSOR(ExternalUnsignedShortArray) | 2856 CAST_ACCESSOR(ExternalUnsignedShortArray) |
| 2699 CAST_ACCESSOR(ExternalIntArray) | 2857 CAST_ACCESSOR(ExternalIntArray) |
| 2700 CAST_ACCESSOR(ExternalUnsignedIntArray) | 2858 CAST_ACCESSOR(ExternalUnsignedIntArray) |
| 2701 CAST_ACCESSOR(ExternalFloatArray) | 2859 CAST_ACCESSOR(ExternalFloatArray) |
| 2702 CAST_ACCESSOR(ExternalDoubleArray) | 2860 CAST_ACCESSOR(ExternalDoubleArray) |
| 2703 CAST_ACCESSOR(ExternalPixelArray) | 2861 CAST_ACCESSOR(ExternalPixelArray) |
| 2704 CAST_ACCESSOR(Struct) | 2862 CAST_ACCESSOR(Struct) |
| 2705 CAST_ACCESSOR(AccessorInfo) | 2863 CAST_ACCESSOR(AccessorInfo) |
| 2706 | 2864 |
| 2865 template <class Traits> |
| 2866 FixedTypedArray<Traits>* FixedTypedArray<Traits>::cast(Object* object) { |
| 2867 SLOW_ASSERT(object->IsHeapObject() && |
| 2868 HeapObject::cast(object)->map()->instance_type() == |
| 2869 Traits::kInstanceType); |
| 2870 return reinterpret_cast<FixedTypedArray<Traits>*>(object); |
| 2871 } |
| 2872 |
| 2707 | 2873 |
| 2708 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) | 2874 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) |
| 2709 STRUCT_LIST(MAKE_STRUCT_CAST) | 2875 STRUCT_LIST(MAKE_STRUCT_CAST) |
| 2710 #undef MAKE_STRUCT_CAST | 2876 #undef MAKE_STRUCT_CAST |
| 2711 | 2877 |
| 2712 | 2878 |
| 2713 template <typename Shape, typename Key> | 2879 template <typename Shape, typename Key> |
| 2714 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { | 2880 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { |
| 2715 ASSERT(obj->IsHashTable()); | 2881 ASSERT(obj->IsHashTable()); |
| 2716 return reinterpret_cast<HashTable*>(obj); | 2882 return reinterpret_cast<HashTable*>(obj); |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3472 } | 3638 } |
| 3473 | 3639 |
| 3474 | 3640 |
| 3475 void ExternalDoubleArray::set(int index, double value) { | 3641 void ExternalDoubleArray::set(int index, double value) { |
| 3476 ASSERT((index >= 0) && (index < this->length())); | 3642 ASSERT((index >= 0) && (index < this->length())); |
| 3477 double* ptr = static_cast<double*>(external_pointer()); | 3643 double* ptr = static_cast<double*>(external_pointer()); |
| 3478 ptr[index] = value; | 3644 ptr[index] = value; |
| 3479 } | 3645 } |
| 3480 | 3646 |
| 3481 | 3647 |
| 3648 int FixedTypedArrayBase::size() { |
| 3649 InstanceType instance_type = map()->instance_type(); |
| 3650 int element_size; |
| 3651 switch (instance_type) { |
| 3652 case FIXED_UINT8_ARRAY_TYPE: |
| 3653 case FIXED_INT8_ARRAY_TYPE: |
| 3654 case FIXED_UINT8_CLAMPED_ARRAY_TYPE: |
| 3655 element_size = 1; |
| 3656 break; |
| 3657 case FIXED_UINT16_ARRAY_TYPE: |
| 3658 case FIXED_INT16_ARRAY_TYPE: |
| 3659 element_size = 2; |
| 3660 break; |
| 3661 case FIXED_UINT32_ARRAY_TYPE: |
| 3662 case FIXED_INT32_ARRAY_TYPE: |
| 3663 case FIXED_FLOAT32_ARRAY_TYPE: |
| 3664 element_size = 4; |
| 3665 break; |
| 3666 case FIXED_FLOAT64_ARRAY_TYPE: |
| 3667 element_size = 8; |
| 3668 break; |
| 3669 default: |
| 3670 UNREACHABLE(); |
| 3671 return 0; |
| 3672 } |
| 3673 return OBJECT_POINTER_ALIGN(kDataOffset + length() * element_size); |
| 3674 } |
| 3675 |
| 3676 |
| 3677 template <class Traits> |
| 3678 typename Traits::ElementType FixedTypedArray<Traits>::get_scalar(int index) { |
| 3679 ASSERT((index >= 0) && (index < this->length())); |
| 3680 ElementType* ptr = reinterpret_cast<ElementType*>( |
| 3681 FIELD_ADDR(this, kDataOffset)); |
| 3682 return ptr[index]; |
| 3683 } |
| 3684 |
| 3685 template <class Traits> |
| 3686 void FixedTypedArray<Traits>::set(int index, ElementType value) { |
| 3687 ASSERT((index >= 0) && (index < this->length())); |
| 3688 ElementType* ptr = reinterpret_cast<ElementType*>( |
| 3689 FIELD_ADDR(this, kDataOffset)); |
| 3690 ptr[index] = value; |
| 3691 } |
| 3692 |
| 3693 |
| 3694 template <class Traits> |
| 3695 MaybeObject* FixedTypedArray<Traits>::get(int index) { |
| 3696 return Traits::ToObject(GetHeap(), get_scalar(index)); |
| 3697 } |
| 3698 |
| 3699 template <class Traits> |
| 3700 MaybeObject* FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) { |
| 3701 ElementType cast_value = Traits::defaultValue(); |
| 3702 if (index < static_cast<uint32_t>(length())) { |
| 3703 if (value->IsSmi()) { |
| 3704 int int_value = Smi::cast(value)->value(); |
| 3705 cast_value = static_cast<ElementType>(int_value); |
| 3706 } else if (value->IsHeapNumber()) { |
| 3707 double double_value = HeapNumber::cast(value)->value(); |
| 3708 cast_value = static_cast<ElementType>(DoubleToInt32(double_value)); |
| 3709 } else { |
| 3710 // Clamp undefined to the default value. All other types have been |
| 3711 // converted to a number type further up in the call chain. |
| 3712 ASSERT(value->IsUndefined()); |
| 3713 } |
| 3714 set(index, cast_value); |
| 3715 } |
| 3716 return Traits::ToObject(GetHeap(), cast_value); |
| 3717 } |
| 3718 |
| 3719 template <class Traits> |
| 3720 Handle<Object> FixedTypedArray<Traits>::SetValue( |
| 3721 Handle<FixedTypedArray<Traits> > array, |
| 3722 uint32_t index, |
| 3723 Handle<Object> value) { |
| 3724 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 3725 array->SetValue(index, *value), |
| 3726 Object); |
| 3727 } |
| 3728 |
| 3729 |
| 3730 MaybeObject* Uint8ArrayTraits::ToObject(Heap*, uint8_t scalar) { |
| 3731 return Smi::FromInt(scalar); |
| 3732 } |
| 3733 |
| 3734 |
| 3735 MaybeObject* Uint8ClampedArrayTraits::ToObject(Heap*, uint8_t scalar) { |
| 3736 return Smi::FromInt(scalar); |
| 3737 } |
| 3738 |
| 3739 |
| 3740 MaybeObject* Int8ArrayTraits::ToObject(Heap*, int8_t scalar) { |
| 3741 return Smi::FromInt(scalar); |
| 3742 } |
| 3743 |
| 3744 |
| 3745 MaybeObject* Uint16ArrayTraits::ToObject(Heap*, uint16_t scalar) { |
| 3746 return Smi::FromInt(scalar); |
| 3747 } |
| 3748 |
| 3749 |
| 3750 MaybeObject* Int16ArrayTraits::ToObject(Heap*, int16_t scalar) { |
| 3751 return Smi::FromInt(scalar); |
| 3752 } |
| 3753 |
| 3754 |
| 3755 MaybeObject* Uint32ArrayTraits::ToObject(Heap* heap, uint32_t scalar) { |
| 3756 return heap->NumberFromUint32(scalar); |
| 3757 } |
| 3758 |
| 3759 |
| 3760 MaybeObject* Int32ArrayTraits::ToObject(Heap* heap, int32_t scalar) { |
| 3761 return heap->NumberFromInt32(scalar); |
| 3762 } |
| 3763 |
| 3764 |
| 3765 MaybeObject* Float32ArrayTraits::ToObject(Heap* heap, float scalar) { |
| 3766 return heap->NumberFromDouble(scalar); |
| 3767 } |
| 3768 |
| 3769 |
| 3770 MaybeObject* Float64ArrayTraits::ToObject(Heap* heap, double scalar) { |
| 3771 return heap->NumberFromDouble(scalar); |
| 3772 } |
| 3773 |
| 3774 |
| 3482 int Map::visitor_id() { | 3775 int Map::visitor_id() { |
| 3483 return READ_BYTE_FIELD(this, kVisitorIdOffset); | 3776 return READ_BYTE_FIELD(this, kVisitorIdOffset); |
| 3484 } | 3777 } |
| 3485 | 3778 |
| 3486 | 3779 |
| 3487 void Map::set_visitor_id(int id) { | 3780 void Map::set_visitor_id(int id) { |
| 3488 ASSERT(0 <= id && id < 256); | 3781 ASSERT(0 <= id && id < 256); |
| 3489 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id)); | 3782 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id)); |
| 3490 } | 3783 } |
| 3491 | 3784 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3532 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { | 3825 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { |
| 3533 return FixedDoubleArray::SizeFor( | 3826 return FixedDoubleArray::SizeFor( |
| 3534 reinterpret_cast<FixedDoubleArray*>(this)->length()); | 3827 reinterpret_cast<FixedDoubleArray*>(this)->length()); |
| 3535 } | 3828 } |
| 3536 if (instance_type == CONSTANT_POOL_ARRAY_TYPE) { | 3829 if (instance_type == CONSTANT_POOL_ARRAY_TYPE) { |
| 3537 return ConstantPoolArray::SizeFor( | 3830 return ConstantPoolArray::SizeFor( |
| 3538 reinterpret_cast<ConstantPoolArray*>(this)->count_of_int64_entries(), | 3831 reinterpret_cast<ConstantPoolArray*>(this)->count_of_int64_entries(), |
| 3539 reinterpret_cast<ConstantPoolArray*>(this)->count_of_ptr_entries(), | 3832 reinterpret_cast<ConstantPoolArray*>(this)->count_of_ptr_entries(), |
| 3540 reinterpret_cast<ConstantPoolArray*>(this)->count_of_int32_entries()); | 3833 reinterpret_cast<ConstantPoolArray*>(this)->count_of_int32_entries()); |
| 3541 } | 3834 } |
| 3835 if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE && |
| 3836 instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE) { |
| 3837 return reinterpret_cast<FixedTypedArrayBase*>(this)->size(); |
| 3838 } |
| 3542 ASSERT(instance_type == CODE_TYPE); | 3839 ASSERT(instance_type == CODE_TYPE); |
| 3543 return reinterpret_cast<Code*>(this)->CodeSize(); | 3840 return reinterpret_cast<Code*>(this)->CodeSize(); |
| 3544 } | 3841 } |
| 3545 | 3842 |
| 3546 | 3843 |
| 3547 void Map::set_instance_size(int value) { | 3844 void Map::set_instance_size(int value) { |
| 3548 ASSERT_EQ(0, value & (kPointerSize - 1)); | 3845 ASSERT_EQ(0, value & (kPointerSize - 1)); |
| 3549 value >>= kPointerSizeLog2; | 3846 value >>= kPointerSizeLog2; |
| 3550 ASSERT(0 <= value && value < 256); | 3847 ASSERT(0 <= value && value < 256); |
| 3551 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value)); | 3848 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value)); |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4476 } | 4773 } |
| 4477 | 4774 |
| 4478 | 4775 |
| 4479 void Map::set_transitions(TransitionArray* transition_array, | 4776 void Map::set_transitions(TransitionArray* transition_array, |
| 4480 WriteBarrierMode mode) { | 4777 WriteBarrierMode mode) { |
| 4481 // Transition arrays are not shared. When one is replaced, it should not | 4778 // Transition arrays are not shared. When one is replaced, it should not |
| 4482 // keep referenced objects alive, so we zap it. | 4779 // keep referenced objects alive, so we zap it. |
| 4483 // When there is another reference to the array somewhere (e.g. a handle), | 4780 // When there is another reference to the array somewhere (e.g. a handle), |
| 4484 // not zapping turns from a waste of memory into a source of crashes. | 4781 // not zapping turns from a waste of memory into a source of crashes. |
| 4485 if (HasTransitionArray()) { | 4782 if (HasTransitionArray()) { |
| 4783 #ifdef DEBUG |
| 4784 for (int i = 0; i < transitions()->number_of_transitions(); i++) { |
| 4785 Map* target = transitions()->GetTarget(i); |
| 4786 if (target->instance_descriptors() == instance_descriptors()) { |
| 4787 Name* key = transitions()->GetKey(i); |
| 4788 int new_target_index = transition_array->Search(key); |
| 4789 ASSERT(new_target_index != TransitionArray::kNotFound); |
| 4790 ASSERT(transition_array->GetTarget(new_target_index) == target); |
| 4791 } |
| 4792 } |
| 4793 #endif |
| 4486 ASSERT(transitions() != transition_array); | 4794 ASSERT(transitions() != transition_array); |
| 4487 ZapTransitions(); | 4795 ZapTransitions(); |
| 4488 } | 4796 } |
| 4489 | 4797 |
| 4490 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); | 4798 WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); |
| 4491 CONDITIONAL_WRITE_BARRIER( | 4799 CONDITIONAL_WRITE_BARRIER( |
| 4492 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); | 4800 GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); |
| 4493 } | 4801 } |
| 4494 | 4802 |
| 4495 | 4803 |
| (...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5700 EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE) | 6008 EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE) |
| 5701 EXTERNAL_ELEMENTS_CHECK(UnsignedInt, | 6009 EXTERNAL_ELEMENTS_CHECK(UnsignedInt, |
| 5702 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE) | 6010 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE) |
| 5703 EXTERNAL_ELEMENTS_CHECK(Float, | 6011 EXTERNAL_ELEMENTS_CHECK(Float, |
| 5704 EXTERNAL_FLOAT_ARRAY_TYPE) | 6012 EXTERNAL_FLOAT_ARRAY_TYPE) |
| 5705 EXTERNAL_ELEMENTS_CHECK(Double, | 6013 EXTERNAL_ELEMENTS_CHECK(Double, |
| 5706 EXTERNAL_DOUBLE_ARRAY_TYPE) | 6014 EXTERNAL_DOUBLE_ARRAY_TYPE) |
| 5707 EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE) | 6015 EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE) |
| 5708 | 6016 |
| 5709 | 6017 |
| 6018 bool JSObject::HasFixedTypedArrayElements() { |
| 6019 HeapObject* array = elements(); |
| 6020 ASSERT(array != NULL); |
| 6021 return array->IsFixedTypedArrayBase(); |
| 6022 } |
| 6023 |
| 6024 |
| 5710 bool JSObject::HasNamedInterceptor() { | 6025 bool JSObject::HasNamedInterceptor() { |
| 5711 return map()->has_named_interceptor(); | 6026 return map()->has_named_interceptor(); |
| 5712 } | 6027 } |
| 5713 | 6028 |
| 5714 | 6029 |
| 5715 bool JSObject::HasIndexedInterceptor() { | 6030 bool JSObject::HasIndexedInterceptor() { |
| 5716 return map()->has_indexed_interceptor(); | 6031 return map()->has_indexed_interceptor(); |
| 5717 } | 6032 } |
| 5718 | 6033 |
| 5719 | 6034 |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6487 #undef WRITE_INT_FIELD | 6802 #undef WRITE_INT_FIELD |
| 6488 #undef READ_INTPTR_FIELD | 6803 #undef READ_INTPTR_FIELD |
| 6489 #undef WRITE_INTPTR_FIELD | 6804 #undef WRITE_INTPTR_FIELD |
| 6490 #undef READ_UINT32_FIELD | 6805 #undef READ_UINT32_FIELD |
| 6491 #undef WRITE_UINT32_FIELD | 6806 #undef WRITE_UINT32_FIELD |
| 6492 #undef READ_SHORT_FIELD | 6807 #undef READ_SHORT_FIELD |
| 6493 #undef WRITE_SHORT_FIELD | 6808 #undef WRITE_SHORT_FIELD |
| 6494 #undef READ_BYTE_FIELD | 6809 #undef READ_BYTE_FIELD |
| 6495 #undef WRITE_BYTE_FIELD | 6810 #undef WRITE_BYTE_FIELD |
| 6496 | 6811 |
| 6497 | |
| 6498 } } // namespace v8::internal | 6812 } } // namespace v8::internal |
| 6499 | 6813 |
| 6500 #endif // V8_OBJECTS_INL_H_ | 6814 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |