| 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 |