Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(106)

Side by Side Diff: src/factory.cc

Issue 157503002: A64: Synchronize with r18444. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/factory.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 280
281 Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length, 281 Handle<SeqTwoByteString> Factory::NewRawTwoByteString(int length,
282 PretenureFlag pretenure) { 282 PretenureFlag pretenure) {
283 CALL_HEAP_FUNCTION( 283 CALL_HEAP_FUNCTION(
284 isolate(), 284 isolate(),
285 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), 285 isolate()->heap()->AllocateRawTwoByteString(length, pretenure),
286 SeqTwoByteString); 286 SeqTwoByteString);
287 } 287 }
288 288
289 289
290 Handle<String> Factory::NewConsString(Handle<String> first, 290 // Returns true for a character in a range. Both limits are inclusive.
291 Handle<String> second) { 291 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
292 CALL_HEAP_FUNCTION(isolate(), 292 // This makes uses of the the unsigned wraparound.
293 isolate()->heap()->AllocateConsString(*first, *second), 293 return character - from <= to - from;
294 String);
295 } 294 }
296 295
297 296
297 static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
298 uint16_t c1,
299 uint16_t c2) {
300 // Numeric strings have a different hash algorithm not known by
301 // LookupTwoCharsStringIfExists, so we skip this step for such strings.
302 if (!Between(c1, '0', '9') || !Between(c2, '0', '9')) {
303 String* result;
304 StringTable* table = isolate->heap()->string_table();
305 if (table->LookupTwoCharsStringIfExists(c1, c2, &result)) {
306 return handle(result);
307 }
308 }
309
310 // Now we know the length is 2, we might as well make use of that fact
311 // when building the new string.
312 if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
313 // We can do this.
314 ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this.
315 Handle<SeqOneByteString> str = isolate->factory()->NewRawOneByteString(2);
316 uint8_t* dest = str->GetChars();
317 dest[0] = static_cast<uint8_t>(c1);
318 dest[1] = static_cast<uint8_t>(c2);
319 return str;
320 } else {
321 Handle<SeqTwoByteString> str = isolate->factory()->NewRawTwoByteString(2);
322 uc16* dest = str->GetChars();
323 dest[0] = c1;
324 dest[1] = c2;
325 return str;
326 }
327 }
328
329
298 template<typename SinkChar, typename StringType> 330 template<typename SinkChar, typename StringType>
299 Handle<String> ConcatStringContent(Handle<StringType> result, 331 Handle<String> ConcatStringContent(Handle<StringType> result,
300 Handle<String> first, 332 Handle<String> first,
301 Handle<String> second) { 333 Handle<String> second) {
302 DisallowHeapAllocation pointer_stays_valid; 334 DisallowHeapAllocation pointer_stays_valid;
303 SinkChar* sink = result->GetChars(); 335 SinkChar* sink = result->GetChars();
304 String::WriteToFlat(*first, sink, 0, first->length()); 336 String::WriteToFlat(*first, sink, 0, first->length());
305 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); 337 String::WriteToFlat(*second, sink + first->length(), 0, second->length());
306 return result; 338 return result;
307 } 339 }
308 340
309 341
342 Handle<ConsString> Factory::NewRawConsString(String::Encoding encoding) {
343 Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING)
344 ? cons_ascii_string_map() : cons_string_map();
345 CALL_HEAP_FUNCTION(isolate(),
346 isolate()->heap()->Allocate(*map, NEW_SPACE),
347 ConsString);
348 }
349
350
351 Handle<String> Factory::NewConsString(Handle<String> left,
352 Handle<String> right) {
353 int left_length = left->length();
354 if (left_length == 0) return right;
355 int right_length = right->length();
356 if (right_length == 0) return left;
357
358 int length = left_length + right_length;
359
360 if (length == 2) {
361 uint16_t c1 = left->Get(0);
362 uint16_t c2 = right->Get(0);
363 return MakeOrFindTwoCharacterString(isolate(), c1, c2);
364 }
365
366 // Make sure that an out of memory exception is thrown if the length
367 // of the new cons string is too large.
368 if (length > String::kMaxLength || length < 0) {
369 isolate()->context()->mark_out_of_memory();
370 V8::FatalProcessOutOfMemory("String concatenation result too large.");
371 UNREACHABLE();
372 return Handle<String>::null();
373 }
374
375 bool left_is_one_byte = left->IsOneByteRepresentation();
376 bool right_is_one_byte = right->IsOneByteRepresentation();
377 bool is_one_byte = left_is_one_byte && right_is_one_byte;
378 bool is_one_byte_data_in_two_byte_string = false;
379 if (!is_one_byte) {
380 // At least one of the strings uses two-byte representation so we
381 // can't use the fast case code for short ASCII strings below, but
382 // we can try to save memory if all chars actually fit in ASCII.
383 is_one_byte_data_in_two_byte_string =
384 left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars();
385 if (is_one_byte_data_in_two_byte_string) {
386 isolate()->counters()->string_add_runtime_ext_to_ascii()->Increment();
387 }
388 }
389
390 // If the resulting string is small make a flat string.
391 if (length < ConsString::kMinLength) {
392 // Note that neither of the two inputs can be a slice because:
393 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength);
394 ASSERT(left->IsFlat());
395 ASSERT(right->IsFlat());
396
397 if (is_one_byte) {
398 Handle<SeqOneByteString> result = NewRawOneByteString(length);
399 DisallowHeapAllocation no_gc;
400 uint8_t* dest = result->GetChars();
401 // Copy left part.
402 const uint8_t* src = left->IsExternalString()
403 ? Handle<ExternalAsciiString>::cast(left)->GetChars()
404 : Handle<SeqOneByteString>::cast(left)->GetChars();
405 for (int i = 0; i < left_length; i++) *dest++ = src[i];
406 // Copy right part.
407 src = right->IsExternalString()
408 ? Handle<ExternalAsciiString>::cast(right)->GetChars()
409 : Handle<SeqOneByteString>::cast(right)->GetChars();
410 for (int i = 0; i < right_length; i++) *dest++ = src[i];
411 return result;
412 }
413
414 return (is_one_byte_data_in_two_byte_string)
415 ? ConcatStringContent<uint8_t>(NewRawOneByteString(length), left, right)
416 : ConcatStringContent<uc16>(NewRawTwoByteString(length), left, right);
417 }
418
419 Handle<ConsString> result = NewRawConsString(
420 (is_one_byte || is_one_byte_data_in_two_byte_string)
421 ? String::ONE_BYTE_ENCODING
422 : String::TWO_BYTE_ENCODING);
423
424 DisallowHeapAllocation no_gc;
425 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
426
427 result->set_hash_field(String::kEmptyHashField);
428 result->set_length(length);
429 result->set_first(*left, mode);
430 result->set_second(*right, mode);
431 return result;
432 }
433
434
310 Handle<String> Factory::NewFlatConcatString(Handle<String> first, 435 Handle<String> Factory::NewFlatConcatString(Handle<String> first,
311 Handle<String> second) { 436 Handle<String> second) {
312 int total_length = first->length() + second->length(); 437 int total_length = first->length() + second->length();
313 if (first->IsOneByteRepresentation() && second->IsOneByteRepresentation()) { 438 if (first->IsOneByteRepresentation() && second->IsOneByteRepresentation()) {
314 return ConcatStringContent<uint8_t>( 439 return ConcatStringContent<uint8_t>(
315 NewRawOneByteString(total_length), first, second); 440 NewRawOneByteString(total_length), first, second);
316 } else { 441 } else {
317 return ConcatStringContent<uc16>( 442 return ConcatStringContent<uc16>(
318 NewRawTwoByteString(total_length), first, second); 443 NewRawTwoByteString(total_length), first, second);
319 } 444 }
320 } 445 }
321 446
322 447
323 Handle<String> Factory::NewSubString(Handle<String> str, 448 Handle<SlicedString> Factory::NewRawSlicedString(String::Encoding encoding) {
324 int begin, 449 Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING)
325 int end) { 450 ? sliced_ascii_string_map() : sliced_string_map();
326 CALL_HEAP_FUNCTION(isolate(), 451 CALL_HEAP_FUNCTION(isolate(),
327 str->SubString(begin, end), 452 isolate()->heap()->Allocate(*map, NEW_SPACE),
328 String); 453 SlicedString);
329 } 454 }
330 455
331 456
332 Handle<String> Factory::NewProperSubString(Handle<String> str, 457 Handle<String> Factory::NewProperSubString(Handle<String> str,
333 int begin, 458 int begin,
334 int end) { 459 int end) {
460 #if VERIFY_HEAP
461 if (FLAG_verify_heap) str->StringVerify();
462 #endif
335 ASSERT(begin > 0 || end < str->length()); 463 ASSERT(begin > 0 || end < str->length());
336 CALL_HEAP_FUNCTION(isolate(), 464
337 isolate()->heap()->AllocateSubString(*str, begin, end), 465 int length = end - begin;
338 String); 466 if (length <= 0) return empty_string();
467 if (length == 1) {
468 return LookupSingleCharacterStringFromCode(isolate(), str->Get(begin));
469 }
470 if (length == 2) {
471 // Optimization for 2-byte strings often used as keys in a decompression
472 // dictionary. Check whether we already have the string in the string
473 // table to prevent creation of many unnecessary strings.
474 uint16_t c1 = str->Get(begin);
475 uint16_t c2 = str->Get(begin + 1);
476 return MakeOrFindTwoCharacterString(isolate(), c1, c2);
477 }
478
479 if (!FLAG_string_slices || length < SlicedString::kMinLength) {
480 if (str->IsOneByteRepresentation()) {
481 Handle<SeqOneByteString> result = NewRawOneByteString(length);
482 uint8_t* dest = result->GetChars();
483 DisallowHeapAllocation no_gc;
484 String::WriteToFlat(*str, dest, begin, end);
485 return result;
486 } else {
487 Handle<SeqTwoByteString> result = NewRawTwoByteString(length);
488 uc16* dest = result->GetChars();
489 DisallowHeapAllocation no_gc;
490 String::WriteToFlat(*str, dest, begin, end);
491 return result;
492 }
493 }
494
495 int offset = begin;
496
497 while (str->IsConsString()) {
498 Handle<ConsString> cons = Handle<ConsString>::cast(str);
499 int split = cons->first()->length();
500 if (split <= offset) {
501 // Slice is fully contained in the second part.
502 str = Handle<String>(cons->second(), isolate());
503 offset -= split; // Adjust for offset.
504 continue;
505 } else if (offset + length <= split) {
506 // Slice is fully contained in the first part.
507 str = Handle<String>(cons->first(), isolate());
508 continue;
509 }
510 break;
511 }
512
513 if (str->IsSlicedString()) {
514 Handle<SlicedString> slice = Handle<SlicedString>::cast(str);
515 str = Handle<String>(slice->parent(), isolate());
516 offset += slice->offset();
517 } else {
518 str = FlattenGetString(str);
519 }
520
521 ASSERT(str->IsSeqString() || str->IsExternalString());
522 Handle<SlicedString> slice = NewRawSlicedString(
523 str->IsOneByteRepresentation() ? String::ONE_BYTE_ENCODING
524 : String::TWO_BYTE_ENCODING);
525
526 slice->set_hash_field(String::kEmptyHashField);
527 slice->set_length(length);
528 slice->set_parent(*str);
529 slice->set_offset(offset);
530 return slice;
339 } 531 }
340 532
341 533
342 Handle<String> Factory::NewExternalStringFromAscii( 534 Handle<String> Factory::NewExternalStringFromAscii(
343 const ExternalAsciiString::Resource* resource) { 535 const ExternalAsciiString::Resource* resource) {
344 CALL_HEAP_FUNCTION( 536 CALL_HEAP_FUNCTION(
345 isolate(), 537 isolate(),
346 isolate()->heap()->AllocateExternalStringFromAscii(resource), 538 isolate()->heap()->AllocateExternalStringFromAscii(resource),
347 String); 539 String);
348 } 540 }
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 function_info, 917 function_info,
726 MapForNewFunction(isolate(), function_info), 918 MapForNewFunction(isolate(), function_info),
727 pretenure); 919 pretenure);
728 920
729 if (function_info->ic_age() != isolate()->heap()->global_ic_age()) { 921 if (function_info->ic_age() != isolate()->heap()->global_ic_age()) {
730 function_info->ResetForNewContext(isolate()->heap()->global_ic_age()); 922 function_info->ResetForNewContext(isolate()->heap()->global_ic_age());
731 } 923 }
732 924
733 result->set_context(*context); 925 result->set_context(*context);
734 926
735 int index = function_info->SearchOptimizedCodeMap(context->native_context()); 927 int index = function_info->SearchOptimizedCodeMap(context->native_context(),
928 BailoutId::None());
736 if (!function_info->bound() && index < 0) { 929 if (!function_info->bound() && index < 0) {
737 int number_of_literals = function_info->num_literals(); 930 int number_of_literals = function_info->num_literals();
738 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure); 931 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure);
739 if (number_of_literals > 0) { 932 if (number_of_literals > 0) {
740 // Store the native context in the literals array prefix. This 933 // Store the native context in the literals array prefix. This
741 // context will be used when creating object, regexp and array 934 // context will be used when creating object, regexp and array
742 // literals in this function. 935 // literals in this function.
743 literals->set(JSFunction::kLiteralNativeContextIndex, 936 literals->set(JSFunction::kLiteralNativeContextIndex,
744 context->native_context()); 937 context->native_context());
745 } 938 }
746 result->set_literals(*literals); 939 result->set_literals(*literals);
747 } 940 }
748 941
749 if (index > 0) { 942 if (index > 0) {
750 // Caching of optimized code enabled and optimized code found. 943 // Caching of optimized code enabled and optimized code found.
751 function_info->InstallFromOptimizedCodeMap(*result, index); 944 FixedArray* literals =
945 function_info->GetLiteralsFromOptimizedCodeMap(index);
946 if (literals != NULL) result->set_literals(literals);
947 result->ReplaceCode(function_info->GetCodeFromOptimizedCodeMap(index));
752 return result; 948 return result;
753 } 949 }
754 950
755 if (isolate()->use_crankshaft() && 951 if (isolate()->use_crankshaft() &&
756 FLAG_always_opt && 952 FLAG_always_opt &&
757 result->is_compiled() && 953 result->is_compiled() &&
758 !function_info->is_toplevel() && 954 !function_info->is_toplevel() &&
759 function_info->allows_lazy_compilation() && 955 function_info->allows_lazy_compilation() &&
760 !function_info->optimization_disabled() && 956 !function_info->optimization_disabled() &&
761 !isolate()->DebuggerHasBreakPoints()) { 957 !isolate()->DebuggerHasBreakPoints()) {
762 result->MarkForLazyRecompilation(); 958 result->MarkForOptimization();
763 } 959 }
764 return result; 960 return result;
765 } 961 }
766 962
767 963
768 Handle<Object> Factory::NewNumber(double value, 964 Handle<Object> Factory::NewNumber(double value,
769 PretenureFlag pretenure) { 965 PretenureFlag pretenure) {
770 CALL_HEAP_FUNCTION( 966 CALL_HEAP_FUNCTION(
771 isolate(), 967 isolate(),
772 isolate()->heap()->NumberFromDouble(value, pretenure), Object); 968 isolate()->heap()->NumberFromDouble(value, pretenure), Object);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 space -= Min(space, strlen(message)); 1085 space -= Min(space, strlen(message));
890 p = &buffer[kBufferSize] - space; 1086 p = &buffer[kBufferSize] - space;
891 1087
892 for (unsigned i = 0; i < ARRAY_SIZE(args); i++) { 1088 for (unsigned i = 0; i < ARRAY_SIZE(args); i++) {
893 if (space > 0) { 1089 if (space > 0) {
894 *p++ = ' '; 1090 *p++ = ' ';
895 space--; 1091 space--;
896 if (space > 0) { 1092 if (space > 0) {
897 MaybeObject* maybe_arg = args->GetElement(isolate(), i); 1093 MaybeObject* maybe_arg = args->GetElement(isolate(), i);
898 Handle<String> arg_str(reinterpret_cast<String*>(maybe_arg)); 1094 Handle<String> arg_str(reinterpret_cast<String*>(maybe_arg));
899 const char* arg = *arg_str->ToCString(); 1095 SmartArrayPointer<char> arg = arg_str->ToCString();
900 Vector<char> v2(p, static_cast<int>(space)); 1096 Vector<char> v2(p, static_cast<int>(space));
901 OS::StrNCpy(v2, arg, space); 1097 OS::StrNCpy(v2, arg.get(), space);
902 space -= Min(space, strlen(arg)); 1098 space -= Min(space, strlen(arg.get()));
903 p = &buffer[kBufferSize] - space; 1099 p = &buffer[kBufferSize] - space;
904 } 1100 }
905 } 1101 }
906 } 1102 }
907 if (space > 0) { 1103 if (space > 0) {
908 *p = '\0'; 1104 *p = '\0';
909 } else { 1105 } else {
910 buffer[kBufferSize - 1] = '\0'; 1106 buffer[kBufferSize - 1] = '\0';
911 } 1107 }
912 Handle<String> error_string = NewStringFromUtf8(CStrVector(buffer), TENURED); 1108 Handle<String> error_string = NewStringFromUtf8(CStrVector(buffer), TENURED);
(...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 return Handle<Object>::null(); 1993 return Handle<Object>::null();
1798 } 1994 }
1799 1995
1800 1996
1801 Handle<Object> Factory::ToBoolean(bool value) { 1997 Handle<Object> Factory::ToBoolean(bool value) {
1802 return value ? true_value() : false_value(); 1998 return value ? true_value() : false_value();
1803 } 1999 }
1804 2000
1805 2001
1806 } } // namespace v8::internal 2002 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/factory.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698