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