| 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 2507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2518 | 2518 |
| 2519 MaybeObject* Heap::AllocateExternalStringFromTwoByte( | 2519 MaybeObject* Heap::AllocateExternalStringFromTwoByte( |
| 2520 ExternalTwoByteString::Resource* resource) { | 2520 ExternalTwoByteString::Resource* resource) { |
| 2521 size_t length = resource->length(); | 2521 size_t length = resource->length(); |
| 2522 if (length > static_cast<size_t>(String::kMaxLength)) { | 2522 if (length > static_cast<size_t>(String::kMaxLength)) { |
| 2523 Top::context()->mark_out_of_memory(); | 2523 Top::context()->mark_out_of_memory(); |
| 2524 return Failure::OutOfMemoryException(); | 2524 return Failure::OutOfMemoryException(); |
| 2525 } | 2525 } |
| 2526 | 2526 |
| 2527 // For small strings we check whether the resource contains only | 2527 // For small strings we check whether the resource contains only |
| 2528 // ascii characters. If yes, we use a different string map. | 2528 // ASCII characters. If yes, we use a different string map. |
| 2529 bool is_ascii = true; | 2529 static const size_t kAsciiCheckLengthLimit = 32; |
| 2530 if (length >= static_cast<size_t>(String::kMinNonFlatLength)) { | 2530 bool is_ascii = length <= kAsciiCheckLengthLimit && |
| 2531 is_ascii = false; | 2531 String::IsAscii(resource->data(), static_cast<int>(length)); |
| 2532 } else { | |
| 2533 const uc16* data = resource->data(); | |
| 2534 for (size_t i = 0; i < length; i++) { | |
| 2535 if (data[i] > String::kMaxAsciiCharCode) { | |
| 2536 is_ascii = false; | |
| 2537 break; | |
| 2538 } | |
| 2539 } | |
| 2540 } | |
| 2541 | |
| 2542 Map* map = is_ascii ? | 2532 Map* map = is_ascii ? |
| 2543 Heap::external_string_with_ascii_data_map() : Heap::external_string_map(); | 2533 Heap::external_string_with_ascii_data_map() : Heap::external_string_map(); |
| 2544 Object* result; | 2534 Object* result; |
| 2545 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); | 2535 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); |
| 2546 if (!maybe_result->ToObject(&result)) return maybe_result; | 2536 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2547 } | 2537 } |
| 2548 | 2538 |
| 2549 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); | 2539 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); |
| 2550 external_string->set_length(static_cast<int>(length)); | 2540 external_string->set_length(static_cast<int>(length)); |
| 2551 external_string->set_hash_field(String::kEmptyHashField); | 2541 external_string->set_hash_field(String::kEmptyHashField); |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3276 | 3266 |
| 3277 // Copy the characters into the new object. | 3267 // Copy the characters into the new object. |
| 3278 SeqAsciiString* string_result = SeqAsciiString::cast(result); | 3268 SeqAsciiString* string_result = SeqAsciiString::cast(result); |
| 3279 for (int i = 0; i < string.length(); i++) { | 3269 for (int i = 0; i < string.length(); i++) { |
| 3280 string_result->SeqAsciiStringSet(i, string[i]); | 3270 string_result->SeqAsciiStringSet(i, string[i]); |
| 3281 } | 3271 } |
| 3282 return result; | 3272 return result; |
| 3283 } | 3273 } |
| 3284 | 3274 |
| 3285 | 3275 |
| 3286 MaybeObject* Heap::AllocateStringFromUtf8(Vector<const char> string, | 3276 MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string, |
| 3287 PretenureFlag pretenure) { | 3277 PretenureFlag pretenure) { |
| 3288 // V8 only supports characters in the Basic Multilingual Plane. | 3278 // V8 only supports characters in the Basic Multilingual Plane. |
| 3289 const uc32 kMaxSupportedChar = 0xFFFF; | 3279 const uc32 kMaxSupportedChar = 0xFFFF; |
| 3290 // Count the number of characters in the UTF-8 string and check if | 3280 // Count the number of characters in the UTF-8 string and check if |
| 3291 // it is an ASCII string. | 3281 // it is an ASCII string. |
| 3292 Access<ScannerConstants::Utf8Decoder> | 3282 Access<ScannerConstants::Utf8Decoder> |
| 3293 decoder(ScannerConstants::utf8_decoder()); | 3283 decoder(ScannerConstants::utf8_decoder()); |
| 3294 decoder->Reset(string.start(), string.length()); | 3284 decoder->Reset(string.start(), string.length()); |
| 3295 int chars = 0; | 3285 int chars = 0; |
| 3296 bool is_ascii = true; | |
| 3297 while (decoder->has_more()) { | 3286 while (decoder->has_more()) { |
| 3298 uc32 r = decoder->GetNext(); | 3287 decoder->GetNext(); |
| 3299 if (r > String::kMaxAsciiCharCode) is_ascii = false; | |
| 3300 chars++; | 3288 chars++; |
| 3301 } | 3289 } |
| 3302 | 3290 |
| 3303 // If the string is ascii, we do not need to convert the characters | |
| 3304 // since UTF8 is backwards compatible with ascii. | |
| 3305 if (is_ascii) return AllocateStringFromAscii(string, pretenure); | |
| 3306 | |
| 3307 Object* result; | 3291 Object* result; |
| 3308 { MaybeObject* maybe_result = AllocateRawTwoByteString(chars, pretenure); | 3292 { MaybeObject* maybe_result = AllocateRawTwoByteString(chars, pretenure); |
| 3309 if (!maybe_result->ToObject(&result)) return maybe_result; | 3293 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3310 } | 3294 } |
| 3311 | 3295 |
| 3312 // Convert and copy the characters into the new object. | 3296 // Convert and copy the characters into the new object. |
| 3313 String* string_result = String::cast(result); | 3297 String* string_result = String::cast(result); |
| 3314 decoder->Reset(string.start(), string.length()); | 3298 decoder->Reset(string.start(), string.length()); |
| 3315 for (int i = 0; i < chars; i++) { | 3299 for (int i = 0; i < chars; i++) { |
| 3316 uc32 r = decoder->GetNext(); | 3300 uc32 r = decoder->GetNext(); |
| 3317 if (r > kMaxSupportedChar) { r = unibrow::Utf8::kBadChar; } | 3301 if (r > kMaxSupportedChar) { r = unibrow::Utf8::kBadChar; } |
| 3318 string_result->Set(i, r); | 3302 string_result->Set(i, r); |
| 3319 } | 3303 } |
| 3320 return result; | 3304 return result; |
| 3321 } | 3305 } |
| 3322 | 3306 |
| 3323 | 3307 |
| 3324 MaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string, | 3308 MaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string, |
| 3325 PretenureFlag pretenure) { | 3309 PretenureFlag pretenure) { |
| 3326 // Check if the string is an ASCII string. | 3310 // Check if the string is an ASCII string. |
| 3327 int i = 0; | |
| 3328 while (i < string.length() && string[i] <= String::kMaxAsciiCharCode) i++; | |
| 3329 | |
| 3330 MaybeObject* maybe_result; | 3311 MaybeObject* maybe_result; |
| 3331 if (i == string.length()) { // It's an ASCII string. | 3312 if (String::IsAscii(string.start(), string.length())) { |
| 3332 maybe_result = AllocateRawAsciiString(string.length(), pretenure); | 3313 maybe_result = AllocateRawAsciiString(string.length(), pretenure); |
| 3333 } else { // It's not an ASCII string. | 3314 } else { // It's not an ASCII string. |
| 3334 maybe_result = AllocateRawTwoByteString(string.length(), pretenure); | 3315 maybe_result = AllocateRawTwoByteString(string.length(), pretenure); |
| 3335 } | 3316 } |
| 3336 Object* result; | 3317 Object* result; |
| 3337 if (!maybe_result->ToObject(&result)) return maybe_result; | 3318 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3338 | 3319 |
| 3339 // Copy the characters into the new object, which may be either ASCII or | 3320 // Copy the characters into the new object, which may be either ASCII or |
| 3340 // UTF-16. | 3321 // UTF-16. |
| 3341 String* string_result = String::cast(result); | 3322 String* string_result = String::cast(result); |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4000 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 3981 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
| 4001 } | 3982 } |
| 4002 // Can't use set_symbol_table because SymbolTable::cast knows that | 3983 // Can't use set_symbol_table because SymbolTable::cast knows that |
| 4003 // SymbolTable is a singleton and checks for identity. | 3984 // SymbolTable is a singleton and checks for identity. |
| 4004 roots_[kSymbolTableRootIndex] = new_table; | 3985 roots_[kSymbolTableRootIndex] = new_table; |
| 4005 ASSERT(symbol != NULL); | 3986 ASSERT(symbol != NULL); |
| 4006 return symbol; | 3987 return symbol; |
| 4007 } | 3988 } |
| 4008 | 3989 |
| 4009 | 3990 |
| 3991 MaybeObject* Heap::LookupAsciiSymbol(Vector<const char> string) { |
| 3992 Object* symbol = NULL; |
| 3993 Object* new_table; |
| 3994 { MaybeObject* maybe_new_table = |
| 3995 symbol_table()->LookupAsciiSymbol(string, &symbol); |
| 3996 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
| 3997 } |
| 3998 // Can't use set_symbol_table because SymbolTable::cast knows that |
| 3999 // SymbolTable is a singleton and checks for identity. |
| 4000 roots_[kSymbolTableRootIndex] = new_table; |
| 4001 ASSERT(symbol != NULL); |
| 4002 return symbol; |
| 4003 } |
| 4004 |
| 4005 |
| 4006 MaybeObject* Heap::LookupTwoByteSymbol(Vector<const uc16> string) { |
| 4007 Object* symbol = NULL; |
| 4008 Object* new_table; |
| 4009 { MaybeObject* maybe_new_table = |
| 4010 symbol_table()->LookupTwoByteSymbol(string, &symbol); |
| 4011 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
| 4012 } |
| 4013 // Can't use set_symbol_table because SymbolTable::cast knows that |
| 4014 // SymbolTable is a singleton and checks for identity. |
| 4015 roots_[kSymbolTableRootIndex] = new_table; |
| 4016 ASSERT(symbol != NULL); |
| 4017 return symbol; |
| 4018 } |
| 4019 |
| 4020 |
| 4010 MaybeObject* Heap::LookupSymbol(String* string) { | 4021 MaybeObject* Heap::LookupSymbol(String* string) { |
| 4011 if (string->IsSymbol()) return string; | 4022 if (string->IsSymbol()) return string; |
| 4012 Object* symbol = NULL; | 4023 Object* symbol = NULL; |
| 4013 Object* new_table; | 4024 Object* new_table; |
| 4014 { MaybeObject* maybe_new_table = | 4025 { MaybeObject* maybe_new_table = |
| 4015 symbol_table()->LookupString(string, &symbol); | 4026 symbol_table()->LookupString(string, &symbol); |
| 4016 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 4027 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
| 4017 } | 4028 } |
| 4018 // Can't use set_symbol_table because SymbolTable::cast knows that | 4029 // Can't use set_symbol_table because SymbolTable::cast knows that |
| 4019 // SymbolTable is a singleton and checks for identity. | 4030 // SymbolTable is a singleton and checks for identity. |
| (...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5489 void ExternalStringTable::TearDown() { | 5500 void ExternalStringTable::TearDown() { |
| 5490 new_space_strings_.Free(); | 5501 new_space_strings_.Free(); |
| 5491 old_space_strings_.Free(); | 5502 old_space_strings_.Free(); |
| 5492 } | 5503 } |
| 5493 | 5504 |
| 5494 | 5505 |
| 5495 List<Object*> ExternalStringTable::new_space_strings_; | 5506 List<Object*> ExternalStringTable::new_space_strings_; |
| 5496 List<Object*> ExternalStringTable::old_space_strings_; | 5507 List<Object*> ExternalStringTable::old_space_strings_; |
| 5497 | 5508 |
| 5498 } } // namespace v8::internal | 5509 } } // namespace v8::internal |
| OLD | NEW |