| 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 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 #define DEFINE_KEYWORD_SYMBOL_INDEX(t, s, p, a) \ | 33 #define DEFINE_KEYWORD_SYMBOL_INDEX(t, s, p, a) \ |
| 34 s, | 34 s, |
| 35 DART_KEYWORD_LIST(DEFINE_KEYWORD_SYMBOL_INDEX) | 35 DART_KEYWORD_LIST(DEFINE_KEYWORD_SYMBOL_INDEX) |
| 36 #undef DEFINE_KEYWORD_SYMBOL_INDEX | 36 #undef DEFINE_KEYWORD_SYMBOL_INDEX |
| 37 }; | 37 }; |
| 38 | 38 |
| 39 DEFINE_FLAG(bool, dump_symbol_stats, false, "Dump symbol table statistics"); | 39 DEFINE_FLAG(bool, dump_symbol_stats, false, "Dump symbol table statistics"); |
| 40 | 40 |
| 41 | 41 |
| 42 const char* Symbols::Name(SymbolId symbol) { | |
| 43 ASSERT((symbol > kIllegal) && (symbol < kNullCharId)); | |
| 44 return names[symbol]; | |
| 45 } | |
| 46 | |
| 47 | |
| 48 const String& Symbols::Keyword(Token::Kind keyword) { | |
| 49 const int kw_index = keyword - Token::kFirstKeyword; | |
| 50 ASSERT((0 <= kw_index) && (kw_index < Token::kNumKeywords)); | |
| 51 // First keyword symbol is in symbol_handles_[kKwTableStart + 1]. | |
| 52 const intptr_t keyword_id = Symbols::kKwTableStart + 1 + kw_index; | |
| 53 ASSERT(symbol_handles_[keyword_id] != NULL); | |
| 54 return *symbol_handles_[keyword_id]; | |
| 55 } | |
| 56 | |
| 57 | |
| 58 void Symbols::InitOnce(Isolate* isolate) { | |
| 59 // Should only be run by the vm isolate. | |
| 60 ASSERT(isolate == Dart::vm_isolate()); | |
| 61 | |
| 62 // Create and setup a symbol table in the vm isolate. | |
| 63 SetupSymbolTable(isolate); | |
| 64 | |
| 65 // Create all predefined symbols. | |
| 66 ASSERT((sizeof(names) / sizeof(const char*)) == Symbols::kNullCharId); | |
| 67 | |
| 68 // Set up all the predefined string symbols and create symbols for language | |
| 69 // keywords. We don't expect to find any overlaps between the predefined | |
| 70 // string symbols and the language keywords. If an overlap is introduced | |
| 71 // inadvertantly the ASSERT in AddToVMIsolate while fail. | |
| 72 for (intptr_t i = 1; i < Symbols::kNullCharId; i++) { | |
| 73 String* str = String::ReadOnlyHandle(); | |
| 74 *str = OneByteString::New(names[i], Heap::kOld); | |
| 75 AddToVMIsolate(*str); | |
| 76 symbol_handles_[i] = str; | |
| 77 } | |
| 78 | |
| 79 // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast. | |
| 80 for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { | |
| 81 intptr_t idx = (kNullCharId + c); | |
| 82 ASSERT(idx < kMaxPredefinedId); | |
| 83 ASSERT(Utf::IsLatin1(c)); | |
| 84 uint8_t ch = static_cast<uint8_t>(c); | |
| 85 String* str = String::ReadOnlyHandle(); | |
| 86 *str = OneByteString::New(&ch, 1, Heap::kOld); | |
| 87 AddToVMIsolate(*str); | |
| 88 predefined_[c] = str->raw(); | |
| 89 symbol_handles_[idx] = str; | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 | |
| 94 RawString* StringFrom(const uint8_t* data, intptr_t len, Heap::Space space) { | 42 RawString* StringFrom(const uint8_t* data, intptr_t len, Heap::Space space) { |
| 95 return String::FromLatin1(data, len, space); | 43 return String::FromLatin1(data, len, space); |
| 96 } | 44 } |
| 97 RawString* StringFrom(const uint16_t* data, intptr_t len, Heap::Space space) { | 45 RawString* StringFrom(const uint16_t* data, intptr_t len, Heap::Space space) { |
| 98 return String::FromUTF16(data, len, space); | 46 return String::FromUTF16(data, len, space); |
| 99 } | 47 } |
| 100 RawString* StringFrom(const int32_t* data, intptr_t len, Heap::Space space) { | 48 RawString* StringFrom(const int32_t* data, intptr_t len, Heap::Space space) { |
| 101 return String::FromUTF32(data, len, space); | 49 return String::FromUTF32(data, len, space); |
| 102 } | 50 } |
| 103 | 51 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 static RawObject* NewKey(const StringSlice& slice) { | 170 static RawObject* NewKey(const StringSlice& slice) { |
| 223 return slice.ToSymbol(); | 171 return slice.ToSymbol(); |
| 224 } | 172 } |
| 225 static RawObject* NewKey(const ConcatString& concat) { | 173 static RawObject* NewKey(const ConcatString& concat) { |
| 226 return concat.ToSymbol(); | 174 return concat.ToSymbol(); |
| 227 } | 175 } |
| 228 }; | 176 }; |
| 229 typedef UnorderedHashSet<SymbolTraits> SymbolTable; | 177 typedef UnorderedHashSet<SymbolTraits> SymbolTable; |
| 230 | 178 |
| 231 | 179 |
| 180 const char* Symbols::Name(SymbolId symbol) { |
| 181 ASSERT((symbol > kIllegal) && (symbol < kNullCharId)); |
| 182 return names[symbol]; |
| 183 } |
| 184 |
| 185 |
| 186 const String& Symbols::Keyword(Token::Kind keyword) { |
| 187 const int kw_index = keyword - Token::kFirstKeyword; |
| 188 ASSERT((0 <= kw_index) && (kw_index < Token::kNumKeywords)); |
| 189 // First keyword symbol is in symbol_handles_[kKwTableStart + 1]. |
| 190 const intptr_t keyword_id = Symbols::kKwTableStart + 1 + kw_index; |
| 191 ASSERT(symbol_handles_[keyword_id] != NULL); |
| 192 return *symbol_handles_[keyword_id]; |
| 193 } |
| 194 |
| 195 |
| 196 void Symbols::InitOnce(Isolate* vm_isolate) { |
| 197 // Should only be run by the vm isolate. |
| 198 ASSERT(Isolate::Current() == Dart::vm_isolate()); |
| 199 ASSERT(vm_isolate == Dart::vm_isolate()); |
| 200 |
| 201 // Create and setup a symbol table in the vm isolate. |
| 202 SetupSymbolTable(vm_isolate); |
| 203 |
| 204 // Create all predefined symbols. |
| 205 ASSERT((sizeof(names) / sizeof(const char*)) == Symbols::kNullCharId); |
| 206 |
| 207 SymbolTable table(vm_isolate, vm_isolate->object_store()->symbol_table()); |
| 208 |
| 209 // First set up all the predefined string symbols. |
| 210 // Create symbols for language keywords. Some keywords are equal to |
| 211 // symbols we already created, so use New() instead of Add() to ensure |
| 212 // that the symbols are canonicalized. |
| 213 for (intptr_t i = 1; i < Symbols::kNullCharId; i++) { |
| 214 String* str = String::ReadOnlyHandle(); |
| 215 *str = OneByteString::New(names[i], Heap::kOld); |
| 216 str->Hash(); |
| 217 str->SetCanonical(); |
| 218 bool present = table.Insert(*str); |
| 219 ASSERT(!present); |
| 220 symbol_handles_[i] = str; |
| 221 } |
| 222 |
| 223 // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast. |
| 224 for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { |
| 225 intptr_t idx = (kNullCharId + c); |
| 226 ASSERT(idx < kMaxPredefinedId); |
| 227 ASSERT(Utf::IsLatin1(c)); |
| 228 uint8_t ch = static_cast<uint8_t>(c); |
| 229 String* str = String::ReadOnlyHandle(); |
| 230 *str = OneByteString::New(&ch, 1, Heap::kOld); |
| 231 str->Hash(); |
| 232 str->SetCanonical(); |
| 233 bool present = table.Insert(*str); |
| 234 ASSERT(!present); |
| 235 predefined_[c] = str->raw(); |
| 236 symbol_handles_[idx] = str; |
| 237 } |
| 238 |
| 239 vm_isolate->object_store()->set_symbol_table(table.Release()); |
| 240 } |
| 241 |
| 242 |
| 243 void Symbols::InitOnceFromSnapshot(Isolate* vm_isolate) { |
| 244 // Should only be run by the vm isolate. |
| 245 ASSERT(Isolate::Current() == Dart::vm_isolate()); |
| 246 ASSERT(vm_isolate == Dart::vm_isolate()); |
| 247 |
| 248 SymbolTable table(vm_isolate, vm_isolate->object_store()->symbol_table()); |
| 249 |
| 250 // Lookup all the predefined string symbols and language keyword symbols |
| 251 // and cache them in the read only handles for fast access. |
| 252 for (intptr_t i = 1; i < Symbols::kNullCharId; i++) { |
| 253 String* str = String::ReadOnlyHandle(); |
| 254 const unsigned char* name = |
| 255 reinterpret_cast<const unsigned char*>(names[i]); |
| 256 *str ^= table.GetOrNull(Latin1Array(name, strlen(names[i]))); |
| 257 ASSERT(!str->IsNull()); |
| 258 ASSERT(str->HasHash()); |
| 259 ASSERT(str->IsCanonical()); |
| 260 symbol_handles_[i] = str; |
| 261 } |
| 262 |
| 263 // Lookup Latin1 character Symbols and cache them in read only handles, |
| 264 // so that Symbols::FromCharCode is fast. |
| 265 for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { |
| 266 intptr_t idx = (kNullCharId + c); |
| 267 ASSERT(idx < kMaxPredefinedId); |
| 268 ASSERT(Utf::IsLatin1(c)); |
| 269 uint8_t ch = static_cast<uint8_t>(c); |
| 270 String* str = String::ReadOnlyHandle(); |
| 271 *str ^= table.GetOrNull(Latin1Array(&ch, 1)); |
| 272 ASSERT(!str->IsNull()); |
| 273 ASSERT(str->HasHash()); |
| 274 ASSERT(str->IsCanonical()); |
| 275 predefined_[c] = str->raw(); |
| 276 symbol_handles_[idx] = str; |
| 277 } |
| 278 |
| 279 vm_isolate->object_store()->set_symbol_table(table.Release()); |
| 280 } |
| 281 |
| 282 |
| 283 void Symbols::AddPredefinedSymbolsToIsolate() { |
| 284 // Should only be run by regular Dart isolates. |
| 285 Isolate* isolate = Isolate::Current(); |
| 286 ASSERT(isolate != Dart::vm_isolate()); |
| 287 String& str = String::Handle(isolate); |
| 288 |
| 289 SymbolTable table(isolate, isolate->object_store()->symbol_table()); |
| 290 |
| 291 // Set up all the predefined string symbols and create symbols for |
| 292 // language keywords. |
| 293 for (intptr_t i = 1; i < Symbols::kNullCharId; i++) { |
| 294 str = OneByteString::New(names[i], Heap::kOld); |
| 295 str.Hash(); |
| 296 str.SetCanonical(); |
| 297 bool present = table.Insert(str); |
| 298 ASSERT(!present); |
| 299 } |
| 300 |
| 301 // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast. |
| 302 for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { |
| 303 intptr_t idx = (kNullCharId + c); |
| 304 ASSERT(idx < kMaxPredefinedId); |
| 305 ASSERT(Utf::IsLatin1(c)); |
| 306 uint8_t ch = static_cast<uint8_t>(c); |
| 307 str = OneByteString::New(&ch, 1, Heap::kOld); |
| 308 str.Hash(); |
| 309 str.SetCanonical(); |
| 310 bool present = table.Insert(str); |
| 311 ASSERT(!present); |
| 312 } |
| 313 |
| 314 isolate->object_store()->set_symbol_table(table.Release()); |
| 315 } |
| 316 |
| 317 |
| 232 void Symbols::SetupSymbolTable(Isolate* isolate) { | 318 void Symbols::SetupSymbolTable(Isolate* isolate) { |
| 233 ASSERT(isolate != NULL); | 319 ASSERT(isolate != NULL); |
| 234 | 320 |
| 235 // Setup the symbol table used within the String class. | 321 // Setup the symbol table used within the String class. |
| 236 const intptr_t initial_size = (isolate == Dart::vm_isolate()) ? | 322 const intptr_t initial_size = (isolate == Dart::vm_isolate()) ? |
| 237 kInitialVMIsolateSymtabSize : kInitialSymtabSize; | 323 kInitialVMIsolateSymtabSize : kInitialSymtabSize; |
| 238 Array& array = | 324 Array& array = |
| 239 Array::Handle(HashTables::New<SymbolTable>(initial_size, Heap::kOld)); | 325 Array::Handle(HashTables::New<SymbolTable>(initial_size, Heap::kOld)); |
| 240 isolate->object_store()->set_symbol_table(array); | 326 isolate->object_store()->set_symbol_table(array); |
| 241 } | 327 } |
| 242 | 328 |
| 243 | 329 |
| 244 void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) { | 330 void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) { |
| 245 ASSERT(isolate != NULL); | 331 ASSERT(isolate != NULL); |
| 246 SymbolTable table(isolate, isolate->object_store()->symbol_table()); | 332 SymbolTable table(isolate, isolate->object_store()->symbol_table()); |
| 247 *size = table.NumOccupied(); | 333 *size = table.NumOccupied(); |
| 248 *capacity = table.NumEntries(); | 334 *capacity = table.NumEntries(); |
| 249 table.Release(); | 335 table.Release(); |
| 250 } | 336 } |
| 251 | 337 |
| 252 | 338 |
| 253 void Symbols::AddToVMIsolate(const String& str) { | |
| 254 // Should only be run by the vm isolate. | |
| 255 ASSERT(Isolate::Current() == Dart::vm_isolate()); | |
| 256 Isolate* isolate = Dart::vm_isolate(); | |
| 257 SymbolTable table(isolate, isolate->object_store()->symbol_table()); | |
| 258 bool present = table.Insert(str); | |
| 259 str.SetCanonical(); | |
| 260 ASSERT(!present); | |
| 261 isolate->object_store()->set_symbol_table(table.Release()); | |
| 262 } | |
| 263 | |
| 264 | |
| 265 RawString* Symbols::New(const char* cstr, intptr_t len) { | 339 RawString* Symbols::New(const char* cstr, intptr_t len) { |
| 266 ASSERT((cstr != NULL) && (len >= 0)); | 340 ASSERT((cstr != NULL) && (len >= 0)); |
| 267 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr); | 341 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr); |
| 268 return Symbols::FromUTF8(utf8_array, len); | 342 return Symbols::FromUTF8(utf8_array, len); |
| 269 } | 343 } |
| 270 | 344 |
| 271 | 345 |
| 272 RawString* Symbols::FromUTF8(const uint8_t* utf8_array, intptr_t array_len) { | 346 RawString* Symbols::FromUTF8(const uint8_t* utf8_array, intptr_t array_len) { |
| 273 if (array_len == 0 || utf8_array == NULL) { | 347 if (array_len == 0 || utf8_array == NULL) { |
| 274 return FromLatin1(reinterpret_cast<uint8_t*>(NULL), 0); | 348 return FromLatin1(reinterpret_cast<uint8_t*>(NULL), 0); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 RawObject* Symbols::GetVMSymbol(intptr_t object_id) { | 457 RawObject* Symbols::GetVMSymbol(intptr_t object_id) { |
| 384 ASSERT(IsVMSymbolId(object_id)); | 458 ASSERT(IsVMSymbolId(object_id)); |
| 385 intptr_t i = (object_id - kMaxPredefinedObjectIds); | 459 intptr_t i = (object_id - kMaxPredefinedObjectIds); |
| 386 if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) { | 460 if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) { |
| 387 return symbol_handles_[i]->raw(); | 461 return symbol_handles_[i]->raw(); |
| 388 } | 462 } |
| 389 return Object::null(); | 463 return Object::null(); |
| 390 } | 464 } |
| 391 | 465 |
| 392 } // namespace dart | 466 } // namespace dart |
| OLD | NEW |