| 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 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 #include <limits.h> | 28 #include <limits.h> |
| 29 | 29 |
| 30 #include "v8.h" | 30 #include "v8.h" |
| 31 | 31 |
| 32 #include "api.h" | 32 #include "api.h" |
| 33 #include "compilation-cache.h" | 33 #include "compilation-cache.h" |
| 34 #include "execution.h" | 34 #include "execution.h" |
| 35 #include "snapshot.h" | 35 #include "snapshot.h" |
| 36 #include "platform.h" | 36 #include "platform.h" |
| 37 #include "top.h" | |
| 38 #include "utils.h" | 37 #include "utils.h" |
| 39 #include "cctest.h" | 38 #include "cctest.h" |
| 40 #include "parser.h" | 39 #include "parser.h" |
| 41 #include "unicode-inl.h" | 40 #include "unicode-inl.h" |
| 42 | 41 |
| 43 static const bool kLogThreading = true; | 42 static const bool kLogThreading = true; |
| 44 | 43 |
| 45 static bool IsNaN(double x) { | 44 static bool IsNaN(double x) { |
| 46 #ifdef WIN32 | 45 #ifdef WIN32 |
| 47 return _isnan(x); | 46 return _isnan(x); |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 LocalContext env; | 390 LocalContext env; |
| 392 TestResource* resource = new TestResource(two_byte_source); | 391 TestResource* resource = new TestResource(two_byte_source); |
| 393 Local<String> source = String::NewExternal(resource); | 392 Local<String> source = String::NewExternal(resource); |
| 394 Local<Script> script = Script::Compile(source); | 393 Local<Script> script = Script::Compile(source); |
| 395 Local<Value> value = script->Run(); | 394 Local<Value> value = script->Run(); |
| 396 CHECK(value->IsNumber()); | 395 CHECK(value->IsNumber()); |
| 397 CHECK_EQ(7, value->Int32Value()); | 396 CHECK_EQ(7, value->Int32Value()); |
| 398 CHECK(source->IsExternal()); | 397 CHECK(source->IsExternal()); |
| 399 CHECK_EQ(resource, | 398 CHECK_EQ(resource, |
| 400 static_cast<TestResource*>(source->GetExternalStringResource())); | 399 static_cast<TestResource*>(source->GetExternalStringResource())); |
| 401 i::Heap::CollectAllGarbage(false); | 400 HEAP->CollectAllGarbage(false); |
| 402 CHECK_EQ(0, TestResource::dispose_count); | 401 CHECK_EQ(0, TestResource::dispose_count); |
| 403 } | 402 } |
| 404 i::CompilationCache::Clear(); | 403 v8::internal::Isolate::Current()->compilation_cache()->Clear(); |
| 405 i::Heap::CollectAllGarbage(false); | 404 HEAP->CollectAllGarbage(false); |
| 406 CHECK_EQ(1, TestResource::dispose_count); | 405 CHECK_EQ(1, TestResource::dispose_count); |
| 407 } | 406 } |
| 408 | 407 |
| 409 | 408 |
| 410 THREADED_TEST(ScriptUsingAsciiStringResource) { | 409 THREADED_TEST(ScriptUsingAsciiStringResource) { |
| 411 TestAsciiResource::dispose_count = 0; | 410 TestAsciiResource::dispose_count = 0; |
| 412 const char* c_source = "1 + 2 * 3"; | 411 const char* c_source = "1 + 2 * 3"; |
| 413 { | 412 { |
| 414 v8::HandleScope scope; | 413 v8::HandleScope scope; |
| 415 LocalContext env; | 414 LocalContext env; |
| 416 Local<String> source = | 415 Local<String> source = |
| 417 String::NewExternal(new TestAsciiResource(i::StrDup(c_source))); | 416 String::NewExternal(new TestAsciiResource(i::StrDup(c_source))); |
| 418 Local<Script> script = Script::Compile(source); | 417 Local<Script> script = Script::Compile(source); |
| 419 Local<Value> value = script->Run(); | 418 Local<Value> value = script->Run(); |
| 420 CHECK(value->IsNumber()); | 419 CHECK(value->IsNumber()); |
| 421 CHECK_EQ(7, value->Int32Value()); | 420 CHECK_EQ(7, value->Int32Value()); |
| 422 i::Heap::CollectAllGarbage(false); | 421 HEAP->CollectAllGarbage(false); |
| 423 CHECK_EQ(0, TestAsciiResource::dispose_count); | 422 CHECK_EQ(0, TestAsciiResource::dispose_count); |
| 424 } | 423 } |
| 425 i::CompilationCache::Clear(); | 424 i::Isolate::Current()->compilation_cache()->Clear(); |
| 426 i::Heap::CollectAllGarbage(false); | 425 HEAP->CollectAllGarbage(false); |
| 427 CHECK_EQ(1, TestAsciiResource::dispose_count); | 426 CHECK_EQ(1, TestAsciiResource::dispose_count); |
| 428 } | 427 } |
| 429 | 428 |
| 430 | 429 |
| 431 THREADED_TEST(ScriptMakingExternalString) { | 430 THREADED_TEST(ScriptMakingExternalString) { |
| 432 TestResource::dispose_count = 0; | 431 TestResource::dispose_count = 0; |
| 433 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); | 432 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); |
| 434 { | 433 { |
| 435 v8::HandleScope scope; | 434 v8::HandleScope scope; |
| 436 LocalContext env; | 435 LocalContext env; |
| 437 Local<String> source = String::New(two_byte_source); | 436 Local<String> source = String::New(two_byte_source); |
| 438 // Trigger GCs so that the newly allocated string moves to old gen. | 437 // Trigger GCs so that the newly allocated string moves to old gen. |
| 439 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 438 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 440 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 439 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 441 bool success = source->MakeExternal(new TestResource(two_byte_source)); | 440 bool success = source->MakeExternal(new TestResource(two_byte_source)); |
| 442 CHECK(success); | 441 CHECK(success); |
| 443 Local<Script> script = Script::Compile(source); | 442 Local<Script> script = Script::Compile(source); |
| 444 Local<Value> value = script->Run(); | 443 Local<Value> value = script->Run(); |
| 445 CHECK(value->IsNumber()); | 444 CHECK(value->IsNumber()); |
| 446 CHECK_EQ(7, value->Int32Value()); | 445 CHECK_EQ(7, value->Int32Value()); |
| 447 i::Heap::CollectAllGarbage(false); | 446 HEAP->CollectAllGarbage(false); |
| 448 CHECK_EQ(0, TestResource::dispose_count); | 447 CHECK_EQ(0, TestResource::dispose_count); |
| 449 } | 448 } |
| 450 i::CompilationCache::Clear(); | 449 i::Isolate::Current()->compilation_cache()->Clear(); |
| 451 i::Heap::CollectAllGarbage(false); | 450 HEAP->CollectAllGarbage(false); |
| 452 CHECK_EQ(1, TestResource::dispose_count); | 451 CHECK_EQ(1, TestResource::dispose_count); |
| 453 } | 452 } |
| 454 | 453 |
| 455 | 454 |
| 456 THREADED_TEST(ScriptMakingExternalAsciiString) { | 455 THREADED_TEST(ScriptMakingExternalAsciiString) { |
| 457 TestAsciiResource::dispose_count = 0; | 456 TestAsciiResource::dispose_count = 0; |
| 458 const char* c_source = "1 + 2 * 3"; | 457 const char* c_source = "1 + 2 * 3"; |
| 459 { | 458 { |
| 460 v8::HandleScope scope; | 459 v8::HandleScope scope; |
| 461 LocalContext env; | 460 LocalContext env; |
| 462 Local<String> source = v8_str(c_source); | 461 Local<String> source = v8_str(c_source); |
| 463 // Trigger GCs so that the newly allocated string moves to old gen. | 462 // Trigger GCs so that the newly allocated string moves to old gen. |
| 464 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 463 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 465 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 464 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 466 bool success = source->MakeExternal( | 465 bool success = source->MakeExternal( |
| 467 new TestAsciiResource(i::StrDup(c_source))); | 466 new TestAsciiResource(i::StrDup(c_source))); |
| 468 CHECK(success); | 467 CHECK(success); |
| 469 Local<Script> script = Script::Compile(source); | 468 Local<Script> script = Script::Compile(source); |
| 470 Local<Value> value = script->Run(); | 469 Local<Value> value = script->Run(); |
| 471 CHECK(value->IsNumber()); | 470 CHECK(value->IsNumber()); |
| 472 CHECK_EQ(7, value->Int32Value()); | 471 CHECK_EQ(7, value->Int32Value()); |
| 473 i::Heap::CollectAllGarbage(false); | 472 HEAP->CollectAllGarbage(false); |
| 474 CHECK_EQ(0, TestAsciiResource::dispose_count); | 473 CHECK_EQ(0, TestAsciiResource::dispose_count); |
| 475 } | 474 } |
| 476 i::CompilationCache::Clear(); | 475 i::Isolate::Current()->compilation_cache()->Clear(); |
| 477 i::Heap::CollectAllGarbage(false); | 476 HEAP->CollectAllGarbage(false); |
| 478 CHECK_EQ(1, TestAsciiResource::dispose_count); | 477 CHECK_EQ(1, TestAsciiResource::dispose_count); |
| 479 } | 478 } |
| 480 | 479 |
| 481 | 480 |
| 482 TEST(MakingExternalStringConditions) { | 481 TEST(MakingExternalStringConditions) { |
| 483 v8::HandleScope scope; | 482 v8::HandleScope scope; |
| 484 LocalContext env; | 483 LocalContext env; |
| 485 | 484 |
| 486 // Free some space in the new space so that we can check freshness. | 485 // Free some space in the new space so that we can check freshness. |
| 487 i::Heap::CollectGarbage(i::NEW_SPACE); | 486 HEAP->CollectGarbage(i::NEW_SPACE); |
| 488 i::Heap::CollectGarbage(i::NEW_SPACE); | 487 HEAP->CollectGarbage(i::NEW_SPACE); |
| 489 | 488 |
| 490 uint16_t* two_byte_string = AsciiToTwoByteString("small"); | 489 uint16_t* two_byte_string = AsciiToTwoByteString("small"); |
| 491 Local<String> small_string = String::New(two_byte_string); | 490 Local<String> small_string = String::New(two_byte_string); |
| 492 i::DeleteArray(two_byte_string); | 491 i::DeleteArray(two_byte_string); |
| 493 | 492 |
| 494 // We should refuse to externalize newly created small string. | 493 // We should refuse to externalize newly created small string. |
| 495 CHECK(!small_string->CanMakeExternal()); | 494 CHECK(!small_string->CanMakeExternal()); |
| 496 // Trigger GCs so that the newly allocated string moves to old gen. | 495 // Trigger GCs so that the newly allocated string moves to old gen. |
| 497 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 496 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 498 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 497 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 499 // Old space strings should be accepted. | 498 // Old space strings should be accepted. |
| 500 CHECK(small_string->CanMakeExternal()); | 499 CHECK(small_string->CanMakeExternal()); |
| 501 | 500 |
| 502 two_byte_string = AsciiToTwoByteString("small 2"); | 501 two_byte_string = AsciiToTwoByteString("small 2"); |
| 503 small_string = String::New(two_byte_string); | 502 small_string = String::New(two_byte_string); |
| 504 i::DeleteArray(two_byte_string); | 503 i::DeleteArray(two_byte_string); |
| 505 | 504 |
| 506 // We should refuse externalizing newly created small string. | 505 // We should refuse externalizing newly created small string. |
| 507 CHECK(!small_string->CanMakeExternal()); | 506 CHECK(!small_string->CanMakeExternal()); |
| 508 for (int i = 0; i < 100; i++) { | 507 for (int i = 0; i < 100; i++) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 523 // Large strings should be immediately accepted. | 522 // Large strings should be immediately accepted. |
| 524 CHECK(large_string->CanMakeExternal()); | 523 CHECK(large_string->CanMakeExternal()); |
| 525 } | 524 } |
| 526 | 525 |
| 527 | 526 |
| 528 TEST(MakingExternalAsciiStringConditions) { | 527 TEST(MakingExternalAsciiStringConditions) { |
| 529 v8::HandleScope scope; | 528 v8::HandleScope scope; |
| 530 LocalContext env; | 529 LocalContext env; |
| 531 | 530 |
| 532 // Free some space in the new space so that we can check freshness. | 531 // Free some space in the new space so that we can check freshness. |
| 533 i::Heap::CollectGarbage(i::NEW_SPACE); | 532 HEAP->CollectGarbage(i::NEW_SPACE); |
| 534 i::Heap::CollectGarbage(i::NEW_SPACE); | 533 HEAP->CollectGarbage(i::NEW_SPACE); |
| 535 | 534 |
| 536 Local<String> small_string = String::New("small"); | 535 Local<String> small_string = String::New("small"); |
| 537 // We should refuse to externalize newly created small string. | 536 // We should refuse to externalize newly created small string. |
| 538 CHECK(!small_string->CanMakeExternal()); | 537 CHECK(!small_string->CanMakeExternal()); |
| 539 // Trigger GCs so that the newly allocated string moves to old gen. | 538 // Trigger GCs so that the newly allocated string moves to old gen. |
| 540 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 539 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 541 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 540 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 542 // Old space strings should be accepted. | 541 // Old space strings should be accepted. |
| 543 CHECK(small_string->CanMakeExternal()); | 542 CHECK(small_string->CanMakeExternal()); |
| 544 | 543 |
| 545 small_string = String::New("small 2"); | 544 small_string = String::New("small 2"); |
| 546 // We should refuse externalizing newly created small string. | 545 // We should refuse externalizing newly created small string. |
| 547 CHECK(!small_string->CanMakeExternal()); | 546 CHECK(!small_string->CanMakeExternal()); |
| 548 for (int i = 0; i < 100; i++) { | 547 for (int i = 0; i < 100; i++) { |
| 549 String::Value value(small_string); | 548 String::Value value(small_string); |
| 550 } | 549 } |
| 551 // Frequently used strings should be accepted. | 550 // Frequently used strings should be accepted. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 563 | 562 |
| 564 | 563 |
| 565 THREADED_TEST(UsingExternalString) { | 564 THREADED_TEST(UsingExternalString) { |
| 566 { | 565 { |
| 567 v8::HandleScope scope; | 566 v8::HandleScope scope; |
| 568 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 567 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
| 569 Local<String> string = | 568 Local<String> string = |
| 570 String::NewExternal(new TestResource(two_byte_string)); | 569 String::NewExternal(new TestResource(two_byte_string)); |
| 571 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 570 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
| 572 // Trigger GCs so that the newly allocated string moves to old gen. | 571 // Trigger GCs so that the newly allocated string moves to old gen. |
| 573 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 572 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 574 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 573 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 575 i::Handle<i::String> isymbol = i::Factory::SymbolFromString(istring); | 574 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); |
| 576 CHECK(isymbol->IsSymbol()); | 575 CHECK(isymbol->IsSymbol()); |
| 577 } | 576 } |
| 578 i::Heap::CollectAllGarbage(false); | 577 HEAP->CollectAllGarbage(false); |
| 579 i::Heap::CollectAllGarbage(false); | 578 HEAP->CollectAllGarbage(false); |
| 580 } | 579 } |
| 581 | 580 |
| 582 | 581 |
| 583 THREADED_TEST(UsingExternalAsciiString) { | 582 THREADED_TEST(UsingExternalAsciiString) { |
| 584 { | 583 { |
| 585 v8::HandleScope scope; | 584 v8::HandleScope scope; |
| 586 const char* one_byte_string = "test string"; | 585 const char* one_byte_string = "test string"; |
| 587 Local<String> string = String::NewExternal( | 586 Local<String> string = String::NewExternal( |
| 588 new TestAsciiResource(i::StrDup(one_byte_string))); | 587 new TestAsciiResource(i::StrDup(one_byte_string))); |
| 589 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 588 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
| 590 // Trigger GCs so that the newly allocated string moves to old gen. | 589 // Trigger GCs so that the newly allocated string moves to old gen. |
| 591 i::Heap::CollectGarbage(i::NEW_SPACE); // in survivor space now | 590 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 592 i::Heap::CollectGarbage(i::NEW_SPACE); // in old gen now | 591 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 593 i::Handle<i::String> isymbol = i::Factory::SymbolFromString(istring); | 592 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); |
| 594 CHECK(isymbol->IsSymbol()); | 593 CHECK(isymbol->IsSymbol()); |
| 595 } | 594 } |
| 596 i::Heap::CollectAllGarbage(false); | 595 HEAP->CollectAllGarbage(false); |
| 597 i::Heap::CollectAllGarbage(false); | 596 HEAP->CollectAllGarbage(false); |
| 598 } | 597 } |
| 599 | 598 |
| 600 | 599 |
| 601 THREADED_TEST(ScavengeExternalString) { | 600 THREADED_TEST(ScavengeExternalString) { |
| 602 TestResource::dispose_count = 0; | 601 TestResource::dispose_count = 0; |
| 603 bool in_new_space = false; | 602 bool in_new_space = false; |
| 604 { | 603 { |
| 605 v8::HandleScope scope; | 604 v8::HandleScope scope; |
| 606 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 605 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
| 607 Local<String> string = | 606 Local<String> string = |
| 608 String::NewExternal(new TestResource(two_byte_string)); | 607 String::NewExternal(new TestResource(two_byte_string)); |
| 609 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 608 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
| 610 i::Heap::CollectGarbage(i::NEW_SPACE); | 609 HEAP->CollectGarbage(i::NEW_SPACE); |
| 611 in_new_space = i::Heap::InNewSpace(*istring); | 610 in_new_space = HEAP->InNewSpace(*istring); |
| 612 CHECK(in_new_space || i::Heap::old_data_space()->Contains(*istring)); | 611 CHECK(in_new_space || HEAP->old_data_space()->Contains(*istring)); |
| 613 CHECK_EQ(0, TestResource::dispose_count); | 612 CHECK_EQ(0, TestResource::dispose_count); |
| 614 } | 613 } |
| 615 i::Heap::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); | 614 HEAP->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); |
| 616 CHECK_EQ(1, TestResource::dispose_count); | 615 CHECK_EQ(1, TestResource::dispose_count); |
| 617 } | 616 } |
| 618 | 617 |
| 619 | 618 |
| 620 THREADED_TEST(ScavengeExternalAsciiString) { | 619 THREADED_TEST(ScavengeExternalAsciiString) { |
| 621 TestAsciiResource::dispose_count = 0; | 620 TestAsciiResource::dispose_count = 0; |
| 622 bool in_new_space = false; | 621 bool in_new_space = false; |
| 623 { | 622 { |
| 624 v8::HandleScope scope; | 623 v8::HandleScope scope; |
| 625 const char* one_byte_string = "test string"; | 624 const char* one_byte_string = "test string"; |
| 626 Local<String> string = String::NewExternal( | 625 Local<String> string = String::NewExternal( |
| 627 new TestAsciiResource(i::StrDup(one_byte_string))); | 626 new TestAsciiResource(i::StrDup(one_byte_string))); |
| 628 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 627 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
| 629 i::Heap::CollectGarbage(i::NEW_SPACE); | 628 HEAP->CollectGarbage(i::NEW_SPACE); |
| 630 in_new_space = i::Heap::InNewSpace(*istring); | 629 in_new_space = HEAP->InNewSpace(*istring); |
| 631 CHECK(in_new_space || i::Heap::old_data_space()->Contains(*istring)); | 630 CHECK(in_new_space || HEAP->old_data_space()->Contains(*istring)); |
| 632 CHECK_EQ(0, TestAsciiResource::dispose_count); | 631 CHECK_EQ(0, TestAsciiResource::dispose_count); |
| 633 } | 632 } |
| 634 i::Heap::CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); | 633 HEAP->CollectGarbage(in_new_space ? i::NEW_SPACE : i::OLD_DATA_SPACE); |
| 635 CHECK_EQ(1, TestAsciiResource::dispose_count); | 634 CHECK_EQ(1, TestAsciiResource::dispose_count); |
| 636 } | 635 } |
| 637 | 636 |
| 638 | 637 |
| 639 class TestAsciiResourceWithDisposeControl: public TestAsciiResource { | 638 class TestAsciiResourceWithDisposeControl: public TestAsciiResource { |
| 640 public: | 639 public: |
| 641 static int dispose_calls; | 640 static int dispose_calls; |
| 642 | 641 |
| 643 TestAsciiResourceWithDisposeControl(const char* data, bool dispose) | 642 TestAsciiResourceWithDisposeControl(const char* data, bool dispose) |
| 644 : TestAsciiResource(data), | 643 : TestAsciiResource(data), |
| (...skipping 19 matching lines...) Expand all Loading... |
| 664 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 663 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
| 665 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); | 664 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); |
| 666 { | 665 { |
| 667 v8::HandleScope scope; | 666 v8::HandleScope scope; |
| 668 LocalContext env; | 667 LocalContext env; |
| 669 Local<String> source = String::NewExternal(&res_stack); | 668 Local<String> source = String::NewExternal(&res_stack); |
| 670 Local<Script> script = Script::Compile(source); | 669 Local<Script> script = Script::Compile(source); |
| 671 Local<Value> value = script->Run(); | 670 Local<Value> value = script->Run(); |
| 672 CHECK(value->IsNumber()); | 671 CHECK(value->IsNumber()); |
| 673 CHECK_EQ(7, value->Int32Value()); | 672 CHECK_EQ(7, value->Int32Value()); |
| 674 i::Heap::CollectAllGarbage(false); | 673 HEAP->CollectAllGarbage(false); |
| 675 CHECK_EQ(0, TestAsciiResource::dispose_count); | 674 CHECK_EQ(0, TestAsciiResource::dispose_count); |
| 676 } | 675 } |
| 677 i::CompilationCache::Clear(); | 676 i::Isolate::Current()->compilation_cache()->Clear(); |
| 678 i::Heap::CollectAllGarbage(false); | 677 HEAP->CollectAllGarbage(false); |
| 679 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 678 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
| 680 CHECK_EQ(0, TestAsciiResource::dispose_count); | 679 CHECK_EQ(0, TestAsciiResource::dispose_count); |
| 681 | 680 |
| 682 // Use a heap allocated external string resource allocated object. | 681 // Use a heap allocated external string resource allocated object. |
| 683 TestAsciiResource::dispose_count = 0; | 682 TestAsciiResource::dispose_count = 0; |
| 684 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 683 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
| 685 TestAsciiResource* res_heap = | 684 TestAsciiResource* res_heap = |
| 686 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); | 685 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); |
| 687 { | 686 { |
| 688 v8::HandleScope scope; | 687 v8::HandleScope scope; |
| 689 LocalContext env; | 688 LocalContext env; |
| 690 Local<String> source = String::NewExternal(res_heap); | 689 Local<String> source = String::NewExternal(res_heap); |
| 691 Local<Script> script = Script::Compile(source); | 690 Local<Script> script = Script::Compile(source); |
| 692 Local<Value> value = script->Run(); | 691 Local<Value> value = script->Run(); |
| 693 CHECK(value->IsNumber()); | 692 CHECK(value->IsNumber()); |
| 694 CHECK_EQ(7, value->Int32Value()); | 693 CHECK_EQ(7, value->Int32Value()); |
| 695 i::Heap::CollectAllGarbage(false); | 694 HEAP->CollectAllGarbage(false); |
| 696 CHECK_EQ(0, TestAsciiResource::dispose_count); | 695 CHECK_EQ(0, TestAsciiResource::dispose_count); |
| 697 } | 696 } |
| 698 i::CompilationCache::Clear(); | 697 i::Isolate::Current()->compilation_cache()->Clear(); |
| 699 i::Heap::CollectAllGarbage(false); | 698 HEAP->CollectAllGarbage(false); |
| 700 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 699 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
| 701 CHECK_EQ(1, TestAsciiResource::dispose_count); | 700 CHECK_EQ(1, TestAsciiResource::dispose_count); |
| 702 } | 701 } |
| 703 | 702 |
| 704 | 703 |
| 705 THREADED_TEST(StringConcat) { | 704 THREADED_TEST(StringConcat) { |
| 706 { | 705 { |
| 707 v8::HandleScope scope; | 706 v8::HandleScope scope; |
| 708 LocalContext env; | 707 LocalContext env; |
| 709 const char* one_byte_string_1 = "function a_times_t"; | 708 const char* one_byte_string_1 = "function a_times_t"; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 735 | 734 |
| 736 source = String::Concat(source, right); | 735 source = String::Concat(source, right); |
| 737 right = String::NewExternal( | 736 right = String::NewExternal( |
| 738 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); | 737 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); |
| 739 source = String::Concat(source, right); | 738 source = String::Concat(source, right); |
| 740 Local<Script> script = Script::Compile(source); | 739 Local<Script> script = Script::Compile(source); |
| 741 Local<Value> value = script->Run(); | 740 Local<Value> value = script->Run(); |
| 742 CHECK(value->IsNumber()); | 741 CHECK(value->IsNumber()); |
| 743 CHECK_EQ(68, value->Int32Value()); | 742 CHECK_EQ(68, value->Int32Value()); |
| 744 } | 743 } |
| 745 i::CompilationCache::Clear(); | 744 i::Isolate::Current()->compilation_cache()->Clear(); |
| 746 i::Heap::CollectAllGarbage(false); | 745 HEAP->CollectAllGarbage(false); |
| 747 i::Heap::CollectAllGarbage(false); | 746 HEAP->CollectAllGarbage(false); |
| 748 } | 747 } |
| 749 | 748 |
| 750 | 749 |
| 751 THREADED_TEST(GlobalProperties) { | 750 THREADED_TEST(GlobalProperties) { |
| 752 v8::HandleScope scope; | 751 v8::HandleScope scope; |
| 753 LocalContext env; | 752 LocalContext env; |
| 754 v8::Handle<v8::Object> global = env->Global(); | 753 v8::Handle<v8::Object> global = env->Global(); |
| 755 global->Set(v8_str("pi"), v8_num(3.1415926)); | 754 global->Set(v8_str("pi"), v8_num(3.1415926)); |
| 756 Local<Value> pi = global->Get(v8_str("pi")); | 755 Local<Value> pi = global->Get(v8_str("pi")); |
| 757 CHECK_EQ(3.1415926, pi->NumberValue()); | 756 CHECK_EQ(3.1415926, pi->NumberValue()); |
| (...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1572 | 1571 |
| 1573 char* data = new char[100]; | 1572 char* data = new char[100]; |
| 1574 | 1573 |
| 1575 void* aligned = data; | 1574 void* aligned = data; |
| 1576 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); | 1575 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); |
| 1577 void* unaligned = data + 1; | 1576 void* unaligned = data + 1; |
| 1578 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); | 1577 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); |
| 1579 | 1578 |
| 1580 // Check reading and writing aligned pointers. | 1579 // Check reading and writing aligned pointers. |
| 1581 obj->SetPointerInInternalField(0, aligned); | 1580 obj->SetPointerInInternalField(0, aligned); |
| 1582 i::Heap::CollectAllGarbage(false); | 1581 HEAP->CollectAllGarbage(false); |
| 1583 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); | 1582 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); |
| 1584 | 1583 |
| 1585 // Check reading and writing unaligned pointers. | 1584 // Check reading and writing unaligned pointers. |
| 1586 obj->SetPointerInInternalField(0, unaligned); | 1585 obj->SetPointerInInternalField(0, unaligned); |
| 1587 i::Heap::CollectAllGarbage(false); | 1586 HEAP->CollectAllGarbage(false); |
| 1588 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); | 1587 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); |
| 1589 | 1588 |
| 1590 delete[] data; | 1589 delete[] data; |
| 1591 } | 1590 } |
| 1592 | 1591 |
| 1593 | 1592 |
| 1594 THREADED_TEST(InternalFieldsNativePointersAndExternal) { | 1593 THREADED_TEST(InternalFieldsNativePointersAndExternal) { |
| 1595 v8::HandleScope scope; | 1594 v8::HandleScope scope; |
| 1596 LocalContext env; | 1595 LocalContext env; |
| 1597 | 1596 |
| 1598 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 1597 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
| 1599 Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); | 1598 Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); |
| 1600 instance_templ->SetInternalFieldCount(1); | 1599 instance_templ->SetInternalFieldCount(1); |
| 1601 Local<v8::Object> obj = templ->GetFunction()->NewInstance(); | 1600 Local<v8::Object> obj = templ->GetFunction()->NewInstance(); |
| 1602 CHECK_EQ(1, obj->InternalFieldCount()); | 1601 CHECK_EQ(1, obj->InternalFieldCount()); |
| 1603 CHECK(obj->GetPointerFromInternalField(0) == NULL); | 1602 CHECK(obj->GetPointerFromInternalField(0) == NULL); |
| 1604 | 1603 |
| 1605 char* data = new char[100]; | 1604 char* data = new char[100]; |
| 1606 | 1605 |
| 1607 void* aligned = data; | 1606 void* aligned = data; |
| 1608 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); | 1607 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); |
| 1609 void* unaligned = data + 1; | 1608 void* unaligned = data + 1; |
| 1610 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); | 1609 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); |
| 1611 | 1610 |
| 1612 obj->SetPointerInInternalField(0, aligned); | 1611 obj->SetPointerInInternalField(0, aligned); |
| 1613 i::Heap::CollectAllGarbage(false); | 1612 HEAP->CollectAllGarbage(false); |
| 1614 CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0))); | 1613 CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0))); |
| 1615 | 1614 |
| 1616 obj->SetPointerInInternalField(0, unaligned); | 1615 obj->SetPointerInInternalField(0, unaligned); |
| 1617 i::Heap::CollectAllGarbage(false); | 1616 HEAP->CollectAllGarbage(false); |
| 1618 CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0))); | 1617 CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0))); |
| 1619 | 1618 |
| 1620 obj->SetInternalField(0, v8::External::Wrap(aligned)); | 1619 obj->SetInternalField(0, v8::External::Wrap(aligned)); |
| 1621 i::Heap::CollectAllGarbage(false); | 1620 HEAP->CollectAllGarbage(false); |
| 1622 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); | 1621 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); |
| 1623 | 1622 |
| 1624 obj->SetInternalField(0, v8::External::Wrap(unaligned)); | 1623 obj->SetInternalField(0, v8::External::Wrap(unaligned)); |
| 1625 i::Heap::CollectAllGarbage(false); | 1624 HEAP->CollectAllGarbage(false); |
| 1626 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); | 1625 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); |
| 1627 | 1626 |
| 1628 delete[] data; | 1627 delete[] data; |
| 1629 } | 1628 } |
| 1630 | 1629 |
| 1631 | 1630 |
| 1632 THREADED_TEST(IdentityHash) { | 1631 THREADED_TEST(IdentityHash) { |
| 1633 v8::HandleScope scope; | 1632 v8::HandleScope scope; |
| 1634 LocalContext env; | 1633 LocalContext env; |
| 1635 | 1634 |
| 1636 // Ensure that the test starts with an fresh heap to test whether the hash | 1635 // Ensure that the test starts with an fresh heap to test whether the hash |
| 1637 // code is based on the address. | 1636 // code is based on the address. |
| 1638 i::Heap::CollectAllGarbage(false); | 1637 HEAP->CollectAllGarbage(false); |
| 1639 Local<v8::Object> obj = v8::Object::New(); | 1638 Local<v8::Object> obj = v8::Object::New(); |
| 1640 int hash = obj->GetIdentityHash(); | 1639 int hash = obj->GetIdentityHash(); |
| 1641 int hash1 = obj->GetIdentityHash(); | 1640 int hash1 = obj->GetIdentityHash(); |
| 1642 CHECK_EQ(hash, hash1); | 1641 CHECK_EQ(hash, hash1); |
| 1643 int hash2 = v8::Object::New()->GetIdentityHash(); | 1642 int hash2 = v8::Object::New()->GetIdentityHash(); |
| 1644 // Since the identity hash is essentially a random number two consecutive | 1643 // Since the identity hash is essentially a random number two consecutive |
| 1645 // objects should not be assigned the same hash code. If the test below fails | 1644 // objects should not be assigned the same hash code. If the test below fails |
| 1646 // the random number generator should be evaluated. | 1645 // the random number generator should be evaluated. |
| 1647 CHECK_NE(hash, hash2); | 1646 CHECK_NE(hash, hash2); |
| 1648 i::Heap::CollectAllGarbage(false); | 1647 HEAP->CollectAllGarbage(false); |
| 1649 int hash3 = v8::Object::New()->GetIdentityHash(); | 1648 int hash3 = v8::Object::New()->GetIdentityHash(); |
| 1650 // Make sure that the identity hash is not based on the initial address of | 1649 // Make sure that the identity hash is not based on the initial address of |
| 1651 // the object alone. If the test below fails the random number generator | 1650 // the object alone. If the test below fails the random number generator |
| 1652 // should be evaluated. | 1651 // should be evaluated. |
| 1653 CHECK_NE(hash, hash3); | 1652 CHECK_NE(hash, hash3); |
| 1654 int hash4 = obj->GetIdentityHash(); | 1653 int hash4 = obj->GetIdentityHash(); |
| 1655 CHECK_EQ(hash, hash4); | 1654 CHECK_EQ(hash, hash4); |
| 1656 | 1655 |
| 1657 // Check identity hashes behaviour in the presence of JS accessors. | 1656 // Check identity hashes behaviour in the presence of JS accessors. |
| 1658 // Put a getter for 'v8::IdentityHash' on the Object's prototype: | 1657 // Put a getter for 'v8::IdentityHash' on the Object's prototype: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1675 | 1674 |
| 1676 THREADED_TEST(HiddenProperties) { | 1675 THREADED_TEST(HiddenProperties) { |
| 1677 v8::HandleScope scope; | 1676 v8::HandleScope scope; |
| 1678 LocalContext env; | 1677 LocalContext env; |
| 1679 | 1678 |
| 1680 v8::Local<v8::Object> obj = v8::Object::New(); | 1679 v8::Local<v8::Object> obj = v8::Object::New(); |
| 1681 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); | 1680 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); |
| 1682 v8::Local<v8::String> empty = v8_str(""); | 1681 v8::Local<v8::String> empty = v8_str(""); |
| 1683 v8::Local<v8::String> prop_name = v8_str("prop_name"); | 1682 v8::Local<v8::String> prop_name = v8_str("prop_name"); |
| 1684 | 1683 |
| 1685 i::Heap::CollectAllGarbage(false); | 1684 HEAP->CollectAllGarbage(false); |
| 1686 | 1685 |
| 1687 // Make sure delete of a non-existent hidden value works | 1686 // Make sure delete of a non-existent hidden value works |
| 1688 CHECK(obj->DeleteHiddenValue(key)); | 1687 CHECK(obj->DeleteHiddenValue(key)); |
| 1689 | 1688 |
| 1690 CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); | 1689 CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); |
| 1691 CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); | 1690 CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); |
| 1692 CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); | 1691 CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); |
| 1693 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1692 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1694 | 1693 |
| 1695 i::Heap::CollectAllGarbage(false); | 1694 HEAP->CollectAllGarbage(false); |
| 1696 | 1695 |
| 1697 // Make sure we do not find the hidden property. | 1696 // Make sure we do not find the hidden property. |
| 1698 CHECK(!obj->Has(empty)); | 1697 CHECK(!obj->Has(empty)); |
| 1699 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1698 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1700 CHECK(obj->Get(empty)->IsUndefined()); | 1699 CHECK(obj->Get(empty)->IsUndefined()); |
| 1701 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1700 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1702 CHECK(obj->Set(empty, v8::Integer::New(2003))); | 1701 CHECK(obj->Set(empty, v8::Integer::New(2003))); |
| 1703 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1702 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1704 CHECK_EQ(2003, obj->Get(empty)->Int32Value()); | 1703 CHECK_EQ(2003, obj->Get(empty)->Int32Value()); |
| 1705 | 1704 |
| 1706 i::Heap::CollectAllGarbage(false); | 1705 HEAP->CollectAllGarbage(false); |
| 1707 | 1706 |
| 1708 // Add another property and delete it afterwards to force the object in | 1707 // Add another property and delete it afterwards to force the object in |
| 1709 // slow case. | 1708 // slow case. |
| 1710 CHECK(obj->Set(prop_name, v8::Integer::New(2008))); | 1709 CHECK(obj->Set(prop_name, v8::Integer::New(2008))); |
| 1711 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1710 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1712 CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); | 1711 CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); |
| 1713 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1712 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1714 CHECK(obj->Delete(prop_name)); | 1713 CHECK(obj->Delete(prop_name)); |
| 1715 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1714 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1716 | 1715 |
| 1717 i::Heap::CollectAllGarbage(false); | 1716 HEAP->CollectAllGarbage(false); |
| 1718 | 1717 |
| 1719 CHECK(obj->DeleteHiddenValue(key)); | 1718 CHECK(obj->DeleteHiddenValue(key)); |
| 1720 CHECK(obj->GetHiddenValue(key).IsEmpty()); | 1719 CHECK(obj->GetHiddenValue(key).IsEmpty()); |
| 1721 } | 1720 } |
| 1722 | 1721 |
| 1723 | 1722 |
| 1724 static bool interceptor_for_hidden_properties_called; | 1723 static bool interceptor_for_hidden_properties_called; |
| 1725 static v8::Handle<Value> InterceptorForHiddenProperties( | 1724 static v8::Handle<Value> InterceptorForHiddenProperties( |
| 1726 Local<String> name, const AccessorInfo& info) { | 1725 Local<String> name, const AccessorInfo& info) { |
| 1727 interceptor_for_hidden_properties_called = true; | 1726 interceptor_for_hidden_properties_called = true; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1840 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1839 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 1841 Persistent<Value> g1_children[] = { g1c1 }; | 1840 Persistent<Value> g1_children[] = { g1c1 }; |
| 1842 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1841 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 1843 Persistent<Value> g2_children[] = { g2c1 }; | 1842 Persistent<Value> g2_children[] = { g2c1 }; |
| 1844 V8::AddObjectGroup(g1_objects, 2); | 1843 V8::AddObjectGroup(g1_objects, 2); |
| 1845 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1844 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 1846 V8::AddObjectGroup(g2_objects, 2); | 1845 V8::AddObjectGroup(g2_objects, 2); |
| 1847 V8::AddImplicitReferences(g2s2, g2_children, 1); | 1846 V8::AddImplicitReferences(g2s2, g2_children, 1); |
| 1848 } | 1847 } |
| 1849 // Do a full GC | 1848 // Do a full GC |
| 1850 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1849 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
| 1851 | 1850 |
| 1852 // All object should be alive. | 1851 // All object should be alive. |
| 1853 CHECK_EQ(0, NumberOfWeakCalls); | 1852 CHECK_EQ(0, NumberOfWeakCalls); |
| 1854 | 1853 |
| 1855 // Weaken the root. | 1854 // Weaken the root. |
| 1856 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1855 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
| 1857 // But make children strong roots---all the objects (except for children) | 1856 // But make children strong roots---all the objects (except for children) |
| 1858 // should be collectable now. | 1857 // should be collectable now. |
| 1859 g1c1.ClearWeak(); | 1858 g1c1.ClearWeak(); |
| 1860 g2c1.ClearWeak(); | 1859 g2c1.ClearWeak(); |
| 1861 | 1860 |
| 1862 // Groups are deleted, rebuild groups. | 1861 // Groups are deleted, rebuild groups. |
| 1863 { | 1862 { |
| 1864 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1863 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 1865 Persistent<Value> g1_children[] = { g1c1 }; | 1864 Persistent<Value> g1_children[] = { g1c1 }; |
| 1866 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1865 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 1867 Persistent<Value> g2_children[] = { g2c1 }; | 1866 Persistent<Value> g2_children[] = { g2c1 }; |
| 1868 V8::AddObjectGroup(g1_objects, 2); | 1867 V8::AddObjectGroup(g1_objects, 2); |
| 1869 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1868 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 1870 V8::AddObjectGroup(g2_objects, 2); | 1869 V8::AddObjectGroup(g2_objects, 2); |
| 1871 V8::AddImplicitReferences(g2s2, g2_children, 1); | 1870 V8::AddImplicitReferences(g2s2, g2_children, 1); |
| 1872 } | 1871 } |
| 1873 | 1872 |
| 1874 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1873 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
| 1875 | 1874 |
| 1876 // All objects should be gone. 5 global handles in total. | 1875 // All objects should be gone. 5 global handles in total. |
| 1877 CHECK_EQ(5, NumberOfWeakCalls); | 1876 CHECK_EQ(5, NumberOfWeakCalls); |
| 1878 | 1877 |
| 1879 // And now make children weak again and collect them. | 1878 // And now make children weak again and collect them. |
| 1880 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1879 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
| 1881 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1880 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
| 1882 | 1881 |
| 1883 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1882 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
| 1884 CHECK_EQ(7, NumberOfWeakCalls); | 1883 CHECK_EQ(7, NumberOfWeakCalls); |
| 1885 } | 1884 } |
| 1886 | 1885 |
| 1887 | 1886 |
| 1888 THREADED_TEST(ApiObjectGroupsCycle) { | 1887 THREADED_TEST(ApiObjectGroupsCycle) { |
| 1889 HandleScope scope; | 1888 HandleScope scope; |
| 1890 LocalContext env; | 1889 LocalContext env; |
| 1891 | 1890 |
| 1892 NumberOfWeakCalls = 0; | 1891 NumberOfWeakCalls = 0; |
| 1893 | 1892 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1929 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 1928 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
| 1930 Persistent<Value> g3_children[] = { g1s1 }; | 1929 Persistent<Value> g3_children[] = { g1s1 }; |
| 1931 V8::AddObjectGroup(g1_objects, 2); | 1930 V8::AddObjectGroup(g1_objects, 2); |
| 1932 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1931 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 1933 V8::AddObjectGroup(g2_objects, 2); | 1932 V8::AddObjectGroup(g2_objects, 2); |
| 1934 V8::AddImplicitReferences(g2s1, g2_children, 1); | 1933 V8::AddImplicitReferences(g2s1, g2_children, 1); |
| 1935 V8::AddObjectGroup(g3_objects, 2); | 1934 V8::AddObjectGroup(g3_objects, 2); |
| 1936 V8::AddImplicitReferences(g3s1, g3_children, 1); | 1935 V8::AddImplicitReferences(g3s1, g3_children, 1); |
| 1937 } | 1936 } |
| 1938 // Do a full GC | 1937 // Do a full GC |
| 1939 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1938 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
| 1940 | 1939 |
| 1941 // All object should be alive. | 1940 // All object should be alive. |
| 1942 CHECK_EQ(0, NumberOfWeakCalls); | 1941 CHECK_EQ(0, NumberOfWeakCalls); |
| 1943 | 1942 |
| 1944 // Weaken the root. | 1943 // Weaken the root. |
| 1945 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1944 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); |
| 1946 | 1945 |
| 1947 // Groups are deleted, rebuild groups. | 1946 // Groups are deleted, rebuild groups. |
| 1948 { | 1947 { |
| 1949 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1948 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 1950 Persistent<Value> g1_children[] = { g2s1 }; | 1949 Persistent<Value> g1_children[] = { g2s1 }; |
| 1951 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1950 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 1952 Persistent<Value> g2_children[] = { g3s1 }; | 1951 Persistent<Value> g2_children[] = { g3s1 }; |
| 1953 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 1952 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
| 1954 Persistent<Value> g3_children[] = { g1s1 }; | 1953 Persistent<Value> g3_children[] = { g1s1 }; |
| 1955 V8::AddObjectGroup(g1_objects, 2); | 1954 V8::AddObjectGroup(g1_objects, 2); |
| 1956 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1955 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 1957 V8::AddObjectGroup(g2_objects, 2); | 1956 V8::AddObjectGroup(g2_objects, 2); |
| 1958 V8::AddImplicitReferences(g2s1, g2_children, 1); | 1957 V8::AddImplicitReferences(g2s1, g2_children, 1); |
| 1959 V8::AddObjectGroup(g3_objects, 2); | 1958 V8::AddObjectGroup(g3_objects, 2); |
| 1960 V8::AddImplicitReferences(g3s1, g3_children, 1); | 1959 V8::AddImplicitReferences(g3s1, g3_children, 1); |
| 1961 } | 1960 } |
| 1962 | 1961 |
| 1963 i::Heap::CollectGarbage(i::OLD_POINTER_SPACE); | 1962 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); |
| 1964 | 1963 |
| 1965 // All objects should be gone. 7 global handles in total. | 1964 // All objects should be gone. 7 global handles in total. |
| 1966 CHECK_EQ(7, NumberOfWeakCalls); | 1965 CHECK_EQ(7, NumberOfWeakCalls); |
| 1967 } | 1966 } |
| 1968 | 1967 |
| 1969 | 1968 |
| 1970 THREADED_TEST(ScriptException) { | 1969 THREADED_TEST(ScriptException) { |
| 1971 v8::HandleScope scope; | 1970 v8::HandleScope scope; |
| 1972 LocalContext env; | 1971 LocalContext env; |
| 1973 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); | 1972 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2257 "}"); | 2256 "}"); |
| 2258 // Check for out of memory state. | 2257 // Check for out of memory state. |
| 2259 CHECK(result.IsEmpty()); | 2258 CHECK(result.IsEmpty()); |
| 2260 CHECK(context->HasOutOfMemoryException()); | 2259 CHECK(context->HasOutOfMemoryException()); |
| 2261 } | 2260 } |
| 2262 | 2261 |
| 2263 | 2262 |
| 2264 TEST(HugeConsStringOutOfMemory) { | 2263 TEST(HugeConsStringOutOfMemory) { |
| 2265 // It's not possible to read a snapshot into a heap with different dimensions. | 2264 // It's not possible to read a snapshot into a heap with different dimensions. |
| 2266 if (i::Snapshot::IsEnabled()) return; | 2265 if (i::Snapshot::IsEnabled()) return; |
| 2267 v8::HandleScope scope; | |
| 2268 LocalContext context; | |
| 2269 // Set heap limits. | 2266 // Set heap limits. |
| 2270 static const int K = 1024; | 2267 static const int K = 1024; |
| 2271 v8::ResourceConstraints constraints; | 2268 v8::ResourceConstraints constraints; |
| 2272 constraints.set_max_young_space_size(256 * K); | 2269 constraints.set_max_young_space_size(256 * K); |
| 2273 constraints.set_max_old_space_size(2 * K * K); | 2270 constraints.set_max_old_space_size(2 * K * K); |
| 2274 v8::SetResourceConstraints(&constraints); | 2271 v8::SetResourceConstraints(&constraints); |
| 2275 | 2272 |
| 2276 // Execute a script that causes out of memory. | 2273 // Execute a script that causes out of memory. |
| 2277 v8::V8::IgnoreOutOfMemoryException(); | 2274 v8::V8::IgnoreOutOfMemoryException(); |
| 2278 | 2275 |
| 2276 v8::HandleScope scope; |
| 2277 LocalContext context; |
| 2278 |
| 2279 // Build huge string. This should fail with out of memory exception. | 2279 // Build huge string. This should fail with out of memory exception. |
| 2280 Local<Value> result = CompileRun( | 2280 Local<Value> result = CompileRun( |
| 2281 "var str = Array.prototype.join.call({length: 513}, \"A\").toUpperCase();" | 2281 "var str = Array.prototype.join.call({length: 513}, \"A\").toUpperCase();" |
| 2282 "for (var i = 0; i < 22; i++) { str = str + str; }"); | 2282 "for (var i = 0; i < 22; i++) { str = str + str; }"); |
| 2283 | 2283 |
| 2284 // Check for out of memory state. | 2284 // Check for out of memory state. |
| 2285 CHECK(result.IsEmpty()); | 2285 CHECK(result.IsEmpty()); |
| 2286 CHECK(context->HasOutOfMemoryException()); | 2286 CHECK(context->HasOutOfMemoryException()); |
| 2287 } | 2287 } |
| 2288 | 2288 |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2688 args[1], | 2688 args[1], |
| 2689 args[2], | 2689 args[2], |
| 2690 args[3] }; | 2690 args[3] }; |
| 2691 if (count % cInterval == 0) { | 2691 if (count % cInterval == 0) { |
| 2692 v8::TryCatch try_catch; | 2692 v8::TryCatch try_catch; |
| 2693 Local<Value> result = fun.As<Function>()->Call(global, 4, argv); | 2693 Local<Value> result = fun.As<Function>()->Call(global, 4, argv); |
| 2694 int expected = args[3]->Int32Value(); | 2694 int expected = args[3]->Int32Value(); |
| 2695 if (try_catch.HasCaught()) { | 2695 if (try_catch.HasCaught()) { |
| 2696 CHECK_EQ(expected, count); | 2696 CHECK_EQ(expected, count); |
| 2697 CHECK(result.IsEmpty()); | 2697 CHECK(result.IsEmpty()); |
| 2698 CHECK(!i::Top::has_scheduled_exception()); | 2698 CHECK(!i::Isolate::Current()->has_scheduled_exception()); |
| 2699 } else { | 2699 } else { |
| 2700 CHECK_NE(expected, count); | 2700 CHECK_NE(expected, count); |
| 2701 } | 2701 } |
| 2702 return result; | 2702 return result; |
| 2703 } else { | 2703 } else { |
| 2704 return fun.As<Function>()->Call(global, 4, argv); | 2704 return fun.As<Function>()->Call(global, 4, argv); |
| 2705 } | 2705 } |
| 2706 } | 2706 } |
| 2707 } | 2707 } |
| 2708 | 2708 |
| (...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4380 | 4380 |
| 4381 static bool in_scavenge = false; | 4381 static bool in_scavenge = false; |
| 4382 static int last = -1; | 4382 static int last = -1; |
| 4383 | 4383 |
| 4384 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { | 4384 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { |
| 4385 CHECK_EQ(-1, last); | 4385 CHECK_EQ(-1, last); |
| 4386 last = 0; | 4386 last = 0; |
| 4387 obj.Dispose(); | 4387 obj.Dispose(); |
| 4388 obj.Clear(); | 4388 obj.Clear(); |
| 4389 in_scavenge = true; | 4389 in_scavenge = true; |
| 4390 i::Heap::PerformScavenge(); | 4390 HEAP->PerformScavenge(); |
| 4391 in_scavenge = false; | 4391 in_scavenge = false; |
| 4392 *(reinterpret_cast<bool*>(data)) = true; | 4392 *(reinterpret_cast<bool*>(data)) = true; |
| 4393 } | 4393 } |
| 4394 | 4394 |
| 4395 static void CheckIsNotInvokedInScavenge(v8::Persistent<v8::Value> obj, | 4395 static void CheckIsNotInvokedInScavenge(v8::Persistent<v8::Value> obj, |
| 4396 void* data) { | 4396 void* data) { |
| 4397 CHECK_EQ(0, last); | 4397 CHECK_EQ(0, last); |
| 4398 last = 1; | 4398 last = 1; |
| 4399 *(reinterpret_cast<bool*>(data)) = in_scavenge; | 4399 *(reinterpret_cast<bool*>(data)) = in_scavenge; |
| 4400 obj.Dispose(); | 4400 obj.Dispose(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4417 object_b = v8::Persistent<v8::Object>::New(v8::Object::New()); | 4417 object_b = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 4418 object_a = v8::Persistent<v8::Object>::New(v8::Object::New()); | 4418 object_a = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 4419 } | 4419 } |
| 4420 | 4420 |
| 4421 bool object_a_disposed = false; | 4421 bool object_a_disposed = false; |
| 4422 object_a.MakeWeak(&object_a_disposed, &ForceScavenge); | 4422 object_a.MakeWeak(&object_a_disposed, &ForceScavenge); |
| 4423 bool released_in_scavenge = false; | 4423 bool released_in_scavenge = false; |
| 4424 object_b.MakeWeak(&released_in_scavenge, &CheckIsNotInvokedInScavenge); | 4424 object_b.MakeWeak(&released_in_scavenge, &CheckIsNotInvokedInScavenge); |
| 4425 | 4425 |
| 4426 while (!object_a_disposed) { | 4426 while (!object_a_disposed) { |
| 4427 i::Heap::CollectAllGarbage(false); | 4427 HEAP->CollectAllGarbage(false); |
| 4428 } | 4428 } |
| 4429 CHECK(!released_in_scavenge); | 4429 CHECK(!released_in_scavenge); |
| 4430 } | 4430 } |
| 4431 | 4431 |
| 4432 | 4432 |
| 4433 v8::Handle<Function> args_fun; | 4433 v8::Handle<Function> args_fun; |
| 4434 | 4434 |
| 4435 | 4435 |
| 4436 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { | 4436 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { |
| 4437 ApiTestFuzzer::Fuzz(); | 4437 ApiTestFuzzer::Fuzz(); |
| 4438 CHECK_EQ(args_fun, args.Callee()); | 4438 CHECK_EQ(args_fun, args.Callee()); |
| 4439 CHECK_EQ(3, args.Length()); | 4439 CHECK_EQ(3, args.Length()); |
| 4440 CHECK_EQ(v8::Integer::New(1), args[0]); | 4440 CHECK_EQ(v8::Integer::New(1), args[0]); |
| 4441 CHECK_EQ(v8::Integer::New(2), args[1]); | 4441 CHECK_EQ(v8::Integer::New(2), args[1]); |
| 4442 CHECK_EQ(v8::Integer::New(3), args[2]); | 4442 CHECK_EQ(v8::Integer::New(3), args[2]); |
| 4443 CHECK_EQ(v8::Undefined(), args[3]); | 4443 CHECK_EQ(v8::Undefined(), args[3]); |
| 4444 v8::HandleScope scope; | 4444 v8::HandleScope scope; |
| 4445 i::Heap::CollectAllGarbage(false); | 4445 HEAP->CollectAllGarbage(false); |
| 4446 return v8::Undefined(); | 4446 return v8::Undefined(); |
| 4447 } | 4447 } |
| 4448 | 4448 |
| 4449 | 4449 |
| 4450 THREADED_TEST(Arguments) { | 4450 THREADED_TEST(Arguments) { |
| 4451 v8::HandleScope scope; | 4451 v8::HandleScope scope; |
| 4452 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); | 4452 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); |
| 4453 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); | 4453 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); |
| 4454 LocalContext context(NULL, global); | 4454 LocalContext context(NULL, global); |
| 4455 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); | 4455 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); |
| (...skipping 2220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6676 | 6676 |
| 6677 Local<v8::Object> o0 = t->GetFunction()->NewInstance(); | 6677 Local<v8::Object> o0 = t->GetFunction()->NewInstance(); |
| 6678 Local<v8::Object> o1 = t->GetFunction()->NewInstance(); | 6678 Local<v8::Object> o1 = t->GetFunction()->NewInstance(); |
| 6679 | 6679 |
| 6680 CHECK(o0->SetPrototype(o1)); | 6680 CHECK(o0->SetPrototype(o1)); |
| 6681 // If setting the prototype leads to the cycle, SetPrototype should | 6681 // If setting the prototype leads to the cycle, SetPrototype should |
| 6682 // return false and keep VM in sane state. | 6682 // return false and keep VM in sane state. |
| 6683 v8::TryCatch try_catch; | 6683 v8::TryCatch try_catch; |
| 6684 CHECK(!o1->SetPrototype(o0)); | 6684 CHECK(!o1->SetPrototype(o0)); |
| 6685 CHECK(!try_catch.HasCaught()); | 6685 CHECK(!try_catch.HasCaught()); |
| 6686 ASSERT(!i::Top::has_pending_exception()); | 6686 ASSERT(!i::Isolate::Current()->has_pending_exception()); |
| 6687 | 6687 |
| 6688 CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value()); | 6688 CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value()); |
| 6689 } | 6689 } |
| 6690 | 6690 |
| 6691 | 6691 |
| 6692 THREADED_TEST(GetterSetterExceptions) { | 6692 THREADED_TEST(GetterSetterExceptions) { |
| 6693 v8::HandleScope handle_scope; | 6693 v8::HandleScope handle_scope; |
| 6694 LocalContext context; | 6694 LocalContext context; |
| 6695 CompileRun( | 6695 CompileRun( |
| 6696 "function Foo() { };" | 6696 "function Foo() { };" |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7058 "var p = new constructor();" | 7058 "var p = new constructor();" |
| 7059 "p.hasOwnProperty('ostehaps');"); | 7059 "p.hasOwnProperty('ostehaps');"); |
| 7060 CHECK_EQ(false, value->BooleanValue()); | 7060 CHECK_EQ(false, value->BooleanValue()); |
| 7061 } | 7061 } |
| 7062 | 7062 |
| 7063 | 7063 |
| 7064 static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC( | 7064 static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC( |
| 7065 Local<String> name, | 7065 Local<String> name, |
| 7066 const AccessorInfo& info) { | 7066 const AccessorInfo& info) { |
| 7067 ApiTestFuzzer::Fuzz(); | 7067 ApiTestFuzzer::Fuzz(); |
| 7068 i::Heap::CollectAllGarbage(false); | 7068 HEAP->CollectAllGarbage(false); |
| 7069 return v8::Handle<Value>(); | 7069 return v8::Handle<Value>(); |
| 7070 } | 7070 } |
| 7071 | 7071 |
| 7072 | 7072 |
| 7073 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { | 7073 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { |
| 7074 v8::HandleScope scope; | 7074 v8::HandleScope scope; |
| 7075 LocalContext context; | 7075 LocalContext context; |
| 7076 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 7076 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
| 7077 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); | 7077 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); |
| 7078 instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); | 7078 instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7788 "};"); | 7788 "};"); |
| 7789 CHECK_EQ(239 * 10, value->Int32Value()); | 7789 CHECK_EQ(239 * 10, value->Int32Value()); |
| 7790 } | 7790 } |
| 7791 | 7791 |
| 7792 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, | 7792 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, |
| 7793 const AccessorInfo& info) { | 7793 const AccessorInfo& info) { |
| 7794 ApiTestFuzzer::Fuzz(); | 7794 ApiTestFuzzer::Fuzz(); |
| 7795 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); | 7795 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); |
| 7796 ++(*call_count); | 7796 ++(*call_count); |
| 7797 if ((*call_count) % 20 == 0) { | 7797 if ((*call_count) % 20 == 0) { |
| 7798 i::Heap::CollectAllGarbage(true); | 7798 HEAP->CollectAllGarbage(true); |
| 7799 } | 7799 } |
| 7800 return v8::Handle<Value>(); | 7800 return v8::Handle<Value>(); |
| 7801 } | 7801 } |
| 7802 | 7802 |
| 7803 static v8::Handle<Value> FastApiCallback_TrivialSignature( | 7803 static v8::Handle<Value> FastApiCallback_TrivialSignature( |
| 7804 const v8::Arguments& args) { | 7804 const v8::Arguments& args) { |
| 7805 ApiTestFuzzer::Fuzz(); | 7805 ApiTestFuzzer::Fuzz(); |
| 7806 CHECK_EQ(args.This(), args.Holder()); | 7806 CHECK_EQ(args.This(), args.Holder()); |
| 7807 CHECK(args.Data()->Equals(v8_str("method_data"))); | 7807 CHECK(args.Data()->Equals(v8_str("method_data"))); |
| 7808 return v8::Integer::New(args[0]->Int32Value() + 1); | 7808 return v8::Integer::New(args[0]->Int32Value() + 1); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 7826 "for (var i = 0; i < 1000; i++) {" | 7826 "for (var i = 0; i < 1000; i++) {" |
| 7827 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" | 7827 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" |
| 7828 "}" | 7828 "}" |
| 7829 "garbage = undefined;"); | 7829 "garbage = undefined;"); |
| 7830 } | 7830 } |
| 7831 | 7831 |
| 7832 | 7832 |
| 7833 v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) { | 7833 v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) { |
| 7834 static int count = 0; | 7834 static int count = 0; |
| 7835 if (count++ % 3 == 0) { | 7835 if (count++ % 3 == 0) { |
| 7836 i::Heap::CollectAllGarbage(true); // This should move the stub | 7836 HEAP-> CollectAllGarbage(true); // This should move the stub |
| 7837 GenerateSomeGarbage(); // This should ensure the old stub memory is flushed | 7837 GenerateSomeGarbage(); // This should ensure the old stub memory is flushed |
| 7838 } | 7838 } |
| 7839 return v8::Handle<v8::Value>(); | 7839 return v8::Handle<v8::Value>(); |
| 7840 } | 7840 } |
| 7841 | 7841 |
| 7842 | 7842 |
| 7843 THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) { | 7843 THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) { |
| 7844 v8::HandleScope scope; | 7844 v8::HandleScope scope; |
| 7845 LocalContext context; | 7845 LocalContext context; |
| 7846 v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(); | 7846 v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7881 " }" | 7881 " }" |
| 7882 "}" | 7882 "}" |
| 7883 "f(); result;"); | 7883 "f(); result;"); |
| 7884 CHECK_EQ(v8_str("ggggg"), result); | 7884 CHECK_EQ(v8_str("ggggg"), result); |
| 7885 } | 7885 } |
| 7886 | 7886 |
| 7887 | 7887 |
| 7888 v8::Handle<v8::Value> DirectGetterCallback(Local<String> name, | 7888 v8::Handle<v8::Value> DirectGetterCallback(Local<String> name, |
| 7889 const v8::AccessorInfo& info) { | 7889 const v8::AccessorInfo& info) { |
| 7890 if (++p_getter_count % 3 == 0) { | 7890 if (++p_getter_count % 3 == 0) { |
| 7891 i::Heap::CollectAllGarbage(true); | 7891 HEAP->CollectAllGarbage(true); |
| 7892 GenerateSomeGarbage(); | 7892 GenerateSomeGarbage(); |
| 7893 } | 7893 } |
| 7894 return v8::Handle<v8::Value>(); | 7894 return v8::Handle<v8::Value>(); |
| 7895 } | 7895 } |
| 7896 | 7896 |
| 7897 | 7897 |
| 7898 THREADED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { | 7898 THREADED_TEST(LoadICFastApi_DirectCall_GCMoveStub) { |
| 7899 v8::HandleScope scope; | 7899 v8::HandleScope scope; |
| 7900 LocalContext context; | 7900 LocalContext context; |
| 7901 v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(); | 7901 v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(); |
| (...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8796 | 8796 |
| 8797 void ApiTestFuzzer::Setup(PartOfTest part) { | 8797 void ApiTestFuzzer::Setup(PartOfTest part) { |
| 8798 linear_congruential_generator = i::FLAG_testing_prng_seed; | 8798 linear_congruential_generator = i::FLAG_testing_prng_seed; |
| 8799 fuzzing_ = true; | 8799 fuzzing_ = true; |
| 8800 int start = (part == FIRST_PART) ? 0 : (RegisterThreadedTest::count() >> 1); | 8800 int start = (part == FIRST_PART) ? 0 : (RegisterThreadedTest::count() >> 1); |
| 8801 int end = (part == FIRST_PART) | 8801 int end = (part == FIRST_PART) |
| 8802 ? (RegisterThreadedTest::count() >> 1) | 8802 ? (RegisterThreadedTest::count() >> 1) |
| 8803 : RegisterThreadedTest::count(); | 8803 : RegisterThreadedTest::count(); |
| 8804 active_tests_ = tests_being_run_ = end - start; | 8804 active_tests_ = tests_being_run_ = end - start; |
| 8805 for (int i = 0; i < tests_being_run_; i++) { | 8805 for (int i = 0; i < tests_being_run_; i++) { |
| 8806 RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer(i + start); | 8806 RegisterThreadedTest::nth(i)->fuzzer_ = new ApiTestFuzzer( |
| 8807 i::Isolate::Current(), i + start); |
| 8807 } | 8808 } |
| 8808 for (int i = 0; i < active_tests_; i++) { | 8809 for (int i = 0; i < active_tests_; i++) { |
| 8809 RegisterThreadedTest::nth(i)->fuzzer_->Start(); | 8810 RegisterThreadedTest::nth(i)->fuzzer_->Start(); |
| 8810 } | 8811 } |
| 8811 } | 8812 } |
| 8812 | 8813 |
| 8813 | 8814 |
| 8814 static void CallTestNumber(int test_number) { | 8815 static void CallTestNumber(int test_number) { |
| 8815 (RegisterThreadedTest::nth(test_number)->callback())(); | 8816 (RegisterThreadedTest::nth(test_number)->callback())(); |
| 8816 } | 8817 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9018 return count; | 9019 return count; |
| 9019 } | 9020 } |
| 9020 | 9021 |
| 9021 | 9022 |
| 9022 static void CheckSurvivingGlobalObjectsCount(int expected) { | 9023 static void CheckSurvivingGlobalObjectsCount(int expected) { |
| 9023 // We need to collect all garbage twice to be sure that everything | 9024 // We need to collect all garbage twice to be sure that everything |
| 9024 // has been collected. This is because inline caches are cleared in | 9025 // has been collected. This is because inline caches are cleared in |
| 9025 // the first garbage collection but some of the maps have already | 9026 // the first garbage collection but some of the maps have already |
| 9026 // been marked at that point. Therefore some of the maps are not | 9027 // been marked at that point. Therefore some of the maps are not |
| 9027 // collected until the second garbage collection. | 9028 // collected until the second garbage collection. |
| 9028 i::Heap::CollectAllGarbage(false); | 9029 HEAP->CollectAllGarbage(false); |
| 9029 i::Heap::CollectAllGarbage(false); | 9030 HEAP->CollectAllGarbage(false); |
| 9030 int count = GetGlobalObjectsCount(); | 9031 int count = GetGlobalObjectsCount(); |
| 9031 #ifdef DEBUG | 9032 #ifdef DEBUG |
| 9032 if (count != expected) i::Heap::TracePathToGlobal(); | 9033 if (count != expected) HEAP->TracePathToGlobal(); |
| 9033 #endif | 9034 #endif |
| 9034 CHECK_EQ(expected, count); | 9035 CHECK_EQ(expected, count); |
| 9035 } | 9036 } |
| 9036 | 9037 |
| 9037 | 9038 |
| 9038 TEST(DontLeakGlobalObjects) { | 9039 TEST(DontLeakGlobalObjects) { |
| 9039 // Regression test for issues 1139850 and 1174891. | 9040 // Regression test for issues 1139850 and 1174891. |
| 9040 | 9041 |
| 9041 v8::V8::Initialize(); | 9042 v8::V8::Initialize(); |
| 9042 | 9043 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9088 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9089 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9089 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9090 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9090 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9091 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9091 } | 9092 } |
| 9092 // Note: order is implementation dependent alas: currently | 9093 // Note: order is implementation dependent alas: currently |
| 9093 // global handle nodes are processed by PostGarbageCollectionProcessing | 9094 // global handle nodes are processed by PostGarbageCollectionProcessing |
| 9094 // in reverse allocation order, so if second allocated handle is deleted, | 9095 // in reverse allocation order, so if second allocated handle is deleted, |
| 9095 // weak callback of the first handle would be able to 'reallocate' it. | 9096 // weak callback of the first handle would be able to 'reallocate' it. |
| 9096 handle1.MakeWeak(NULL, NewPersistentHandleCallback); | 9097 handle1.MakeWeak(NULL, NewPersistentHandleCallback); |
| 9097 handle2.Dispose(); | 9098 handle2.Dispose(); |
| 9098 i::Heap::CollectAllGarbage(false); | 9099 HEAP->CollectAllGarbage(false); |
| 9099 } | 9100 } |
| 9100 | 9101 |
| 9101 | 9102 |
| 9102 v8::Persistent<v8::Object> to_be_disposed; | 9103 v8::Persistent<v8::Object> to_be_disposed; |
| 9103 | 9104 |
| 9104 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { | 9105 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { |
| 9105 to_be_disposed.Dispose(); | 9106 to_be_disposed.Dispose(); |
| 9106 i::Heap::CollectAllGarbage(false); | 9107 HEAP->CollectAllGarbage(false); |
| 9107 handle.Dispose(); | 9108 handle.Dispose(); |
| 9108 } | 9109 } |
| 9109 | 9110 |
| 9110 | 9111 |
| 9111 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { | 9112 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { |
| 9112 LocalContext context; | 9113 LocalContext context; |
| 9113 | 9114 |
| 9114 v8::Persistent<v8::Object> handle1, handle2; | 9115 v8::Persistent<v8::Object> handle1, handle2; |
| 9115 { | 9116 { |
| 9116 v8::HandleScope scope; | 9117 v8::HandleScope scope; |
| 9117 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9118 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9118 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9119 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9119 } | 9120 } |
| 9120 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); | 9121 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); |
| 9121 to_be_disposed = handle2; | 9122 to_be_disposed = handle2; |
| 9122 i::Heap::CollectAllGarbage(false); | 9123 HEAP->CollectAllGarbage(false); |
| 9123 } | 9124 } |
| 9124 | 9125 |
| 9125 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { | 9126 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { |
| 9126 handle.Dispose(); | 9127 handle.Dispose(); |
| 9127 } | 9128 } |
| 9128 | 9129 |
| 9129 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { | 9130 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { |
| 9130 v8::HandleScope scope; | 9131 v8::HandleScope scope; |
| 9131 v8::Persistent<v8::Object>::New(v8::Object::New()); | 9132 v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9132 handle.Dispose(); | 9133 handle.Dispose(); |
| 9133 } | 9134 } |
| 9134 | 9135 |
| 9135 | 9136 |
| 9136 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { | 9137 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { |
| 9137 LocalContext context; | 9138 LocalContext context; |
| 9138 | 9139 |
| 9139 v8::Persistent<v8::Object> handle1, handle2, handle3; | 9140 v8::Persistent<v8::Object> handle1, handle2, handle3; |
| 9140 { | 9141 { |
| 9141 v8::HandleScope scope; | 9142 v8::HandleScope scope; |
| 9142 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9143 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9143 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9144 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9144 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 9145 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 9145 } | 9146 } |
| 9146 handle2.MakeWeak(NULL, DisposingCallback); | 9147 handle2.MakeWeak(NULL, DisposingCallback); |
| 9147 handle3.MakeWeak(NULL, HandleCreatingCallback); | 9148 handle3.MakeWeak(NULL, HandleCreatingCallback); |
| 9148 i::Heap::CollectAllGarbage(false); | 9149 HEAP->CollectAllGarbage(false); |
| 9149 } | 9150 } |
| 9150 | 9151 |
| 9151 | 9152 |
| 9152 THREADED_TEST(CheckForCrossContextObjectLiterals) { | 9153 THREADED_TEST(CheckForCrossContextObjectLiterals) { |
| 9153 v8::V8::Initialize(); | 9154 v8::V8::Initialize(); |
| 9154 | 9155 |
| 9155 const int nof = 2; | 9156 const int nof = 2; |
| 9156 const char* sources[nof] = { | 9157 const char* sources[nof] = { |
| 9157 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", | 9158 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", |
| 9158 "Object()" | 9159 "Object()" |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9384 const char* elmv1[] = {"a", "b"}; | 9385 const char* elmv1[] = {"a", "b"}; |
| 9385 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); | 9386 CheckProperties(elms->Get(v8::Integer::New(1)), elmc1, elmv1); |
| 9386 int elmc2 = 3; | 9387 int elmc2 = 3; |
| 9387 const char* elmv2[] = {"0", "1", "2"}; | 9388 const char* elmv2[] = {"0", "1", "2"}; |
| 9388 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); | 9389 CheckProperties(elms->Get(v8::Integer::New(2)), elmc2, elmv2); |
| 9389 int elmc3 = 4; | 9390 int elmc3 = 4; |
| 9390 const char* elmv3[] = {"w", "z", "x", "y"}; | 9391 const char* elmv3[] = {"w", "z", "x", "y"}; |
| 9391 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); | 9392 CheckProperties(elms->Get(v8::Integer::New(3)), elmc3, elmv3); |
| 9392 } | 9393 } |
| 9393 | 9394 |
| 9395 THREADED_TEST(PropertyEnumeration2) { |
| 9396 v8::HandleScope scope; |
| 9397 LocalContext context; |
| 9398 v8::Handle<v8::Value> obj = v8::Script::Compile(v8::String::New( |
| 9399 "var result = [];" |
| 9400 "result[0] = {};" |
| 9401 "result[1] = {a: 1, b: 2};" |
| 9402 "result[2] = [1, 2, 3];" |
| 9403 "var proto = {x: 1, y: 2, z: 3};" |
| 9404 "var x = { __proto__: proto, w: 0, z: 1 };" |
| 9405 "result[3] = x;" |
| 9406 "result;"))->Run(); |
| 9407 v8::Handle<v8::Array> elms = obj.As<v8::Array>(); |
| 9408 CHECK_EQ(4, elms->Length()); |
| 9409 int elmc0 = 0; |
| 9410 const char** elmv0 = NULL; |
| 9411 CheckProperties(elms->Get(v8::Integer::New(0)), elmc0, elmv0); |
| 9412 |
| 9413 v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(0)); |
| 9414 v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames(); |
| 9415 CHECK_EQ(0, props->Length()); |
| 9416 for (uint32_t i = 0; i < props->Length(); i++) { |
| 9417 printf("p[%d]\n", i); |
| 9418 } |
| 9419 } |
| 9394 | 9420 |
| 9395 static bool NamedSetAccessBlocker(Local<v8::Object> obj, | 9421 static bool NamedSetAccessBlocker(Local<v8::Object> obj, |
| 9396 Local<Value> name, | 9422 Local<Value> name, |
| 9397 v8::AccessType type, | 9423 v8::AccessType type, |
| 9398 Local<Value> data) { | 9424 Local<Value> data) { |
| 9399 return type != v8::ACCESS_SET; | 9425 return type != v8::ACCESS_SET; |
| 9400 } | 9426 } |
| 9401 | 9427 |
| 9402 | 9428 |
| 9403 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, | 9429 static bool IndexedSetAccessBlocker(Local<v8::Object> obj, |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9876 class RegExpInterruptTest { | 9902 class RegExpInterruptTest { |
| 9877 public: | 9903 public: |
| 9878 RegExpInterruptTest() : block_(NULL) {} | 9904 RegExpInterruptTest() : block_(NULL) {} |
| 9879 ~RegExpInterruptTest() { delete block_; } | 9905 ~RegExpInterruptTest() { delete block_; } |
| 9880 void RunTest() { | 9906 void RunTest() { |
| 9881 block_ = i::OS::CreateSemaphore(0); | 9907 block_ = i::OS::CreateSemaphore(0); |
| 9882 gc_count_ = 0; | 9908 gc_count_ = 0; |
| 9883 gc_during_regexp_ = 0; | 9909 gc_during_regexp_ = 0; |
| 9884 regexp_success_ = false; | 9910 regexp_success_ = false; |
| 9885 gc_success_ = false; | 9911 gc_success_ = false; |
| 9886 GCThread gc_thread(this); | 9912 GCThread gc_thread(i::Isolate::Current(), this); |
| 9887 gc_thread.Start(); | 9913 gc_thread.Start(); |
| 9888 v8::Locker::StartPreemption(1); | 9914 v8::Locker::StartPreemption(1); |
| 9889 | 9915 |
| 9890 LongRunningRegExp(); | 9916 LongRunningRegExp(); |
| 9891 { | 9917 { |
| 9892 v8::Unlocker unlock; | 9918 v8::Unlocker unlock; |
| 9893 gc_thread.Join(); | 9919 gc_thread.Join(); |
| 9894 } | 9920 } |
| 9895 v8::Locker::StopPreemption(); | 9921 v8::Locker::StopPreemption(); |
| 9896 CHECK(regexp_success_); | 9922 CHECK(regexp_success_); |
| 9897 CHECK(gc_success_); | 9923 CHECK(gc_success_); |
| 9898 } | 9924 } |
| 9899 private: | 9925 private: |
| 9900 // Number of garbage collections required. | 9926 // Number of garbage collections required. |
| 9901 static const int kRequiredGCs = 5; | 9927 static const int kRequiredGCs = 5; |
| 9902 | 9928 |
| 9903 class GCThread : public i::Thread { | 9929 class GCThread : public i::Thread { |
| 9904 public: | 9930 public: |
| 9905 explicit GCThread(RegExpInterruptTest* test) | 9931 explicit GCThread(i::Isolate* isolate, RegExpInterruptTest* test) |
| 9906 : test_(test) {} | 9932 : Thread(isolate), test_(test) {} |
| 9907 virtual void Run() { | 9933 virtual void Run() { |
| 9908 test_->CollectGarbage(); | 9934 test_->CollectGarbage(); |
| 9909 } | 9935 } |
| 9910 private: | 9936 private: |
| 9911 RegExpInterruptTest* test_; | 9937 RegExpInterruptTest* test_; |
| 9912 }; | 9938 }; |
| 9913 | 9939 |
| 9914 void CollectGarbage() { | 9940 void CollectGarbage() { |
| 9915 block_->Wait(); | 9941 block_->Wait(); |
| 9916 while (gc_during_regexp_ < kRequiredGCs) { | 9942 while (gc_during_regexp_ < kRequiredGCs) { |
| 9917 { | 9943 { |
| 9918 v8::Locker lock; | 9944 v8::Locker lock; |
| 9919 // TODO(lrn): Perhaps create some garbage before collecting. | 9945 // TODO(lrn): Perhaps create some garbage before collecting. |
| 9920 i::Heap::CollectAllGarbage(false); | 9946 HEAP->CollectAllGarbage(false); |
| 9921 gc_count_++; | 9947 gc_count_++; |
| 9922 } | 9948 } |
| 9923 i::OS::Sleep(1); | 9949 i::OS::Sleep(1); |
| 9924 } | 9950 } |
| 9925 gc_success_ = true; | 9951 gc_success_ = true; |
| 9926 } | 9952 } |
| 9927 | 9953 |
| 9928 void LongRunningRegExp() { | 9954 void LongRunningRegExp() { |
| 9929 block_->Signal(); // Enable garbage collection thread on next preemption. | 9955 block_->Signal(); // Enable garbage collection thread on next preemption. |
| 9930 int rounds = 0; | 9956 int rounds = 0; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9998 class ApplyInterruptTest { | 10024 class ApplyInterruptTest { |
| 9999 public: | 10025 public: |
| 10000 ApplyInterruptTest() : block_(NULL) {} | 10026 ApplyInterruptTest() : block_(NULL) {} |
| 10001 ~ApplyInterruptTest() { delete block_; } | 10027 ~ApplyInterruptTest() { delete block_; } |
| 10002 void RunTest() { | 10028 void RunTest() { |
| 10003 block_ = i::OS::CreateSemaphore(0); | 10029 block_ = i::OS::CreateSemaphore(0); |
| 10004 gc_count_ = 0; | 10030 gc_count_ = 0; |
| 10005 gc_during_apply_ = 0; | 10031 gc_during_apply_ = 0; |
| 10006 apply_success_ = false; | 10032 apply_success_ = false; |
| 10007 gc_success_ = false; | 10033 gc_success_ = false; |
| 10008 GCThread gc_thread(this); | 10034 GCThread gc_thread(i::Isolate::Current(), this); |
| 10009 gc_thread.Start(); | 10035 gc_thread.Start(); |
| 10010 v8::Locker::StartPreemption(1); | 10036 v8::Locker::StartPreemption(1); |
| 10011 | 10037 |
| 10012 LongRunningApply(); | 10038 LongRunningApply(); |
| 10013 { | 10039 { |
| 10014 v8::Unlocker unlock; | 10040 v8::Unlocker unlock; |
| 10015 gc_thread.Join(); | 10041 gc_thread.Join(); |
| 10016 } | 10042 } |
| 10017 v8::Locker::StopPreemption(); | 10043 v8::Locker::StopPreemption(); |
| 10018 CHECK(apply_success_); | 10044 CHECK(apply_success_); |
| 10019 CHECK(gc_success_); | 10045 CHECK(gc_success_); |
| 10020 } | 10046 } |
| 10021 private: | 10047 private: |
| 10022 // Number of garbage collections required. | 10048 // Number of garbage collections required. |
| 10023 static const int kRequiredGCs = 2; | 10049 static const int kRequiredGCs = 2; |
| 10024 | 10050 |
| 10025 class GCThread : public i::Thread { | 10051 class GCThread : public i::Thread { |
| 10026 public: | 10052 public: |
| 10027 explicit GCThread(ApplyInterruptTest* test) | 10053 explicit GCThread(i::Isolate* isolate, ApplyInterruptTest* test) |
| 10028 : test_(test) {} | 10054 : Thread(isolate), test_(test) {} |
| 10029 virtual void Run() { | 10055 virtual void Run() { |
| 10030 test_->CollectGarbage(); | 10056 test_->CollectGarbage(); |
| 10031 } | 10057 } |
| 10032 private: | 10058 private: |
| 10033 ApplyInterruptTest* test_; | 10059 ApplyInterruptTest* test_; |
| 10034 }; | 10060 }; |
| 10035 | 10061 |
| 10036 void CollectGarbage() { | 10062 void CollectGarbage() { |
| 10037 block_->Wait(); | 10063 block_->Wait(); |
| 10038 while (gc_during_apply_ < kRequiredGCs) { | 10064 while (gc_during_apply_ < kRequiredGCs) { |
| 10039 { | 10065 { |
| 10040 v8::Locker lock; | 10066 v8::Locker lock; |
| 10041 i::Heap::CollectAllGarbage(false); | 10067 HEAP->CollectAllGarbage(false); |
| 10042 gc_count_++; | 10068 gc_count_++; |
| 10043 } | 10069 } |
| 10044 i::OS::Sleep(1); | 10070 i::OS::Sleep(1); |
| 10045 } | 10071 } |
| 10046 gc_success_ = true; | 10072 gc_success_ = true; |
| 10047 } | 10073 } |
| 10048 | 10074 |
| 10049 void LongRunningApply() { | 10075 void LongRunningApply() { |
| 10050 block_->Signal(); | 10076 block_->Signal(); |
| 10051 int rounds = 0; | 10077 int rounds = 0; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10160 i::Vector<const i::uc16> data_; | 10186 i::Vector<const i::uc16> data_; |
| 10161 }; | 10187 }; |
| 10162 | 10188 |
| 10163 | 10189 |
| 10164 static void MorphAString(i::String* string, | 10190 static void MorphAString(i::String* string, |
| 10165 AsciiVectorResource* ascii_resource, | 10191 AsciiVectorResource* ascii_resource, |
| 10166 UC16VectorResource* uc16_resource) { | 10192 UC16VectorResource* uc16_resource) { |
| 10167 CHECK(i::StringShape(string).IsExternal()); | 10193 CHECK(i::StringShape(string).IsExternal()); |
| 10168 if (string->IsAsciiRepresentation()) { | 10194 if (string->IsAsciiRepresentation()) { |
| 10169 // Check old map is not symbol or long. | 10195 // Check old map is not symbol or long. |
| 10170 CHECK(string->map() == i::Heap::external_ascii_string_map()); | 10196 CHECK(string->map() == HEAP->external_ascii_string_map()); |
| 10171 // Morph external string to be TwoByte string. | 10197 // Morph external string to be TwoByte string. |
| 10172 string->set_map(i::Heap::external_string_map()); | 10198 string->set_map(HEAP->external_string_map()); |
| 10173 i::ExternalTwoByteString* morphed = | 10199 i::ExternalTwoByteString* morphed = |
| 10174 i::ExternalTwoByteString::cast(string); | 10200 i::ExternalTwoByteString::cast(string); |
| 10175 morphed->set_resource(uc16_resource); | 10201 morphed->set_resource(uc16_resource); |
| 10176 } else { | 10202 } else { |
| 10177 // Check old map is not symbol or long. | 10203 // Check old map is not symbol or long. |
| 10178 CHECK(string->map() == i::Heap::external_string_map()); | 10204 CHECK(string->map() == HEAP->external_string_map()); |
| 10179 // Morph external string to be ASCII string. | 10205 // Morph external string to be ASCII string. |
| 10180 string->set_map(i::Heap::external_ascii_string_map()); | 10206 string->set_map(HEAP->external_ascii_string_map()); |
| 10181 i::ExternalAsciiString* morphed = | 10207 i::ExternalAsciiString* morphed = |
| 10182 i::ExternalAsciiString::cast(string); | 10208 i::ExternalAsciiString::cast(string); |
| 10183 morphed->set_resource(ascii_resource); | 10209 morphed->set_resource(ascii_resource); |
| 10184 } | 10210 } |
| 10185 } | 10211 } |
| 10186 | 10212 |
| 10187 | 10213 |
| 10188 // Test that we can still flatten a string if the components it is built up | 10214 // Test that we can still flatten a string if the components it is built up |
| 10189 // from have been turned into 16 bit strings in the mean time. | 10215 // from have been turned into 16 bit strings in the mean time. |
| 10190 THREADED_TEST(MorphCompositeStringTest) { | 10216 THREADED_TEST(MorphCompositeStringTest) { |
| 10191 const char* c_string = "Now is the time for all good men" | 10217 const char* c_string = "Now is the time for all good men" |
| 10192 " to come to the aid of the party"; | 10218 " to come to the aid of the party"; |
| 10193 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); | 10219 uint16_t* two_byte_string = AsciiToTwoByteString(c_string); |
| 10194 { | 10220 { |
| 10195 v8::HandleScope scope; | 10221 v8::HandleScope scope; |
| 10196 LocalContext env; | 10222 LocalContext env; |
| 10197 AsciiVectorResource ascii_resource( | 10223 AsciiVectorResource ascii_resource( |
| 10198 i::Vector<const char>(c_string, i::StrLength(c_string))); | 10224 i::Vector<const char>(c_string, i::StrLength(c_string))); |
| 10199 UC16VectorResource uc16_resource( | 10225 UC16VectorResource uc16_resource( |
| 10200 i::Vector<const uint16_t>(two_byte_string, | 10226 i::Vector<const uint16_t>(two_byte_string, |
| 10201 i::StrLength(c_string))); | 10227 i::StrLength(c_string))); |
| 10202 | 10228 |
| 10203 Local<String> lhs(v8::Utils::ToLocal( | 10229 Local<String> lhs(v8::Utils::ToLocal( |
| 10204 i::Factory::NewExternalStringFromAscii(&ascii_resource))); | 10230 FACTORY->NewExternalStringFromAscii(&ascii_resource))); |
| 10205 Local<String> rhs(v8::Utils::ToLocal( | 10231 Local<String> rhs(v8::Utils::ToLocal( |
| 10206 i::Factory::NewExternalStringFromAscii(&ascii_resource))); | 10232 FACTORY->NewExternalStringFromAscii(&ascii_resource))); |
| 10207 | 10233 |
| 10208 env->Global()->Set(v8_str("lhs"), lhs); | 10234 env->Global()->Set(v8_str("lhs"), lhs); |
| 10209 env->Global()->Set(v8_str("rhs"), rhs); | 10235 env->Global()->Set(v8_str("rhs"), rhs); |
| 10210 | 10236 |
| 10211 CompileRun( | 10237 CompileRun( |
| 10212 "var cons = lhs + rhs;" | 10238 "var cons = lhs + rhs;" |
| 10213 "var slice = lhs.substring(1, lhs.length - 1);" | 10239 "var slice = lhs.substring(1, lhs.length - 1);" |
| 10214 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); | 10240 "var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);"); |
| 10215 | 10241 |
| 10216 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); | 10242 MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10281 | 10307 |
| 10282 // Initialize the contents of two_byte_content_ to be a uc16 representation | 10308 // Initialize the contents of two_byte_content_ to be a uc16 representation |
| 10283 // of "aaaaaaaaaaaaaab". | 10309 // of "aaaaaaaaaaaaaab". |
| 10284 for (int i = 0; i < 14; i++) { | 10310 for (int i = 0; i < 14; i++) { |
| 10285 two_byte_content_[i] = 'a'; | 10311 two_byte_content_[i] = 'a'; |
| 10286 } | 10312 } |
| 10287 two_byte_content_[14] = 'b'; | 10313 two_byte_content_[14] = 'b'; |
| 10288 | 10314 |
| 10289 // Create the input string for the regexp - the one we are going to change | 10315 // Create the input string for the regexp - the one we are going to change |
| 10290 // properties of. | 10316 // properties of. |
| 10291 input_ = i::Factory::NewExternalStringFromAscii(&ascii_resource_); | 10317 input_ = FACTORY->NewExternalStringFromAscii(&ascii_resource_); |
| 10292 | 10318 |
| 10293 // Inject the input as a global variable. | 10319 // Inject the input as a global variable. |
| 10294 i::Handle<i::String> input_name = | 10320 i::Handle<i::String> input_name = |
| 10295 i::Factory::NewStringFromAscii(i::Vector<const char>("input", 5)); | 10321 FACTORY->NewStringFromAscii(i::Vector<const char>("input", 5)); |
| 10296 i::Top::global_context()->global()->SetProperty( | 10322 i::Isolate::Current()->global_context()->global()->SetProperty( |
| 10297 *input_name, | 10323 *input_name, |
| 10298 *input_, | 10324 *input_, |
| 10299 NONE, | 10325 NONE, |
| 10300 i::kNonStrictMode)->ToObjectChecked(); | 10326 i::kNonStrictMode)->ToObjectChecked(); |
| 10301 | 10327 |
| 10302 MorphThread morph_thread(this); | 10328 MorphThread morph_thread(i::Isolate::Current(), this); |
| 10303 morph_thread.Start(); | 10329 morph_thread.Start(); |
| 10304 v8::Locker::StartPreemption(1); | 10330 v8::Locker::StartPreemption(1); |
| 10305 LongRunningRegExp(); | 10331 LongRunningRegExp(); |
| 10306 { | 10332 { |
| 10307 v8::Unlocker unlock; | 10333 v8::Unlocker unlock; |
| 10308 morph_thread.Join(); | 10334 morph_thread.Join(); |
| 10309 } | 10335 } |
| 10310 v8::Locker::StopPreemption(); | 10336 v8::Locker::StopPreemption(); |
| 10311 CHECK(regexp_success_); | 10337 CHECK(regexp_success_); |
| 10312 CHECK(morph_success_); | 10338 CHECK(morph_success_); |
| 10313 } | 10339 } |
| 10314 private: | 10340 private: |
| 10315 | 10341 |
| 10316 // Number of string modifications required. | 10342 // Number of string modifications required. |
| 10317 static const int kRequiredModifications = 5; | 10343 static const int kRequiredModifications = 5; |
| 10318 static const int kMaxModifications = 100; | 10344 static const int kMaxModifications = 100; |
| 10319 | 10345 |
| 10320 class MorphThread : public i::Thread { | 10346 class MorphThread : public i::Thread { |
| 10321 public: | 10347 public: |
| 10322 explicit MorphThread(RegExpStringModificationTest* test) | 10348 explicit MorphThread(i::Isolate* isolate, |
| 10323 : test_(test) {} | 10349 RegExpStringModificationTest* test) |
| 10350 : Thread(isolate), test_(test) {} |
| 10324 virtual void Run() { | 10351 virtual void Run() { |
| 10325 test_->MorphString(); | 10352 test_->MorphString(); |
| 10326 } | 10353 } |
| 10327 private: | 10354 private: |
| 10328 RegExpStringModificationTest* test_; | 10355 RegExpStringModificationTest* test_; |
| 10329 }; | 10356 }; |
| 10330 | 10357 |
| 10331 void MorphString() { | 10358 void MorphString() { |
| 10332 block_->Wait(); | 10359 block_->Wait(); |
| 10333 while (morphs_during_regexp_ < kRequiredModifications && | 10360 while (morphs_during_regexp_ < kRequiredModifications && |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10746 } | 10773 } |
| 10747 | 10774 |
| 10748 | 10775 |
| 10749 THREADED_TEST(PixelArray) { | 10776 THREADED_TEST(PixelArray) { |
| 10750 v8::HandleScope scope; | 10777 v8::HandleScope scope; |
| 10751 LocalContext context; | 10778 LocalContext context; |
| 10752 const int kElementCount = 260; | 10779 const int kElementCount = 260; |
| 10753 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 10780 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
| 10754 i::Handle<i::ExternalPixelArray> pixels = | 10781 i::Handle<i::ExternalPixelArray> pixels = |
| 10755 i::Handle<i::ExternalPixelArray>::cast( | 10782 i::Handle<i::ExternalPixelArray>::cast( |
| 10756 i::Factory::NewExternalArray(kElementCount, | 10783 FACTORY->NewExternalArray(kElementCount, |
| 10757 v8::kExternalPixelArray, | 10784 v8::kExternalPixelArray, |
| 10758 pixel_data)); | 10785 pixel_data)); |
| 10759 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 10786 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
| 10760 for (int i = 0; i < kElementCount; i++) { | 10787 for (int i = 0; i < kElementCount; i++) { |
| 10761 pixels->set(i, i % 256); | 10788 pixels->set(i, i % 256); |
| 10762 } | 10789 } |
| 10763 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 10790 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
| 10764 for (int i = 0; i < kElementCount; i++) { | 10791 for (int i = 0; i < kElementCount; i++) { |
| 10765 CHECK_EQ(i % 256, pixels->get(i)); | 10792 CHECK_EQ(i % 256, pixels->get(i)); |
| 10766 CHECK_EQ(i % 256, pixel_data[i]); | 10793 CHECK_EQ(i % 256, pixel_data[i]); |
| 10767 } | 10794 } |
| 10768 | 10795 |
| 10769 v8::Handle<v8::Object> obj = v8::Object::New(); | 10796 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 10770 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 10797 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
| 10771 // Set the elements to be the pixels. | 10798 // Set the elements to be the pixels. |
| 10772 // jsobj->set_elements(*pixels); | 10799 // jsobj->set_elements(*pixels); |
| 10773 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 10800 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11155 } | 11182 } |
| 11156 | 11183 |
| 11157 | 11184 |
| 11158 THREADED_TEST(PixelArrayWithInterceptor) { | 11185 THREADED_TEST(PixelArrayWithInterceptor) { |
| 11159 v8::HandleScope scope; | 11186 v8::HandleScope scope; |
| 11160 LocalContext context; | 11187 LocalContext context; |
| 11161 const int kElementCount = 260; | 11188 const int kElementCount = 260; |
| 11162 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 11189 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
| 11163 i::Handle<i::ExternalPixelArray> pixels = | 11190 i::Handle<i::ExternalPixelArray> pixels = |
| 11164 i::Handle<i::ExternalPixelArray>::cast( | 11191 i::Handle<i::ExternalPixelArray>::cast( |
| 11165 i::Factory::NewExternalArray(kElementCount, | 11192 FACTORY->NewExternalArray(kElementCount, |
| 11166 v8::kExternalPixelArray, | 11193 v8::kExternalPixelArray, |
| 11167 pixel_data)); | 11194 pixel_data)); |
| 11168 for (int i = 0; i < kElementCount; i++) { | 11195 for (int i = 0; i < kElementCount; i++) { |
| 11169 pixels->set(i, i % 256); | 11196 pixels->set(i, i % 256); |
| 11170 } | 11197 } |
| 11171 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); | 11198 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); |
| 11172 templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, | 11199 templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter, |
| 11173 NotHandledIndexedPropertySetter); | 11200 NotHandledIndexedPropertySetter); |
| 11174 v8::Handle<v8::Object> obj = templ->NewInstance(); | 11201 v8::Handle<v8::Object> obj = templ->NewInstance(); |
| 11175 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 11202 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
| 11176 context->Global()->Set(v8_str("pixels"), obj); | 11203 context->Global()->Set(v8_str("pixels"), obj); |
| 11177 v8::Handle<v8::Value> result = CompileRun("pixels[1]"); | 11204 v8::Handle<v8::Value> result = CompileRun("pixels[1]"); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11218 int64_t low, | 11245 int64_t low, |
| 11219 int64_t high) { | 11246 int64_t high) { |
| 11220 v8::HandleScope scope; | 11247 v8::HandleScope scope; |
| 11221 LocalContext context; | 11248 LocalContext context; |
| 11222 const int kElementCount = 40; | 11249 const int kElementCount = 40; |
| 11223 int element_size = ExternalArrayElementSize(array_type); | 11250 int element_size = ExternalArrayElementSize(array_type); |
| 11224 ElementType* array_data = | 11251 ElementType* array_data = |
| 11225 static_cast<ElementType*>(malloc(kElementCount * element_size)); | 11252 static_cast<ElementType*>(malloc(kElementCount * element_size)); |
| 11226 i::Handle<ExternalArrayClass> array = | 11253 i::Handle<ExternalArrayClass> array = |
| 11227 i::Handle<ExternalArrayClass>::cast( | 11254 i::Handle<ExternalArrayClass>::cast( |
| 11228 i::Factory::NewExternalArray(kElementCount, array_type, array_data)); | 11255 FACTORY->NewExternalArray(kElementCount, array_type, array_data)); |
| 11229 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 11256 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
| 11230 for (int i = 0; i < kElementCount; i++) { | 11257 for (int i = 0; i < kElementCount; i++) { |
| 11231 array->set(i, static_cast<ElementType>(i)); | 11258 array->set(i, static_cast<ElementType>(i)); |
| 11232 } | 11259 } |
| 11233 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 11260 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
| 11234 for (int i = 0; i < kElementCount; i++) { | 11261 for (int i = 0; i < kElementCount; i++) { |
| 11235 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get(i))); | 11262 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array->get(i))); |
| 11236 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); | 11263 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); |
| 11237 } | 11264 } |
| 11238 | 11265 |
| 11239 v8::Handle<v8::Object> obj = v8::Object::New(); | 11266 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 11240 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 11267 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
| 11241 // Set the elements to be the external array. | 11268 // Set the elements to be the external array. |
| 11242 obj->SetIndexedPropertiesToExternalArrayData(array_data, | 11269 obj->SetIndexedPropertiesToExternalArrayData(array_data, |
| 11243 array_type, | 11270 array_type, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11340 result = CompileRun("var tmp_array = ext_array;" | 11367 result = CompileRun("var tmp_array = ext_array;" |
| 11341 "var sum = 0;" | 11368 "var sum = 0;" |
| 11342 "for (var i = 0; i < 8; i++) {" | 11369 "for (var i = 0; i < 8; i++) {" |
| 11343 " tmp_array[i] = i;" | 11370 " tmp_array[i] = i;" |
| 11344 " sum += tmp_array[i];" | 11371 " sum += tmp_array[i];" |
| 11345 " if (i == 4) {" | 11372 " if (i == 4) {" |
| 11346 " tmp_array = {};" | 11373 " tmp_array = {};" |
| 11347 " }" | 11374 " }" |
| 11348 "}" | 11375 "}" |
| 11349 "sum;"); | 11376 "sum;"); |
| 11350 i::Heap::CollectAllGarbage(false); // Force GC to trigger verification. | 11377 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. |
| 11351 CHECK_EQ(28, result->Int32Value()); | 11378 CHECK_EQ(28, result->Int32Value()); |
| 11352 | 11379 |
| 11353 // Make sure out-of-range loads do not throw. | 11380 // Make sure out-of-range loads do not throw. |
| 11354 i::OS::SNPrintF(test_buf, | 11381 i::OS::SNPrintF(test_buf, |
| 11355 "var caught_exception = false;" | 11382 "var caught_exception = false;" |
| 11356 "try {" | 11383 "try {" |
| 11357 " ext_array[%d];" | 11384 " ext_array[%d];" |
| 11358 "} catch (e) {" | 11385 "} catch (e) {" |
| 11359 " caught_exception = true;" | 11386 " caught_exception = true;" |
| 11360 "}" | 11387 "}" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11497 // This catches bugs in the instructions used for the KeyedLoadIC | 11524 // This catches bugs in the instructions used for the KeyedLoadIC |
| 11498 // for byte and word types. | 11525 // for byte and word types. |
| 11499 { | 11526 { |
| 11500 const int kXSize = 300; | 11527 const int kXSize = 300; |
| 11501 const int kYSize = 300; | 11528 const int kYSize = 300; |
| 11502 const int kLargeElementCount = kXSize * kYSize * 4; | 11529 const int kLargeElementCount = kXSize * kYSize * 4; |
| 11503 ElementType* large_array_data = | 11530 ElementType* large_array_data = |
| 11504 static_cast<ElementType*>(malloc(kLargeElementCount * element_size)); | 11531 static_cast<ElementType*>(malloc(kLargeElementCount * element_size)); |
| 11505 i::Handle<ExternalArrayClass> large_array = | 11532 i::Handle<ExternalArrayClass> large_array = |
| 11506 i::Handle<ExternalArrayClass>::cast( | 11533 i::Handle<ExternalArrayClass>::cast( |
| 11507 i::Factory::NewExternalArray(kLargeElementCount, | 11534 FACTORY->NewExternalArray(kLargeElementCount, |
| 11508 array_type, | 11535 array_type, |
| 11509 array_data)); | 11536 array_data)); |
| 11510 v8::Handle<v8::Object> large_obj = v8::Object::New(); | 11537 v8::Handle<v8::Object> large_obj = v8::Object::New(); |
| 11511 // Set the elements to be the external array. | 11538 // Set the elements to be the external array. |
| 11512 large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data, | 11539 large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data, |
| 11513 array_type, | 11540 array_type, |
| 11514 kLargeElementCount); | 11541 kLargeElementCount); |
| 11515 context->Global()->Set(v8_str("large_array"), large_obj); | 11542 context->Global()->Set(v8_str("large_array"), large_obj); |
| 11516 // Initialize contents of a few rows. | 11543 // Initialize contents of a few rows. |
| 11517 for (int x = 0; x < 300; x++) { | 11544 for (int x = 0; x < 300; x++) { |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11933 if (rv) | 11960 if (rv) |
| 11934 break; | 11961 break; |
| 11935 } | 11962 } |
| 11936 CHECK(rv == true); | 11963 CHECK(rv == true); |
| 11937 } | 11964 } |
| 11938 | 11965 |
| 11939 | 11966 |
| 11940 static uint32_t* stack_limit; | 11967 static uint32_t* stack_limit; |
| 11941 | 11968 |
| 11942 static v8::Handle<Value> GetStackLimitCallback(const v8::Arguments& args) { | 11969 static v8::Handle<Value> GetStackLimitCallback(const v8::Arguments& args) { |
| 11943 stack_limit = reinterpret_cast<uint32_t*>(i::StackGuard::real_climit()); | 11970 stack_limit = reinterpret_cast<uint32_t*>( |
| 11971 i::Isolate::Current()->stack_guard()->real_climit()); |
| 11944 return v8::Undefined(); | 11972 return v8::Undefined(); |
| 11945 } | 11973 } |
| 11946 | 11974 |
| 11947 | 11975 |
| 11948 // Uses the address of a local variable to determine the stack top now. | 11976 // Uses the address of a local variable to determine the stack top now. |
| 11949 // Given a size, returns an address that is that far from the current | 11977 // Given a size, returns an address that is that far from the current |
| 11950 // top of stack. | 11978 // top of stack. |
| 11951 static uint32_t* ComputeStackLimit(uint32_t size) { | 11979 static uint32_t* ComputeStackLimit(uint32_t size) { |
| 11952 uint32_t* answer = &size - (size / sizeof(size)); | 11980 uint32_t* answer = &size - (size / sizeof(size)); |
| 11953 // If the size is very large and the stack is very near the bottom of | 11981 // If the size is very large and the stack is very near the bottom of |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12199 Local<v8::String> obj = v8::String::New(""); | 12227 Local<v8::String> obj = v8::String::New(""); |
| 12200 context->SetData(obj); | 12228 context->SetData(obj); |
| 12201 CompileRun(source_simple); | 12229 CompileRun(source_simple); |
| 12202 context->Exit(); | 12230 context->Exit(); |
| 12203 } | 12231 } |
| 12204 context.Dispose(); | 12232 context.Dispose(); |
| 12205 for (gc_count = 1; gc_count < 10; gc_count++) { | 12233 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 12206 other_context->Enter(); | 12234 other_context->Enter(); |
| 12207 CompileRun(source_simple); | 12235 CompileRun(source_simple); |
| 12208 other_context->Exit(); | 12236 other_context->Exit(); |
| 12209 i::Heap::CollectAllGarbage(false); | 12237 HEAP->CollectAllGarbage(false); |
| 12210 if (GetGlobalObjectsCount() == 1) break; | 12238 if (GetGlobalObjectsCount() == 1) break; |
| 12211 } | 12239 } |
| 12212 CHECK_GE(2, gc_count); | 12240 CHECK_GE(2, gc_count); |
| 12213 CHECK_EQ(1, GetGlobalObjectsCount()); | 12241 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 12214 | 12242 |
| 12215 // Eval in a function creates reference from the compilation cache to the | 12243 // Eval in a function creates reference from the compilation cache to the |
| 12216 // global object. | 12244 // global object. |
| 12217 const char* source_eval = "function f(){eval('1')}; f()"; | 12245 const char* source_eval = "function f(){eval('1')}; f()"; |
| 12218 context = Context::New(); | 12246 context = Context::New(); |
| 12219 { | 12247 { |
| 12220 v8::HandleScope scope; | 12248 v8::HandleScope scope; |
| 12221 | 12249 |
| 12222 context->Enter(); | 12250 context->Enter(); |
| 12223 CompileRun(source_eval); | 12251 CompileRun(source_eval); |
| 12224 context->Exit(); | 12252 context->Exit(); |
| 12225 } | 12253 } |
| 12226 context.Dispose(); | 12254 context.Dispose(); |
| 12227 for (gc_count = 1; gc_count < 10; gc_count++) { | 12255 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 12228 other_context->Enter(); | 12256 other_context->Enter(); |
| 12229 CompileRun(source_eval); | 12257 CompileRun(source_eval); |
| 12230 other_context->Exit(); | 12258 other_context->Exit(); |
| 12231 i::Heap::CollectAllGarbage(false); | 12259 HEAP->CollectAllGarbage(false); |
| 12232 if (GetGlobalObjectsCount() == 1) break; | 12260 if (GetGlobalObjectsCount() == 1) break; |
| 12233 } | 12261 } |
| 12234 CHECK_GE(2, gc_count); | 12262 CHECK_GE(2, gc_count); |
| 12235 CHECK_EQ(1, GetGlobalObjectsCount()); | 12263 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 12236 | 12264 |
| 12237 // Looking up the line number for an exception creates reference from the | 12265 // Looking up the line number for an exception creates reference from the |
| 12238 // compilation cache to the global object. | 12266 // compilation cache to the global object. |
| 12239 const char* source_exception = "function f(){throw 1;} f()"; | 12267 const char* source_exception = "function f(){throw 1;} f()"; |
| 12240 context = Context::New(); | 12268 context = Context::New(); |
| 12241 { | 12269 { |
| 12242 v8::HandleScope scope; | 12270 v8::HandleScope scope; |
| 12243 | 12271 |
| 12244 context->Enter(); | 12272 context->Enter(); |
| 12245 v8::TryCatch try_catch; | 12273 v8::TryCatch try_catch; |
| 12246 CompileRun(source_exception); | 12274 CompileRun(source_exception); |
| 12247 CHECK(try_catch.HasCaught()); | 12275 CHECK(try_catch.HasCaught()); |
| 12248 v8::Handle<v8::Message> message = try_catch.Message(); | 12276 v8::Handle<v8::Message> message = try_catch.Message(); |
| 12249 CHECK(!message.IsEmpty()); | 12277 CHECK(!message.IsEmpty()); |
| 12250 CHECK_EQ(1, message->GetLineNumber()); | 12278 CHECK_EQ(1, message->GetLineNumber()); |
| 12251 context->Exit(); | 12279 context->Exit(); |
| 12252 } | 12280 } |
| 12253 context.Dispose(); | 12281 context.Dispose(); |
| 12254 for (gc_count = 1; gc_count < 10; gc_count++) { | 12282 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 12255 other_context->Enter(); | 12283 other_context->Enter(); |
| 12256 CompileRun(source_exception); | 12284 CompileRun(source_exception); |
| 12257 other_context->Exit(); | 12285 other_context->Exit(); |
| 12258 i::Heap::CollectAllGarbage(false); | 12286 HEAP->CollectAllGarbage(false); |
| 12259 if (GetGlobalObjectsCount() == 1) break; | 12287 if (GetGlobalObjectsCount() == 1) break; |
| 12260 } | 12288 } |
| 12261 CHECK_GE(2, gc_count); | 12289 CHECK_GE(2, gc_count); |
| 12262 CHECK_EQ(1, GetGlobalObjectsCount()); | 12290 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 12263 | 12291 |
| 12264 other_context.Dispose(); | 12292 other_context.Dispose(); |
| 12265 } | 12293 } |
| 12266 | 12294 |
| 12267 | 12295 |
| 12268 THREADED_TEST(ScriptOrigin) { | 12296 THREADED_TEST(ScriptOrigin) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12466 ++epilogue_call_count_second; | 12494 ++epilogue_call_count_second; |
| 12467 } | 12495 } |
| 12468 | 12496 |
| 12469 TEST(GCCallbacks) { | 12497 TEST(GCCallbacks) { |
| 12470 LocalContext context; | 12498 LocalContext context; |
| 12471 | 12499 |
| 12472 v8::V8::AddGCPrologueCallback(PrologueCallback); | 12500 v8::V8::AddGCPrologueCallback(PrologueCallback); |
| 12473 v8::V8::AddGCEpilogueCallback(EpilogueCallback); | 12501 v8::V8::AddGCEpilogueCallback(EpilogueCallback); |
| 12474 CHECK_EQ(0, prologue_call_count); | 12502 CHECK_EQ(0, prologue_call_count); |
| 12475 CHECK_EQ(0, epilogue_call_count); | 12503 CHECK_EQ(0, epilogue_call_count); |
| 12476 i::Heap::CollectAllGarbage(false); | 12504 HEAP->CollectAllGarbage(false); |
| 12477 CHECK_EQ(1, prologue_call_count); | 12505 CHECK_EQ(1, prologue_call_count); |
| 12478 CHECK_EQ(1, epilogue_call_count); | 12506 CHECK_EQ(1, epilogue_call_count); |
| 12479 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); | 12507 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); |
| 12480 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); | 12508 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); |
| 12481 i::Heap::CollectAllGarbage(false); | 12509 HEAP->CollectAllGarbage(false); |
| 12482 CHECK_EQ(2, prologue_call_count); | 12510 CHECK_EQ(2, prologue_call_count); |
| 12483 CHECK_EQ(2, epilogue_call_count); | 12511 CHECK_EQ(2, epilogue_call_count); |
| 12484 CHECK_EQ(1, prologue_call_count_second); | 12512 CHECK_EQ(1, prologue_call_count_second); |
| 12485 CHECK_EQ(1, epilogue_call_count_second); | 12513 CHECK_EQ(1, epilogue_call_count_second); |
| 12486 v8::V8::RemoveGCPrologueCallback(PrologueCallback); | 12514 v8::V8::RemoveGCPrologueCallback(PrologueCallback); |
| 12487 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); | 12515 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); |
| 12488 i::Heap::CollectAllGarbage(false); | 12516 HEAP->CollectAllGarbage(false); |
| 12489 CHECK_EQ(2, prologue_call_count); | 12517 CHECK_EQ(2, prologue_call_count); |
| 12490 CHECK_EQ(2, epilogue_call_count); | 12518 CHECK_EQ(2, epilogue_call_count); |
| 12491 CHECK_EQ(2, prologue_call_count_second); | 12519 CHECK_EQ(2, prologue_call_count_second); |
| 12492 CHECK_EQ(2, epilogue_call_count_second); | 12520 CHECK_EQ(2, epilogue_call_count_second); |
| 12493 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); | 12521 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); |
| 12494 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); | 12522 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); |
| 12495 i::Heap::CollectAllGarbage(false); | 12523 HEAP->CollectAllGarbage(false); |
| 12496 CHECK_EQ(2, prologue_call_count); | 12524 CHECK_EQ(2, prologue_call_count); |
| 12497 CHECK_EQ(2, epilogue_call_count); | 12525 CHECK_EQ(2, epilogue_call_count); |
| 12498 CHECK_EQ(2, prologue_call_count_second); | 12526 CHECK_EQ(2, prologue_call_count_second); |
| 12499 CHECK_EQ(2, epilogue_call_count_second); | 12527 CHECK_EQ(2, epilogue_call_count_second); |
| 12500 } | 12528 } |
| 12501 | 12529 |
| 12502 | 12530 |
| 12503 THREADED_TEST(AddToJSFunctionResultCache) { | 12531 THREADED_TEST(AddToJSFunctionResultCache) { |
| 12504 i::FLAG_allow_natives_syntax = true; | 12532 i::FLAG_allow_natives_syntax = true; |
| 12505 v8::HandleScope scope; | 12533 v8::HandleScope scope; |
| 12506 | 12534 |
| 12507 LocalContext context; | 12535 LocalContext context; |
| 12508 | 12536 |
| 12509 const char* code = | 12537 const char* code = |
| 12510 "(function() {" | 12538 "(function() {" |
| 12511 " var key0 = 'a';" | 12539 " var key0 = 'a';" |
| 12512 " var key1 = 'b';" | 12540 " var key1 = 'b';" |
| 12513 " var r0 = %_GetFromCache(0, key0);" | 12541 " var r0 = %_GetFromCache(0, key0);" |
| 12514 " var r1 = %_GetFromCache(0, key1);" | 12542 " var r1 = %_GetFromCache(0, key1);" |
| 12515 " var r0_ = %_GetFromCache(0, key0);" | 12543 " var r0_ = %_GetFromCache(0, key0);" |
| 12516 " if (r0 !== r0_)" | 12544 " if (r0 !== r0_)" |
| 12517 " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" | 12545 " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" |
| 12518 " var r1_ = %_GetFromCache(0, key1);" | 12546 " var r1_ = %_GetFromCache(0, key1);" |
| 12519 " if (r1 !== r1_)" | 12547 " if (r1 !== r1_)" |
| 12520 " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" | 12548 " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" |
| 12521 " return 'PASSED';" | 12549 " return 'PASSED';" |
| 12522 "})()"; | 12550 "})()"; |
| 12523 i::Heap::ClearJSFunctionResultCaches(); | 12551 HEAP->ClearJSFunctionResultCaches(); |
| 12524 ExpectString(code, "PASSED"); | 12552 ExpectString(code, "PASSED"); |
| 12525 } | 12553 } |
| 12526 | 12554 |
| 12527 | 12555 |
| 12528 static const int k0CacheSize = 16; | 12556 static const int k0CacheSize = 16; |
| 12529 | 12557 |
| 12530 THREADED_TEST(FillJSFunctionResultCache) { | 12558 THREADED_TEST(FillJSFunctionResultCache) { |
| 12531 i::FLAG_allow_natives_syntax = true; | 12559 i::FLAG_allow_natives_syntax = true; |
| 12532 v8::HandleScope scope; | 12560 v8::HandleScope scope; |
| 12533 | 12561 |
| 12534 LocalContext context; | 12562 LocalContext context; |
| 12535 | 12563 |
| 12536 const char* code = | 12564 const char* code = |
| 12537 "(function() {" | 12565 "(function() {" |
| 12538 " var k = 'a';" | 12566 " var k = 'a';" |
| 12539 " var r = %_GetFromCache(0, k);" | 12567 " var r = %_GetFromCache(0, k);" |
| 12540 " for (var i = 0; i < 16; i++) {" | 12568 " for (var i = 0; i < 16; i++) {" |
| 12541 " %_GetFromCache(0, 'a' + i);" | 12569 " %_GetFromCache(0, 'a' + i);" |
| 12542 " };" | 12570 " };" |
| 12543 " if (r === %_GetFromCache(0, k))" | 12571 " if (r === %_GetFromCache(0, k))" |
| 12544 " return 'FAILED: k0CacheSize is too small';" | 12572 " return 'FAILED: k0CacheSize is too small';" |
| 12545 " return 'PASSED';" | 12573 " return 'PASSED';" |
| 12546 "})()"; | 12574 "})()"; |
| 12547 i::Heap::ClearJSFunctionResultCaches(); | 12575 HEAP->ClearJSFunctionResultCaches(); |
| 12548 ExpectString(code, "PASSED"); | 12576 ExpectString(code, "PASSED"); |
| 12549 } | 12577 } |
| 12550 | 12578 |
| 12551 | 12579 |
| 12552 THREADED_TEST(RoundRobinGetFromCache) { | 12580 THREADED_TEST(RoundRobinGetFromCache) { |
| 12553 i::FLAG_allow_natives_syntax = true; | 12581 i::FLAG_allow_natives_syntax = true; |
| 12554 v8::HandleScope scope; | 12582 v8::HandleScope scope; |
| 12555 | 12583 |
| 12556 LocalContext context; | 12584 LocalContext context; |
| 12557 | 12585 |
| 12558 const char* code = | 12586 const char* code = |
| 12559 "(function() {" | 12587 "(function() {" |
| 12560 " var keys = [];" | 12588 " var keys = [];" |
| 12561 " for (var i = 0; i < 16; i++) keys.push(i);" | 12589 " for (var i = 0; i < 16; i++) keys.push(i);" |
| 12562 " var values = [];" | 12590 " var values = [];" |
| 12563 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" | 12591 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" |
| 12564 " for (var i = 0; i < 16; i++) {" | 12592 " for (var i = 0; i < 16; i++) {" |
| 12565 " var v = %_GetFromCache(0, keys[i]);" | 12593 " var v = %_GetFromCache(0, keys[i]);" |
| 12566 " if (v !== values[i])" | 12594 " if (v !== values[i])" |
| 12567 " return 'Wrong value for ' + " | 12595 " return 'Wrong value for ' + " |
| 12568 " keys[i] + ': ' + v + ' vs. ' + values[i];" | 12596 " keys[i] + ': ' + v + ' vs. ' + values[i];" |
| 12569 " };" | 12597 " };" |
| 12570 " return 'PASSED';" | 12598 " return 'PASSED';" |
| 12571 "})()"; | 12599 "})()"; |
| 12572 i::Heap::ClearJSFunctionResultCaches(); | 12600 HEAP->ClearJSFunctionResultCaches(); |
| 12573 ExpectString(code, "PASSED"); | 12601 ExpectString(code, "PASSED"); |
| 12574 } | 12602 } |
| 12575 | 12603 |
| 12576 | 12604 |
| 12577 THREADED_TEST(ReverseGetFromCache) { | 12605 THREADED_TEST(ReverseGetFromCache) { |
| 12578 i::FLAG_allow_natives_syntax = true; | 12606 i::FLAG_allow_natives_syntax = true; |
| 12579 v8::HandleScope scope; | 12607 v8::HandleScope scope; |
| 12580 | 12608 |
| 12581 LocalContext context; | 12609 LocalContext context; |
| 12582 | 12610 |
| 12583 const char* code = | 12611 const char* code = |
| 12584 "(function() {" | 12612 "(function() {" |
| 12585 " var keys = [];" | 12613 " var keys = [];" |
| 12586 " for (var i = 0; i < 16; i++) keys.push(i);" | 12614 " for (var i = 0; i < 16; i++) keys.push(i);" |
| 12587 " var values = [];" | 12615 " var values = [];" |
| 12588 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" | 12616 " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" |
| 12589 " for (var i = 15; i >= 16; i--) {" | 12617 " for (var i = 15; i >= 16; i--) {" |
| 12590 " var v = %_GetFromCache(0, keys[i]);" | 12618 " var v = %_GetFromCache(0, keys[i]);" |
| 12591 " if (v !== values[i])" | 12619 " if (v !== values[i])" |
| 12592 " return 'Wrong value for ' + " | 12620 " return 'Wrong value for ' + " |
| 12593 " keys[i] + ': ' + v + ' vs. ' + values[i];" | 12621 " keys[i] + ': ' + v + ' vs. ' + values[i];" |
| 12594 " };" | 12622 " };" |
| 12595 " return 'PASSED';" | 12623 " return 'PASSED';" |
| 12596 "})()"; | 12624 "})()"; |
| 12597 i::Heap::ClearJSFunctionResultCaches(); | 12625 HEAP->ClearJSFunctionResultCaches(); |
| 12598 ExpectString(code, "PASSED"); | 12626 ExpectString(code, "PASSED"); |
| 12599 } | 12627 } |
| 12600 | 12628 |
| 12601 | 12629 |
| 12602 THREADED_TEST(TestEviction) { | 12630 THREADED_TEST(TestEviction) { |
| 12603 i::FLAG_allow_natives_syntax = true; | 12631 i::FLAG_allow_natives_syntax = true; |
| 12604 v8::HandleScope scope; | 12632 v8::HandleScope scope; |
| 12605 | 12633 |
| 12606 LocalContext context; | 12634 LocalContext context; |
| 12607 | 12635 |
| 12608 const char* code = | 12636 const char* code = |
| 12609 "(function() {" | 12637 "(function() {" |
| 12610 " for (var i = 0; i < 2*16; i++) {" | 12638 " for (var i = 0; i < 2*16; i++) {" |
| 12611 " %_GetFromCache(0, 'a' + i);" | 12639 " %_GetFromCache(0, 'a' + i);" |
| 12612 " };" | 12640 " };" |
| 12613 " return 'PASSED';" | 12641 " return 'PASSED';" |
| 12614 "})()"; | 12642 "})()"; |
| 12615 i::Heap::ClearJSFunctionResultCaches(); | 12643 HEAP->ClearJSFunctionResultCaches(); |
| 12616 ExpectString(code, "PASSED"); | 12644 ExpectString(code, "PASSED"); |
| 12617 } | 12645 } |
| 12618 | 12646 |
| 12619 | 12647 |
| 12620 THREADED_TEST(TwoByteStringInAsciiCons) { | 12648 THREADED_TEST(TwoByteStringInAsciiCons) { |
| 12621 // See Chromium issue 47824. | 12649 // See Chromium issue 47824. |
| 12622 v8::HandleScope scope; | 12650 v8::HandleScope scope; |
| 12623 | 12651 |
| 12624 LocalContext context; | 12652 LocalContext context; |
| 12625 const char* init_code = | 12653 const char* init_code = |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12695 | 12723 |
| 12696 reresult = CompileRun("str2.charCodeAt(2);"); | 12724 reresult = CompileRun("str2.charCodeAt(2);"); |
| 12697 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); | 12725 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); |
| 12698 } | 12726 } |
| 12699 | 12727 |
| 12700 | 12728 |
| 12701 // Failed access check callback that performs a GC on each invocation. | 12729 // Failed access check callback that performs a GC on each invocation. |
| 12702 void FailedAccessCheckCallbackGC(Local<v8::Object> target, | 12730 void FailedAccessCheckCallbackGC(Local<v8::Object> target, |
| 12703 v8::AccessType type, | 12731 v8::AccessType type, |
| 12704 Local<v8::Value> data) { | 12732 Local<v8::Value> data) { |
| 12705 i::Heap::CollectAllGarbage(true); | 12733 HEAP->CollectAllGarbage(true); |
| 12706 } | 12734 } |
| 12707 | 12735 |
| 12708 | 12736 |
| 12709 TEST(GCInFailedAccessCheckCallback) { | 12737 TEST(GCInFailedAccessCheckCallback) { |
| 12710 // Install a failed access check callback that performs a GC on each | 12738 // Install a failed access check callback that performs a GC on each |
| 12711 // invocation. Then force the callback to be called from va | 12739 // invocation. Then force the callback to be called from va |
| 12712 | 12740 |
| 12713 v8::V8::Initialize(); | 12741 v8::V8::Initialize(); |
| 12714 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); | 12742 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); |
| 12715 | 12743 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12776 | 12804 |
| 12777 CHECK_EQ(false, global0->HasRealIndexedProperty(0)); | 12805 CHECK_EQ(false, global0->HasRealIndexedProperty(0)); |
| 12778 CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); | 12806 CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); |
| 12779 CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); | 12807 CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); |
| 12780 | 12808 |
| 12781 // Reset the failed access check callback so it does not influence | 12809 // Reset the failed access check callback so it does not influence |
| 12782 // the other tests. | 12810 // the other tests. |
| 12783 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); | 12811 v8::V8::SetFailedAccessCheckCallbackFunction(NULL); |
| 12784 } | 12812 } |
| 12785 | 12813 |
| 12814 TEST(DefaultIsolateGetCurrent) { |
| 12815 CHECK(v8::Isolate::GetCurrent() != NULL); |
| 12816 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 12817 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12818 printf("*** %s\n", "DefaultIsolateGetCurrent success"); |
| 12819 } |
| 12820 |
| 12821 TEST(IsolateNewDispose) { |
| 12822 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); |
| 12823 v8::Isolate* isolate = v8::Isolate::New(); |
| 12824 CHECK(isolate != NULL); |
| 12825 CHECK(!reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12826 CHECK(current_isolate != isolate); |
| 12827 CHECK(current_isolate == v8::Isolate::GetCurrent()); |
| 12828 |
| 12829 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12830 last_location = last_message = NULL; |
| 12831 isolate->Dispose(); |
| 12832 CHECK_EQ(last_location, NULL); |
| 12833 CHECK_EQ(last_message, NULL); |
| 12834 } |
| 12835 |
| 12836 TEST(IsolateEnterExitDefault) { |
| 12837 v8::HandleScope scope; |
| 12838 LocalContext context; |
| 12839 v8::Isolate* current_isolate = v8::Isolate::GetCurrent(); |
| 12840 CHECK(current_isolate != NULL); // Default isolate. |
| 12841 ExpectString("'hello'", "hello"); |
| 12842 current_isolate->Enter(); |
| 12843 ExpectString("'still working'", "still working"); |
| 12844 current_isolate->Exit(); |
| 12845 ExpectString("'still working 2'", "still working 2"); |
| 12846 current_isolate->Exit(); |
| 12847 // Default isolate is always, well, 'default current'. |
| 12848 CHECK_EQ(v8::Isolate::GetCurrent(), current_isolate); |
| 12849 // Still working since default isolate is auto-entering any thread |
| 12850 // that has no isolate and attempts to execute V8 APIs. |
| 12851 ExpectString("'still working 3'", "still working 3"); |
| 12852 } |
| 12853 |
| 12854 TEST(DisposeDefaultIsolate) { |
| 12855 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12856 |
| 12857 // Run some V8 code to trigger default isolate to become 'current'. |
| 12858 v8::HandleScope scope; |
| 12859 LocalContext context; |
| 12860 ExpectString("'run some V8'", "run some V8"); |
| 12861 |
| 12862 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 12863 CHECK(reinterpret_cast<i::Isolate*>(isolate)->IsDefaultIsolate()); |
| 12864 last_location = last_message = NULL; |
| 12865 isolate->Dispose(); |
| 12866 // It is not possible to dispose default isolate via Isolate API. |
| 12867 CHECK_NE(last_location, NULL); |
| 12868 CHECK_NE(last_message, NULL); |
| 12869 } |
| 12870 |
| 12871 TEST(RunDefaultAndAnotherIsolate) { |
| 12872 v8::HandleScope scope; |
| 12873 LocalContext context; |
| 12874 |
| 12875 // Enter new isolate. |
| 12876 v8::Isolate* isolate = v8::Isolate::New(); |
| 12877 CHECK(isolate); |
| 12878 isolate->Enter(); |
| 12879 { // Need this block because subsequent Exit() will deallocate Heap, |
| 12880 // so we need all scope objects to be deconstructed when it happens. |
| 12881 v8::HandleScope scope_new; |
| 12882 LocalContext context_new; |
| 12883 |
| 12884 // Run something in new isolate. |
| 12885 CompileRun("var foo = 153;"); |
| 12886 ExpectTrue("function f() { return foo == 153; }; f()"); |
| 12887 } |
| 12888 isolate->Exit(); |
| 12889 |
| 12890 // This runs automatically in default isolate. |
| 12891 // Variables in another isolate should be not available. |
| 12892 ExpectTrue("function f() {" |
| 12893 " try {" |
| 12894 " foo;" |
| 12895 " return false;" |
| 12896 " } catch(e) {" |
| 12897 " return true;" |
| 12898 " }" |
| 12899 "};" |
| 12900 "var bar = 371;" |
| 12901 "f()"); |
| 12902 |
| 12903 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12904 last_location = last_message = NULL; |
| 12905 isolate->Dispose(); |
| 12906 CHECK_EQ(last_location, NULL); |
| 12907 CHECK_EQ(last_message, NULL); |
| 12908 |
| 12909 // Check that default isolate still runs. |
| 12910 ExpectTrue("function f() { return bar == 371; }; f()"); |
| 12911 } |
| 12912 |
| 12913 TEST(DisposeIsolateWhenInUse) { |
| 12914 v8::Isolate* isolate = v8::Isolate::New(); |
| 12915 CHECK(isolate); |
| 12916 isolate->Enter(); |
| 12917 v8::HandleScope scope; |
| 12918 LocalContext context; |
| 12919 // Run something in this isolate. |
| 12920 ExpectTrue("true"); |
| 12921 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 12922 last_location = last_message = NULL; |
| 12923 // Still entered, should fail. |
| 12924 isolate->Dispose(); |
| 12925 CHECK_NE(last_location, NULL); |
| 12926 CHECK_NE(last_message, NULL); |
| 12927 } |
| 12928 |
| 12929 TEST(RunTwoIsolatesOnSingleThread) { |
| 12930 // Run isolate 1. |
| 12931 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 12932 isolate1->Enter(); |
| 12933 v8::Persistent<v8::Context> context1 = v8::Context::New(); |
| 12934 |
| 12935 { |
| 12936 v8::Context::Scope cscope(context1); |
| 12937 v8::HandleScope scope; |
| 12938 // Run something in new isolate. |
| 12939 CompileRun("var foo = 'isolate 1';"); |
| 12940 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 12941 } |
| 12942 |
| 12943 // Run isolate 2. |
| 12944 v8::Isolate* isolate2 = v8::Isolate::New(); |
| 12945 v8::Persistent<v8::Context> context2; |
| 12946 |
| 12947 { |
| 12948 v8::Isolate::Scope iscope(isolate2); |
| 12949 context2 = v8::Context::New(); |
| 12950 v8::Context::Scope cscope(context2); |
| 12951 v8::HandleScope scope; |
| 12952 |
| 12953 // Run something in new isolate. |
| 12954 CompileRun("var foo = 'isolate 2';"); |
| 12955 ExpectString("function f() { return foo; }; f()", "isolate 2"); |
| 12956 } |
| 12957 |
| 12958 { |
| 12959 v8::Context::Scope cscope(context1); |
| 12960 v8::HandleScope scope; |
| 12961 // Now again in isolate 1 |
| 12962 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 12963 } |
| 12964 |
| 12965 isolate1->Exit(); |
| 12966 |
| 12967 // Run some stuff in default isolate. |
| 12968 v8::Persistent<v8::Context> context_default = v8::Context::New(); |
| 12969 |
| 12970 { |
| 12971 v8::Context::Scope cscope(context_default); |
| 12972 v8::HandleScope scope; |
| 12973 // Variables in other isolates should be not available, verify there |
| 12974 // is an exception. |
| 12975 ExpectTrue("function f() {" |
| 12976 " try {" |
| 12977 " foo;" |
| 12978 " return false;" |
| 12979 " } catch(e) {" |
| 12980 " return true;" |
| 12981 " }" |
| 12982 "};" |
| 12983 "var isDefaultIsolate = true;" |
| 12984 "f()"); |
| 12985 } |
| 12986 |
| 12987 isolate1->Enter(); |
| 12988 |
| 12989 { |
| 12990 v8::Isolate::Scope iscope(isolate2); |
| 12991 v8::Context::Scope cscope(context2); |
| 12992 v8::HandleScope scope; |
| 12993 ExpectString("function f() { return foo; }; f()", "isolate 2"); |
| 12994 } |
| 12995 |
| 12996 { |
| 12997 v8::Context::Scope cscope(context1); |
| 12998 v8::HandleScope scope; |
| 12999 ExpectString("function f() { return foo; }; f()", "isolate 1"); |
| 13000 } |
| 13001 |
| 13002 { |
| 13003 v8::Isolate::Scope iscope(isolate2); |
| 13004 context2.Dispose(); |
| 13005 } |
| 13006 |
| 13007 context1.Dispose(); |
| 13008 isolate1->Exit(); |
| 13009 |
| 13010 v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
| 13011 last_location = last_message = NULL; |
| 13012 |
| 13013 isolate1->Dispose(); |
| 13014 CHECK_EQ(last_location, NULL); |
| 13015 CHECK_EQ(last_message, NULL); |
| 13016 |
| 13017 isolate2->Dispose(); |
| 13018 CHECK_EQ(last_location, NULL); |
| 13019 CHECK_EQ(last_message, NULL); |
| 13020 |
| 13021 // Check that default isolate still runs. |
| 13022 { |
| 13023 v8::Context::Scope cscope(context_default); |
| 13024 v8::HandleScope scope; |
| 13025 ExpectTrue("function f() { return isDefaultIsolate; }; f()"); |
| 13026 } |
| 13027 } |
| 13028 |
| 13029 static int CalcFibonacci(v8::Isolate* isolate, int limit) { |
| 13030 v8::Isolate::Scope isolate_scope(isolate); |
| 13031 v8::HandleScope scope; |
| 13032 LocalContext context; |
| 13033 i::ScopedVector<char> code(1024); |
| 13034 i::OS::SNPrintF(code, "function fib(n) {" |
| 13035 " if (n <= 2) return 1;" |
| 13036 " return fib(n-1) + fib(n-2);" |
| 13037 "}" |
| 13038 "fib(%d)", limit); |
| 13039 Local<Value> value = CompileRun(code.start()); |
| 13040 CHECK(value->IsNumber()); |
| 13041 return static_cast<int>(value->NumberValue()); |
| 13042 } |
| 13043 |
| 13044 class IsolateThread : public v8::internal::Thread { |
| 13045 public: |
| 13046 explicit IsolateThread(v8::Isolate* isolate, int fib_limit) |
| 13047 : Thread(NULL), |
| 13048 isolate_(isolate), |
| 13049 fib_limit_(fib_limit), |
| 13050 result_(0) { } |
| 13051 |
| 13052 void Run() { |
| 13053 result_ = CalcFibonacci(isolate_, fib_limit_); |
| 13054 } |
| 13055 |
| 13056 int result() { return result_; } |
| 13057 |
| 13058 private: |
| 13059 v8::Isolate* isolate_; |
| 13060 int fib_limit_; |
| 13061 int result_; |
| 13062 }; |
| 13063 |
| 13064 TEST(MultipleIsolatesOnIndividualThreads) { |
| 13065 v8::Isolate* isolate1 = v8::Isolate::New(); |
| 13066 v8::Isolate* isolate2 = v8::Isolate::New(); |
| 13067 |
| 13068 IsolateThread thread1(isolate1, 21); |
| 13069 IsolateThread thread2(isolate2, 12); |
| 13070 |
| 13071 // Compute some fibonacci numbers on 3 threads in 3 isolates. |
| 13072 thread1.Start(); |
| 13073 thread2.Start(); |
| 13074 |
| 13075 int result1 = CalcFibonacci(v8::Isolate::GetCurrent(), 21); |
| 13076 int result2 = CalcFibonacci(v8::Isolate::GetCurrent(), 12); |
| 13077 |
| 13078 thread1.Join(); |
| 13079 thread2.Join(); |
| 13080 |
| 13081 // Compare results. The actual fibonacci numbers for 12 and 21 are taken |
| 13082 // (I'm lazy!) from http://en.wikipedia.org/wiki/Fibonacci_number |
| 13083 CHECK_EQ(result1, 10946); |
| 13084 CHECK_EQ(result2, 144); |
| 13085 CHECK_EQ(result1, thread1.result()); |
| 13086 CHECK_EQ(result2, thread2.result()); |
| 13087 |
| 13088 isolate1->Dispose(); |
| 13089 isolate2->Dispose(); |
| 13090 } |
| 13091 |
| 13092 |
| 13093 class InitDefaultIsolateThread : public v8::internal::Thread { |
| 13094 public: |
| 13095 enum TestCase { IgnoreOOM, SetResourceConstraints, SetFatalHandler }; |
| 13096 |
| 13097 explicit InitDefaultIsolateThread(TestCase testCase) |
| 13098 : Thread(NULL), |
| 13099 testCase_(testCase), |
| 13100 result_(false) { } |
| 13101 |
| 13102 void Run() { |
| 13103 switch (testCase_) { |
| 13104 case IgnoreOOM: |
| 13105 v8::V8::IgnoreOutOfMemoryException(); |
| 13106 break; |
| 13107 |
| 13108 case SetResourceConstraints: { |
| 13109 static const int K = 1024; |
| 13110 v8::ResourceConstraints constraints; |
| 13111 constraints.set_max_young_space_size(256 * K); |
| 13112 constraints.set_max_old_space_size(4 * K * K); |
| 13113 v8::SetResourceConstraints(&constraints); |
| 13114 break; |
| 13115 } |
| 13116 |
| 13117 case SetFatalHandler: |
| 13118 v8::V8::SetFatalErrorHandler(NULL); |
| 13119 break; |
| 13120 } |
| 13121 result_ = true; |
| 13122 } |
| 13123 |
| 13124 bool result() { return result_; } |
| 13125 |
| 13126 private: |
| 13127 TestCase testCase_; |
| 13128 bool result_; |
| 13129 }; |
| 13130 |
| 13131 |
| 13132 static void InitializeTestHelper(InitDefaultIsolateThread::TestCase testCase) { |
| 13133 InitDefaultIsolateThread thread(testCase); |
| 13134 thread.Start(); |
| 13135 thread.Join(); |
| 13136 CHECK_EQ(thread.result(), true); |
| 13137 } |
| 13138 |
| 13139 TEST(InitializeDefaultIsolateOnSecondaryThread1) { |
| 13140 InitializeTestHelper(InitDefaultIsolateThread::IgnoreOOM); |
| 13141 } |
| 13142 |
| 13143 TEST(InitializeDefaultIsolateOnSecondaryThread2) { |
| 13144 InitializeTestHelper(InitDefaultIsolateThread::SetResourceConstraints); |
| 13145 } |
| 13146 |
| 13147 TEST(InitializeDefaultIsolateOnSecondaryThread3) { |
| 13148 InitializeTestHelper(InitDefaultIsolateThread::SetFatalHandler); |
| 13149 } |
| 13150 |
| 12786 | 13151 |
| 12787 TEST(StringCheckMultipleContexts) { | 13152 TEST(StringCheckMultipleContexts) { |
| 12788 const char* code = | 13153 const char* code = |
| 12789 "(function() { return \"a\".charAt(0); })()"; | 13154 "(function() { return \"a\".charAt(0); })()"; |
| 12790 | 13155 |
| 12791 { | 13156 { |
| 12792 // Run the code twice in the first context to initialize the call IC. | 13157 // Run the code twice in the first context to initialize the call IC. |
| 12793 v8::HandleScope scope; | 13158 v8::HandleScope scope; |
| 12794 LocalContext context1; | 13159 LocalContext context1; |
| 12795 ExpectString(code, "a"); | 13160 ExpectString(code, "a"); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12879 ExpectBoolean("delete cell", true); | 13244 ExpectBoolean("delete cell", true); |
| 12880 ExpectString("(function() {" | 13245 ExpectString("(function() {" |
| 12881 " try {" | 13246 " try {" |
| 12882 " return readCell();" | 13247 " return readCell();" |
| 12883 " } catch(e) {" | 13248 " } catch(e) {" |
| 12884 " return e.toString();" | 13249 " return e.toString();" |
| 12885 " }" | 13250 " }" |
| 12886 "})()", | 13251 "})()", |
| 12887 "ReferenceError: cell is not defined"); | 13252 "ReferenceError: cell is not defined"); |
| 12888 CompileRun("cell = \"new_second\";"); | 13253 CompileRun("cell = \"new_second\";"); |
| 12889 i::Heap::CollectAllGarbage(true); | 13254 HEAP->CollectAllGarbage(true); |
| 12890 ExpectString("readCell()", "new_second"); | 13255 ExpectString("readCell()", "new_second"); |
| 12891 ExpectString("readCell()", "new_second"); | 13256 ExpectString("readCell()", "new_second"); |
| 12892 } | 13257 } |
| 12893 } | 13258 } |
| 12894 | 13259 |
| 12895 | 13260 |
| 12896 TEST(DontDeleteCellLoadICForceDelete) { | 13261 TEST(DontDeleteCellLoadICForceDelete) { |
| 12897 const char* function_code = | 13262 const char* function_code = |
| 12898 "function readCell() { while (true) { return cell; } }"; | 13263 "function readCell() { while (true) { return cell; } }"; |
| 12899 | 13264 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13110 v8::Handle<v8::Function> define_property = | 13475 v8::Handle<v8::Function> define_property = |
| 13111 CompileRun("(function() {" | 13476 CompileRun("(function() {" |
| 13112 " Object.defineProperty(" | 13477 " Object.defineProperty(" |
| 13113 " this," | 13478 " this," |
| 13114 " 1," | 13479 " 1," |
| 13115 " { configurable: true, enumerable: true, value: 3 });" | 13480 " { configurable: true, enumerable: true, value: 3 });" |
| 13116 "})").As<Function>(); | 13481 "})").As<Function>(); |
| 13117 context->DetachGlobal(); | 13482 context->DetachGlobal(); |
| 13118 define_property->Call(proxy, 0, NULL); | 13483 define_property->Call(proxy, 0, NULL); |
| 13119 } | 13484 } |
| OLD | NEW |