OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/symbols.h" | 5 #include "vm/symbols.h" |
6 | 6 |
7 #include "vm/handles.h" | 7 #include "vm/handles.h" |
8 #include "vm/handles_impl.h" | 8 #include "vm/handles_impl.h" |
9 #include "vm/hash_table.h" | 9 #include "vm/hash_table.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 : data_(data), len_(len) { | 55 : data_(data), len_(len) { |
56 hash_ = String::Hash(data, len); | 56 hash_ = String::Hash(data, len); |
57 } | 57 } |
58 RawString* ToSymbol() const { | 58 RawString* ToSymbol() const { |
59 String& result = String::Handle(StringFrom(data_, len_, Heap::kOld)); | 59 String& result = String::Handle(StringFrom(data_, len_, Heap::kOld)); |
60 result.SetCanonical(); | 60 result.SetCanonical(); |
61 result.SetHash(hash_); | 61 result.SetHash(hash_); |
62 return result.raw(); | 62 return result.raw(); |
63 } | 63 } |
64 bool Equals(const String& other) const { | 64 bool Equals(const String& other) const { |
| 65 ASSERT(other.HasHash()); |
| 66 if (other.Hash() != hash_) { |
| 67 return false; |
| 68 } |
65 return other.Equals(data_, len_); | 69 return other.Equals(data_, len_); |
66 } | 70 } |
67 intptr_t Hash() const { return hash_; } | 71 intptr_t Hash() const { return hash_; } |
68 private: | 72 private: |
69 const CharType* data_; | 73 const CharType* data_; |
70 intptr_t len_; | 74 intptr_t len_; |
71 intptr_t hash_; | 75 intptr_t hash_; |
72 }; | 76 }; |
73 typedef CharArray<uint8_t> Latin1Array; | 77 typedef CharArray<uint8_t> Latin1Array; |
74 typedef CharArray<uint16_t> UTF16Array; | 78 typedef CharArray<uint16_t> UTF16Array; |
75 typedef CharArray<int32_t> UTF32Array; | 79 typedef CharArray<int32_t> UTF32Array; |
76 | 80 |
77 | 81 |
78 class StringSlice { | 82 class StringSlice { |
79 public: | 83 public: |
80 StringSlice(const String& str, intptr_t begin_index, intptr_t length) | 84 StringSlice(const String& str, intptr_t begin_index, intptr_t length) |
81 : str_(str), begin_index_(begin_index), len_(length) { | 85 : str_(str), begin_index_(begin_index), len_(length) { |
82 hash_ = is_all() ? str.Hash() : String::Hash(str, begin_index, length); | 86 hash_ = is_all() ? str.Hash() : String::Hash(str, begin_index, length); |
83 } | 87 } |
84 RawString* ToSymbol() const; | 88 RawString* ToSymbol() const; |
85 bool Equals(const String& other) const { | 89 bool Equals(const String& other) const { |
| 90 ASSERT(other.HasHash()); |
| 91 if (other.Hash() != hash_) { |
| 92 return false; |
| 93 } |
86 return other.Equals(str_, begin_index_, len_); | 94 return other.Equals(str_, begin_index_, len_); |
87 } | 95 } |
88 intptr_t Hash() const { return hash_; } | 96 intptr_t Hash() const { return hash_; } |
89 private: | 97 private: |
90 bool is_all() const { return begin_index_ == 0 && len_ == str_.Length(); } | 98 bool is_all() const { return begin_index_ == 0 && len_ == str_.Length(); } |
91 const String& str_; | 99 const String& str_; |
92 intptr_t begin_index_; | 100 intptr_t begin_index_; |
93 intptr_t len_; | 101 intptr_t len_; |
94 intptr_t hash_; | 102 intptr_t hash_; |
95 }; | 103 }; |
(...skipping 12 matching lines...) Expand all Loading... |
108 } | 116 } |
109 } | 117 } |
110 | 118 |
111 | 119 |
112 class ConcatString { | 120 class ConcatString { |
113 public: | 121 public: |
114 ConcatString(const String& str1, const String& str2) | 122 ConcatString(const String& str1, const String& str2) |
115 : str1_(str1), str2_(str2), hash_(String::HashConcat(str1, str2)) {} | 123 : str1_(str1), str2_(str2), hash_(String::HashConcat(str1, str2)) {} |
116 RawString* ToSymbol() const; | 124 RawString* ToSymbol() const; |
117 bool Equals(const String& other) const { | 125 bool Equals(const String& other) const { |
| 126 ASSERT(other.HasHash()); |
| 127 if (other.Hash() != hash_) { |
| 128 return false; |
| 129 } |
118 return other.EqualsConcat(str1_, str2_); | 130 return other.EqualsConcat(str1_, str2_); |
119 } | 131 } |
120 intptr_t Hash() const { return hash_; } | 132 intptr_t Hash() const { return hash_; } |
121 private: | 133 private: |
122 const String& str1_; | 134 const String& str1_; |
123 const String& str2_; | 135 const String& str2_; |
124 intptr_t hash_; | 136 intptr_t hash_; |
125 }; | 137 }; |
126 | 138 |
127 | 139 |
128 RawString* ConcatString::ToSymbol() const { | 140 RawString* ConcatString::ToSymbol() const { |
129 String& result = String::Handle(String::Concat(str1_, str2_, Heap::kOld)); | 141 String& result = String::Handle(String::Concat(str1_, str2_, Heap::kOld)); |
130 result.SetCanonical(); | 142 result.SetCanonical(); |
131 result.SetHash(hash_); | 143 result.SetHash(hash_); |
132 return result.raw(); | 144 return result.raw(); |
133 } | 145 } |
134 | 146 |
135 | 147 |
136 class SymbolTraits { | 148 class SymbolTraits { |
137 public: | 149 public: |
138 static bool IsMatch(const Object& a, const Object& b) { | 150 static bool IsMatch(const Object& a, const Object& b) { |
139 const String& a_str = String::Cast(a); | 151 const String& a_str = String::Cast(a); |
140 const String& b_str = String::Cast(b); | 152 const String& b_str = String::Cast(b); |
141 ASSERT(a_str.HasHash()); | 153 ASSERT(a_str.HasHash()); |
142 ASSERT(b_str.HasHash()); | 154 ASSERT(b_str.HasHash()); |
143 return a_str.Equals(b_str); | 155 if (a_str.Hash() != b_str.Hash()) { |
| 156 return false; |
| 157 } |
| 158 intptr_t a_len = a_str.Length(); |
| 159 if (a_len != b_str.Length()) { |
| 160 return false; |
| 161 } |
| 162 // Use a comparison which does not consider the state of the canonical bit. |
| 163 return a_str.Equals(b_str, 0, a_len); |
144 } | 164 } |
145 template<typename CharType> | 165 template<typename CharType> |
146 static bool IsMatch(const CharArray<CharType>& array, const Object& obj) { | 166 static bool IsMatch(const CharArray<CharType>& array, const Object& obj) { |
147 return array.Equals(String::Cast(obj)); | 167 return array.Equals(String::Cast(obj)); |
148 } | 168 } |
149 static bool IsMatch(const StringSlice& slice, const Object& obj) { | 169 static bool IsMatch(const StringSlice& slice, const Object& obj) { |
150 return slice.Equals(String::Cast(obj)); | 170 return slice.Equals(String::Cast(obj)); |
151 } | 171 } |
152 static bool IsMatch(const ConcatString& concat, const Object& obj) { | 172 static bool IsMatch(const ConcatString& concat, const Object& obj) { |
153 return concat.Equals(String::Cast(obj)); | 173 return concat.Equals(String::Cast(obj)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 SymbolTable table(zone, vm_isolate->object_store()->symbol_table()); | 230 SymbolTable table(zone, vm_isolate->object_store()->symbol_table()); |
211 | 231 |
212 // First set up all the predefined string symbols. | 232 // First set up all the predefined string symbols. |
213 // Create symbols for language keywords. Some keywords are equal to | 233 // Create symbols for language keywords. Some keywords are equal to |
214 // symbols we already created, so use New() instead of Add() to ensure | 234 // symbols we already created, so use New() instead of Add() to ensure |
215 // that the symbols are canonicalized. | 235 // that the symbols are canonicalized. |
216 for (intptr_t i = 1; i < Symbols::kNullCharId; i++) { | 236 for (intptr_t i = 1; i < Symbols::kNullCharId; i++) { |
217 String* str = String::ReadOnlyHandle(); | 237 String* str = String::ReadOnlyHandle(); |
218 *str = OneByteString::New(names[i], Heap::kOld); | 238 *str = OneByteString::New(names[i], Heap::kOld); |
219 str->Hash(); | 239 str->Hash(); |
220 RawString* entry = reinterpret_cast<RawString*>(table.InsertOrGet(*str)); | 240 *str ^= table.InsertOrGet(*str); |
221 *str = entry; | |
222 str->SetCanonical(); // Make canonical once entered. | 241 str->SetCanonical(); // Make canonical once entered. |
223 symbol_handles_[i] = str; | 242 symbol_handles_[i] = str; |
224 } | 243 } |
225 | 244 |
226 // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast. | 245 // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast. |
227 for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { | 246 for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { |
228 intptr_t idx = (kNullCharId + c); | 247 intptr_t idx = (kNullCharId + c); |
229 ASSERT(idx < kMaxPredefinedId); | 248 ASSERT(idx < kMaxPredefinedId); |
230 ASSERT(Utf::IsLatin1(c)); | 249 ASSERT(Utf::IsLatin1(c)); |
231 uint8_t ch = static_cast<uint8_t>(c); | 250 uint8_t ch = static_cast<uint8_t>(c); |
232 String* str = String::ReadOnlyHandle(); | 251 String* str = String::ReadOnlyHandle(); |
233 *str = OneByteString::New(&ch, 1, Heap::kOld); | 252 *str = OneByteString::New(&ch, 1, Heap::kOld); |
234 str->Hash(); | 253 str->Hash(); |
235 RawString* entry = reinterpret_cast<RawString*>(table.InsertOrGet(*str)); | 254 *str ^= table.InsertOrGet(*str); |
236 *str = entry; | |
237 ASSERT(predefined_[c] == NULL); | 255 ASSERT(predefined_[c] == NULL); |
238 str->SetCanonical(); // Make canonical once entered. | 256 str->SetCanonical(); // Make canonical once entered. |
239 predefined_[c] = str->raw(); | 257 predefined_[c] = str->raw(); |
240 symbol_handles_[idx] = str; | 258 symbol_handles_[idx] = str; |
241 } | 259 } |
242 | 260 |
243 vm_isolate->object_store()->set_symbol_table(table.Release()); | 261 vm_isolate->object_store()->set_symbol_table(table.Release()); |
244 } | 262 } |
245 | 263 |
246 | 264 |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 RawObject* Symbols::GetVMSymbol(intptr_t object_id) { | 753 RawObject* Symbols::GetVMSymbol(intptr_t object_id) { |
736 ASSERT(IsVMSymbolId(object_id)); | 754 ASSERT(IsVMSymbolId(object_id)); |
737 intptr_t i = (object_id - kMaxPredefinedObjectIds); | 755 intptr_t i = (object_id - kMaxPredefinedObjectIds); |
738 if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) { | 756 if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) { |
739 return symbol_handles_[i]->raw(); | 757 return symbol_handles_[i]->raw(); |
740 } | 758 } |
741 return Object::null(); | 759 return Object::null(); |
742 } | 760 } |
743 | 761 |
744 } // namespace dart | 762 } // namespace dart |
OLD | NEW |