| 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 |