OLD | NEW |
1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 using ::v8::ObjectTemplate; | 51 using ::v8::ObjectTemplate; |
52 using ::v8::Value; | 52 using ::v8::Value; |
53 using ::v8::Context; | 53 using ::v8::Context; |
54 using ::v8::Local; | 54 using ::v8::Local; |
55 using ::v8::String; | 55 using ::v8::String; |
56 using ::v8::Script; | 56 using ::v8::Script; |
57 using ::v8::Function; | 57 using ::v8::Function; |
58 using ::v8::AccessorInfo; | 58 using ::v8::AccessorInfo; |
59 using ::v8::Extension; | 59 using ::v8::Extension; |
60 | 60 |
61 namespace i = ::v8::internal; | 61 namespace i = ::i; |
62 | 62 |
63 | 63 |
64 static void ExpectString(const char* code, const char* expected) { | 64 static void ExpectString(const char* code, const char* expected) { |
65 Local<Value> result = CompileRun(code); | 65 Local<Value> result = CompileRun(code); |
66 CHECK(result->IsString()); | 66 CHECK(result->IsString()); |
67 String::AsciiValue ascii(result); | 67 String::AsciiValue ascii(result); |
68 CHECK_EQ(expected, *ascii); | 68 CHECK_EQ(expected, *ascii); |
69 } | 69 } |
70 | 70 |
71 | 71 |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 LocalContext env; | 374 LocalContext env; |
375 TestResource* resource = new TestResource(two_byte_source); | 375 TestResource* resource = new TestResource(two_byte_source); |
376 Local<String> source = String::NewExternal(resource); | 376 Local<String> source = String::NewExternal(resource); |
377 Local<Script> script = Script::Compile(source); | 377 Local<Script> script = Script::Compile(source); |
378 Local<Value> value = script->Run(); | 378 Local<Value> value = script->Run(); |
379 CHECK(value->IsNumber()); | 379 CHECK(value->IsNumber()); |
380 CHECK_EQ(7, value->Int32Value()); | 380 CHECK_EQ(7, value->Int32Value()); |
381 CHECK(source->IsExternal()); | 381 CHECK(source->IsExternal()); |
382 CHECK_EQ(resource, | 382 CHECK_EQ(resource, |
383 static_cast<TestResource*>(source->GetExternalStringResource())); | 383 static_cast<TestResource*>(source->GetExternalStringResource())); |
384 v8::internal::Heap::CollectAllGarbage(false); | 384 i::Heap::CollectAllGarbage(false); |
385 CHECK_EQ(0, TestResource::dispose_count); | 385 CHECK_EQ(0, TestResource::dispose_count); |
386 } | 386 } |
387 v8::internal::CompilationCache::Clear(); | 387 i::CompilationCache::Clear(); |
388 v8::internal::Heap::CollectAllGarbage(false); | 388 i::Heap::CollectAllGarbage(false); |
389 CHECK_EQ(1, TestResource::dispose_count); | 389 CHECK_EQ(1, TestResource::dispose_count); |
390 } | 390 } |
391 | 391 |
392 | 392 |
393 THREADED_TEST(ScriptUsingAsciiStringResource) { | 393 THREADED_TEST(ScriptUsingAsciiStringResource) { |
394 TestAsciiResource::dispose_count = 0; | 394 TestAsciiResource::dispose_count = 0; |
395 const char* c_source = "1 + 2 * 3"; | 395 const char* c_source = "1 + 2 * 3"; |
396 { | 396 { |
397 v8::HandleScope scope; | 397 v8::HandleScope scope; |
398 LocalContext env; | 398 LocalContext env; |
399 Local<String> source = | 399 Local<String> source = |
400 String::NewExternal(new TestAsciiResource(i::StrDup(c_source))); | 400 String::NewExternal(new TestAsciiResource(i::StrDup(c_source))); |
401 Local<Script> script = Script::Compile(source); | 401 Local<Script> script = Script::Compile(source); |
402 Local<Value> value = script->Run(); | 402 Local<Value> value = script->Run(); |
403 CHECK(value->IsNumber()); | 403 CHECK(value->IsNumber()); |
404 CHECK_EQ(7, value->Int32Value()); | 404 CHECK_EQ(7, value->Int32Value()); |
405 v8::internal::Heap::CollectAllGarbage(false); | 405 i::Heap::CollectAllGarbage(false); |
406 CHECK_EQ(0, TestAsciiResource::dispose_count); | 406 CHECK_EQ(0, TestAsciiResource::dispose_count); |
407 } | 407 } |
408 v8::internal::CompilationCache::Clear(); | 408 i::CompilationCache::Clear(); |
409 v8::internal::Heap::CollectAllGarbage(false); | 409 i::Heap::CollectAllGarbage(false); |
410 CHECK_EQ(1, TestAsciiResource::dispose_count); | 410 CHECK_EQ(1, TestAsciiResource::dispose_count); |
411 } | 411 } |
412 | 412 |
413 | 413 |
414 THREADED_TEST(ScriptMakingExternalString) { | 414 THREADED_TEST(ScriptMakingExternalString) { |
415 TestResource::dispose_count = 0; | 415 TestResource::dispose_count = 0; |
416 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); | 416 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); |
417 { | 417 { |
418 v8::HandleScope scope; | 418 v8::HandleScope scope; |
419 LocalContext env; | 419 LocalContext env; |
420 Local<String> source = String::New(two_byte_source); | 420 Local<String> source = String::New(two_byte_source); |
421 // Trigger GCs so that the newly allocated string moves to old gen. | 421 // Trigger GCs so that the newly allocated string moves to old gen. |
422 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now | 422 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now |
423 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now | 423 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now |
424 bool success = source->MakeExternal(new TestResource(two_byte_source)); | 424 bool success = source->MakeExternal(new TestResource(two_byte_source)); |
425 CHECK(success); | 425 CHECK(success); |
426 Local<Script> script = Script::Compile(source); | 426 Local<Script> script = Script::Compile(source); |
427 Local<Value> value = script->Run(); | 427 Local<Value> value = script->Run(); |
428 CHECK(value->IsNumber()); | 428 CHECK(value->IsNumber()); |
429 CHECK_EQ(7, value->Int32Value()); | 429 CHECK_EQ(7, value->Int32Value()); |
430 v8::internal::Heap::CollectAllGarbage(false); | 430 i::Heap::CollectAllGarbage(false); |
431 CHECK_EQ(0, TestResource::dispose_count); | 431 CHECK_EQ(0, TestResource::dispose_count); |
432 } | 432 } |
433 v8::internal::CompilationCache::Clear(); | 433 i::CompilationCache::Clear(); |
434 v8::internal::Heap::CollectAllGarbage(false); | 434 i::Heap::CollectAllGarbage(false); |
435 CHECK_EQ(1, TestResource::dispose_count); | 435 CHECK_EQ(1, TestResource::dispose_count); |
436 } | 436 } |
437 | 437 |
438 | 438 |
439 THREADED_TEST(ScriptMakingExternalAsciiString) { | 439 THREADED_TEST(ScriptMakingExternalAsciiString) { |
440 TestAsciiResource::dispose_count = 0; | 440 TestAsciiResource::dispose_count = 0; |
441 const char* c_source = "1 + 2 * 3"; | 441 const char* c_source = "1 + 2 * 3"; |
442 { | 442 { |
443 v8::HandleScope scope; | 443 v8::HandleScope scope; |
444 LocalContext env; | 444 LocalContext env; |
445 Local<String> source = v8_str(c_source); | 445 Local<String> source = v8_str(c_source); |
446 // Trigger GCs so that the newly allocated string moves to old gen. | 446 // Trigger GCs so that the newly allocated string moves to old gen. |
447 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now | 447 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in survivor space now |
448 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now | 448 i::Heap::CollectGarbage(0, i::NEW_SPACE); // in old gen now |
449 bool success = source->MakeExternal( | 449 bool success = source->MakeExternal( |
450 new TestAsciiResource(i::StrDup(c_source))); | 450 new TestAsciiResource(i::StrDup(c_source))); |
451 CHECK(success); | 451 CHECK(success); |
452 Local<Script> script = Script::Compile(source); | 452 Local<Script> script = Script::Compile(source); |
453 Local<Value> value = script->Run(); | 453 Local<Value> value = script->Run(); |
454 CHECK(value->IsNumber()); | 454 CHECK(value->IsNumber()); |
455 CHECK_EQ(7, value->Int32Value()); | 455 CHECK_EQ(7, value->Int32Value()); |
456 v8::internal::Heap::CollectAllGarbage(false); | 456 i::Heap::CollectAllGarbage(false); |
457 CHECK_EQ(0, TestAsciiResource::dispose_count); | 457 CHECK_EQ(0, TestAsciiResource::dispose_count); |
458 } | 458 } |
459 v8::internal::CompilationCache::Clear(); | 459 i::CompilationCache::Clear(); |
460 v8::internal::Heap::CollectAllGarbage(false); | 460 i::Heap::CollectAllGarbage(false); |
461 CHECK_EQ(1, TestAsciiResource::dispose_count); | 461 CHECK_EQ(1, TestAsciiResource::dispose_count); |
462 } | 462 } |
463 | 463 |
464 | 464 |
465 TEST(MakingExternalStringConditions) { | 465 TEST(MakingExternalStringConditions) { |
466 v8::HandleScope scope; | 466 v8::HandleScope scope; |
467 LocalContext env; | 467 LocalContext env; |
468 | 468 |
469 // Free some space in the new space so that we can check freshness. | 469 // Free some space in the new space so that we can check freshness. |
470 i::Heap::CollectGarbage(0, i::NEW_SPACE); | 470 i::Heap::CollectGarbage(0, i::NEW_SPACE); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 638 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
639 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); | 639 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); |
640 { | 640 { |
641 v8::HandleScope scope; | 641 v8::HandleScope scope; |
642 LocalContext env; | 642 LocalContext env; |
643 Local<String> source = String::NewExternal(&res_stack); | 643 Local<String> source = String::NewExternal(&res_stack); |
644 Local<Script> script = Script::Compile(source); | 644 Local<Script> script = Script::Compile(source); |
645 Local<Value> value = script->Run(); | 645 Local<Value> value = script->Run(); |
646 CHECK(value->IsNumber()); | 646 CHECK(value->IsNumber()); |
647 CHECK_EQ(7, value->Int32Value()); | 647 CHECK_EQ(7, value->Int32Value()); |
648 v8::internal::Heap::CollectAllGarbage(false); | 648 i::Heap::CollectAllGarbage(false); |
649 CHECK_EQ(0, TestAsciiResource::dispose_count); | 649 CHECK_EQ(0, TestAsciiResource::dispose_count); |
650 } | 650 } |
651 v8::internal::CompilationCache::Clear(); | 651 i::CompilationCache::Clear(); |
652 v8::internal::Heap::CollectAllGarbage(false); | 652 i::Heap::CollectAllGarbage(false); |
653 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 653 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
654 CHECK_EQ(0, TestAsciiResource::dispose_count); | 654 CHECK_EQ(0, TestAsciiResource::dispose_count); |
655 | 655 |
656 // Use a heap allocated external string resource allocated object. | 656 // Use a heap allocated external string resource allocated object. |
657 TestAsciiResource::dispose_count = 0; | 657 TestAsciiResource::dispose_count = 0; |
658 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 658 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
659 TestAsciiResource* res_heap = | 659 TestAsciiResource* res_heap = |
660 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); | 660 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); |
661 { | 661 { |
662 v8::HandleScope scope; | 662 v8::HandleScope scope; |
663 LocalContext env; | 663 LocalContext env; |
664 Local<String> source = String::NewExternal(res_heap); | 664 Local<String> source = String::NewExternal(res_heap); |
665 Local<Script> script = Script::Compile(source); | 665 Local<Script> script = Script::Compile(source); |
666 Local<Value> value = script->Run(); | 666 Local<Value> value = script->Run(); |
667 CHECK(value->IsNumber()); | 667 CHECK(value->IsNumber()); |
668 CHECK_EQ(7, value->Int32Value()); | 668 CHECK_EQ(7, value->Int32Value()); |
669 v8::internal::Heap::CollectAllGarbage(false); | 669 i::Heap::CollectAllGarbage(false); |
670 CHECK_EQ(0, TestAsciiResource::dispose_count); | 670 CHECK_EQ(0, TestAsciiResource::dispose_count); |
671 } | 671 } |
672 v8::internal::CompilationCache::Clear(); | 672 i::CompilationCache::Clear(); |
673 v8::internal::Heap::CollectAllGarbage(false); | 673 i::Heap::CollectAllGarbage(false); |
674 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 674 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
675 CHECK_EQ(1, TestAsciiResource::dispose_count); | 675 CHECK_EQ(1, TestAsciiResource::dispose_count); |
676 } | 676 } |
677 | 677 |
678 | 678 |
679 THREADED_TEST(StringConcat) { | 679 THREADED_TEST(StringConcat) { |
680 { | 680 { |
681 v8::HandleScope scope; | 681 v8::HandleScope scope; |
682 LocalContext env; | 682 LocalContext env; |
683 const char* one_byte_string_1 = "function a_times_t"; | 683 const char* one_byte_string_1 = "function a_times_t"; |
(...skipping 17 matching lines...) Expand all Loading... |
701 right = String::New(AsciiToTwoByteString(two_byte_string_2)); | 701 right = String::New(AsciiToTwoByteString(two_byte_string_2)); |
702 source = String::Concat(source, right); | 702 source = String::Concat(source, right); |
703 right = String::NewExternal( | 703 right = String::NewExternal( |
704 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); | 704 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); |
705 source = String::Concat(source, right); | 705 source = String::Concat(source, right); |
706 Local<Script> script = Script::Compile(source); | 706 Local<Script> script = Script::Compile(source); |
707 Local<Value> value = script->Run(); | 707 Local<Value> value = script->Run(); |
708 CHECK(value->IsNumber()); | 708 CHECK(value->IsNumber()); |
709 CHECK_EQ(68, value->Int32Value()); | 709 CHECK_EQ(68, value->Int32Value()); |
710 } | 710 } |
711 v8::internal::CompilationCache::Clear(); | 711 i::CompilationCache::Clear(); |
712 i::Heap::CollectAllGarbage(false); | 712 i::Heap::CollectAllGarbage(false); |
713 i::Heap::CollectAllGarbage(false); | 713 i::Heap::CollectAllGarbage(false); |
714 } | 714 } |
715 | 715 |
716 | 716 |
717 THREADED_TEST(GlobalProperties) { | 717 THREADED_TEST(GlobalProperties) { |
718 v8::HandleScope scope; | 718 v8::HandleScope scope; |
719 LocalContext env; | 719 LocalContext env; |
720 v8::Handle<v8::Object> global = env->Global(); | 720 v8::Handle<v8::Object> global = env->Global(); |
721 global->Set(v8_str("pi"), v8_num(3.1415926)); | 721 global->Set(v8_str("pi"), v8_num(3.1415926)); |
(...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1874 | 1874 |
1875 | 1875 |
1876 static const char* js_code_causing_out_of_memory = | 1876 static const char* js_code_causing_out_of_memory = |
1877 "var a = new Array(); while(true) a.push(a);"; | 1877 "var a = new Array(); while(true) a.push(a);"; |
1878 | 1878 |
1879 | 1879 |
1880 // These tests run for a long time and prevent us from running tests | 1880 // These tests run for a long time and prevent us from running tests |
1881 // that come after them so they cannot run in parallel. | 1881 // that come after them so they cannot run in parallel. |
1882 TEST(OutOfMemory) { | 1882 TEST(OutOfMemory) { |
1883 // It's not possible to read a snapshot into a heap with different dimensions. | 1883 // It's not possible to read a snapshot into a heap with different dimensions. |
1884 if (v8::internal::Snapshot::IsEnabled()) return; | 1884 if (i::Snapshot::IsEnabled()) return; |
1885 // Set heap limits. | 1885 // Set heap limits. |
1886 static const int K = 1024; | 1886 static const int K = 1024; |
1887 v8::ResourceConstraints constraints; | 1887 v8::ResourceConstraints constraints; |
1888 constraints.set_max_young_space_size(256 * K); | 1888 constraints.set_max_young_space_size(256 * K); |
1889 constraints.set_max_old_space_size(4 * K * K); | 1889 constraints.set_max_old_space_size(4 * K * K); |
1890 v8::SetResourceConstraints(&constraints); | 1890 v8::SetResourceConstraints(&constraints); |
1891 | 1891 |
1892 // Execute a script that causes out of memory. | 1892 // Execute a script that causes out of memory. |
1893 v8::HandleScope scope; | 1893 v8::HandleScope scope; |
1894 LocalContext context; | 1894 LocalContext context; |
(...skipping 20 matching lines...) Expand all Loading... |
1915 // Check for out of memory state. | 1915 // Check for out of memory state. |
1916 CHECK(result.IsEmpty()); | 1916 CHECK(result.IsEmpty()); |
1917 CHECK(context->HasOutOfMemoryException()); | 1917 CHECK(context->HasOutOfMemoryException()); |
1918 | 1918 |
1919 return result; | 1919 return result; |
1920 } | 1920 } |
1921 | 1921 |
1922 | 1922 |
1923 TEST(OutOfMemoryNested) { | 1923 TEST(OutOfMemoryNested) { |
1924 // It's not possible to read a snapshot into a heap with different dimensions. | 1924 // It's not possible to read a snapshot into a heap with different dimensions. |
1925 if (v8::internal::Snapshot::IsEnabled()) return; | 1925 if (i::Snapshot::IsEnabled()) return; |
1926 // Set heap limits. | 1926 // Set heap limits. |
1927 static const int K = 1024; | 1927 static const int K = 1024; |
1928 v8::ResourceConstraints constraints; | 1928 v8::ResourceConstraints constraints; |
1929 constraints.set_max_young_space_size(256 * K); | 1929 constraints.set_max_young_space_size(256 * K); |
1930 constraints.set_max_old_space_size(4 * K * K); | 1930 constraints.set_max_old_space_size(4 * K * K); |
1931 v8::SetResourceConstraints(&constraints); | 1931 v8::SetResourceConstraints(&constraints); |
1932 | 1932 |
1933 v8::HandleScope scope; | 1933 v8::HandleScope scope; |
1934 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 1934 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
1935 templ->Set(v8_str("ProvokeOutOfMemory"), | 1935 templ->Set(v8_str("ProvokeOutOfMemory"), |
1936 v8::FunctionTemplate::New(ProvokeOutOfMemory)); | 1936 v8::FunctionTemplate::New(ProvokeOutOfMemory)); |
1937 LocalContext context(0, templ); | 1937 LocalContext context(0, templ); |
1938 v8::V8::IgnoreOutOfMemoryException(); | 1938 v8::V8::IgnoreOutOfMemoryException(); |
1939 Local<Value> result = CompileRun( | 1939 Local<Value> result = CompileRun( |
1940 "var thrown = false;" | 1940 "var thrown = false;" |
1941 "try {" | 1941 "try {" |
1942 " ProvokeOutOfMemory();" | 1942 " ProvokeOutOfMemory();" |
1943 "} catch (e) {" | 1943 "} catch (e) {" |
1944 " thrown = true;" | 1944 " thrown = true;" |
1945 "}"); | 1945 "}"); |
1946 // Check for out of memory state. | 1946 // Check for out of memory state. |
1947 CHECK(result.IsEmpty()); | 1947 CHECK(result.IsEmpty()); |
1948 CHECK(context->HasOutOfMemoryException()); | 1948 CHECK(context->HasOutOfMemoryException()); |
1949 } | 1949 } |
1950 | 1950 |
1951 | 1951 |
1952 TEST(HugeConsStringOutOfMemory) { | 1952 TEST(HugeConsStringOutOfMemory) { |
1953 // It's not possible to read a snapshot into a heap with different dimensions. | 1953 // It's not possible to read a snapshot into a heap with different dimensions. |
1954 if (v8::internal::Snapshot::IsEnabled()) return; | 1954 if (i::Snapshot::IsEnabled()) return; |
1955 v8::HandleScope scope; | 1955 v8::HandleScope scope; |
1956 LocalContext context; | 1956 LocalContext context; |
1957 // Set heap limits. | 1957 // Set heap limits. |
1958 static const int K = 1024; | 1958 static const int K = 1024; |
1959 v8::ResourceConstraints constraints; | 1959 v8::ResourceConstraints constraints; |
1960 constraints.set_max_young_space_size(256 * K); | 1960 constraints.set_max_young_space_size(256 * K); |
1961 constraints.set_max_old_space_size(2 * K * K); | 1961 constraints.set_max_old_space_size(2 * K * K); |
1962 v8::SetResourceConstraints(&constraints); | 1962 v8::SetResourceConstraints(&constraints); |
1963 | 1963 |
1964 // Execute a script that causes out of memory. | 1964 // Execute a script that causes out of memory. |
(...skipping 4839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6804 "};"); | 6804 "};"); |
6805 CHECK_EQ(239 * 10, value->Int32Value()); | 6805 CHECK_EQ(239 * 10, value->Int32Value()); |
6806 } | 6806 } |
6807 | 6807 |
6808 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, | 6808 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, |
6809 const AccessorInfo& info) { | 6809 const AccessorInfo& info) { |
6810 ApiTestFuzzer::Fuzz(); | 6810 ApiTestFuzzer::Fuzz(); |
6811 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); | 6811 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); |
6812 ++(*call_count); | 6812 ++(*call_count); |
6813 if ((*call_count) % 20 == 0) { | 6813 if ((*call_count) % 20 == 0) { |
6814 v8::internal::Heap::CollectAllGarbage(true); | 6814 i::Heap::CollectAllGarbage(true); |
6815 } | 6815 } |
6816 return v8::Handle<Value>(); | 6816 return v8::Handle<Value>(); |
6817 } | 6817 } |
6818 | 6818 |
6819 static v8::Handle<Value> FastApiCallback_TrivialSignature( | 6819 static v8::Handle<Value> FastApiCallback_TrivialSignature( |
6820 const v8::Arguments& args) { | 6820 const v8::Arguments& args) { |
6821 ApiTestFuzzer::Fuzz(); | 6821 ApiTestFuzzer::Fuzz(); |
6822 CHECK_EQ(args.This(), args.Holder()); | 6822 CHECK_EQ(args.This(), args.Holder()); |
6823 CHECK(args.Data()->Equals(v8_str("method_data"))); | 6823 CHECK(args.Data()->Equals(v8_str("method_data"))); |
6824 return v8::Integer::New(args[0]->Int32Value() + 1); | 6824 return v8::Integer::New(args[0]->Int32Value() + 1); |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7613 CHECK(value->IsString() && value->Equals(v8_str("[object global]"))); | 7613 CHECK(value->IsString() && value->Equals(v8_str("[object global]"))); |
7614 | 7614 |
7615 // Check ordinary object | 7615 // Check ordinary object |
7616 Local<Value> object = v8_compile("new Object()")->Run(); | 7616 Local<Value> object = v8_compile("new Object()")->Run(); |
7617 value = object.As<v8::Object>()->ObjectProtoToString(); | 7617 value = object.As<v8::Object>()->ObjectProtoToString(); |
7618 CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); | 7618 CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); |
7619 } | 7619 } |
7620 | 7620 |
7621 | 7621 |
7622 bool ApiTestFuzzer::fuzzing_ = false; | 7622 bool ApiTestFuzzer::fuzzing_ = false; |
7623 v8::internal::Semaphore* ApiTestFuzzer::all_tests_done_= | 7623 i::Semaphore* ApiTestFuzzer::all_tests_done_= |
7624 v8::internal::OS::CreateSemaphore(0); | 7624 i::OS::CreateSemaphore(0); |
7625 int ApiTestFuzzer::active_tests_; | 7625 int ApiTestFuzzer::active_tests_; |
7626 int ApiTestFuzzer::tests_being_run_; | 7626 int ApiTestFuzzer::tests_being_run_; |
7627 int ApiTestFuzzer::current_; | 7627 int ApiTestFuzzer::current_; |
7628 | 7628 |
7629 | 7629 |
7630 // We are in a callback and want to switch to another thread (if we | 7630 // We are in a callback and want to switch to another thread (if we |
7631 // are currently running the thread fuzzing test). | 7631 // are currently running the thread fuzzing test). |
7632 void ApiTestFuzzer::Fuzz() { | 7632 void ApiTestFuzzer::Fuzz() { |
7633 if (!fuzzing_) return; | 7633 if (!fuzzing_) return; |
7634 ApiTestFuzzer* test = RegisterThreadedTest::nth(current_)->fuzzer_; | 7634 ApiTestFuzzer* test = RegisterThreadedTest::nth(current_)->fuzzer_; |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7892 " unlock_for_a_moment();" | 7892 " unlock_for_a_moment();" |
7893 " return 42;" | 7893 " return 42;" |
7894 "})();"); | 7894 "})();"); |
7895 CHECK_EQ(42, script->Run()->Int32Value()); | 7895 CHECK_EQ(42, script->Run()->Int32Value()); |
7896 } | 7896 } |
7897 } | 7897 } |
7898 | 7898 |
7899 | 7899 |
7900 static int GetGlobalObjectsCount() { | 7900 static int GetGlobalObjectsCount() { |
7901 int count = 0; | 7901 int count = 0; |
7902 v8::internal::HeapIterator it; | 7902 i::HeapIterator it; |
7903 for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) | 7903 for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) |
7904 if (object->IsJSGlobalObject()) count++; | 7904 if (object->IsJSGlobalObject()) count++; |
7905 return count; | 7905 return count; |
7906 } | 7906 } |
7907 | 7907 |
7908 | 7908 |
7909 static int GetSurvivingGlobalObjectsCount() { | 7909 static int GetSurvivingGlobalObjectsCount() { |
7910 // We need to collect all garbage twice to be sure that everything | 7910 // We need to collect all garbage twice to be sure that everything |
7911 // has been collected. This is because inline caches are cleared in | 7911 // has been collected. This is because inline caches are cleared in |
7912 // the first garbage collection but some of the maps have already | 7912 // the first garbage collection but some of the maps have already |
7913 // been marked at that point. Therefore some of the maps are not | 7913 // been marked at that point. Therefore some of the maps are not |
7914 // collected until the second garbage collection. | 7914 // collected until the second garbage collection. |
7915 v8::internal::Heap::CollectAllGarbage(false); | 7915 i::Heap::CollectAllGarbage(false); |
7916 v8::internal::Heap::CollectAllGarbage(false); | 7916 i::Heap::CollectAllGarbage(false); |
7917 int count = GetGlobalObjectsCount(); | 7917 int count = GetGlobalObjectsCount(); |
7918 #ifdef DEBUG | 7918 #ifdef DEBUG |
7919 if (count > 0) v8::internal::Heap::TracePathToGlobal(); | 7919 if (count > 0) i::Heap::TracePathToGlobal(); |
7920 #endif | 7920 #endif |
7921 return count; | 7921 return count; |
7922 } | 7922 } |
7923 | 7923 |
7924 | 7924 |
7925 TEST(DontLeakGlobalObjects) { | 7925 TEST(DontLeakGlobalObjects) { |
7926 // Regression test for issues 1139850 and 1174891. | 7926 // Regression test for issues 1139850 and 1174891. |
7927 | 7927 |
7928 v8::V8::Initialize(); | 7928 v8::V8::Initialize(); |
7929 | 7929 |
(...skipping 2084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10014 "!failed;"); | 10014 "!failed;"); |
10015 CHECK_EQ(true, result->BooleanValue()); | 10015 CHECK_EQ(true, result->BooleanValue()); |
10016 free(large_array_data); | 10016 free(large_array_data); |
10017 } | 10017 } |
10018 | 10018 |
10019 free(array_data); | 10019 free(array_data); |
10020 } | 10020 } |
10021 | 10021 |
10022 | 10022 |
10023 THREADED_TEST(ExternalByteArray) { | 10023 THREADED_TEST(ExternalByteArray) { |
10024 ExternalArrayTestHelper<v8::internal::ExternalByteArray, int8_t>( | 10024 ExternalArrayTestHelper<i::ExternalByteArray, int8_t>( |
10025 v8::kExternalByteArray, | 10025 v8::kExternalByteArray, |
10026 -128, | 10026 -128, |
10027 127); | 10027 127); |
10028 } | 10028 } |
10029 | 10029 |
10030 | 10030 |
10031 THREADED_TEST(ExternalUnsignedByteArray) { | 10031 THREADED_TEST(ExternalUnsignedByteArray) { |
10032 ExternalArrayTestHelper<v8::internal::ExternalUnsignedByteArray, uint8_t>( | 10032 ExternalArrayTestHelper<i::ExternalUnsignedByteArray, uint8_t>( |
10033 v8::kExternalUnsignedByteArray, | 10033 v8::kExternalUnsignedByteArray, |
10034 0, | 10034 0, |
10035 255); | 10035 255); |
10036 } | 10036 } |
10037 | 10037 |
10038 | 10038 |
10039 THREADED_TEST(ExternalShortArray) { | 10039 THREADED_TEST(ExternalShortArray) { |
10040 ExternalArrayTestHelper<v8::internal::ExternalShortArray, int16_t>( | 10040 ExternalArrayTestHelper<i::ExternalShortArray, int16_t>( |
10041 v8::kExternalShortArray, | 10041 v8::kExternalShortArray, |
10042 -32768, | 10042 -32768, |
10043 32767); | 10043 32767); |
10044 } | 10044 } |
10045 | 10045 |
10046 | 10046 |
10047 THREADED_TEST(ExternalUnsignedShortArray) { | 10047 THREADED_TEST(ExternalUnsignedShortArray) { |
10048 ExternalArrayTestHelper<v8::internal::ExternalUnsignedShortArray, uint16_t>( | 10048 ExternalArrayTestHelper<i::ExternalUnsignedShortArray, uint16_t>( |
10049 v8::kExternalUnsignedShortArray, | 10049 v8::kExternalUnsignedShortArray, |
10050 0, | 10050 0, |
10051 65535); | 10051 65535); |
10052 } | 10052 } |
10053 | 10053 |
10054 | 10054 |
10055 THREADED_TEST(ExternalIntArray) { | 10055 THREADED_TEST(ExternalIntArray) { |
10056 ExternalArrayTestHelper<v8::internal::ExternalIntArray, int32_t>( | 10056 ExternalArrayTestHelper<i::ExternalIntArray, int32_t>( |
10057 v8::kExternalIntArray, | 10057 v8::kExternalIntArray, |
10058 INT_MIN, // -2147483648 | 10058 INT_MIN, // -2147483648 |
10059 INT_MAX); // 2147483647 | 10059 INT_MAX); // 2147483647 |
10060 } | 10060 } |
10061 | 10061 |
10062 | 10062 |
10063 THREADED_TEST(ExternalUnsignedIntArray) { | 10063 THREADED_TEST(ExternalUnsignedIntArray) { |
10064 ExternalArrayTestHelper<v8::internal::ExternalUnsignedIntArray, uint32_t>( | 10064 ExternalArrayTestHelper<i::ExternalUnsignedIntArray, uint32_t>( |
10065 v8::kExternalUnsignedIntArray, | 10065 v8::kExternalUnsignedIntArray, |
10066 0, | 10066 0, |
10067 UINT_MAX); // 4294967295 | 10067 UINT_MAX); // 4294967295 |
10068 } | 10068 } |
10069 | 10069 |
10070 | 10070 |
10071 THREADED_TEST(ExternalFloatArray) { | 10071 THREADED_TEST(ExternalFloatArray) { |
10072 ExternalArrayTestHelper<v8::internal::ExternalFloatArray, float>( | 10072 ExternalArrayTestHelper<i::ExternalFloatArray, float>( |
10073 v8::kExternalFloatArray, | 10073 v8::kExternalFloatArray, |
10074 -500, | 10074 -500, |
10075 500); | 10075 500); |
10076 } | 10076 } |
10077 | 10077 |
10078 | 10078 |
10079 THREADED_TEST(ExternalArrays) { | 10079 THREADED_TEST(ExternalArrays) { |
10080 TestExternalByteArray(); | 10080 TestExternalByteArray(); |
10081 TestExternalUnsignedByteArray(); | 10081 TestExternalUnsignedByteArray(); |
10082 TestExternalShortArray(); | 10082 TestExternalShortArray(); |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10540 Local<v8::String> obj = v8::String::New(""); | 10540 Local<v8::String> obj = v8::String::New(""); |
10541 context->SetData(obj); | 10541 context->SetData(obj); |
10542 CompileRun(source_simple); | 10542 CompileRun(source_simple); |
10543 context->Exit(); | 10543 context->Exit(); |
10544 } | 10544 } |
10545 context.Dispose(); | 10545 context.Dispose(); |
10546 for (gc_count = 1; gc_count < 10; gc_count++) { | 10546 for (gc_count = 1; gc_count < 10; gc_count++) { |
10547 other_context->Enter(); | 10547 other_context->Enter(); |
10548 CompileRun(source_simple); | 10548 CompileRun(source_simple); |
10549 other_context->Exit(); | 10549 other_context->Exit(); |
10550 v8::internal::Heap::CollectAllGarbage(false); | 10550 i::Heap::CollectAllGarbage(false); |
10551 if (GetGlobalObjectsCount() == 1) break; | 10551 if (GetGlobalObjectsCount() == 1) break; |
10552 } | 10552 } |
10553 CHECK_GE(2, gc_count); | 10553 CHECK_GE(2, gc_count); |
10554 CHECK_EQ(1, GetGlobalObjectsCount()); | 10554 CHECK_EQ(1, GetGlobalObjectsCount()); |
10555 | 10555 |
10556 // Eval in a function creates reference from the compilation cache to the | 10556 // Eval in a function creates reference from the compilation cache to the |
10557 // global object. | 10557 // global object. |
10558 const char* source_eval = "function f(){eval('1')}; f()"; | 10558 const char* source_eval = "function f(){eval('1')}; f()"; |
10559 context = Context::New(); | 10559 context = Context::New(); |
10560 { | 10560 { |
10561 v8::HandleScope scope; | 10561 v8::HandleScope scope; |
10562 | 10562 |
10563 context->Enter(); | 10563 context->Enter(); |
10564 CompileRun(source_eval); | 10564 CompileRun(source_eval); |
10565 context->Exit(); | 10565 context->Exit(); |
10566 } | 10566 } |
10567 context.Dispose(); | 10567 context.Dispose(); |
10568 for (gc_count = 1; gc_count < 10; gc_count++) { | 10568 for (gc_count = 1; gc_count < 10; gc_count++) { |
10569 other_context->Enter(); | 10569 other_context->Enter(); |
10570 CompileRun(source_eval); | 10570 CompileRun(source_eval); |
10571 other_context->Exit(); | 10571 other_context->Exit(); |
10572 v8::internal::Heap::CollectAllGarbage(false); | 10572 i::Heap::CollectAllGarbage(false); |
10573 if (GetGlobalObjectsCount() == 1) break; | 10573 if (GetGlobalObjectsCount() == 1) break; |
10574 } | 10574 } |
10575 CHECK_GE(2, gc_count); | 10575 CHECK_GE(2, gc_count); |
10576 CHECK_EQ(1, GetGlobalObjectsCount()); | 10576 CHECK_EQ(1, GetGlobalObjectsCount()); |
10577 | 10577 |
10578 // Looking up the line number for an exception creates reference from the | 10578 // Looking up the line number for an exception creates reference from the |
10579 // compilation cache to the global object. | 10579 // compilation cache to the global object. |
10580 const char* source_exception = "function f(){throw 1;} f()"; | 10580 const char* source_exception = "function f(){throw 1;} f()"; |
10581 context = Context::New(); | 10581 context = Context::New(); |
10582 { | 10582 { |
10583 v8::HandleScope scope; | 10583 v8::HandleScope scope; |
10584 | 10584 |
10585 context->Enter(); | 10585 context->Enter(); |
10586 v8::TryCatch try_catch; | 10586 v8::TryCatch try_catch; |
10587 CompileRun(source_exception); | 10587 CompileRun(source_exception); |
10588 CHECK(try_catch.HasCaught()); | 10588 CHECK(try_catch.HasCaught()); |
10589 v8::Handle<v8::Message> message = try_catch.Message(); | 10589 v8::Handle<v8::Message> message = try_catch.Message(); |
10590 CHECK(!message.IsEmpty()); | 10590 CHECK(!message.IsEmpty()); |
10591 CHECK_EQ(1, message->GetLineNumber()); | 10591 CHECK_EQ(1, message->GetLineNumber()); |
10592 context->Exit(); | 10592 context->Exit(); |
10593 } | 10593 } |
10594 context.Dispose(); | 10594 context.Dispose(); |
10595 for (gc_count = 1; gc_count < 10; gc_count++) { | 10595 for (gc_count = 1; gc_count < 10; gc_count++) { |
10596 other_context->Enter(); | 10596 other_context->Enter(); |
10597 CompileRun(source_exception); | 10597 CompileRun(source_exception); |
10598 other_context->Exit(); | 10598 other_context->Exit(); |
10599 v8::internal::Heap::CollectAllGarbage(false); | 10599 i::Heap::CollectAllGarbage(false); |
10600 if (GetGlobalObjectsCount() == 1) break; | 10600 if (GetGlobalObjectsCount() == 1) break; |
10601 } | 10601 } |
10602 CHECK_GE(2, gc_count); | 10602 CHECK_GE(2, gc_count); |
10603 CHECK_EQ(1, GetGlobalObjectsCount()); | 10603 CHECK_EQ(1, GetGlobalObjectsCount()); |
10604 | 10604 |
10605 other_context.Dispose(); | 10605 other_context.Dispose(); |
10606 } | 10606 } |
10607 | 10607 |
10608 | 10608 |
10609 THREADED_TEST(ScriptOrigin) { | 10609 THREADED_TEST(ScriptOrigin) { |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10852 " var r0 = %_GetFromCache(0, key0);" | 10852 " var r0 = %_GetFromCache(0, key0);" |
10853 " var r1 = %_GetFromCache(0, key1);" | 10853 " var r1 = %_GetFromCache(0, key1);" |
10854 " var r0_ = %_GetFromCache(0, key0);" | 10854 " var r0_ = %_GetFromCache(0, key0);" |
10855 " if (r0 !== r0_)" | 10855 " if (r0 !== r0_)" |
10856 " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" | 10856 " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" |
10857 " var r1_ = %_GetFromCache(0, key1);" | 10857 " var r1_ = %_GetFromCache(0, key1);" |
10858 " if (r1 !== r1_)" | 10858 " if (r1 !== r1_)" |
10859 " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" | 10859 " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" |
10860 " return 'PASSED';" | 10860 " return 'PASSED';" |
10861 "})()"; | 10861 "})()"; |
10862 v8::internal::Heap::ClearJSFunctionResultCaches(); | 10862 i::Heap::ClearJSFunctionResultCaches(); |
10863 ExpectString(code, "PASSED"); | 10863 ExpectString(code, "PASSED"); |
10864 } | 10864 } |
10865 | 10865 |
10866 | 10866 |
10867 static const int k0CacheSize = 16; | 10867 static const int k0CacheSize = 16; |
10868 | 10868 |
10869 THREADED_TEST(FillJSFunctionResultCache) { | 10869 THREADED_TEST(FillJSFunctionResultCache) { |
10870 i::FLAG_allow_natives_syntax = true; | 10870 i::FLAG_allow_natives_syntax = true; |
10871 v8::HandleScope scope; | 10871 v8::HandleScope scope; |
10872 | 10872 |
10873 LocalContext context; | 10873 LocalContext context; |
10874 | 10874 |
10875 const char* code = | 10875 const char* code = |
10876 "(function() {" | 10876 "(function() {" |
10877 " var k = 'a';" | 10877 " var k = 'a';" |
10878 " var r = %_GetFromCache(0, k);" | 10878 " var r = %_GetFromCache(0, k);" |
10879 " for (var i = 0; i < 16; i++) {" | 10879 " for (var i = 0; i < 16; i++) {" |
10880 " %_GetFromCache(0, 'a' + i);" | 10880 " %_GetFromCache(0, 'a' + i);" |
10881 " };" | 10881 " };" |
10882 " if (r === %_GetFromCache(0, k))" | 10882 " if (r === %_GetFromCache(0, k))" |
10883 " return 'FAILED: k0CacheSize is too small';" | 10883 " return 'FAILED: k0CacheSize is too small';" |
10884 " return 'PASSED';" | 10884 " return 'PASSED';" |
10885 "})()"; | 10885 "})()"; |
10886 v8::internal::Heap::ClearJSFunctionResultCaches(); | 10886 i::Heap::ClearJSFunctionResultCaches(); |
10887 ExpectString(code, "PASSED"); | 10887 ExpectString(code, "PASSED"); |
10888 } | 10888 } |
10889 | 10889 |
10890 | 10890 |
10891 THREADED_TEST(RoundRobinGetFromCache) { | 10891 THREADED_TEST(RoundRobinGetFromCache) { |
10892 i::FLAG_allow_natives_syntax = true; | 10892 i::FLAG_allow_natives_syntax = true; |
10893 v8::HandleScope scope; | 10893 v8::HandleScope scope; |
10894 | 10894 |
10895 LocalContext context; | 10895 LocalContext context; |
10896 | 10896 |
10897 const char* code = | 10897 const char* code = |
10898 "(function() {" | 10898 "(function() {" |
10899 " var keys = [];" | 10899 " var keys = [];" |
10900 " for (var i = 0; i < 16; i++) keys.push(i);" | 10900 " for (var i = 0; i < 16; i++) keys.push(i);" |
10901 " var values = [];" | 10901 " var values = [];" |
10902 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" | 10902 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" |
10903 " for (var i = 0; i < 16; i++) {" | 10903 " for (var i = 0; i < 16; i++) {" |
10904 " var v = %_GetFromCache(0, keys[i]);" | 10904 " var v = %_GetFromCache(0, keys[i]);" |
10905 " if (v !== values[i])" | 10905 " if (v !== values[i])" |
10906 " return 'Wrong value for ' + " | 10906 " return 'Wrong value for ' + " |
10907 " keys[i] + ': ' + v + ' vs. ' + values[i];" | 10907 " keys[i] + ': ' + v + ' vs. ' + values[i];" |
10908 " };" | 10908 " };" |
10909 " return 'PASSED';" | 10909 " return 'PASSED';" |
10910 "})()"; | 10910 "})()"; |
10911 v8::internal::Heap::ClearJSFunctionResultCaches(); | 10911 i::Heap::ClearJSFunctionResultCaches(); |
10912 ExpectString(code, "PASSED"); | 10912 ExpectString(code, "PASSED"); |
10913 } | 10913 } |
10914 | 10914 |
10915 | 10915 |
10916 THREADED_TEST(ReverseGetFromCache) { | 10916 THREADED_TEST(ReverseGetFromCache) { |
10917 i::FLAG_allow_natives_syntax = true; | 10917 i::FLAG_allow_natives_syntax = true; |
10918 v8::HandleScope scope; | 10918 v8::HandleScope scope; |
10919 | 10919 |
10920 LocalContext context; | 10920 LocalContext context; |
10921 | 10921 |
10922 const char* code = | 10922 const char* code = |
10923 "(function() {" | 10923 "(function() {" |
10924 " var keys = [];" | 10924 " var keys = [];" |
10925 " for (var i = 0; i < 16; i++) keys.push(i);" | 10925 " for (var i = 0; i < 16; i++) keys.push(i);" |
10926 " var values = [];" | 10926 " var values = [];" |
10927 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" | 10927 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" |
10928 " for (var i = 15; i >= 16; i--) {" | 10928 " for (var i = 15; i >= 16; i--) {" |
10929 " var v = %_GetFromCache(0, keys[i]);" | 10929 " var v = %_GetFromCache(0, keys[i]);" |
10930 " if (v !== values[i])" | 10930 " if (v !== values[i])" |
10931 " return 'Wrong value for ' + " | 10931 " return 'Wrong value for ' + " |
10932 " keys[i] + ': ' + v + ' vs. ' + values[i];" | 10932 " keys[i] + ': ' + v + ' vs. ' + values[i];" |
10933 " };" | 10933 " };" |
10934 " return 'PASSED';" | 10934 " return 'PASSED';" |
10935 "})()"; | 10935 "})()"; |
10936 v8::internal::Heap::ClearJSFunctionResultCaches(); | 10936 i::Heap::ClearJSFunctionResultCaches(); |
10937 ExpectString(code, "PASSED"); | 10937 ExpectString(code, "PASSED"); |
10938 } | 10938 } |
10939 | 10939 |
10940 | 10940 |
10941 THREADED_TEST(TestEviction) { | 10941 THREADED_TEST(TestEviction) { |
10942 i::FLAG_allow_natives_syntax = true; | 10942 i::FLAG_allow_natives_syntax = true; |
10943 v8::HandleScope scope; | 10943 v8::HandleScope scope; |
10944 | 10944 |
10945 LocalContext context; | 10945 LocalContext context; |
10946 | 10946 |
10947 const char* code = | 10947 const char* code = |
10948 "(function() {" | 10948 "(function() {" |
10949 " for (var i = 0; i < 2*16; i++) {" | 10949 " for (var i = 0; i < 2*16; i++) {" |
10950 " %_GetFromCache(0, 'a' + i);" | 10950 " %_GetFromCache(0, 'a' + i);" |
10951 " };" | 10951 " };" |
10952 " return 'PASSED';" | 10952 " return 'PASSED';" |
10953 "})()"; | 10953 "})()"; |
10954 v8::internal::Heap::ClearJSFunctionResultCaches(); | 10954 i::Heap::ClearJSFunctionResultCaches(); |
10955 ExpectString(code, "PASSED"); | 10955 ExpectString(code, "PASSED"); |
10956 } | 10956 } |
| 10957 |
| 10958 |
| 10959 THREADED_TEST(TwoByteStringInAsciiCons) { |
| 10960 // See Chromium issue 47824. |
| 10961 v8::HandleScope scope; |
| 10962 |
| 10963 LocalContext context; |
| 10964 const char* init_code = |
| 10965 "var str1 = 'abelspendabel';" |
| 10966 "var str2 = str1 + str1 + str1;" |
| 10967 "str2;"; |
| 10968 Local<Value> result = CompileRun(init_code); |
| 10969 |
| 10970 CHECK(result->IsString()); |
| 10971 i::Handle<i::String> string = v8::Utils::OpenHandle(String::Cast(*result)); |
| 10972 int length = string->length(); |
| 10973 CHECK(string->IsAsciiRepresentation()); |
| 10974 |
| 10975 FlattenString(string); |
| 10976 i::Handle<i::String> flat_string = FlattenGetString(string); |
| 10977 |
| 10978 CHECK(string->IsAsciiRepresentation()); |
| 10979 CHECK(flat_string->IsAsciiRepresentation()); |
| 10980 |
| 10981 // Create external resource. |
| 10982 uint16_t* uc16_buffer = new uint16_t[length + 1]; |
| 10983 |
| 10984 i::String::WriteToFlat(*flat_string, uc16_buffer, 0, length); |
| 10985 uc16_buffer[length] = 0; |
| 10986 |
| 10987 TestResource resource(uc16_buffer); |
| 10988 |
| 10989 flat_string->MakeExternal(&resource); |
| 10990 |
| 10991 CHECK(flat_string->IsTwoByteRepresentation()); |
| 10992 |
| 10993 // At this point, we should have a Cons string which is flat and ASCII, |
| 10994 // with a first half that is a two-byte string (although it only contains |
| 10995 // ASCII characters). This is a valid sequence of steps, and it can happen |
| 10996 // in real pages. |
| 10997 |
| 10998 CHECK(string->IsAsciiRepresentation()); |
| 10999 i::ConsString* cons = i::ConsString::cast(*string); |
| 11000 CHECK_EQ(0, cons->second()->length()); |
| 11001 CHECK(cons->first()->IsTwoByteRepresentation()); |
| 11002 |
| 11003 // Check that some string operations work. |
| 11004 |
| 11005 // Atom RegExp. |
| 11006 Local<Value> reresult = CompileRun("str2.match(/abel/g).length;"); |
| 11007 CHECK_EQ(6, reresult->Int32Value()); |
| 11008 |
| 11009 // Nonatom RegExp. |
| 11010 reresult = CompileRun("str2.match(/abe./g).length;"); |
| 11011 CHECK_EQ(6, reresult->Int32Value()); |
| 11012 |
| 11013 reresult = CompileRun("str2.search(/bel/g);"); |
| 11014 CHECK_EQ(1, reresult->Int32Value()); |
| 11015 |
| 11016 reresult = CompileRun("str2.search(/be./g);"); |
| 11017 CHECK_EQ(1, reresult->Int32Value()); |
| 11018 |
| 11019 ExpectTrue("/bel/g.test(str2);"); |
| 11020 |
| 11021 ExpectTrue("/be./g.test(str2);"); |
| 11022 |
| 11023 reresult = CompileRun("/bel/g.exec(str2);"); |
| 11024 CHECK(!reresult->IsNull()); |
| 11025 |
| 11026 reresult = CompileRun("/be./g.exec(str2);"); |
| 11027 CHECK(!reresult->IsNull()); |
| 11028 |
| 11029 ExpectString("str2.substring(2, 10);", "elspenda"); |
| 11030 |
| 11031 ExpectString("str2.substring(2, 20);", "elspendabelabelspe"); |
| 11032 |
| 11033 ExpectString("str2.charAt(2);", "e"); |
| 11034 |
| 11035 reresult = CompileRun("str2.charCodeAt(2);"); |
| 11036 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); |
| 11037 } |
OLD | NEW |