OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 } | 430 } |
431 | 431 |
432 private: | 432 private: |
433 uint16_t* data_; | 433 uint16_t* data_; |
434 size_t length_; | 434 size_t length_; |
435 int* counter_; | 435 int* counter_; |
436 bool owning_data_; | 436 bool owning_data_; |
437 }; | 437 }; |
438 | 438 |
439 | 439 |
440 class TestAsciiResource: public String::ExternalAsciiStringResource { | 440 class TestOneByteResource : public String::ExternalOneByteStringResource { |
441 public: | 441 public: |
442 explicit TestAsciiResource(const char* data, int* counter = NULL, | 442 explicit TestOneByteResource(const char* data, int* counter = NULL, |
443 size_t offset = 0) | 443 size_t offset = 0) |
444 : orig_data_(data), | 444 : orig_data_(data), |
445 data_(data + offset), | 445 data_(data + offset), |
446 length_(strlen(data) - offset), | 446 length_(strlen(data) - offset), |
447 counter_(counter) {} | 447 counter_(counter) {} |
448 | 448 |
449 ~TestAsciiResource() { | 449 ~TestOneByteResource() { |
450 i::DeleteArray(orig_data_); | 450 i::DeleteArray(orig_data_); |
451 if (counter_ != NULL) ++*counter_; | 451 if (counter_ != NULL) ++*counter_; |
452 } | 452 } |
453 | 453 |
454 const char* data() const { | 454 const char* data() const { |
455 return data_; | 455 return data_; |
456 } | 456 } |
457 | 457 |
458 size_t length() const { | 458 size_t length() const { |
459 return length_; | 459 return length_; |
(...skipping 29 matching lines...) Expand all Loading... |
489 CHECK_EQ(String::TWO_BYTE_ENCODING, encoding); | 489 CHECK_EQ(String::TWO_BYTE_ENCODING, encoding); |
490 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 490 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
491 CHECK_EQ(0, dispose_count); | 491 CHECK_EQ(0, dispose_count); |
492 } | 492 } |
493 CcTest::i_isolate()->compilation_cache()->Clear(); | 493 CcTest::i_isolate()->compilation_cache()->Clear(); |
494 CcTest::heap()->CollectAllAvailableGarbage(); | 494 CcTest::heap()->CollectAllAvailableGarbage(); |
495 CHECK_EQ(1, dispose_count); | 495 CHECK_EQ(1, dispose_count); |
496 } | 496 } |
497 | 497 |
498 | 498 |
499 THREADED_TEST(ScriptUsingAsciiStringResource) { | 499 THREADED_TEST(ScriptUsingOneByteStringResource) { |
500 int dispose_count = 0; | 500 int dispose_count = 0; |
501 const char* c_source = "1 + 2 * 3"; | 501 const char* c_source = "1 + 2 * 3"; |
502 { | 502 { |
503 LocalContext env; | 503 LocalContext env; |
504 v8::HandleScope scope(env->GetIsolate()); | 504 v8::HandleScope scope(env->GetIsolate()); |
505 TestAsciiResource* resource = new TestAsciiResource(i::StrDup(c_source), | 505 TestOneByteResource* resource = |
506 &dispose_count); | 506 new TestOneByteResource(i::StrDup(c_source), &dispose_count); |
507 Local<String> source = String::NewExternal(env->GetIsolate(), resource); | 507 Local<String> source = String::NewExternal(env->GetIsolate(), resource); |
508 CHECK(source->IsExternalAscii()); | 508 CHECK(source->IsExternalOneByte()); |
509 CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource), | 509 CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource), |
510 source->GetExternalAsciiStringResource()); | 510 source->GetExternalOneByteStringResource()); |
511 String::Encoding encoding = String::UNKNOWN_ENCODING; | 511 String::Encoding encoding = String::UNKNOWN_ENCODING; |
512 CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource), | 512 CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource), |
513 source->GetExternalStringResourceBase(&encoding)); | 513 source->GetExternalStringResourceBase(&encoding)); |
514 CHECK_EQ(String::ASCII_ENCODING, encoding); | 514 CHECK_EQ(String::ONE_BYTE_ENCODING, encoding); |
515 Local<Script> script = v8_compile(source); | 515 Local<Script> script = v8_compile(source); |
516 Local<Value> value = script->Run(); | 516 Local<Value> value = script->Run(); |
517 CHECK(value->IsNumber()); | 517 CHECK(value->IsNumber()); |
518 CHECK_EQ(7, value->Int32Value()); | 518 CHECK_EQ(7, value->Int32Value()); |
519 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 519 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
520 CHECK_EQ(0, dispose_count); | 520 CHECK_EQ(0, dispose_count); |
521 } | 521 } |
522 CcTest::i_isolate()->compilation_cache()->Clear(); | 522 CcTest::i_isolate()->compilation_cache()->Clear(); |
523 CcTest::heap()->CollectAllAvailableGarbage(); | 523 CcTest::heap()->CollectAllAvailableGarbage(); |
524 CHECK_EQ(1, dispose_count); | 524 CHECK_EQ(1, dispose_count); |
525 } | 525 } |
526 | 526 |
527 | 527 |
528 THREADED_TEST(ScriptMakingExternalString) { | 528 THREADED_TEST(ScriptMakingExternalString) { |
529 int dispose_count = 0; | 529 int dispose_count = 0; |
530 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); | 530 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); |
531 { | 531 { |
532 LocalContext env; | 532 LocalContext env; |
533 v8::HandleScope scope(env->GetIsolate()); | 533 v8::HandleScope scope(env->GetIsolate()); |
534 Local<String> source = | 534 Local<String> source = |
535 String::NewFromTwoByte(env->GetIsolate(), two_byte_source); | 535 String::NewFromTwoByte(env->GetIsolate(), two_byte_source); |
536 // Trigger GCs so that the newly allocated string moves to old gen. | 536 // Trigger GCs so that the newly allocated string moves to old gen. |
537 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | 537 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
538 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | 538 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
539 CHECK_EQ(source->IsExternal(), false); | 539 CHECK_EQ(source->IsExternal(), false); |
540 CHECK_EQ(source->IsExternalAscii(), false); | 540 CHECK_EQ(source->IsExternalOneByte(), false); |
541 String::Encoding encoding = String::UNKNOWN_ENCODING; | 541 String::Encoding encoding = String::UNKNOWN_ENCODING; |
542 CHECK_EQ(NULL, source->GetExternalStringResourceBase(&encoding)); | 542 CHECK_EQ(NULL, source->GetExternalStringResourceBase(&encoding)); |
543 CHECK_EQ(String::ASCII_ENCODING, encoding); | 543 CHECK_EQ(String::ONE_BYTE_ENCODING, encoding); |
544 bool success = source->MakeExternal(new TestResource(two_byte_source, | 544 bool success = source->MakeExternal(new TestResource(two_byte_source, |
545 &dispose_count)); | 545 &dispose_count)); |
546 CHECK(success); | 546 CHECK(success); |
547 Local<Script> script = v8_compile(source); | 547 Local<Script> script = v8_compile(source); |
548 Local<Value> value = script->Run(); | 548 Local<Value> value = script->Run(); |
549 CHECK(value->IsNumber()); | 549 CHECK(value->IsNumber()); |
550 CHECK_EQ(7, value->Int32Value()); | 550 CHECK_EQ(7, value->Int32Value()); |
551 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 551 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
552 CHECK_EQ(0, dispose_count); | 552 CHECK_EQ(0, dispose_count); |
553 } | 553 } |
554 CcTest::i_isolate()->compilation_cache()->Clear(); | 554 CcTest::i_isolate()->compilation_cache()->Clear(); |
555 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 555 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
556 CHECK_EQ(1, dispose_count); | 556 CHECK_EQ(1, dispose_count); |
557 } | 557 } |
558 | 558 |
559 | 559 |
560 THREADED_TEST(ScriptMakingExternalAsciiString) { | 560 THREADED_TEST(ScriptMakingExternalOneByteString) { |
561 int dispose_count = 0; | 561 int dispose_count = 0; |
562 const char* c_source = "1 + 2 * 3"; | 562 const char* c_source = "1 + 2 * 3"; |
563 { | 563 { |
564 LocalContext env; | 564 LocalContext env; |
565 v8::HandleScope scope(env->GetIsolate()); | 565 v8::HandleScope scope(env->GetIsolate()); |
566 Local<String> source = v8_str(c_source); | 566 Local<String> source = v8_str(c_source); |
567 // Trigger GCs so that the newly allocated string moves to old gen. | 567 // Trigger GCs so that the newly allocated string moves to old gen. |
568 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | 568 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
569 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | 569 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
570 bool success = source->MakeExternal( | 570 bool success = source->MakeExternal( |
571 new TestAsciiResource(i::StrDup(c_source), &dispose_count)); | 571 new TestOneByteResource(i::StrDup(c_source), &dispose_count)); |
572 CHECK(success); | 572 CHECK(success); |
573 Local<Script> script = v8_compile(source); | 573 Local<Script> script = v8_compile(source); |
574 Local<Value> value = script->Run(); | 574 Local<Value> value = script->Run(); |
575 CHECK(value->IsNumber()); | 575 CHECK(value->IsNumber()); |
576 CHECK_EQ(7, value->Int32Value()); | 576 CHECK_EQ(7, value->Int32Value()); |
577 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 577 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
578 CHECK_EQ(0, dispose_count); | 578 CHECK_EQ(0, dispose_count); |
579 } | 579 } |
580 CcTest::i_isolate()->compilation_cache()->Clear(); | 580 CcTest::i_isolate()->compilation_cache()->Clear(); |
581 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 581 CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 two_byte_string = AsciiToTwoByteString(buf); | 624 two_byte_string = AsciiToTwoByteString(buf); |
625 Local<String> large_string = | 625 Local<String> large_string = |
626 String::NewFromTwoByte(env->GetIsolate(), two_byte_string); | 626 String::NewFromTwoByte(env->GetIsolate(), two_byte_string); |
627 i::DeleteArray(buf); | 627 i::DeleteArray(buf); |
628 i::DeleteArray(two_byte_string); | 628 i::DeleteArray(two_byte_string); |
629 // Large strings should be immediately accepted. | 629 // Large strings should be immediately accepted. |
630 CHECK(large_string->CanMakeExternal()); | 630 CHECK(large_string->CanMakeExternal()); |
631 } | 631 } |
632 | 632 |
633 | 633 |
634 TEST(MakingExternalAsciiStringConditions) { | 634 TEST(MakingExternalOneByteStringConditions) { |
635 LocalContext env; | 635 LocalContext env; |
636 v8::HandleScope scope(env->GetIsolate()); | 636 v8::HandleScope scope(env->GetIsolate()); |
637 | 637 |
638 // Free some space in the new space so that we can check freshness. | 638 // Free some space in the new space so that we can check freshness. |
639 CcTest::heap()->CollectGarbage(i::NEW_SPACE); | 639 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
640 CcTest::heap()->CollectGarbage(i::NEW_SPACE); | 640 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
641 | 641 |
642 Local<String> small_string = String::NewFromUtf8(env->GetIsolate(), "s1"); | 642 Local<String> small_string = String::NewFromUtf8(env->GetIsolate(), "s1"); |
643 // We should refuse to externalize newly created small string. | 643 // We should refuse to externalize newly created small string. |
644 CHECK(!small_string->CanMakeExternal()); | 644 CHECK(!small_string->CanMakeExternal()); |
(...skipping 16 matching lines...) Expand all Loading... |
661 char* buf = i::NewArray<char>(buf_size); | 661 char* buf = i::NewArray<char>(buf_size); |
662 memset(buf, 'a', buf_size); | 662 memset(buf, 'a', buf_size); |
663 buf[buf_size - 1] = '\0'; | 663 buf[buf_size - 1] = '\0'; |
664 Local<String> large_string = String::NewFromUtf8(env->GetIsolate(), buf); | 664 Local<String> large_string = String::NewFromUtf8(env->GetIsolate(), buf); |
665 i::DeleteArray(buf); | 665 i::DeleteArray(buf); |
666 // Large strings should be immediately accepted. | 666 // Large strings should be immediately accepted. |
667 CHECK(large_string->CanMakeExternal()); | 667 CHECK(large_string->CanMakeExternal()); |
668 } | 668 } |
669 | 669 |
670 | 670 |
671 TEST(MakingExternalUnalignedAsciiString) { | 671 TEST(MakingExternalUnalignedOneByteString) { |
672 LocalContext env; | 672 LocalContext env; |
673 v8::HandleScope scope(env->GetIsolate()); | 673 v8::HandleScope scope(env->GetIsolate()); |
674 | 674 |
675 CompileRun("function cons(a, b) { return a + b; }" | 675 CompileRun("function cons(a, b) { return a + b; }" |
676 "function slice(a) { return a.substring(1); }"); | 676 "function slice(a) { return a.substring(1); }"); |
677 // Create a cons string that will land in old pointer space. | 677 // Create a cons string that will land in old pointer space. |
678 Local<String> cons = Local<String>::Cast(CompileRun( | 678 Local<String> cons = Local<String>::Cast(CompileRun( |
679 "cons('abcdefghijklm', 'nopqrstuvwxyz');")); | 679 "cons('abcdefghijklm', 'nopqrstuvwxyz');")); |
680 // Create a sliced string that will land in old pointer space. | 680 // Create a sliced string that will land in old pointer space. |
681 Local<String> slice = Local<String>::Cast(CompileRun( | 681 Local<String> slice = Local<String>::Cast(CompileRun( |
682 "slice('abcdefghijklmnopqrstuvwxyz');")); | 682 "slice('abcdefghijklmnopqrstuvwxyz');")); |
683 | 683 |
684 // Trigger GCs so that the newly allocated string moves to old gen. | 684 // Trigger GCs so that the newly allocated string moves to old gen. |
685 SimulateFullSpace(CcTest::heap()->old_pointer_space()); | 685 SimulateFullSpace(CcTest::heap()->old_pointer_space()); |
686 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | 686 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
687 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | 687 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
688 | 688 |
689 // Turn into external string with unaligned resource data. | 689 // Turn into external string with unaligned resource data. |
690 const char* c_cons = "_abcdefghijklmnopqrstuvwxyz"; | 690 const char* c_cons = "_abcdefghijklmnopqrstuvwxyz"; |
691 bool success = cons->MakeExternal( | 691 bool success = |
692 new TestAsciiResource(i::StrDup(c_cons), NULL, 1)); | 692 cons->MakeExternal(new TestOneByteResource(i::StrDup(c_cons), NULL, 1)); |
693 CHECK(success); | 693 CHECK(success); |
694 const char* c_slice = "_bcdefghijklmnopqrstuvwxyz"; | 694 const char* c_slice = "_bcdefghijklmnopqrstuvwxyz"; |
695 success = slice->MakeExternal( | 695 success = |
696 new TestAsciiResource(i::StrDup(c_slice), NULL, 1)); | 696 slice->MakeExternal(new TestOneByteResource(i::StrDup(c_slice), NULL, 1)); |
697 CHECK(success); | 697 CHECK(success); |
698 | 698 |
699 // Trigger GCs and force evacuation. | 699 // Trigger GCs and force evacuation. |
700 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 700 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
701 CcTest::heap()->CollectAllGarbage(i::Heap::kReduceMemoryFootprintMask); | 701 CcTest::heap()->CollectAllGarbage(i::Heap::kReduceMemoryFootprintMask); |
702 } | 702 } |
703 | 703 |
704 | 704 |
705 THREADED_TEST(UsingExternalString) { | 705 THREADED_TEST(UsingExternalString) { |
706 i::Factory* factory = CcTest::i_isolate()->factory(); | 706 i::Factory* factory = CcTest::i_isolate()->factory(); |
707 { | 707 { |
708 v8::HandleScope scope(CcTest::isolate()); | 708 v8::HandleScope scope(CcTest::isolate()); |
709 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 709 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
710 Local<String> string = String::NewExternal( | 710 Local<String> string = String::NewExternal( |
711 CcTest::isolate(), new TestResource(two_byte_string)); | 711 CcTest::isolate(), new TestResource(two_byte_string)); |
712 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 712 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
713 // Trigger GCs so that the newly allocated string moves to old gen. | 713 // Trigger GCs so that the newly allocated string moves to old gen. |
714 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | 714 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
715 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | 715 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
716 i::Handle<i::String> isymbol = | 716 i::Handle<i::String> isymbol = |
717 factory->InternalizeString(istring); | 717 factory->InternalizeString(istring); |
718 CHECK(isymbol->IsInternalizedString()); | 718 CHECK(isymbol->IsInternalizedString()); |
719 } | 719 } |
720 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 720 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
721 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 721 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
722 } | 722 } |
723 | 723 |
724 | 724 |
725 THREADED_TEST(UsingExternalAsciiString) { | 725 THREADED_TEST(UsingExternalOneByteString) { |
726 i::Factory* factory = CcTest::i_isolate()->factory(); | 726 i::Factory* factory = CcTest::i_isolate()->factory(); |
727 { | 727 { |
728 v8::HandleScope scope(CcTest::isolate()); | 728 v8::HandleScope scope(CcTest::isolate()); |
729 const char* one_byte_string = "test string"; | 729 const char* one_byte_string = "test string"; |
730 Local<String> string = String::NewExternal( | 730 Local<String> string = String::NewExternal( |
731 CcTest::isolate(), new TestAsciiResource(i::StrDup(one_byte_string))); | 731 CcTest::isolate(), new TestOneByteResource(i::StrDup(one_byte_string))); |
732 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 732 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
733 // Trigger GCs so that the newly allocated string moves to old gen. | 733 // Trigger GCs so that the newly allocated string moves to old gen. |
734 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | 734 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
735 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | 735 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
736 i::Handle<i::String> isymbol = | 736 i::Handle<i::String> isymbol = |
737 factory->InternalizeString(istring); | 737 factory->InternalizeString(istring); |
738 CHECK(isymbol->IsInternalizedString()); | 738 CHECK(isymbol->IsInternalizedString()); |
739 } | 739 } |
740 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 740 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
741 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 741 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
(...skipping 15 matching lines...) Expand all Loading... |
757 in_new_space = CcTest::heap()->InNewSpace(*istring); | 757 in_new_space = CcTest::heap()->InNewSpace(*istring); |
758 CHECK(in_new_space || CcTest::heap()->old_data_space()->Contains(*istring)); | 758 CHECK(in_new_space || CcTest::heap()->old_data_space()->Contains(*istring)); |
759 CHECK_EQ(0, dispose_count); | 759 CHECK_EQ(0, dispose_count); |
760 } | 760 } |
761 CcTest::heap()->CollectGarbage( | 761 CcTest::heap()->CollectGarbage( |
762 in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); | 762 in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); |
763 CHECK_EQ(1, dispose_count); | 763 CHECK_EQ(1, dispose_count); |
764 } | 764 } |
765 | 765 |
766 | 766 |
767 THREADED_TEST(ScavengeExternalAsciiString) { | 767 THREADED_TEST(ScavengeExternalOneByteString) { |
768 i::FLAG_stress_compaction = false; | 768 i::FLAG_stress_compaction = false; |
769 i::FLAG_gc_global = false; | 769 i::FLAG_gc_global = false; |
770 int dispose_count = 0; | 770 int dispose_count = 0; |
771 bool in_new_space = false; | 771 bool in_new_space = false; |
772 { | 772 { |
773 v8::HandleScope scope(CcTest::isolate()); | 773 v8::HandleScope scope(CcTest::isolate()); |
774 const char* one_byte_string = "test string"; | 774 const char* one_byte_string = "test string"; |
775 Local<String> string = String::NewExternal( | 775 Local<String> string = String::NewExternal( |
776 CcTest::isolate(), | 776 CcTest::isolate(), |
777 new TestAsciiResource(i::StrDup(one_byte_string), &dispose_count)); | 777 new TestOneByteResource(i::StrDup(one_byte_string), &dispose_count)); |
778 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 778 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
779 CcTest::heap()->CollectGarbage(i::NEW_SPACE); | 779 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
780 in_new_space = CcTest::heap()->InNewSpace(*istring); | 780 in_new_space = CcTest::heap()->InNewSpace(*istring); |
781 CHECK(in_new_space || CcTest::heap()->old_data_space()->Contains(*istring)); | 781 CHECK(in_new_space || CcTest::heap()->old_data_space()->Contains(*istring)); |
782 CHECK_EQ(0, dispose_count); | 782 CHECK_EQ(0, dispose_count); |
783 } | 783 } |
784 CcTest::heap()->CollectGarbage( | 784 CcTest::heap()->CollectGarbage( |
785 in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); | 785 in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); |
786 CHECK_EQ(1, dispose_count); | 786 CHECK_EQ(1, dispose_count); |
787 } | 787 } |
788 | 788 |
789 | 789 |
790 class TestAsciiResourceWithDisposeControl: public TestAsciiResource { | 790 class TestOneByteResourceWithDisposeControl : public TestOneByteResource { |
791 public: | 791 public: |
792 // Only used by non-threaded tests, so it can use static fields. | 792 // Only used by non-threaded tests, so it can use static fields. |
793 static int dispose_calls; | 793 static int dispose_calls; |
794 static int dispose_count; | 794 static int dispose_count; |
795 | 795 |
796 TestAsciiResourceWithDisposeControl(const char* data, bool dispose) | 796 TestOneByteResourceWithDisposeControl(const char* data, bool dispose) |
797 : TestAsciiResource(data, &dispose_count), | 797 : TestOneByteResource(data, &dispose_count), dispose_(dispose) {} |
798 dispose_(dispose) { } | |
799 | 798 |
800 void Dispose() { | 799 void Dispose() { |
801 ++dispose_calls; | 800 ++dispose_calls; |
802 if (dispose_) delete this; | 801 if (dispose_) delete this; |
803 } | 802 } |
804 private: | 803 private: |
805 bool dispose_; | 804 bool dispose_; |
806 }; | 805 }; |
807 | 806 |
808 | 807 |
809 int TestAsciiResourceWithDisposeControl::dispose_count = 0; | 808 int TestOneByteResourceWithDisposeControl::dispose_count = 0; |
810 int TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 809 int TestOneByteResourceWithDisposeControl::dispose_calls = 0; |
811 | 810 |
812 | 811 |
813 TEST(ExternalStringWithDisposeHandling) { | 812 TEST(ExternalStringWithDisposeHandling) { |
814 const char* c_source = "1 + 2 * 3"; | 813 const char* c_source = "1 + 2 * 3"; |
815 | 814 |
816 // Use a stack allocated external string resource allocated object. | 815 // Use a stack allocated external string resource allocated object. |
817 TestAsciiResourceWithDisposeControl::dispose_count = 0; | 816 TestOneByteResourceWithDisposeControl::dispose_count = 0; |
818 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 817 TestOneByteResourceWithDisposeControl::dispose_calls = 0; |
819 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); | 818 TestOneByteResourceWithDisposeControl res_stack(i::StrDup(c_source), false); |
820 { | 819 { |
821 LocalContext env; | 820 LocalContext env; |
822 v8::HandleScope scope(env->GetIsolate()); | 821 v8::HandleScope scope(env->GetIsolate()); |
823 Local<String> source = String::NewExternal(env->GetIsolate(), &res_stack); | 822 Local<String> source = String::NewExternal(env->GetIsolate(), &res_stack); |
824 Local<Script> script = v8_compile(source); | 823 Local<Script> script = v8_compile(source); |
825 Local<Value> value = script->Run(); | 824 Local<Value> value = script->Run(); |
826 CHECK(value->IsNumber()); | 825 CHECK(value->IsNumber()); |
827 CHECK_EQ(7, value->Int32Value()); | 826 CHECK_EQ(7, value->Int32Value()); |
828 CcTest::heap()->CollectAllAvailableGarbage(); | 827 CcTest::heap()->CollectAllAvailableGarbage(); |
829 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 828 CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count); |
830 } | 829 } |
831 CcTest::i_isolate()->compilation_cache()->Clear(); | 830 CcTest::i_isolate()->compilation_cache()->Clear(); |
832 CcTest::heap()->CollectAllAvailableGarbage(); | 831 CcTest::heap()->CollectAllAvailableGarbage(); |
833 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 832 CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_calls); |
834 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 833 CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count); |
835 | 834 |
836 // Use a heap allocated external string resource allocated object. | 835 // Use a heap allocated external string resource allocated object. |
837 TestAsciiResourceWithDisposeControl::dispose_count = 0; | 836 TestOneByteResourceWithDisposeControl::dispose_count = 0; |
838 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 837 TestOneByteResourceWithDisposeControl::dispose_calls = 0; |
839 TestAsciiResource* res_heap = | 838 TestOneByteResource* res_heap = |
840 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); | 839 new TestOneByteResourceWithDisposeControl(i::StrDup(c_source), true); |
841 { | 840 { |
842 LocalContext env; | 841 LocalContext env; |
843 v8::HandleScope scope(env->GetIsolate()); | 842 v8::HandleScope scope(env->GetIsolate()); |
844 Local<String> source = String::NewExternal(env->GetIsolate(), res_heap); | 843 Local<String> source = String::NewExternal(env->GetIsolate(), res_heap); |
845 Local<Script> script = v8_compile(source); | 844 Local<Script> script = v8_compile(source); |
846 Local<Value> value = script->Run(); | 845 Local<Value> value = script->Run(); |
847 CHECK(value->IsNumber()); | 846 CHECK(value->IsNumber()); |
848 CHECK_EQ(7, value->Int32Value()); | 847 CHECK_EQ(7, value->Int32Value()); |
849 CcTest::heap()->CollectAllAvailableGarbage(); | 848 CcTest::heap()->CollectAllAvailableGarbage(); |
850 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 849 CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count); |
851 } | 850 } |
852 CcTest::i_isolate()->compilation_cache()->Clear(); | 851 CcTest::i_isolate()->compilation_cache()->Clear(); |
853 CcTest::heap()->CollectAllAvailableGarbage(); | 852 CcTest::heap()->CollectAllAvailableGarbage(); |
854 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 853 CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_calls); |
855 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count); | 854 CHECK_EQ(1, TestOneByteResourceWithDisposeControl::dispose_count); |
856 } | 855 } |
857 | 856 |
858 | 857 |
859 THREADED_TEST(StringConcat) { | 858 THREADED_TEST(StringConcat) { |
860 { | 859 { |
861 LocalContext env; | 860 LocalContext env; |
862 v8::HandleScope scope(env->GetIsolate()); | 861 v8::HandleScope scope(env->GetIsolate()); |
863 const char* one_byte_string_1 = "function a_times_t"; | 862 const char* one_byte_string_1 = "function a_times_t"; |
864 const char* two_byte_string_1 = "wo_plus_b(a, b) {return "; | 863 const char* two_byte_string_1 = "wo_plus_b(a, b) {return "; |
865 const char* one_byte_extern_1 = "a * 2 + b;} a_times_two_plus_b(4, 8) + "; | 864 const char* one_byte_extern_1 = "a * 2 + b;} a_times_two_plus_b(4, 8) + "; |
866 const char* two_byte_extern_1 = "a_times_two_plus_b(4, 8) + "; | 865 const char* two_byte_extern_1 = "a_times_two_plus_b(4, 8) + "; |
867 const char* one_byte_string_2 = "a_times_two_plus_b(4, 8) + "; | 866 const char* one_byte_string_2 = "a_times_two_plus_b(4, 8) + "; |
868 const char* two_byte_string_2 = "a_times_two_plus_b(4, 8) + "; | 867 const char* two_byte_string_2 = "a_times_two_plus_b(4, 8) + "; |
869 const char* two_byte_extern_2 = "a_times_two_plus_b(1, 2);"; | 868 const char* two_byte_extern_2 = "a_times_two_plus_b(1, 2);"; |
870 Local<String> left = v8_str(one_byte_string_1); | 869 Local<String> left = v8_str(one_byte_string_1); |
871 | 870 |
872 uint16_t* two_byte_source = AsciiToTwoByteString(two_byte_string_1); | 871 uint16_t* two_byte_source = AsciiToTwoByteString(two_byte_string_1); |
873 Local<String> right = | 872 Local<String> right = |
874 String::NewFromTwoByte(env->GetIsolate(), two_byte_source); | 873 String::NewFromTwoByte(env->GetIsolate(), two_byte_source); |
875 i::DeleteArray(two_byte_source); | 874 i::DeleteArray(two_byte_source); |
876 | 875 |
877 Local<String> source = String::Concat(left, right); | 876 Local<String> source = String::Concat(left, right); |
878 right = String::NewExternal( | 877 right = String::NewExternal( |
879 env->GetIsolate(), new TestAsciiResource(i::StrDup(one_byte_extern_1))); | 878 env->GetIsolate(), |
| 879 new TestOneByteResource(i::StrDup(one_byte_extern_1))); |
880 source = String::Concat(source, right); | 880 source = String::Concat(source, right); |
881 right = String::NewExternal( | 881 right = String::NewExternal( |
882 env->GetIsolate(), | 882 env->GetIsolate(), |
883 new TestResource(AsciiToTwoByteString(two_byte_extern_1))); | 883 new TestResource(AsciiToTwoByteString(two_byte_extern_1))); |
884 source = String::Concat(source, right); | 884 source = String::Concat(source, right); |
885 right = v8_str(one_byte_string_2); | 885 right = v8_str(one_byte_string_2); |
886 source = String::Concat(source, right); | 886 source = String::Concat(source, right); |
887 | 887 |
888 two_byte_source = AsciiToTwoByteString(two_byte_string_2); | 888 two_byte_source = AsciiToTwoByteString(two_byte_string_2); |
889 right = String::NewFromTwoByte(env->GetIsolate(), two_byte_source); | 889 right = String::NewFromTwoByte(env->GetIsolate(), two_byte_source); |
(...skipping 14237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15127 CHECK_EQ(v8::Integer::New(isolate, 123), clone->Get(v8_str("beta"))); | 15127 CHECK_EQ(v8::Integer::New(isolate, 123), clone->Get(v8_str("beta"))); |
15128 CHECK_EQ(v8_str("cloneme"), clone->Get(v8_str("gamma"))); | 15128 CHECK_EQ(v8_str("cloneme"), clone->Get(v8_str("gamma"))); |
15129 | 15129 |
15130 // Set a property on the clone, verify each object. | 15130 // Set a property on the clone, verify each object. |
15131 clone->Set(v8_str("beta"), v8::Integer::New(isolate, 456)); | 15131 clone->Set(v8_str("beta"), v8::Integer::New(isolate, 456)); |
15132 CHECK_EQ(v8::Integer::New(isolate, 123), obj->Get(v8_str("beta"))); | 15132 CHECK_EQ(v8::Integer::New(isolate, 123), obj->Get(v8_str("beta"))); |
15133 CHECK_EQ(v8::Integer::New(isolate, 456), clone->Get(v8_str("beta"))); | 15133 CHECK_EQ(v8::Integer::New(isolate, 456), clone->Get(v8_str("beta"))); |
15134 } | 15134 } |
15135 | 15135 |
15136 | 15136 |
15137 class AsciiVectorResource : public v8::String::ExternalAsciiStringResource { | 15137 class OneByteVectorResource : public v8::String::ExternalOneByteStringResource { |
15138 public: | 15138 public: |
15139 explicit AsciiVectorResource(i::Vector<const char> vector) | 15139 explicit OneByteVectorResource(i::Vector<const char> vector) |
15140 : data_(vector) {} | 15140 : data_(vector) {} |
15141 virtual ~AsciiVectorResource() {} | 15141 virtual ~OneByteVectorResource() {} |
15142 virtual size_t length() const { return data_.length(); } | 15142 virtual size_t length() const { return data_.length(); } |
15143 virtual const char* data() const { return data_.start(); } | 15143 virtual const char* data() const { return data_.start(); } |
15144 private: | 15144 private: |
15145 i::Vector<const char> data_; | 15145 i::Vector<const char> data_; |
15146 }; | 15146 }; |
15147 | 15147 |
15148 | 15148 |
15149 class UC16VectorResource : public v8::String::ExternalStringResource { | 15149 class UC16VectorResource : public v8::String::ExternalStringResource { |
15150 public: | 15150 public: |
15151 explicit UC16VectorResource(i::Vector<const i::uc16> vector) | 15151 explicit UC16VectorResource(i::Vector<const i::uc16> vector) |
15152 : data_(vector) {} | 15152 : data_(vector) {} |
15153 virtual ~UC16VectorResource() {} | 15153 virtual ~UC16VectorResource() {} |
15154 virtual size_t length() const { return data_.length(); } | 15154 virtual size_t length() const { return data_.length(); } |
15155 virtual const i::uc16* data() const { return data_.start(); } | 15155 virtual const i::uc16* data() const { return data_.start(); } |
15156 private: | 15156 private: |
15157 i::Vector<const i::uc16> data_; | 15157 i::Vector<const i::uc16> data_; |
15158 }; | 15158 }; |
15159 | 15159 |
15160 | 15160 |
15161 static void MorphAString(i::String* string, | 15161 static void MorphAString(i::String* string, |
15162 AsciiVectorResource* ascii_resource, | 15162 OneByteVectorResource* one_byte_resource, |
15163 UC16VectorResource* uc16_resource) { | 15163 UC16VectorResource* uc16_resource) { |
15164 CHECK(i::StringShape(string).IsExternal()); | 15164 CHECK(i::StringShape(string).IsExternal()); |
15165 if (string->IsOneByteRepresentation()) { | 15165 if (string->IsOneByteRepresentation()) { |
15166 // Check old map is not internalized or long. | 15166 // Check old map is not internalized or long. |
15167 CHECK(string->map() == CcTest::heap()->external_ascii_string_map()); | 15167 CHECK(string->map() == CcTest::heap()->external_one_byte_string_map()); |
15168 // Morph external string to be TwoByte string. | 15168 // Morph external string to be TwoByte string. |
15169 string->set_map(CcTest::heap()->external_string_map()); | 15169 string->set_map(CcTest::heap()->external_string_map()); |
15170 i::ExternalTwoByteString* morphed = | 15170 i::ExternalTwoByteString* morphed = |
15171 i::ExternalTwoByteString::cast(string); | 15171 i::ExternalTwoByteString::cast(string); |
15172 morphed->set_resource(uc16_resource); | 15172 morphed->set_resource(uc16_resource); |
15173 } else { | 15173 } else { |
15174 // Check old map is not internalized or long. | 15174 // Check old map is not internalized or long. |
15175 CHECK(string->map() == CcTest::heap()->external_string_map()); | 15175 CHECK(string->map() == CcTest::heap()->external_string_map()); |
15176 // Morph external string to be ASCII string. | 15176 // Morph external string to be one-byte string. |
15177 string->set_map(CcTest::heap()->external_ascii_string_map()); | 15177 string->set_map(CcTest::heap()->external_one_byte_string_map()); |
15178 i::ExternalAsciiString* morphed = | 15178 i::ExternalOneByteString* morphed = i::ExternalOneByteString::cast(string); |
15179 i::ExternalAsciiString::cast(string); | 15179 morphed->set_resource(one_byte_resource); |
15180 morphed->set_resource(ascii_resource); | |
15181 } | 15180 } |
15182 } | 15181 } |
15183 | 15182 |
15184 | 15183 |
15185 // Test that we can still flatten a string if the components it is built up | 15184 // Test that we can still flatten a string if the components it is built up |
15186 // from have been turned into 16 bit strings in the mean time. | 15185 // from have been turned into 16 bit strings in the mean time. |
15187 THREADED_TEST(MorphCompositeStringTest) { | 15186 THREADED_TEST(MorphCompositeStringTest) { |
15188 char utf_buffer[129]; | 15187 char utf_buffer[129]; |
15189 const char* c_string = "Now is the time for all good men" | 15188 const char* c_string = "Now is the time for all good men" |
15190 " to come to the aid of the party"; | 15189 " to come to the aid of the party"; |
15191 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); | 15190 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); |
15192 { | 15191 { |
15193 LocalContext env; | 15192 LocalContext env; |
15194 i::Factory* factory = CcTest::i_isolate()->factory(); | 15193 i::Factory* factory = CcTest::i_isolate()->factory(); |
15195 v8::HandleScope scope(env->GetIsolate()); | 15194 v8::HandleScope scope(env->GetIsolate()); |
15196 AsciiVectorResource ascii_resource( | 15195 OneByteVectorResource one_byte_resource( |
15197 i::Vector<const char>(c_string, i::StrLength(c_string))); | 15196 i::Vector<const char>(c_string, i::StrLength(c_string))); |
15198 UC16VectorResource uc16_resource( | 15197 UC16VectorResource uc16_resource( |
15199 i::Vector<const uint16_t>(two_byte_string, | 15198 i::Vector<const uint16_t>(two_byte_string, |
15200 i::StrLength(c_string))); | 15199 i::StrLength(c_string))); |
15201 | 15200 |
15202 Local<String> lhs(v8::Utils::ToLocal( | 15201 Local<String> lhs( |
15203 factory->NewExternalStringFromAscii(&ascii_resource) | 15202 v8::Utils::ToLocal(factory->NewExternalStringFromOneByte( |
15204 .ToHandleChecked())); | 15203 &one_byte_resource).ToHandleChecked())); |
15205 Local<String> rhs(v8::Utils::ToLocal( | 15204 Local<String> rhs( |
15206 factory->NewExternalStringFromAscii(&ascii_resource) | 15205 v8::Utils::ToLocal(factory->NewExternalStringFromOneByte( |
15207 .ToHandleChecked())); | 15206 &one_byte_resource).ToHandleChecked())); |
15208 | 15207 |
15209 env->Global()->Set(v8_str("lhs"), lhs); | 15208 env->Global()->Set(v8_str("lhs"), lhs); |
15210 env->Global()->Set(v8_str("rhs"), rhs); | 15209 env->Global()->Set(v8_str("rhs"), rhs); |
15211 | 15210 |
15212 CompileRun( | 15211 CompileRun( |
15213 "var cons = lhs + rhs;" | 15212 "var cons = lhs + rhs;" |
15214 "var slice = lhs.substring(1, lhs.length - 1);" | 15213 "var slice = lhs.substring(1, lhs.length - 1);" |
15215 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); | 15214 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); |
15216 | 15215 |
15217 CHECK(lhs->IsOneByte()); | 15216 CHECK(lhs->IsOneByte()); |
15218 CHECK(rhs->IsOneByte()); | 15217 CHECK(rhs->IsOneByte()); |
15219 | 15218 |
15220 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); | 15219 MorphAString(*v8::Utils::OpenHandle(*lhs), &one_byte_resource, |
15221 MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource); | 15220 &uc16_resource); |
| 15221 MorphAString(*v8::Utils::OpenHandle(*rhs), &one_byte_resource, |
| 15222 &uc16_resource); |
15222 | 15223 |
15223 // This should UTF-8 without flattening, since everything is ASCII. | 15224 // This should UTF-8 without flattening, since everything is ASCII. |
15224 Handle<String> cons = v8_compile("cons")->Run().As<String>(); | 15225 Handle<String> cons = v8_compile("cons")->Run().As<String>(); |
15225 CHECK_EQ(128, cons->Utf8Length()); | 15226 CHECK_EQ(128, cons->Utf8Length()); |
15226 int nchars = -1; | 15227 int nchars = -1; |
15227 CHECK_EQ(129, cons->WriteUtf8(utf_buffer, -1, &nchars)); | 15228 CHECK_EQ(129, cons->WriteUtf8(utf_buffer, -1, &nchars)); |
15228 CHECK_EQ(128, nchars); | 15229 CHECK_EQ(128, nchars); |
15229 CHECK_EQ(0, strcmp( | 15230 CHECK_EQ(0, strcmp( |
15230 utf_buffer, | 15231 utf_buffer, |
15231 "Now is the time for all good men to come to the aid of the party" | 15232 "Now is the time for all good men to come to the aid of the party" |
(...skipping 22 matching lines...) Expand all Loading... |
15254 i::DeleteArray(two_byte_string); | 15255 i::DeleteArray(two_byte_string); |
15255 } | 15256 } |
15256 | 15257 |
15257 | 15258 |
15258 TEST(CompileExternalTwoByteSource) { | 15259 TEST(CompileExternalTwoByteSource) { |
15259 LocalContext context; | 15260 LocalContext context; |
15260 v8::HandleScope scope(context->GetIsolate()); | 15261 v8::HandleScope scope(context->GetIsolate()); |
15261 | 15262 |
15262 // This is a very short list of sources, which currently is to check for a | 15263 // This is a very short list of sources, which currently is to check for a |
15263 // regression caused by r2703. | 15264 // regression caused by r2703. |
15264 const char* ascii_sources[] = { | 15265 const char* one_byte_sources[] = { |
15265 "0.5", | 15266 "0.5", |
15266 "-0.5", // This mainly testes PushBack in the Scanner. | 15267 "-0.5", // This mainly testes PushBack in the Scanner. |
15267 "--0.5", // This mainly testes PushBack in the Scanner. | 15268 "--0.5", // This mainly testes PushBack in the Scanner. |
15268 NULL | 15269 NULL}; |
15269 }; | |
15270 | 15270 |
15271 // Compile the sources as external two byte strings. | 15271 // Compile the sources as external two byte strings. |
15272 for (int i = 0; ascii_sources[i] != NULL; i++) { | 15272 for (int i = 0; one_byte_sources[i] != NULL; i++) { |
15273 uint16_t* two_byte_string = AsciiToTwoByteString(ascii_sources[i]); | 15273 uint16_t* two_byte_string = AsciiToTwoByteString(one_byte_sources[i]); |
15274 TestResource* uc16_resource = new TestResource(two_byte_string); | 15274 TestResource* uc16_resource = new TestResource(two_byte_string); |
15275 v8::Local<v8::String> source = | 15275 v8::Local<v8::String> source = |
15276 v8::String::NewExternal(context->GetIsolate(), uc16_resource); | 15276 v8::String::NewExternal(context->GetIsolate(), uc16_resource); |
15277 v8::Script::Compile(source); | 15277 v8::Script::Compile(source); |
15278 } | 15278 } |
15279 } | 15279 } |
15280 | 15280 |
15281 | 15281 |
15282 #ifndef V8_INTERPRETED_REGEXP | 15282 #ifndef V8_INTERPRETED_REGEXP |
15283 | 15283 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15322 // * interrupting with GC | 15322 // * interrupting with GC |
15323 // * turn the subject string from one-byte internal to two-byte external string | 15323 // * turn the subject string from one-byte internal to two-byte external string |
15324 // * force termination | 15324 // * force termination |
15325 TEST(RegExpInterruption) { | 15325 TEST(RegExpInterruption) { |
15326 v8::HandleScope scope(CcTest::isolate()); | 15326 v8::HandleScope scope(CcTest::isolate()); |
15327 LocalContext env; | 15327 LocalContext env; |
15328 | 15328 |
15329 RegExpInterruptionThread timeout_thread(CcTest::isolate()); | 15329 RegExpInterruptionThread timeout_thread(CcTest::isolate()); |
15330 | 15330 |
15331 v8::V8::AddGCPrologueCallback(RunBeforeGC); | 15331 v8::V8::AddGCPrologueCallback(RunBeforeGC); |
15332 static const char* ascii_content = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; | 15332 static const char* one_byte_content = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
15333 i::uc16* uc16_content = AsciiToTwoByteString(ascii_content); | 15333 i::uc16* uc16_content = AsciiToTwoByteString(one_byte_content); |
15334 v8::Local<v8::String> string = v8_str(ascii_content); | 15334 v8::Local<v8::String> string = v8_str(one_byte_content); |
15335 | 15335 |
15336 CcTest::global()->Set(v8_str("a"), string); | 15336 CcTest::global()->Set(v8_str("a"), string); |
15337 regexp_interruption_data.string.Reset(CcTest::isolate(), string); | 15337 regexp_interruption_data.string.Reset(CcTest::isolate(), string); |
15338 regexp_interruption_data.string_resource = new UC16VectorResource( | 15338 regexp_interruption_data.string_resource = new UC16VectorResource( |
15339 i::Vector<const i::uc16>(uc16_content, i::StrLength(ascii_content))); | 15339 i::Vector<const i::uc16>(uc16_content, i::StrLength(one_byte_content))); |
15340 | 15340 |
15341 v8::TryCatch try_catch; | 15341 v8::TryCatch try_catch; |
15342 timeout_thread.Start(); | 15342 timeout_thread.Start(); |
15343 | 15343 |
15344 CompileRun("/((a*)*)*b/.exec(a)"); | 15344 CompileRun("/((a*)*)*b/.exec(a)"); |
15345 CHECK(try_catch.HasTerminated()); | 15345 CHECK(try_catch.HasTerminated()); |
15346 | 15346 |
15347 timeout_thread.Join(); | 15347 timeout_thread.Join(); |
15348 | 15348 |
15349 regexp_interruption_data.string.Reset(); | 15349 regexp_interruption_data.string.Reset(); |
(...skipping 2611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17961 public: | 17961 public: |
17962 explicit VisitorImpl(TestResource** resource) { | 17962 explicit VisitorImpl(TestResource** resource) { |
17963 for (int i = 0; i < 4; i++) { | 17963 for (int i = 0; i < 4; i++) { |
17964 resource_[i] = resource[i]; | 17964 resource_[i] = resource[i]; |
17965 found_resource_[i] = false; | 17965 found_resource_[i] = false; |
17966 } | 17966 } |
17967 } | 17967 } |
17968 virtual ~VisitorImpl() {} | 17968 virtual ~VisitorImpl() {} |
17969 virtual void VisitExternalString(v8::Handle<v8::String> string) { | 17969 virtual void VisitExternalString(v8::Handle<v8::String> string) { |
17970 if (!string->IsExternal()) { | 17970 if (!string->IsExternal()) { |
17971 CHECK(string->IsExternalAscii()); | 17971 CHECK(string->IsExternalOneByte()); |
17972 return; | 17972 return; |
17973 } | 17973 } |
17974 v8::String::ExternalStringResource* resource = | 17974 v8::String::ExternalStringResource* resource = |
17975 string->GetExternalStringResource(); | 17975 string->GetExternalStringResource(); |
17976 CHECK(resource); | 17976 CHECK(resource); |
17977 for (int i = 0; i < 4; i++) { | 17977 for (int i = 0; i < 4; i++) { |
17978 if (resource_[i] == resource) { | 17978 if (resource_[i] == resource) { |
17979 CHECK(!found_resource_[i]); | 17979 CHECK(!found_resource_[i]); |
17980 found_resource_[i] = true; | 17980 found_resource_[i] = true; |
17981 } | 17981 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18018 TEST(ExternalizeOldSpaceOneByteCons) { | 18018 TEST(ExternalizeOldSpaceOneByteCons) { |
18019 LocalContext env; | 18019 LocalContext env; |
18020 v8::HandleScope scope(env->GetIsolate()); | 18020 v8::HandleScope scope(env->GetIsolate()); |
18021 v8::Local<v8::String> cons = | 18021 v8::Local<v8::String> cons = |
18022 CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(); | 18022 CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(); |
18023 CHECK(v8::Utils::OpenHandle(*cons)->IsConsString()); | 18023 CHECK(v8::Utils::OpenHandle(*cons)->IsConsString()); |
18024 CcTest::heap()->CollectAllAvailableGarbage(); | 18024 CcTest::heap()->CollectAllAvailableGarbage(); |
18025 CHECK(CcTest::heap()->old_pointer_space()->Contains( | 18025 CHECK(CcTest::heap()->old_pointer_space()->Contains( |
18026 *v8::Utils::OpenHandle(*cons))); | 18026 *v8::Utils::OpenHandle(*cons))); |
18027 | 18027 |
18028 TestAsciiResource* resource = | 18028 TestOneByteResource* resource = |
18029 new TestAsciiResource(i::StrDup("Romeo Montague Juliet Capulet")); | 18029 new TestOneByteResource(i::StrDup("Romeo Montague Juliet Capulet")); |
18030 cons->MakeExternal(resource); | 18030 cons->MakeExternal(resource); |
18031 | 18031 |
18032 CHECK(cons->IsExternalAscii()); | 18032 CHECK(cons->IsExternalOneByte()); |
18033 CHECK_EQ(resource, cons->GetExternalAsciiStringResource()); | 18033 CHECK_EQ(resource, cons->GetExternalOneByteStringResource()); |
18034 String::Encoding encoding; | 18034 String::Encoding encoding; |
18035 CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding)); | 18035 CHECK_EQ(resource, cons->GetExternalStringResourceBase(&encoding)); |
18036 CHECK_EQ(String::ONE_BYTE_ENCODING, encoding); | 18036 CHECK_EQ(String::ONE_BYTE_ENCODING, encoding); |
18037 } | 18037 } |
18038 | 18038 |
18039 | 18039 |
18040 TEST(VisitExternalStrings) { | 18040 TEST(VisitExternalStrings) { |
18041 LocalContext env; | 18041 LocalContext env; |
18042 v8::HandleScope scope(env->GetIsolate()); | 18042 v8::HandleScope scope(env->GetIsolate()); |
18043 const char* string = "Some string"; | 18043 const char* string = "Some string"; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
18078 visitor.CheckVisitedResources(); | 18078 visitor.CheckVisitedResources(); |
18079 } | 18079 } |
18080 | 18080 |
18081 | 18081 |
18082 TEST(ExternalStringCollectedAtTearDown) { | 18082 TEST(ExternalStringCollectedAtTearDown) { |
18083 int destroyed = 0; | 18083 int destroyed = 0; |
18084 v8::Isolate* isolate = v8::Isolate::New(); | 18084 v8::Isolate* isolate = v8::Isolate::New(); |
18085 { v8::Isolate::Scope isolate_scope(isolate); | 18085 { v8::Isolate::Scope isolate_scope(isolate); |
18086 v8::HandleScope handle_scope(isolate); | 18086 v8::HandleScope handle_scope(isolate); |
18087 const char* s = "One string to test them all, one string to find them."; | 18087 const char* s = "One string to test them all, one string to find them."; |
18088 TestAsciiResource* inscription = | 18088 TestOneByteResource* inscription = |
18089 new TestAsciiResource(i::StrDup(s), &destroyed); | 18089 new TestOneByteResource(i::StrDup(s), &destroyed); |
18090 v8::Local<v8::String> ring = v8::String::NewExternal(isolate, inscription); | 18090 v8::Local<v8::String> ring = v8::String::NewExternal(isolate, inscription); |
18091 // Ring is still alive. Orcs are roaming freely across our lands. | 18091 // Ring is still alive. Orcs are roaming freely across our lands. |
18092 CHECK_EQ(0, destroyed); | 18092 CHECK_EQ(0, destroyed); |
18093 USE(ring); | 18093 USE(ring); |
18094 } | 18094 } |
18095 | 18095 |
18096 isolate->Dispose(); | 18096 isolate->Dispose(); |
18097 // Ring has been destroyed. Free Peoples of Middle-earth Rejoice. | 18097 // Ring has been destroyed. Free Peoples of Middle-earth Rejoice. |
18098 CHECK_EQ(1, destroyed); | 18098 CHECK_EQ(1, destroyed); |
18099 } | 18099 } |
18100 | 18100 |
18101 | 18101 |
18102 TEST(ExternalInternalizedStringCollectedAtTearDown) { | 18102 TEST(ExternalInternalizedStringCollectedAtTearDown) { |
18103 int destroyed = 0; | 18103 int destroyed = 0; |
18104 v8::Isolate* isolate = v8::Isolate::New(); | 18104 v8::Isolate* isolate = v8::Isolate::New(); |
18105 { v8::Isolate::Scope isolate_scope(isolate); | 18105 { v8::Isolate::Scope isolate_scope(isolate); |
18106 LocalContext env(isolate); | 18106 LocalContext env(isolate); |
18107 v8::HandleScope handle_scope(isolate); | 18107 v8::HandleScope handle_scope(isolate); |
18108 CompileRun("var ring = 'One string to test them all';"); | 18108 CompileRun("var ring = 'One string to test them all';"); |
18109 const char* s = "One string to test them all"; | 18109 const char* s = "One string to test them all"; |
18110 TestAsciiResource* inscription = | 18110 TestOneByteResource* inscription = |
18111 new TestAsciiResource(i::StrDup(s), &destroyed); | 18111 new TestOneByteResource(i::StrDup(s), &destroyed); |
18112 v8::Local<v8::String> ring = CompileRun("ring")->ToString(); | 18112 v8::Local<v8::String> ring = CompileRun("ring")->ToString(); |
18113 CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString()); | 18113 CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString()); |
18114 ring->MakeExternal(inscription); | 18114 ring->MakeExternal(inscription); |
18115 // Ring is still alive. Orcs are roaming freely across our lands. | 18115 // Ring is still alive. Orcs are roaming freely across our lands. |
18116 CHECK_EQ(0, destroyed); | 18116 CHECK_EQ(0, destroyed); |
18117 USE(ring); | 18117 USE(ring); |
18118 } | 18118 } |
18119 | 18119 |
18120 isolate->Dispose(); | 18120 isolate->Dispose(); |
18121 // Ring has been destroyed. Free Peoples of Middle-earth Rejoice. | 18121 // Ring has been destroyed. Free Peoples of Middle-earth Rejoice. |
18122 CHECK_EQ(1, destroyed); | 18122 CHECK_EQ(1, destroyed); |
18123 } | 18123 } |
18124 | 18124 |
18125 | 18125 |
18126 TEST(ExternalInternalizedStringCollectedAtGC) { | 18126 TEST(ExternalInternalizedStringCollectedAtGC) { |
18127 int destroyed = 0; | 18127 int destroyed = 0; |
18128 { LocalContext env; | 18128 { LocalContext env; |
18129 v8::HandleScope handle_scope(env->GetIsolate()); | 18129 v8::HandleScope handle_scope(env->GetIsolate()); |
18130 CompileRun("var ring = 'One string to test them all';"); | 18130 CompileRun("var ring = 'One string to test them all';"); |
18131 const char* s = "One string to test them all"; | 18131 const char* s = "One string to test them all"; |
18132 TestAsciiResource* inscription = | 18132 TestOneByteResource* inscription = |
18133 new TestAsciiResource(i::StrDup(s), &destroyed); | 18133 new TestOneByteResource(i::StrDup(s), &destroyed); |
18134 v8::Local<v8::String> ring = CompileRun("ring")->ToString(); | 18134 v8::Local<v8::String> ring = CompileRun("ring")->ToString(); |
18135 CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString()); | 18135 CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString()); |
18136 ring->MakeExternal(inscription); | 18136 ring->MakeExternal(inscription); |
18137 // Ring is still alive. Orcs are roaming freely across our lands. | 18137 // Ring is still alive. Orcs are roaming freely across our lands. |
18138 CHECK_EQ(0, destroyed); | 18138 CHECK_EQ(0, destroyed); |
18139 USE(ring); | 18139 USE(ring); |
18140 } | 18140 } |
18141 | 18141 |
18142 // Garbage collector deals swift blows to evil. | 18142 // Garbage collector deals swift blows to evil. |
18143 CcTest::i_isolate()->compilation_cache()->Clear(); | 18143 CcTest::i_isolate()->compilation_cache()->Clear(); |
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19066 " for (var i = 0; i < 2*16; i++) {" | 19066 " for (var i = 0; i < 2*16; i++) {" |
19067 " %_GetFromCache(0, 'a' + i);" | 19067 " %_GetFromCache(0, 'a' + i);" |
19068 " };" | 19068 " };" |
19069 " return 'PASSED';" | 19069 " return 'PASSED';" |
19070 "})()"; | 19070 "})()"; |
19071 CcTest::heap()->ClearJSFunctionResultCaches(); | 19071 CcTest::heap()->ClearJSFunctionResultCaches(); |
19072 ExpectString(code, "PASSED"); | 19072 ExpectString(code, "PASSED"); |
19073 } | 19073 } |
19074 | 19074 |
19075 | 19075 |
19076 THREADED_TEST(TwoByteStringInAsciiCons) { | 19076 THREADED_TEST(TwoByteStringInOneByteCons) { |
19077 // See Chromium issue 47824. | 19077 // See Chromium issue 47824. |
19078 LocalContext context; | 19078 LocalContext context; |
19079 v8::HandleScope scope(context->GetIsolate()); | 19079 v8::HandleScope scope(context->GetIsolate()); |
19080 | 19080 |
19081 const char* init_code = | 19081 const char* init_code = |
19082 "var str1 = 'abelspendabel';" | 19082 "var str1 = 'abelspendabel';" |
19083 "var str2 = str1 + str1 + str1;" | 19083 "var str2 = str1 + str1 + str1;" |
19084 "str2;"; | 19084 "str2;"; |
19085 Local<Value> result = CompileRun(init_code); | 19085 Local<Value> result = CompileRun(init_code); |
19086 | 19086 |
(...skipping 17 matching lines...) Expand all Loading... |
19104 uc16_buffer[length] = 0; | 19104 uc16_buffer[length] = 0; |
19105 | 19105 |
19106 TestResource resource(uc16_buffer); | 19106 TestResource resource(uc16_buffer); |
19107 | 19107 |
19108 flat_string->MakeExternal(&resource); | 19108 flat_string->MakeExternal(&resource); |
19109 | 19109 |
19110 CHECK(flat_string->IsTwoByteRepresentation()); | 19110 CHECK(flat_string->IsTwoByteRepresentation()); |
19111 | 19111 |
19112 // If the cons string has been short-circuited, skip the following checks. | 19112 // If the cons string has been short-circuited, skip the following checks. |
19113 if (!string.is_identical_to(flat_string)) { | 19113 if (!string.is_identical_to(flat_string)) { |
19114 // At this point, we should have a Cons string which is flat and ASCII, | 19114 // At this point, we should have a Cons string which is flat and one-byte, |
19115 // with a first half that is a two-byte string (although it only contains | 19115 // with a first half that is a two-byte string (although it only contains |
19116 // ASCII characters). This is a valid sequence of steps, and it can happen | 19116 // one-byte characters). This is a valid sequence of steps, and it can |
19117 // in real pages. | 19117 // happen in real pages. |
19118 CHECK(string->IsOneByteRepresentation()); | 19118 CHECK(string->IsOneByteRepresentation()); |
19119 i::ConsString* cons = i::ConsString::cast(*string); | 19119 i::ConsString* cons = i::ConsString::cast(*string); |
19120 CHECK_EQ(0, cons->second()->length()); | 19120 CHECK_EQ(0, cons->second()->length()); |
19121 CHECK(cons->first()->IsTwoByteRepresentation()); | 19121 CHECK(cons->first()->IsTwoByteRepresentation()); |
19122 } | 19122 } |
19123 | 19123 |
19124 // Check that some string operations work. | 19124 // Check that some string operations work. |
19125 | 19125 |
19126 // Atom RegExp. | 19126 // Atom RegExp. |
19127 Local<Value> reresult = CompileRun("str2.match(/abel/g).length;"); | 19127 Local<Value> reresult = CompileRun("str2.match(/abel/g).length;"); |
(...skipping 3865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
22993 desc = x->GetOwnPropertyDescriptor(v8_str("p1")); | 22993 desc = x->GetOwnPropertyDescriptor(v8_str("p1")); |
22994 Local<Function> set = | 22994 Local<Function> set = |
22995 Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("set"))); | 22995 Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("set"))); |
22996 Local<Function> get = | 22996 Local<Function> get = |
22997 Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("get"))); | 22997 Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("get"))); |
22998 CHECK_EQ(v8_num(13), get->Call(x, 0, NULL)); | 22998 CHECK_EQ(v8_num(13), get->Call(x, 0, NULL)); |
22999 Handle<Value> args[] = { v8_num(14) }; | 22999 Handle<Value> args[] = { v8_num(14) }; |
23000 set->Call(x, 1, args); | 23000 set->Call(x, 1, args); |
23001 CHECK_EQ(v8_num(14), get->Call(x, 0, NULL)); | 23001 CHECK_EQ(v8_num(14), get->Call(x, 0, NULL)); |
23002 } | 23002 } |
OLD | NEW |