| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "factory.h" | 5 #include "factory.h" |
| 6 | 6 |
| 7 #include "isolate-inl.h" | 7 #include "isolate-inl.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 | 248 |
| 249 Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, | 249 Handle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, |
| 250 PretenureFlag pretenure) { | 250 PretenureFlag pretenure) { |
| 251 CALL_HEAP_FUNCTION( | 251 CALL_HEAP_FUNCTION( |
| 252 isolate(), | 252 isolate(), |
| 253 isolate()->heap()->AllocateStringFromTwoByte(string, pretenure), | 253 isolate()->heap()->AllocateStringFromTwoByte(string, pretenure), |
| 254 String); | 254 String); |
| 255 } | 255 } |
| 256 | 256 |
| 257 | 257 |
| 258 Handle<SeqOneByteString> Factory::NewRawOneByteString(int length, | 258 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( |
| 259 PretenureFlag pretenure) { | 259 int length, PretenureFlag pretenure) { |
| 260 CALL_HEAP_FUNCTION( | 260 CALL_HEAP_FUNCTION( |
| 261 isolate(), | 261 isolate(), |
| 262 isolate()->heap()->AllocateRawOneByteString(length, pretenure), | 262 isolate()->heap()->AllocateRawOneByteString(length, pretenure), |
| 263 SeqOneByteString); | 263 SeqOneByteString); |
| 264 } | 264 } |
| 265 | 265 |
| 266 | 266 |
| 267 Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length, | 267 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( |
| 268 PretenureFlag pretenure) { | 268 int length, PretenureFlag pretenure) { |
| 269 CALL_HEAP_FUNCTION( | 269 CALL_HEAP_FUNCTION( |
| 270 isolate(), | 270 isolate(), |
| 271 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), | 271 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), |
| 272 SeqTwoByteString); | 272 SeqTwoByteString); |
| 273 } | 273 } |
| 274 | 274 |
| 275 | 275 |
| 276 // Returns true for a character in a range. Both limits are inclusive. | 276 // Returns true for a character in a range. Both limits are inclusive. |
| 277 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { | 277 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { |
| 278 // This makes uses of the the unsigned wraparound. | 278 // This makes uses of the the unsigned wraparound. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 291 if (table->LookupTwoCharsStringIfExists(c1, c2, &result)) { | 291 if (table->LookupTwoCharsStringIfExists(c1, c2, &result)) { |
| 292 return handle(result); | 292 return handle(result); |
| 293 } | 293 } |
| 294 } | 294 } |
| 295 | 295 |
| 296 // Now we know the length is 2, we might as well make use of that fact | 296 // Now we know the length is 2, we might as well make use of that fact |
| 297 // when building the new string. | 297 // when building the new string. |
| 298 if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) { | 298 if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) { |
| 299 // We can do this. | 299 // We can do this. |
| 300 ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this. | 300 ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this. |
| 301 Handle<SeqOneByteString> str = isolate->factory()->NewRawOneByteString(2); | 301 Handle<SeqOneByteString> str = |
| 302 isolate->factory()->NewRawOneByteString(2).ToHandleChecked(); |
| 302 uint8_t* dest = str->GetChars(); | 303 uint8_t* dest = str->GetChars(); |
| 303 dest[0] = static_cast<uint8_t>(c1); | 304 dest[0] = static_cast<uint8_t>(c1); |
| 304 dest[1] = static_cast<uint8_t>(c2); | 305 dest[1] = static_cast<uint8_t>(c2); |
| 305 return str; | 306 return str; |
| 306 } else { | 307 } else { |
| 307 Handle<SeqTwoByteString> str = isolate->factory()->NewRawTwoByteString(2); | 308 Handle<SeqTwoByteString> str = |
| 309 isolate->factory()->NewRawTwoByteString(2).ToHandleChecked(); |
| 308 uc16* dest = str->GetChars(); | 310 uc16* dest = str->GetChars(); |
| 309 dest[0] = c1; | 311 dest[0] = c1; |
| 310 dest[1] = c2; | 312 dest[1] = c2; |
| 311 return str; | 313 return str; |
| 312 } | 314 } |
| 313 } | 315 } |
| 314 | 316 |
| 315 | 317 |
| 316 template<typename SinkChar, typename StringType> | 318 template<typename SinkChar, typename StringType> |
| 317 Handle<String> ConcatStringContent(Handle<StringType> result, | 319 Handle<String> ConcatStringContent(Handle<StringType> result, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 | 375 |
| 374 // If the resulting string is small make a flat string. | 376 // If the resulting string is small make a flat string. |
| 375 if (length < ConsString::kMinLength) { | 377 if (length < ConsString::kMinLength) { |
| 376 // Note that neither of the two inputs can be a slice because: | 378 // Note that neither of the two inputs can be a slice because: |
| 377 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); | 379 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); |
| 378 ASSERT(left->IsFlat()); | 380 ASSERT(left->IsFlat()); |
| 379 ASSERT(right->IsFlat()); | 381 ASSERT(right->IsFlat()); |
| 380 | 382 |
| 381 STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength); | 383 STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength); |
| 382 if (is_one_byte) { | 384 if (is_one_byte) { |
| 383 Handle<SeqOneByteString> result = NewRawOneByteString(length); | 385 Handle<SeqOneByteString> result = |
| 386 NewRawOneByteString(length).ToHandleChecked(); |
| 384 DisallowHeapAllocation no_gc; | 387 DisallowHeapAllocation no_gc; |
| 385 uint8_t* dest = result->GetChars(); | 388 uint8_t* dest = result->GetChars(); |
| 386 // Copy left part. | 389 // Copy left part. |
| 387 const uint8_t* src = left->IsExternalString() | 390 const uint8_t* src = left->IsExternalString() |
| 388 ? Handle<ExternalAsciiString>::cast(left)->GetChars() | 391 ? Handle<ExternalAsciiString>::cast(left)->GetChars() |
| 389 : Handle<SeqOneByteString>::cast(left)->GetChars(); | 392 : Handle<SeqOneByteString>::cast(left)->GetChars(); |
| 390 for (int i = 0; i < left_length; i++) *dest++ = src[i]; | 393 for (int i = 0; i < left_length; i++) *dest++ = src[i]; |
| 391 // Copy right part. | 394 // Copy right part. |
| 392 src = right->IsExternalString() | 395 src = right->IsExternalString() |
| 393 ? Handle<ExternalAsciiString>::cast(right)->GetChars() | 396 ? Handle<ExternalAsciiString>::cast(right)->GetChars() |
| 394 : Handle<SeqOneByteString>::cast(right)->GetChars(); | 397 : Handle<SeqOneByteString>::cast(right)->GetChars(); |
| 395 for (int i = 0; i < right_length; i++) *dest++ = src[i]; | 398 for (int i = 0; i < right_length; i++) *dest++ = src[i]; |
| 396 return result; | 399 return result; |
| 397 } | 400 } |
| 398 | 401 |
| 399 return (is_one_byte_data_in_two_byte_string) | 402 return (is_one_byte_data_in_two_byte_string) |
| 400 ? ConcatStringContent<uint8_t>(NewRawOneByteString(length), left, right) | 403 ? ConcatStringContent<uint8_t>( |
| 401 : ConcatStringContent<uc16>(NewRawTwoByteString(length), left, right); | 404 NewRawOneByteString(length).ToHandleChecked(), left, right) |
| 405 : ConcatStringContent<uc16>( |
| 406 NewRawTwoByteString(length).ToHandleChecked(), left, right); |
| 402 } | 407 } |
| 403 | 408 |
| 404 Handle<ConsString> result = NewRawConsString( | 409 Handle<ConsString> result = NewRawConsString( |
| 405 (is_one_byte || is_one_byte_data_in_two_byte_string) | 410 (is_one_byte || is_one_byte_data_in_two_byte_string) |
| 406 ? String::ONE_BYTE_ENCODING | 411 ? String::ONE_BYTE_ENCODING |
| 407 : String::TWO_BYTE_ENCODING); | 412 : String::TWO_BYTE_ENCODING); |
| 408 | 413 |
| 409 DisallowHeapAllocation no_gc; | 414 DisallowHeapAllocation no_gc; |
| 410 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 415 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 411 | 416 |
| 412 result->set_hash_field(String::kEmptyHashField); | 417 result->set_hash_field(String::kEmptyHashField); |
| 413 result->set_length(length); | 418 result->set_length(length); |
| 414 result->set_first(*left, mode); | 419 result->set_first(*left, mode); |
| 415 result->set_second(*right, mode); | 420 result->set_second(*right, mode); |
| 416 return result; | 421 return result; |
| 417 } | 422 } |
| 418 | 423 |
| 419 | 424 |
| 420 Handle<String> Factory::NewFlatConcatString(Handle<String> first, | 425 Handle<String> Factory::NewFlatConcatString(Handle<String> first, |
| 421 Handle<String> second) { | 426 Handle<String> second) { |
| 422 int total_length = first->length() + second->length(); | 427 int total_length = first->length() + second->length(); |
| 423 if (first->IsOneByteRepresentation() && second->IsOneByteRepresentation()) { | 428 if (first->IsOneByteRepresentation() && second->IsOneByteRepresentation()) { |
| 424 return ConcatStringContent<uint8_t>( | 429 return ConcatStringContent<uint8_t>( |
| 425 NewRawOneByteString(total_length), first, second); | 430 NewRawOneByteString(total_length).ToHandleChecked(), first, second); |
| 426 } else { | 431 } else { |
| 427 return ConcatStringContent<uc16>( | 432 return ConcatStringContent<uc16>( |
| 428 NewRawTwoByteString(total_length), first, second); | 433 NewRawTwoByteString(total_length).ToHandleChecked(), first, second); |
| 429 } | 434 } |
| 430 } | 435 } |
| 431 | 436 |
| 432 | 437 |
| 433 Handle<SlicedString> Factory::NewRawSlicedString(String::Encoding encoding) { | 438 Handle<SlicedString> Factory::NewRawSlicedString(String::Encoding encoding) { |
| 434 Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING) | 439 Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING) |
| 435 ? sliced_ascii_string_map() : sliced_string_map(); | 440 ? sliced_ascii_string_map() : sliced_string_map(); |
| 436 CALL_HEAP_FUNCTION(isolate(), | 441 CALL_HEAP_FUNCTION(isolate(), |
| 437 isolate()->heap()->Allocate(*map, NEW_SPACE), | 442 isolate()->heap()->Allocate(*map, NEW_SPACE), |
| 438 SlicedString); | 443 SlicedString); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 456 // Optimization for 2-byte strings often used as keys in a decompression | 461 // Optimization for 2-byte strings often used as keys in a decompression |
| 457 // dictionary. Check whether we already have the string in the string | 462 // dictionary. Check whether we already have the string in the string |
| 458 // table to prevent creation of many unnecessary strings. | 463 // table to prevent creation of many unnecessary strings. |
| 459 uint16_t c1 = str->Get(begin); | 464 uint16_t c1 = str->Get(begin); |
| 460 uint16_t c2 = str->Get(begin + 1); | 465 uint16_t c2 = str->Get(begin + 1); |
| 461 return MakeOrFindTwoCharacterString(isolate(), c1, c2); | 466 return MakeOrFindTwoCharacterString(isolate(), c1, c2); |
| 462 } | 467 } |
| 463 | 468 |
| 464 if (!FLAG_string_slices || length < SlicedString::kMinLength) { | 469 if (!FLAG_string_slices || length < SlicedString::kMinLength) { |
| 465 if (str->IsOneByteRepresentation()) { | 470 if (str->IsOneByteRepresentation()) { |
| 466 Handle<SeqOneByteString> result = NewRawOneByteString(length); | 471 Handle<SeqOneByteString> result = |
| 467 ASSERT(!result.is_null()); | 472 NewRawOneByteString(length).ToHandleChecked(); |
| 468 uint8_t* dest = result->GetChars(); | 473 uint8_t* dest = result->GetChars(); |
| 469 DisallowHeapAllocation no_gc; | 474 DisallowHeapAllocation no_gc; |
| 470 String::WriteToFlat(*str, dest, begin, end); | 475 String::WriteToFlat(*str, dest, begin, end); |
| 471 return result; | 476 return result; |
| 472 } else { | 477 } else { |
| 473 Handle<SeqTwoByteString> result = NewRawTwoByteString(length); | 478 Handle<SeqTwoByteString> result = |
| 474 ASSERT(!result.is_null()); | 479 NewRawTwoByteString(length).ToHandleChecked(); |
| 475 uc16* dest = result->GetChars(); | 480 uc16* dest = result->GetChars(); |
| 476 DisallowHeapAllocation no_gc; | 481 DisallowHeapAllocation no_gc; |
| 477 String::WriteToFlat(*str, dest, begin, end); | 482 String::WriteToFlat(*str, dest, begin, end); |
| 478 return result; | 483 return result; |
| 479 } | 484 } |
| 480 } | 485 } |
| 481 | 486 |
| 482 int offset = begin; | 487 int offset = begin; |
| 483 | 488 |
| 484 while (str->IsConsString()) { | 489 while (str->IsConsString()) { |
| (...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1946 if (name->Equals(h->infinity_string())) return infinity_value(); | 1951 if (name->Equals(h->infinity_string())) return infinity_value(); |
| 1947 return Handle<Object>::null(); | 1952 return Handle<Object>::null(); |
| 1948 } | 1953 } |
| 1949 | 1954 |
| 1950 | 1955 |
| 1951 Handle<Object> Factory::ToBoolean(bool value) { | 1956 Handle<Object> Factory::ToBoolean(bool value) { |
| 1952 return value ? true_value() : false_value(); | 1957 return value ? true_value() : false_value(); |
| 1953 } | 1958 } |
| 1954 | 1959 |
| 1955 } } // namespace v8::internal | 1960 } } // namespace v8::internal |
| OLD | NEW |