OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 5125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5136 decoder->Reset(str.start(), str.length()); | 5136 decoder->Reset(str.start(), str.length()); |
5137 int i; | 5137 int i; |
5138 for (i = 0; i < slen && decoder->has_more(); i++) { | 5138 for (i = 0; i < slen && decoder->has_more(); i++) { |
5139 uc32 r = decoder->GetNext(); | 5139 uc32 r = decoder->GetNext(); |
5140 if (Get(i) != r) return false; | 5140 if (Get(i) != r) return false; |
5141 } | 5141 } |
5142 return i == slen && !decoder->has_more(); | 5142 return i == slen && !decoder->has_more(); |
5143 } | 5143 } |
5144 | 5144 |
5145 | 5145 |
| 5146 bool String::IsAsciiEqualTo(Vector<const char> str) { |
| 5147 int slen = length(); |
| 5148 if (str.length() != slen) return false; |
| 5149 for (int i = 0; i < slen; i++) { |
| 5150 if (Get(i) != static_cast<uint16_t>(str[i])) return false; |
| 5151 } |
| 5152 return true; |
| 5153 } |
| 5154 |
| 5155 |
| 5156 bool String::IsTwoByteEqualTo(Vector<const uc16> str) { |
| 5157 int slen = length(); |
| 5158 if (str.length() != slen) return false; |
| 5159 for (int i = 0; i < slen; i++) { |
| 5160 if (Get(i) != str[i]) return false; |
| 5161 } |
| 5162 return true; |
| 5163 } |
| 5164 |
| 5165 |
5146 template <typename schar> | 5166 template <typename schar> |
5147 static inline uint32_t HashSequentialString(const schar* chars, int length) { | 5167 static inline uint32_t HashSequentialString(const schar* chars, int length) { |
5148 StringHasher hasher(length); | 5168 StringHasher hasher(length); |
5149 if (!hasher.has_trivial_hash()) { | 5169 if (!hasher.has_trivial_hash()) { |
5150 int i; | 5170 int i; |
5151 for (i = 0; hasher.is_array_index() && (i < length); i++) { | 5171 for (i = 0; hasher.is_array_index() && (i < length); i++) { |
5152 hasher.AddCharacter(chars[i]); | 5172 hasher.AddCharacter(chars[i]); |
5153 } | 5173 } |
5154 for (; i < length; i++) { | 5174 for (; i < length; i++) { |
5155 hasher.AddCharacterNoIndex(chars[i]); | 5175 hasher.AddCharacterNoIndex(chars[i]); |
(...skipping 2923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8079 if (hash_field_ == 0) Hash(); | 8099 if (hash_field_ == 0) Hash(); |
8080 return Heap::AllocateSymbol(string_, chars_, hash_field_); | 8100 return Heap::AllocateSymbol(string_, chars_, hash_field_); |
8081 } | 8101 } |
8082 | 8102 |
8083 Vector<const char> string_; | 8103 Vector<const char> string_; |
8084 uint32_t hash_field_; | 8104 uint32_t hash_field_; |
8085 int chars_; // Caches the number of characters when computing the hash code. | 8105 int chars_; // Caches the number of characters when computing the hash code. |
8086 }; | 8106 }; |
8087 | 8107 |
8088 | 8108 |
| 8109 template <typename Char> |
| 8110 class SequentialSymbolKey : public HashTableKey { |
| 8111 public: |
| 8112 explicit SequentialSymbolKey(Vector<const Char> string) |
| 8113 : string_(string), hash_field_(0) { } |
| 8114 |
| 8115 uint32_t Hash() { |
| 8116 StringHasher hasher(string_.length()); |
| 8117 |
| 8118 // Very long strings have a trivial hash that doesn't inspect the |
| 8119 // string contents. |
| 8120 if (hasher.has_trivial_hash()) { |
| 8121 hash_field_ = hasher.GetHashField(); |
| 8122 } else { |
| 8123 int i = 0; |
| 8124 // Do the iterative array index computation as long as there is a |
| 8125 // chance this is an array index. |
| 8126 while (i < string_.length() && hasher.is_array_index()) { |
| 8127 hasher.AddCharacter(static_cast<uc32>(string_[i])); |
| 8128 i++; |
| 8129 } |
| 8130 |
| 8131 // Process the remaining characters without updating the array |
| 8132 // index. |
| 8133 while (i < string_.length()) { |
| 8134 hasher.AddCharacterNoIndex(static_cast<uc32>(string_[i])); |
| 8135 i++; |
| 8136 } |
| 8137 hash_field_ = hasher.GetHashField(); |
| 8138 } |
| 8139 |
| 8140 uint32_t result = hash_field_ >> String::kHashShift; |
| 8141 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 8142 return result; |
| 8143 } |
| 8144 |
| 8145 |
| 8146 uint32_t HashForObject(Object* other) { |
| 8147 return String::cast(other)->Hash(); |
| 8148 } |
| 8149 |
| 8150 Vector<const Char> string_; |
| 8151 uint32_t hash_field_; |
| 8152 }; |
| 8153 |
| 8154 |
| 8155 |
| 8156 class AsciiSymbolKey : public SequentialSymbolKey<char> { |
| 8157 public: |
| 8158 explicit AsciiSymbolKey(Vector<const char> str) |
| 8159 : SequentialSymbolKey<char>(str) { } |
| 8160 |
| 8161 bool IsMatch(Object* string) { |
| 8162 return String::cast(string)->IsAsciiEqualTo(string_); |
| 8163 } |
| 8164 |
| 8165 MaybeObject* AsObject() { |
| 8166 if (hash_field_ == 0) Hash(); |
| 8167 return Heap::AllocateAsciiSymbol(string_, hash_field_); |
| 8168 } |
| 8169 }; |
| 8170 |
| 8171 |
| 8172 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { |
| 8173 public: |
| 8174 explicit TwoByteSymbolKey(Vector<const uc16> str) |
| 8175 : SequentialSymbolKey<uc16>(str) { } |
| 8176 |
| 8177 bool IsMatch(Object* string) { |
| 8178 return String::cast(string)->IsTwoByteEqualTo(string_); |
| 8179 } |
| 8180 |
| 8181 MaybeObject* AsObject() { |
| 8182 if (hash_field_ == 0) Hash(); |
| 8183 return Heap::AllocateTwoByteSymbol(string_, hash_field_); |
| 8184 } |
| 8185 }; |
| 8186 |
| 8187 |
8089 // SymbolKey carries a string/symbol object as key. | 8188 // SymbolKey carries a string/symbol object as key. |
8090 class SymbolKey : public HashTableKey { | 8189 class SymbolKey : public HashTableKey { |
8091 public: | 8190 public: |
8092 explicit SymbolKey(String* string) : string_(string) { } | 8191 explicit SymbolKey(String* string) : string_(string) { } |
8093 | 8192 |
8094 bool IsMatch(Object* string) { | 8193 bool IsMatch(Object* string) { |
8095 return String::cast(string)->Equals(string_); | 8194 return String::cast(string)->Equals(string_); |
8096 } | 8195 } |
8097 | 8196 |
8098 uint32_t Hash() { return string_->Hash(); } | 8197 uint32_t Hash() { return string_->Hash(); } |
(...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8823 } | 8922 } |
8824 } | 8923 } |
8825 | 8924 |
8826 | 8925 |
8827 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { | 8926 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) { |
8828 Utf8SymbolKey key(str); | 8927 Utf8SymbolKey key(str); |
8829 return LookupKey(&key, s); | 8928 return LookupKey(&key, s); |
8830 } | 8929 } |
8831 | 8930 |
8832 | 8931 |
| 8932 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, |
| 8933 Object** s) { |
| 8934 AsciiSymbolKey key(str); |
| 8935 return LookupKey(&key, s); |
| 8936 } |
| 8937 |
| 8938 |
| 8939 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, |
| 8940 Object** s) { |
| 8941 TwoByteSymbolKey key(str); |
| 8942 return LookupKey(&key, s); |
| 8943 } |
| 8944 |
8833 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 8945 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
8834 int entry = FindEntry(key); | 8946 int entry = FindEntry(key); |
8835 | 8947 |
8836 // Symbol already in table. | 8948 // Symbol already in table. |
8837 if (entry != kNotFound) { | 8949 if (entry != kNotFound) { |
8838 *s = KeyAt(entry); | 8950 *s = KeyAt(entry); |
8839 return this; | 8951 return this; |
8840 } | 8952 } |
8841 | 8953 |
8842 // Adding new symbol. Grow table if needed. | 8954 // Adding new symbol. Grow table if needed. |
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9747 if (break_point_objects()->IsUndefined()) return 0; | 9859 if (break_point_objects()->IsUndefined()) return 0; |
9748 // Single beak point. | 9860 // Single beak point. |
9749 if (!break_point_objects()->IsFixedArray()) return 1; | 9861 if (!break_point_objects()->IsFixedArray()) return 1; |
9750 // Multiple break points. | 9862 // Multiple break points. |
9751 return FixedArray::cast(break_point_objects())->length(); | 9863 return FixedArray::cast(break_point_objects())->length(); |
9752 } | 9864 } |
9753 #endif | 9865 #endif |
9754 | 9866 |
9755 | 9867 |
9756 } } // namespace v8::internal | 9868 } } // namespace v8::internal |
OLD | NEW |