OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 273 |
274 uint32_t StringShape::full_representation_tag() { | 274 uint32_t StringShape::full_representation_tag() { |
275 return (type_ & (kStringRepresentationMask | kStringEncodingMask)); | 275 return (type_ & (kStringRepresentationMask | kStringEncodingMask)); |
276 } | 276 } |
277 | 277 |
278 | 278 |
279 STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) == | 279 STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) == |
280 Internals::kFullStringRepresentationMask); | 280 Internals::kFullStringRepresentationMask); |
281 | 281 |
282 | 282 |
283 uint32_t StringShape::size_tag() { | |
284 return (type_ & kStringSizeMask); | |
285 } | |
286 | |
287 | |
288 bool StringShape::IsSequentialAscii() { | 283 bool StringShape::IsSequentialAscii() { |
289 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag); | 284 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag); |
290 } | 285 } |
291 | 286 |
292 | 287 |
293 bool StringShape::IsSequentialTwoByte() { | 288 bool StringShape::IsSequentialTwoByte() { |
294 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag); | 289 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag); |
295 } | 290 } |
296 | 291 |
297 | 292 |
(...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1628 template <typename Shape, typename Key> | 1623 template <typename Shape, typename Key> |
1629 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { | 1624 HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) { |
1630 ASSERT(obj->IsHashTable()); | 1625 ASSERT(obj->IsHashTable()); |
1631 return reinterpret_cast<HashTable*>(obj); | 1626 return reinterpret_cast<HashTable*>(obj); |
1632 } | 1627 } |
1633 | 1628 |
1634 | 1629 |
1635 INT_ACCESSORS(Array, length, kLengthOffset) | 1630 INT_ACCESSORS(Array, length, kLengthOffset) |
1636 | 1631 |
1637 | 1632 |
| 1633 INT_ACCESSORS(String, length, kLengthOffset) |
| 1634 |
| 1635 |
| 1636 uint32_t String::hash_field() { |
| 1637 return READ_UINT32_FIELD(this, kHashFieldOffset); |
| 1638 } |
| 1639 |
| 1640 |
| 1641 void String::set_hash_field(uint32_t value) { |
| 1642 WRITE_UINT32_FIELD(this, kHashFieldOffset, value); |
| 1643 } |
| 1644 |
| 1645 |
1638 bool String::Equals(String* other) { | 1646 bool String::Equals(String* other) { |
1639 if (other == this) return true; | 1647 if (other == this) return true; |
1640 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) { | 1648 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) { |
1641 return false; | 1649 return false; |
1642 } | 1650 } |
1643 return SlowEquals(other); | 1651 return SlowEquals(other); |
1644 } | 1652 } |
1645 | 1653 |
1646 | 1654 |
1647 int String::length() { | |
1648 uint32_t len = READ_INT_FIELD(this, kLengthOffset); | |
1649 | |
1650 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); | |
1651 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); | |
1652 ASSERT(kLongStringTag == 0); | |
1653 | |
1654 return len >> (StringShape(this).size_tag() + kLongLengthShift); | |
1655 } | |
1656 | |
1657 | |
1658 void String::set_length(int value) { | |
1659 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); | |
1660 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); | |
1661 ASSERT(kLongStringTag == 0); | |
1662 | |
1663 WRITE_INT_FIELD(this, | |
1664 kLengthOffset, | |
1665 value << (StringShape(this).size_tag() + kLongLengthShift)); | |
1666 } | |
1667 | |
1668 | |
1669 uint32_t String::length_field() { | |
1670 return READ_UINT32_FIELD(this, kLengthOffset); | |
1671 } | |
1672 | |
1673 | |
1674 void String::set_length_field(uint32_t value) { | |
1675 WRITE_UINT32_FIELD(this, kLengthOffset, value); | |
1676 } | |
1677 | |
1678 | |
1679 Object* String::TryFlattenIfNotFlat() { | 1655 Object* String::TryFlattenIfNotFlat() { |
1680 // We don't need to flatten strings that are already flat. Since this code | 1656 // We don't need to flatten strings that are already flat. Since this code |
1681 // is inlined, it can be helpful in the flat case to not call out to Flatten. | 1657 // is inlined, it can be helpful in the flat case to not call out to Flatten. |
1682 if (!IsFlat()) { | 1658 if (!IsFlat()) { |
1683 return TryFlatten(); | 1659 return TryFlatten(); |
1684 } | 1660 } |
1685 return this; | 1661 return this; |
1686 } | 1662 } |
1687 | 1663 |
1688 | 1664 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 | 1748 |
1773 | 1749 |
1774 void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) { | 1750 void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) { |
1775 ASSERT(index >= 0 && index < length()); | 1751 ASSERT(index >= 0 && index < length()); |
1776 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value); | 1752 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value); |
1777 } | 1753 } |
1778 | 1754 |
1779 | 1755 |
1780 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) { | 1756 int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) { |
1781 uint32_t length = READ_INT_FIELD(this, kLengthOffset); | 1757 uint32_t length = READ_INT_FIELD(this, kLengthOffset); |
1782 | |
1783 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); | |
1784 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); | |
1785 ASSERT(kLongStringTag == 0); | |
1786 | |
1787 // Use the map (and not 'this') to compute the size tag, since | |
1788 // TwoByteStringSize is called during GC when maps are encoded. | |
1789 length >>= StringShape(instance_type).size_tag() + kLongLengthShift; | |
1790 | |
1791 return SizeFor(length); | 1758 return SizeFor(length); |
1792 } | 1759 } |
1793 | 1760 |
1794 | 1761 |
1795 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) { | 1762 int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) { |
1796 uint32_t length = READ_INT_FIELD(this, kLengthOffset); | 1763 uint32_t length = READ_INT_FIELD(this, kLengthOffset); |
1797 | |
1798 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift); | |
1799 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift); | |
1800 ASSERT(kLongStringTag == 0); | |
1801 | |
1802 // Use the map (and not 'this') to compute the size tag, since | |
1803 // AsciiStringSize is called during GC when maps are encoded. | |
1804 length >>= StringShape(instance_type).size_tag() + kLongLengthShift; | |
1805 | |
1806 return SizeFor(length); | 1764 return SizeFor(length); |
1807 } | 1765 } |
1808 | 1766 |
1809 | 1767 |
1810 String* ConsString::first() { | 1768 String* ConsString::first() { |
1811 return String::cast(READ_FIELD(this, kFirstOffset)); | 1769 return String::cast(READ_FIELD(this, kFirstOffset)); |
1812 } | 1770 } |
1813 | 1771 |
1814 | 1772 |
1815 Object* ConsString::unchecked_first() { | 1773 Object* ConsString::unchecked_first() { |
(...skipping 27 matching lines...) Expand all Loading... |
1843 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 1801 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); |
1844 } | 1802 } |
1845 | 1803 |
1846 | 1804 |
1847 void ExternalAsciiString::set_resource( | 1805 void ExternalAsciiString::set_resource( |
1848 ExternalAsciiString::Resource* resource) { | 1806 ExternalAsciiString::Resource* resource) { |
1849 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource; | 1807 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource; |
1850 } | 1808 } |
1851 | 1809 |
1852 | 1810 |
1853 Map* ExternalAsciiString::StringMap(int length) { | |
1854 Map* map; | |
1855 // Number of characters: determines the map. | |
1856 if (length <= String::kMaxShortSize) { | |
1857 map = Heap::short_external_ascii_string_map(); | |
1858 } else if (length <= String::kMaxMediumSize) { | |
1859 map = Heap::medium_external_ascii_string_map(); | |
1860 } else { | |
1861 map = Heap::long_external_ascii_string_map(); | |
1862 } | |
1863 return map; | |
1864 } | |
1865 | |
1866 | |
1867 Map* ExternalAsciiString::SymbolMap(int length) { | |
1868 Map* map; | |
1869 // Number of characters: determines the map. | |
1870 if (length <= String::kMaxShortSize) { | |
1871 map = Heap::short_external_ascii_symbol_map(); | |
1872 } else if (length <= String::kMaxMediumSize) { | |
1873 map = Heap::medium_external_ascii_symbol_map(); | |
1874 } else { | |
1875 map = Heap::long_external_ascii_symbol_map(); | |
1876 } | |
1877 return map; | |
1878 } | |
1879 | |
1880 | |
1881 ExternalTwoByteString::Resource* ExternalTwoByteString::resource() { | 1811 ExternalTwoByteString::Resource* ExternalTwoByteString::resource() { |
1882 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); | 1812 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)); |
1883 } | 1813 } |
1884 | 1814 |
1885 | 1815 |
1886 void ExternalTwoByteString::set_resource( | 1816 void ExternalTwoByteString::set_resource( |
1887 ExternalTwoByteString::Resource* resource) { | 1817 ExternalTwoByteString::Resource* resource) { |
1888 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource; | 1818 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource; |
1889 } | 1819 } |
1890 | 1820 |
1891 | 1821 |
1892 Map* ExternalTwoByteString::StringMap(int length) { | |
1893 Map* map; | |
1894 // Number of characters: determines the map. | |
1895 if (length <= String::kMaxShortSize) { | |
1896 map = Heap::short_external_string_map(); | |
1897 } else if (length <= String::kMaxMediumSize) { | |
1898 map = Heap::medium_external_string_map(); | |
1899 } else { | |
1900 map = Heap::long_external_string_map(); | |
1901 } | |
1902 return map; | |
1903 } | |
1904 | |
1905 | |
1906 Map* ExternalTwoByteString::SymbolMap(int length) { | |
1907 Map* map; | |
1908 // Number of characters: determines the map. | |
1909 if (length <= String::kMaxShortSize) { | |
1910 map = Heap::short_external_symbol_map(); | |
1911 } else if (length <= String::kMaxMediumSize) { | |
1912 map = Heap::medium_external_symbol_map(); | |
1913 } else { | |
1914 map = Heap::long_external_symbol_map(); | |
1915 } | |
1916 return map; | |
1917 } | |
1918 | |
1919 | |
1920 byte ByteArray::get(int index) { | 1822 byte ByteArray::get(int index) { |
1921 ASSERT(index >= 0 && index < this->length()); | 1823 ASSERT(index >= 0 && index < this->length()); |
1922 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); | 1824 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); |
1923 } | 1825 } |
1924 | 1826 |
1925 | 1827 |
1926 void ByteArray::set(int index, byte value) { | 1828 void ByteArray::set(int index, byte value) { |
1927 ASSERT(index >= 0 && index < this->length()); | 1829 ASSERT(index >= 0 && index < this->length()); |
1928 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value); | 1830 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value); |
1929 } | 1831 } |
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2893 } | 2795 } |
2894 | 2796 |
2895 | 2797 |
2896 NumberDictionary* JSObject::element_dictionary() { | 2798 NumberDictionary* JSObject::element_dictionary() { |
2897 ASSERT(HasDictionaryElements()); | 2799 ASSERT(HasDictionaryElements()); |
2898 return NumberDictionary::cast(elements()); | 2800 return NumberDictionary::cast(elements()); |
2899 } | 2801 } |
2900 | 2802 |
2901 | 2803 |
2902 bool String::HasHashCode() { | 2804 bool String::HasHashCode() { |
2903 return (length_field() & kHashComputedMask) != 0; | 2805 return (hash_field() & kHashComputedMask) != 0; |
2904 } | 2806 } |
2905 | 2807 |
2906 | 2808 |
2907 uint32_t String::Hash() { | 2809 uint32_t String::Hash() { |
2908 // Fast case: has hash code already been computed? | 2810 // Fast case: has hash code already been computed? |
2909 uint32_t field = length_field(); | 2811 uint32_t field = hash_field(); |
2910 if (field & kHashComputedMask) return field >> kHashShift; | 2812 if (field & kHashComputedMask) return field >> kHashShift; |
2911 // Slow case: compute hash code and set it. | 2813 // Slow case: compute hash code and set it. |
2912 return ComputeAndSetHash(); | 2814 return ComputeAndSetHash(); |
2913 } | 2815 } |
2914 | 2816 |
2915 | 2817 |
2916 StringHasher::StringHasher(int length) | 2818 StringHasher::StringHasher(int length) |
2917 : length_(length), | 2819 : length_(length), |
2918 raw_running_hash_(0), | 2820 raw_running_hash_(0), |
2919 array_index_(0), | 2821 array_index_(0), |
2920 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), | 2822 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize), |
2921 is_first_char_(true), | 2823 is_first_char_(true), |
2922 is_valid_(true) { } | 2824 is_valid_(true) { } |
2923 | 2825 |
2924 | 2826 |
2925 bool StringHasher::has_trivial_hash() { | 2827 bool StringHasher::has_trivial_hash() { |
2926 return length_ > String::kMaxMediumSize; | 2828 return length_ > String::kMaxHashCalcLength; |
2927 } | 2829 } |
2928 | 2830 |
2929 | 2831 |
2930 void StringHasher::AddCharacter(uc32 c) { | 2832 void StringHasher::AddCharacter(uc32 c) { |
2931 // Use the Jenkins one-at-a-time hash function to update the hash | 2833 // Use the Jenkins one-at-a-time hash function to update the hash |
2932 // for the given character. | 2834 // for the given character. |
2933 raw_running_hash_ += c; | 2835 raw_running_hash_ += c; |
2934 raw_running_hash_ += (raw_running_hash_ << 10); | 2836 raw_running_hash_ += (raw_running_hash_ << 10); |
2935 raw_running_hash_ ^= (raw_running_hash_ >> 6); | 2837 raw_running_hash_ ^= (raw_running_hash_ >> 6); |
2936 // Incremental array index computation. | 2838 // Incremental array index computation. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2972 result ^= (result >> 11); | 2874 result ^= (result >> 11); |
2973 result += (result << 15); | 2875 result += (result << 15); |
2974 if (result == 0) { | 2876 if (result == 0) { |
2975 result = 27; | 2877 result = 27; |
2976 } | 2878 } |
2977 return result; | 2879 return result; |
2978 } | 2880 } |
2979 | 2881 |
2980 | 2882 |
2981 bool String::AsArrayIndex(uint32_t* index) { | 2883 bool String::AsArrayIndex(uint32_t* index) { |
2982 uint32_t field = length_field(); | 2884 uint32_t field = hash_field(); |
2983 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false; | 2885 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false; |
2984 return SlowAsArrayIndex(index); | 2886 return SlowAsArrayIndex(index); |
2985 } | 2887 } |
2986 | 2888 |
2987 | 2889 |
2988 Object* JSObject::GetPrototype() { | 2890 Object* JSObject::GetPrototype() { |
2989 return JSObject::cast(this)->map()->prototype(); | 2891 return JSObject::cast(this)->map()->prototype(); |
2990 } | 2892 } |
2991 | 2893 |
2992 | 2894 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3148 #undef WRITE_INT_FIELD | 3050 #undef WRITE_INT_FIELD |
3149 #undef READ_SHORT_FIELD | 3051 #undef READ_SHORT_FIELD |
3150 #undef WRITE_SHORT_FIELD | 3052 #undef WRITE_SHORT_FIELD |
3151 #undef READ_BYTE_FIELD | 3053 #undef READ_BYTE_FIELD |
3152 #undef WRITE_BYTE_FIELD | 3054 #undef WRITE_BYTE_FIELD |
3153 | 3055 |
3154 | 3056 |
3155 } } // namespace v8::internal | 3057 } } // namespace v8::internal |
3156 | 3058 |
3157 #endif // V8_OBJECTS_INL_H_ | 3059 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |