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

Side by Side Diff: src/factory.cc

Issue 59973004: Revert "Handlify concat string and substring." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month 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/handles.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 // Returns true for a character in a range. Both limits are inclusive. 290 Handle<String> Factory::NewConsString(Handle<String> first,
291 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { 291 Handle<String> second) {
292 // This makes uses of the the unsigned wraparound. 292 CALL_HEAP_FUNCTION(isolate(),
293 return character - from <= to - from; 293 isolate()->heap()->AllocateConsString(*first, *second),
294 String);
294 } 295 }
295 296
296 297
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
330 template<typename SinkChar, typename StringType> 298 template<typename SinkChar, typename StringType>
331 Handle<String> ConcatStringContent(Handle<StringType> result, 299 Handle<String> ConcatStringContent(Handle<StringType> result,
332 Handle<String> first, 300 Handle<String> first,
333 Handle<String> second) { 301 Handle<String> second) {
334 DisallowHeapAllocation pointer_stays_valid; 302 DisallowHeapAllocation pointer_stays_valid;
335 SinkChar* sink = result->GetChars(); 303 SinkChar* sink = result->GetChars();
336 String::WriteToFlat(*first, sink, 0, first->length()); 304 String::WriteToFlat(*first, sink, 0, first->length());
337 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); 305 String::WriteToFlat(*second, sink + first->length(), 0, second->length());
338 return result; 306 return result;
339 } 307 }
340 308
341 309
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
435 Handle<String> Factory::NewFlatConcatString(Handle<String> first, 310 Handle<String> Factory::NewFlatConcatString(Handle<String> first,
436 Handle<String> second) { 311 Handle<String> second) {
437 int total_length = first->length() + second->length(); 312 int total_length = first->length() + second->length();
438 if (first->IsOneByteRepresentationUnderneath() && 313 if (first->IsOneByteRepresentationUnderneath() &&
439 second->IsOneByteRepresentationUnderneath()) { 314 second->IsOneByteRepresentationUnderneath()) {
440 return ConcatStringContent<uint8_t>( 315 return ConcatStringContent<uint8_t>(
441 NewRawOneByteString(total_length), first, second); 316 NewRawOneByteString(total_length), first, second);
442 } else { 317 } else {
443 return ConcatStringContent<uc16>( 318 return ConcatStringContent<uc16>(
444 NewRawTwoByteString(total_length), first, second); 319 NewRawTwoByteString(total_length), first, second);
445 } 320 }
446 } 321 }
447 322
448 323
449 Handle<SlicedString> Factory::NewRawSlicedString(String::Encoding encoding) { 324 Handle<String> Factory::NewSubString(Handle<String> str,
450 Handle<Map> map = (encoding == String::ONE_BYTE_ENCODING) 325 int begin,
451 ? sliced_ascii_string_map() : sliced_string_map(); 326 int end) {
452 CALL_HEAP_FUNCTION(isolate(), 327 CALL_HEAP_FUNCTION(isolate(),
453 isolate()->heap()->Allocate(*map, NEW_SPACE), 328 str->SubString(begin, end),
454 SlicedString); 329 String);
455 } 330 }
456 331
457 332
458 Handle<String> Factory::NewProperSubString(Handle<String> str, 333 Handle<String> Factory::NewProperSubString(Handle<String> str,
459 int begin, 334 int begin,
460 int end) { 335 int end) {
461 #if VERIFY_HEAP
462 if (FLAG_verify_heap) str->StringVerify();
463 #endif
464 ASSERT(begin > 0 || end < str->length()); 336 ASSERT(begin > 0 || end < str->length());
465 337 CALL_HEAP_FUNCTION(isolate(),
466 int length = end - begin; 338 isolate()->heap()->AllocateSubString(*str, begin, end),
467 if (length <= 0) return empty_string(); 339 String);
468 if (length == 1) {
469 return LookupSingleCharacterStringFromCode(isolate(), str->Get(begin));
470 }
471 if (length == 2) {
472 // Optimization for 2-byte strings often used as keys in a decompression
473 // dictionary. Check whether we already have the string in the string
474 // table to prevent creation of many unnecessary strings.
475 uint16_t c1 = str->Get(begin);
476 uint16_t c2 = str->Get(begin + 1);
477 return MakeOrFindTwoCharacterString(isolate(), c1, c2);
478 }
479
480 if (!FLAG_string_slices || length < SlicedString::kMinLength) {
481 if (str->IsOneByteRepresentation()) {
482 Handle<SeqOneByteString> result = NewRawOneByteString(length);
483 uint8_t* dest = result->GetChars();
484 DisallowHeapAllocation no_gc;
485 String::WriteToFlat(*str, dest, begin, end);
486 return result;
487 } else {
488 Handle<SeqTwoByteString> result = NewRawTwoByteString(length);
489 uc16* dest = result->GetChars();
490 DisallowHeapAllocation no_gc;
491 String::WriteToFlat(*str, dest, begin, end);
492 return result;
493 }
494 }
495
496 int offset = begin;
497
498 while (str->IsConsString()) {
499 Handle<ConsString> cons = Handle<ConsString>::cast(str);
500 int split = cons->first()->length();
501 if (split <= offset) {
502 // Slice is fully contained in the second part.
503 str = Handle<String>(cons->second(), isolate());
504 offset -= split; // Adjust for offset.
505 continue;
506 } else if (offset + length <= split) {
507 // Slice is fully contained in the first part.
508 str = Handle<String>(cons->first(), isolate());
509 continue;
510 }
511 break;
512 }
513
514 if (str->IsSlicedString()) {
515 Handle<SlicedString> slice = Handle<SlicedString>::cast(str);
516 str = Handle<String>(slice->parent(), isolate());
517 offset += slice->offset();
518 } else {
519 str = FlattenGetString(str);
520 }
521
522 ASSERT(str->IsSeqString() || str->IsExternalString());
523 Handle<SlicedString> slice = NewRawSlicedString(
524 str->IsOneByteRepresentation() ? String::ONE_BYTE_ENCODING
525 : String::TWO_BYTE_ENCODING);
526
527 slice->set_hash_field(String::kEmptyHashField);
528 slice->set_length(length);
529 slice->set_parent(*str);
530 slice->set_offset(offset);
531 return slice;
532 } 340 }
533 341
534 342
535 Handle<String> Factory::NewExternalStringFromAscii( 343 Handle<String> Factory::NewExternalStringFromAscii(
536 const ExternalAsciiString::Resource* resource) { 344 const ExternalAsciiString::Resource* resource) {
537 CALL_HEAP_FUNCTION( 345 CALL_HEAP_FUNCTION(
538 isolate(), 346 isolate(),
539 isolate()->heap()->AllocateExternalStringFromAscii(resource), 347 isolate()->heap()->AllocateExternalStringFromAscii(resource),
540 String); 348 String);
541 } 349 }
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 return Handle<Object>::null(); 1780 return Handle<Object>::null();
1973 } 1781 }
1974 1782
1975 1783
1976 Handle<Object> Factory::ToBoolean(bool value) { 1784 Handle<Object> Factory::ToBoolean(bool value) {
1977 return value ? true_value() : false_value(); 1785 return value ? true_value() : false_value();
1978 } 1786 }
1979 1787
1980 1788
1981 } } // namespace v8::internal 1789 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/factory.h ('k') | src/handles.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698