| 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 10 matching lines...) Expand all Loading... |
| 21 String* Symbols::symbol_handles_[Symbols::kMaxPredefinedId]; | 21 String* Symbols::symbol_handles_[Symbols::kMaxPredefinedId]; |
| 22 | 22 |
| 23 static const char* names[] = { | 23 static const char* names[] = { |
| 24 NULL, | 24 NULL, |
| 25 | 25 |
| 26 #define DEFINE_SYMBOL_LITERAL(symbol, literal) \ | 26 #define DEFINE_SYMBOL_LITERAL(symbol, literal) \ |
| 27 literal, | 27 literal, |
| 28 PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_LITERAL) | 28 PREDEFINED_SYMBOLS_LIST(DEFINE_SYMBOL_LITERAL) |
| 29 #undef DEFINE_SYMBOL_LITERAL | 29 #undef DEFINE_SYMBOL_LITERAL |
| 30 | 30 |
| 31 "", // matches kKwTableStart. | 31 "", // matches kTokenTableStart. |
| 32 | 32 |
| 33 #define DEFINE_KEYWORD_SYMBOL_INDEX(t, s, p, a) \ | 33 #define DEFINE_TOKEN_SYMBOL_INDEX(t, s, p, a) \ |
| 34 s, | 34 s, |
| 35 DART_KEYWORD_LIST(DEFINE_KEYWORD_SYMBOL_INDEX) | 35 DART_TOKEN_LIST(DEFINE_TOKEN_SYMBOL_INDEX) |
| 36 #undef DEFINE_KEYWORD_SYMBOL_INDEX | 36 DART_KEYWORD_LIST(DEFINE_TOKEN_SYMBOL_INDEX) |
| 37 #undef DEFINE_TOKEN_SYMBOL_INDEX |
| 37 }; | 38 }; |
| 38 | 39 |
| 39 RawString* StringFrom(const uint8_t* data, intptr_t len, Heap::Space space) { | 40 RawString* StringFrom(const uint8_t* data, intptr_t len, Heap::Space space) { |
| 40 return String::FromLatin1(data, len, space); | 41 return String::FromLatin1(data, len, space); |
| 41 } | 42 } |
| 42 RawString* StringFrom(const uint16_t* data, intptr_t len, Heap::Space space) { | 43 RawString* StringFrom(const uint16_t* data, intptr_t len, Heap::Space space) { |
| 43 return String::FromUTF16(data, len, space); | 44 return String::FromUTF16(data, len, space); |
| 44 } | 45 } |
| 45 RawString* StringFrom(const int32_t* data, intptr_t len, Heap::Space space) { | 46 RawString* StringFrom(const int32_t* data, intptr_t len, Heap::Space space) { |
| 46 return String::FromUTF32(data, len, space); | 47 return String::FromUTF32(data, len, space); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 }; | 174 }; |
| 174 typedef UnorderedHashSet<SymbolTraits> SymbolTable; | 175 typedef UnorderedHashSet<SymbolTraits> SymbolTable; |
| 175 | 176 |
| 176 | 177 |
| 177 const char* Symbols::Name(SymbolId symbol) { | 178 const char* Symbols::Name(SymbolId symbol) { |
| 178 ASSERT((symbol > kIllegal) && (symbol < kNullCharId)); | 179 ASSERT((symbol > kIllegal) && (symbol < kNullCharId)); |
| 179 return names[symbol]; | 180 return names[symbol]; |
| 180 } | 181 } |
| 181 | 182 |
| 182 | 183 |
| 183 const String& Symbols::Keyword(Token::Kind keyword) { | 184 const String& Symbols::Token(Token::Kind token) { |
| 184 const int kw_index = keyword - Token::kFirstKeyword; | 185 const int tok_index = token; |
| 185 ASSERT((0 <= kw_index) && (kw_index < Token::kNumKeywords)); | 186 ASSERT((0 <= tok_index) && (tok_index < Token::kNumTokens)); |
| 186 // First keyword symbol is in symbol_handles_[kKwTableStart + 1]. | 187 // First keyword symbol is in symbol_handles_[kTokenTableStart + 1]. |
| 187 const intptr_t keyword_id = Symbols::kKwTableStart + 1 + kw_index; | 188 const intptr_t token_id = Symbols::kTokenTableStart + 1 + tok_index; |
| 188 ASSERT(symbol_handles_[keyword_id] != NULL); | 189 ASSERT(symbol_handles_[token_id] != NULL); |
| 189 return *symbol_handles_[keyword_id]; | 190 return *symbol_handles_[token_id]; |
| 190 } | 191 } |
| 191 | 192 |
| 192 | 193 |
| 193 void Symbols::InitOnce(Isolate* vm_isolate) { | 194 void Symbols::InitOnce(Isolate* vm_isolate) { |
| 194 // Should only be run by the vm isolate. | 195 // Should only be run by the vm isolate. |
| 195 ASSERT(Isolate::Current() == Dart::vm_isolate()); | 196 ASSERT(Isolate::Current() == Dart::vm_isolate()); |
| 196 ASSERT(vm_isolate == Dart::vm_isolate()); | 197 ASSERT(vm_isolate == Dart::vm_isolate()); |
| 197 Zone* zone = Thread::Current()->zone(); | 198 Zone* zone = Thread::Current()->zone(); |
| 198 | 199 |
| 199 // Create and setup a symbol table in the vm isolate. | 200 // Create and setup a symbol table in the vm isolate. |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 | 415 |
| 415 void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) { | 416 void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) { |
| 416 ASSERT(isolate != NULL); | 417 ASSERT(isolate != NULL); |
| 417 SymbolTable table(isolate->object_store()->symbol_table()); | 418 SymbolTable table(isolate->object_store()->symbol_table()); |
| 418 *size = table.NumOccupied(); | 419 *size = table.NumOccupied(); |
| 419 *capacity = table.NumEntries(); | 420 *capacity = table.NumEntries(); |
| 420 table.Release(); | 421 table.Release(); |
| 421 } | 422 } |
| 422 | 423 |
| 423 | 424 |
| 424 RawString* Symbols::New(const char* cstr, intptr_t len) { | 425 RawString* Symbols::New(Thread* thread, const char* cstr, intptr_t len) { |
| 425 ASSERT((cstr != NULL) && (len >= 0)); | 426 ASSERT((cstr != NULL) && (len >= 0)); |
| 426 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr); | 427 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(cstr); |
| 427 return Symbols::FromUTF8(utf8_array, len); | 428 return Symbols::FromUTF8(thread, utf8_array, len); |
| 428 } | 429 } |
| 429 | 430 |
| 430 | 431 |
| 431 RawString* Symbols::FromUTF8(const uint8_t* utf8_array, intptr_t array_len) { | 432 RawString* Symbols::FromUTF8(Thread* thread, |
| 433 const uint8_t* utf8_array, |
| 434 intptr_t array_len) { |
| 432 if (array_len == 0 || utf8_array == NULL) { | 435 if (array_len == 0 || utf8_array == NULL) { |
| 433 return FromLatin1(reinterpret_cast<uint8_t*>(NULL), 0); | 436 return FromLatin1(thread, reinterpret_cast<uint8_t*>(NULL), 0); |
| 434 } | 437 } |
| 435 Utf8::Type type; | 438 Utf8::Type type; |
| 436 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); | 439 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); |
| 437 ASSERT(len != 0); | 440 ASSERT(len != 0); |
| 438 Zone* zone = Thread::Current()->zone(); | 441 Zone* zone = thread->zone(); |
| 439 if (type == Utf8::kLatin1) { | 442 if (type == Utf8::kLatin1) { |
| 440 uint8_t* characters = zone->Alloc<uint8_t>(len); | 443 uint8_t* characters = zone->Alloc<uint8_t>(len); |
| 441 Utf8::DecodeToLatin1(utf8_array, array_len, characters, len); | 444 Utf8::DecodeToLatin1(utf8_array, array_len, characters, len); |
| 442 return FromLatin1(characters, len); | 445 return FromLatin1(thread, characters, len); |
| 443 } | 446 } |
| 444 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary)); | 447 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary)); |
| 445 uint16_t* characters = zone->Alloc<uint16_t>(len); | 448 uint16_t* characters = zone->Alloc<uint16_t>(len); |
| 446 Utf8::DecodeToUTF16(utf8_array, array_len, characters, len); | 449 Utf8::DecodeToUTF16(utf8_array, array_len, characters, len); |
| 447 return FromUTF16(characters, len); | 450 return FromUTF16(thread, characters, len); |
| 448 } | 451 } |
| 449 | 452 |
| 450 | 453 |
| 451 RawString* Symbols::FromLatin1(const uint8_t* latin1_array, intptr_t len) { | 454 RawString* Symbols::FromLatin1(Thread* thread, |
| 452 return NewSymbol(Latin1Array(latin1_array, len)); | 455 const uint8_t* latin1_array, |
| 456 intptr_t len) { |
| 457 return NewSymbol(thread, Latin1Array(latin1_array, len)); |
| 453 } | 458 } |
| 454 | 459 |
| 455 | 460 |
| 456 RawString* Symbols::FromUTF16(const uint16_t* utf16_array, intptr_t len) { | 461 RawString* Symbols::FromUTF16(Thread* thread, |
| 457 return NewSymbol(UTF16Array(utf16_array, len)); | 462 const uint16_t* utf16_array, |
| 463 intptr_t len) { |
| 464 return NewSymbol(thread, UTF16Array(utf16_array, len)); |
| 458 } | 465 } |
| 459 | 466 |
| 460 | 467 |
| 461 RawString* Symbols::FromUTF32(const int32_t* utf32_array, intptr_t len) { | 468 RawString* Symbols::FromUTF32(Thread* thread, |
| 462 return NewSymbol(UTF32Array(utf32_array, len)); | 469 const int32_t* utf32_array, |
| 470 intptr_t len) { |
| 471 return NewSymbol(thread, UTF32Array(utf32_array, len)); |
| 463 } | 472 } |
| 464 | 473 |
| 465 | 474 |
| 466 RawString* Symbols::FromConcat(const String& str1, const String& str2) { | 475 RawString* Symbols::FromConcat(Thread* thread, |
| 476 const String& str1, |
| 477 const String& str2) { |
| 467 if (str1.Length() == 0) { | 478 if (str1.Length() == 0) { |
| 468 return New(str2); | 479 return New(thread, str2); |
| 469 } else if (str2.Length() == 0) { | 480 } else if (str2.Length() == 0) { |
| 470 return New(str1); | 481 return New(thread, str1); |
| 471 } else { | 482 } else { |
| 472 return NewSymbol(ConcatString(str1, str2)); | 483 return NewSymbol(thread, ConcatString(str1, str2)); |
| 473 } | 484 } |
| 474 } | 485 } |
| 475 | 486 |
| 476 | 487 |
| 488 RawString* Symbols::FromGet(Thread* thread, const String& str) { |
| 489 return FromConcat(thread, GetterPrefix(), str); |
| 490 } |
| 491 |
| 492 |
| 493 RawString* Symbols::FromSet(Thread* thread, const String& str) { |
| 494 return FromConcat(thread, SetterPrefix(), str); |
| 495 } |
| 496 |
| 497 |
| 498 RawString* Symbols::FromDot(Thread* thread, const String& str) { |
| 499 return FromConcat(thread, str, Dot()); |
| 500 } |
| 501 |
| 502 |
| 477 // TODO(srdjan): If this becomes performance critical code, consider looking | 503 // TODO(srdjan): If this becomes performance critical code, consider looking |
| 478 // up symbol from hash of pieces instead of concatenating them first into | 504 // up symbol from hash of pieces instead of concatenating them first into |
| 479 // a string. | 505 // a string. |
| 480 RawString* Symbols::FromConcatAll( | 506 RawString* Symbols::FromConcatAll(Thread* thread, |
| 481 const GrowableHandlePtrArray<const String>& strs) { | 507 const GrowableHandlePtrArray<const String>& strs) { |
| 482 const intptr_t strs_length = strs.length(); | 508 const intptr_t strs_length = strs.length(); |
| 483 GrowableArray<intptr_t> lengths(strs_length); | 509 GrowableArray<intptr_t> lengths(strs_length); |
| 484 | 510 |
| 485 intptr_t len_sum = 0; | 511 intptr_t len_sum = 0; |
| 486 const intptr_t kOneByteChar = 1; | 512 const intptr_t kOneByteChar = 1; |
| 487 intptr_t char_size = kOneByteChar; | 513 intptr_t char_size = kOneByteChar; |
| 488 | 514 |
| 489 for (intptr_t i = 0; i < strs_length; i++) { | 515 for (intptr_t i = 0; i < strs_length; i++) { |
| 490 const String& str = strs[i]; | 516 const String& str = strs[i]; |
| 491 const intptr_t str_len = str.Length(); | 517 const intptr_t str_len = str.Length(); |
| 492 if ((String::kMaxElements - len_sum) < str_len) { | 518 if ((String::kMaxElements - len_sum) < str_len) { |
| 493 Exceptions::ThrowOOM(); | 519 Exceptions::ThrowOOM(); |
| 494 UNREACHABLE(); | 520 UNREACHABLE(); |
| 495 } | 521 } |
| 496 len_sum += str_len; | 522 len_sum += str_len; |
| 497 lengths.Add(str_len); | 523 lengths.Add(str_len); |
| 498 char_size = Utils::Maximum(char_size, str.CharSize()); | 524 char_size = Utils::Maximum(char_size, str.CharSize()); |
| 499 } | 525 } |
| 500 const bool is_one_byte_string = char_size == kOneByteChar; | 526 const bool is_one_byte_string = char_size == kOneByteChar; |
| 501 | 527 |
| 502 Zone* zone = Thread::Current()->zone(); | 528 Zone* zone = thread->zone(); |
| 503 if (is_one_byte_string) { | 529 if (is_one_byte_string) { |
| 504 uint8_t* buffer = zone->Alloc<uint8_t>(len_sum); | 530 uint8_t* buffer = zone->Alloc<uint8_t>(len_sum); |
| 505 const uint8_t* const orig_buffer = buffer; | 531 const uint8_t* const orig_buffer = buffer; |
| 506 for (intptr_t i = 0; i < strs_length; i++) { | 532 for (intptr_t i = 0; i < strs_length; i++) { |
| 507 NoSafepointScope no_safepoint; | 533 NoSafepointScope no_safepoint; |
| 508 intptr_t str_len = lengths[i]; | 534 intptr_t str_len = lengths[i]; |
| 509 if (str_len > 0) { | 535 if (str_len > 0) { |
| 510 const String& str = strs[i]; | 536 const String& str = strs[i]; |
| 511 ASSERT(str.IsOneByteString() || str.IsExternalOneByteString()); | 537 ASSERT(str.IsOneByteString() || str.IsExternalOneByteString()); |
| 512 const uint8_t* src_p = str.IsOneByteString() ? | 538 const uint8_t* src_p = str.IsOneByteString() ? |
| 513 OneByteString::CharAddr(str, 0) : | 539 OneByteString::CharAddr(str, 0) : |
| 514 ExternalOneByteString::CharAddr(str, 0); | 540 ExternalOneByteString::CharAddr(str, 0); |
| 515 memmove(buffer, src_p, str_len); | 541 memmove(buffer, src_p, str_len); |
| 516 buffer += str_len; | 542 buffer += str_len; |
| 517 } | 543 } |
| 518 } | 544 } |
| 519 ASSERT(len_sum == buffer - orig_buffer); | 545 ASSERT(len_sum == buffer - orig_buffer); |
| 520 return Symbols::FromLatin1(orig_buffer, len_sum); | 546 return Symbols::FromLatin1(thread, orig_buffer, len_sum); |
| 521 } else { | 547 } else { |
| 522 uint16_t* buffer = zone->Alloc<uint16_t>(len_sum); | 548 uint16_t* buffer = zone->Alloc<uint16_t>(len_sum); |
| 523 const uint16_t* const orig_buffer = buffer; | 549 const uint16_t* const orig_buffer = buffer; |
| 524 for (intptr_t i = 0; i < strs_length; i++) { | 550 for (intptr_t i = 0; i < strs_length; i++) { |
| 525 NoSafepointScope no_safepoint; | 551 NoSafepointScope no_safepoint; |
| 526 intptr_t str_len = lengths[i]; | 552 intptr_t str_len = lengths[i]; |
| 527 if (str_len > 0) { | 553 if (str_len > 0) { |
| 528 const String& str = strs[i]; | 554 const String& str = strs[i]; |
| 529 if (str.IsTwoByteString()) { | 555 if (str.IsTwoByteString()) { |
| 530 memmove(buffer, TwoByteString::CharAddr(str, 0), str_len * 2); | 556 memmove(buffer, TwoByteString::CharAddr(str, 0), str_len * 2); |
| 531 } else if (str.IsExternalTwoByteString()) { | 557 } else if (str.IsExternalTwoByteString()) { |
| 532 memmove(buffer, ExternalTwoByteString::CharAddr(str, 0), str_len * 2); | 558 memmove(buffer, ExternalTwoByteString::CharAddr(str, 0), str_len * 2); |
| 533 } else { | 559 } else { |
| 534 // One-byte to two-byte string copy. | 560 // One-byte to two-byte string copy. |
| 535 ASSERT(str.IsOneByteString() || str.IsExternalOneByteString()); | 561 ASSERT(str.IsOneByteString() || str.IsExternalOneByteString()); |
| 536 const uint8_t* src_p = str.IsOneByteString() ? | 562 const uint8_t* src_p = str.IsOneByteString() ? |
| 537 OneByteString::CharAddr(str, 0) : | 563 OneByteString::CharAddr(str, 0) : |
| 538 ExternalOneByteString::CharAddr(str, 0); | 564 ExternalOneByteString::CharAddr(str, 0); |
| 539 for (int n = 0; n < str_len; n++) { | 565 for (int n = 0; n < str_len; n++) { |
| 540 buffer[n] = src_p[n]; | 566 buffer[n] = src_p[n]; |
| 541 } | 567 } |
| 542 } | 568 } |
| 543 buffer += str_len; | 569 buffer += str_len; |
| 544 } | 570 } |
| 545 } | 571 } |
| 546 ASSERT(len_sum == buffer - orig_buffer); | 572 ASSERT(len_sum == buffer - orig_buffer); |
| 547 return Symbols::FromUTF16(orig_buffer, len_sum); | 573 return Symbols::FromUTF16(thread, orig_buffer, len_sum); |
| 548 } | 574 } |
| 549 } | 575 } |
| 550 | 576 |
| 551 | 577 |
| 552 // StringType can be StringSlice, ConcatString, or {Latin1,UTF16,UTF32}Array. | 578 // StringType can be StringSlice, ConcatString, or {Latin1,UTF16,UTF32}Array. |
| 553 template<typename StringType> | 579 template<typename StringType> |
| 554 RawString* Symbols::NewSymbol(const StringType& str) { | 580 RawString* Symbols::NewSymbol(Thread* thread, const StringType& str) { |
| 555 Thread* thread = Thread::Current(); | |
| 556 Isolate* isolate = thread->isolate(); | |
| 557 Zone* zone = thread->zone(); | 581 Zone* zone = thread->zone(); |
| 558 String& symbol = String::Handle(zone); | 582 String& symbol = String::Handle(zone); |
| 559 { | 583 { |
| 560 Isolate* vm_isolate = Dart::vm_isolate(); | 584 Isolate* vm_isolate = Dart::vm_isolate(); |
| 561 SymbolTable table(zone, vm_isolate->object_store()->symbol_table()); | 585 SymbolTable table(zone, vm_isolate->object_store()->symbol_table()); |
| 562 symbol ^= table.GetOrNull(str); | 586 symbol ^= table.GetOrNull(str); |
| 563 table.Release(); | 587 table.Release(); |
| 564 } | 588 } |
| 565 if (symbol.IsNull()) { | 589 if (symbol.IsNull()) { |
| 590 Isolate* isolate = thread->isolate(); |
| 566 SafepointMutexLocker ml(isolate->symbols_mutex()); | 591 SafepointMutexLocker ml(isolate->symbols_mutex()); |
| 567 SymbolTable table(zone, isolate->object_store()->symbol_table()); | 592 SymbolTable table(zone, isolate->object_store()->symbol_table()); |
| 568 symbol ^= table.InsertNewOrGet(str); | 593 symbol ^= table.InsertNewOrGet(str); |
| 569 isolate->object_store()->set_symbol_table(table.Release()); | 594 isolate->object_store()->set_symbol_table(table.Release()); |
| 570 } | 595 } |
| 571 ASSERT(symbol.IsSymbol()); | 596 ASSERT(symbol.IsSymbol()); |
| 572 ASSERT(symbol.HasHash()); | 597 ASSERT(symbol.HasHash()); |
| 573 return symbol.raw(); | 598 return symbol.raw(); |
| 574 } | 599 } |
| 575 | 600 |
| 576 | 601 |
| 577 template<typename StringType> | 602 template<typename StringType> |
| 578 RawString* Symbols::Lookup(const StringType& str) { | 603 RawString* Symbols::Lookup(Thread* thread, const StringType& str) { |
| 579 Thread* thread = Thread::Current(); | |
| 580 Isolate* isolate = thread->isolate(); | 604 Isolate* isolate = thread->isolate(); |
| 581 Zone* zone = thread->zone(); | 605 Zone* zone = thread->zone(); |
| 582 String& symbol = String::Handle(zone); | 606 String& symbol = String::Handle(zone); |
| 583 { | 607 { |
| 584 Isolate* vm_isolate = Dart::vm_isolate(); | 608 Isolate* vm_isolate = Dart::vm_isolate(); |
| 585 SymbolTable table(zone, vm_isolate->object_store()->symbol_table()); | 609 SymbolTable table(zone, vm_isolate->object_store()->symbol_table()); |
| 586 symbol ^= table.GetOrNull(str); | 610 symbol ^= table.GetOrNull(str); |
| 587 table.Release(); | 611 table.Release(); |
| 588 } | 612 } |
| 589 if (symbol.IsNull()) { | 613 if (symbol.IsNull()) { |
| 590 SafepointMutexLocker ml(isolate->symbols_mutex()); | 614 SafepointMutexLocker ml(isolate->symbols_mutex()); |
| 591 SymbolTable table(zone, isolate->object_store()->symbol_table()); | 615 SymbolTable table(zone, isolate->object_store()->symbol_table()); |
| 592 symbol ^= table.GetOrNull(str); | 616 symbol ^= table.GetOrNull(str); |
| 593 table.Release(); | 617 table.Release(); |
| 594 } | 618 } |
| 595 | 619 |
| 596 ASSERT(symbol.IsNull() || symbol.IsSymbol()); | 620 ASSERT(symbol.IsNull() || symbol.IsSymbol()); |
| 597 ASSERT(symbol.IsNull() || symbol.HasHash()); | 621 ASSERT(symbol.IsNull() || symbol.HasHash()); |
| 598 return symbol.raw(); | 622 return symbol.raw(); |
| 599 } | 623 } |
| 600 | 624 |
| 601 | 625 |
| 602 RawString* Symbols::LookupFromConcat(const String& str1, const String& str2) { | 626 RawString* Symbols::LookupFromConcat( |
| 627 Thread* thread, const String& str1, const String& str2) { |
| 603 if (str1.Length() == 0) { | 628 if (str1.Length() == 0) { |
| 604 return Lookup(str2); | 629 return Lookup(thread, str2); |
| 605 } else if (str2.Length() == 0) { | 630 } else if (str2.Length() == 0) { |
| 606 return Lookup(str1); | 631 return Lookup(thread, str1); |
| 607 } else { | 632 } else { |
| 608 return Lookup(ConcatString(str1, str2)); | 633 return Lookup(thread, ConcatString(str1, str2)); |
| 609 } | 634 } |
| 610 } | 635 } |
| 611 | 636 |
| 612 | 637 |
| 613 RawString* Symbols::New(const String& str) { | 638 RawString* Symbols::LookupFromGet(Thread* thread, const String& str) { |
| 639 return LookupFromConcat(thread, GetterPrefix(), str); |
| 640 } |
| 641 |
| 642 |
| 643 RawString* Symbols::LookupFromSet(Thread* thread, const String& str) { |
| 644 return LookupFromConcat(thread, SetterPrefix(), str); |
| 645 } |
| 646 |
| 647 |
| 648 RawString* Symbols::LookupFromDot(Thread* thread, const String& str) { |
| 649 return LookupFromConcat(thread, str, Dot()); |
| 650 } |
| 651 |
| 652 |
| 653 RawString* Symbols::New(Thread* thread, const String& str) { |
| 614 if (str.IsSymbol()) { | 654 if (str.IsSymbol()) { |
| 615 return str.raw(); | 655 return str.raw(); |
| 616 } | 656 } |
| 617 return New(str, 0, str.Length()); | 657 return New(thread, str, 0, str.Length()); |
| 618 } | 658 } |
| 619 | 659 |
| 620 | 660 |
| 621 RawString* Symbols::New(const String& str, intptr_t begin_index, intptr_t len) { | 661 RawString* Symbols::New(Thread* thread, |
| 622 return NewSymbol(StringSlice(str, begin_index, len)); | 662 const String& str, |
| 663 intptr_t begin_index, |
| 664 intptr_t len) { |
| 665 return NewSymbol(thread, StringSlice(str, begin_index, len)); |
| 623 } | 666 } |
| 624 | 667 |
| 625 | 668 |
| 626 | 669 |
| 627 RawString* Symbols::NewFormatted(const char* format, ...) { | 670 RawString* Symbols::NewFormatted(Thread* thread, const char* format, ...) { |
| 628 va_list args; | 671 va_list args; |
| 629 va_start(args, format); | 672 va_start(args, format); |
| 630 RawString* result = NewFormattedV(format, args); | 673 RawString* result = NewFormattedV(thread, format, args); |
| 631 NoSafepointScope no_safepoint; | 674 NoSafepointScope no_safepoint; |
| 632 va_end(args); | 675 va_end(args); |
| 633 return result; | 676 return result; |
| 634 } | 677 } |
| 635 | 678 |
| 636 | 679 |
| 637 RawString* Symbols::NewFormattedV(const char* format, va_list args) { | 680 RawString* Symbols::NewFormattedV(Thread* thread, |
| 681 const char* format, |
| 682 va_list args) { |
| 638 va_list args_copy; | 683 va_list args_copy; |
| 639 va_copy(args_copy, args); | 684 va_copy(args_copy, args); |
| 640 intptr_t len = OS::VSNPrint(NULL, 0, format, args_copy); | 685 intptr_t len = OS::VSNPrint(NULL, 0, format, args_copy); |
| 641 va_end(args_copy); | 686 va_end(args_copy); |
| 642 | 687 |
| 643 Zone* zone = Thread::Current()->zone(); | 688 Zone* zone = Thread::Current()->zone(); |
| 644 char* buffer = zone->Alloc<char>(len + 1); | 689 char* buffer = zone->Alloc<char>(len + 1); |
| 645 OS::VSNPrint(buffer, (len + 1), format, args); | 690 OS::VSNPrint(buffer, (len + 1), format, args); |
| 646 | 691 |
| 647 return Symbols::New(buffer); | 692 return Symbols::New(thread, buffer); |
| 648 } | 693 } |
| 649 | 694 |
| 650 | 695 |
| 651 RawString* Symbols::FromCharCode(int32_t char_code) { | 696 RawString* Symbols::FromCharCode(Thread* thread, int32_t char_code) { |
| 652 if (char_code > kMaxOneCharCodeSymbol) { | 697 if (char_code > kMaxOneCharCodeSymbol) { |
| 653 return FromUTF32(&char_code, 1); | 698 return FromUTF32(thread, &char_code, 1); |
| 654 } | 699 } |
| 655 return predefined_[char_code]; | 700 return predefined_[char_code]; |
| 656 } | 701 } |
| 657 | 702 |
| 658 | 703 |
| 659 void Symbols::DumpStats() { | 704 void Symbols::DumpStats() { |
| 660 if (FLAG_dump_symbol_stats) { | 705 if (FLAG_dump_symbol_stats) { |
| 661 intptr_t size = -1; | 706 intptr_t size = -1; |
| 662 intptr_t capacity = -1; | 707 intptr_t capacity = -1; |
| 663 // First dump VM symbol table stats. | 708 // First dump VM symbol table stats. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 687 RawObject* Symbols::GetVMSymbol(intptr_t object_id) { | 732 RawObject* Symbols::GetVMSymbol(intptr_t object_id) { |
| 688 ASSERT(IsVMSymbolId(object_id)); | 733 ASSERT(IsVMSymbolId(object_id)); |
| 689 intptr_t i = (object_id - kMaxPredefinedObjectIds); | 734 intptr_t i = (object_id - kMaxPredefinedObjectIds); |
| 690 if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) { | 735 if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) { |
| 691 return symbol_handles_[i]->raw(); | 736 return symbol_handles_[i]->raw(); |
| 692 } | 737 } |
| 693 return Object::null(); | 738 return Object::null(); |
| 694 } | 739 } |
| 695 | 740 |
| 696 } // namespace dart | 741 } // namespace dart |
| OLD | NEW |