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