| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 LocalContext env; | 386 LocalContext env; |
| 387 TestResource* resource = new TestResource(two_byte_source, &dispose_count); | 387 TestResource* resource = new TestResource(two_byte_source, &dispose_count); |
| 388 Local<String> source = String::NewExternal(resource); | 388 Local<String> source = String::NewExternal(resource); |
| 389 Local<Script> script = Script::Compile(source); | 389 Local<Script> script = Script::Compile(source); |
| 390 Local<Value> value = script->Run(); | 390 Local<Value> value = script->Run(); |
| 391 CHECK(value->IsNumber()); | 391 CHECK(value->IsNumber()); |
| 392 CHECK_EQ(7, value->Int32Value()); | 392 CHECK_EQ(7, value->Int32Value()); |
| 393 CHECK(source->IsExternal()); | 393 CHECK(source->IsExternal()); |
| 394 CHECK_EQ(resource, | 394 CHECK_EQ(resource, |
| 395 static_cast<TestResource*>(source->GetExternalStringResource())); | 395 static_cast<TestResource*>(source->GetExternalStringResource())); |
| 396 HEAP->CollectAllGarbage(false); | 396 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 397 CHECK_EQ(0, dispose_count); | 397 CHECK_EQ(0, dispose_count); |
| 398 } | 398 } |
| 399 v8::internal::Isolate::Current()->compilation_cache()->Clear(); | 399 v8::internal::Isolate::Current()->compilation_cache()->Clear(); |
| 400 HEAP->CollectAllGarbage(false); | 400 HEAP->CollectAllAvailableGarbage(); |
| 401 CHECK_EQ(1, dispose_count); | 401 CHECK_EQ(1, dispose_count); |
| 402 } | 402 } |
| 403 | 403 |
| 404 | 404 |
| 405 THREADED_TEST(ScriptUsingAsciiStringResource) { | 405 THREADED_TEST(ScriptUsingAsciiStringResource) { |
| 406 int dispose_count = 0; | 406 int dispose_count = 0; |
| 407 const char* c_source = "1 + 2 * 3"; | 407 const char* c_source = "1 + 2 * 3"; |
| 408 { | 408 { |
| 409 v8::HandleScope scope; | 409 v8::HandleScope scope; |
| 410 LocalContext env; | 410 LocalContext env; |
| 411 Local<String> source = | 411 Local<String> source = |
| 412 String::NewExternal(new TestAsciiResource(i::StrDup(c_source), | 412 String::NewExternal(new TestAsciiResource(i::StrDup(c_source), |
| 413 &dispose_count)); | 413 &dispose_count)); |
| 414 Local<Script> script = Script::Compile(source); | 414 Local<Script> script = Script::Compile(source); |
| 415 Local<Value> value = script->Run(); | 415 Local<Value> value = script->Run(); |
| 416 CHECK(value->IsNumber()); | 416 CHECK(value->IsNumber()); |
| 417 CHECK_EQ(7, value->Int32Value()); | 417 CHECK_EQ(7, value->Int32Value()); |
| 418 HEAP->CollectAllGarbage(false); | 418 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 419 CHECK_EQ(0, dispose_count); | 419 CHECK_EQ(0, dispose_count); |
| 420 } | 420 } |
| 421 i::Isolate::Current()->compilation_cache()->Clear(); | 421 i::Isolate::Current()->compilation_cache()->Clear(); |
| 422 HEAP->CollectAllGarbage(false); | 422 HEAP->CollectAllAvailableGarbage(); |
| 423 CHECK_EQ(1, dispose_count); | 423 CHECK_EQ(1, dispose_count); |
| 424 } | 424 } |
| 425 | 425 |
| 426 | 426 |
| 427 THREADED_TEST(ScriptMakingExternalString) { | 427 THREADED_TEST(ScriptMakingExternalString) { |
| 428 int dispose_count = 0; | 428 int dispose_count = 0; |
| 429 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); | 429 uint16_t* two_byte_source = AsciiToTwoByteString("1 + 2 * 3"); |
| 430 { | 430 { |
| 431 v8::HandleScope scope; | 431 v8::HandleScope scope; |
| 432 LocalContext env; | 432 LocalContext env; |
| 433 Local<String> source = String::New(two_byte_source); | 433 Local<String> source = String::New(two_byte_source); |
| 434 // Trigger GCs so that the newly allocated string moves to old gen. | 434 // Trigger GCs so that the newly allocated string moves to old gen. |
| 435 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now | 435 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 436 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now | 436 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 437 bool success = source->MakeExternal(new TestResource(two_byte_source, | 437 bool success = source->MakeExternal(new TestResource(two_byte_source, |
| 438 &dispose_count)); | 438 &dispose_count)); |
| 439 CHECK(success); | 439 CHECK(success); |
| 440 Local<Script> script = Script::Compile(source); | 440 Local<Script> script = Script::Compile(source); |
| 441 Local<Value> value = script->Run(); | 441 Local<Value> value = script->Run(); |
| 442 CHECK(value->IsNumber()); | 442 CHECK(value->IsNumber()); |
| 443 CHECK_EQ(7, value->Int32Value()); | 443 CHECK_EQ(7, value->Int32Value()); |
| 444 HEAP->CollectAllGarbage(false); | 444 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 445 CHECK_EQ(0, dispose_count); | 445 CHECK_EQ(0, dispose_count); |
| 446 } | 446 } |
| 447 i::Isolate::Current()->compilation_cache()->Clear(); | 447 i::Isolate::Current()->compilation_cache()->Clear(); |
| 448 HEAP->CollectAllGarbage(false); | 448 // TODO(1608): This should use kAbortIncrementalMarking. |
| 449 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 449 CHECK_EQ(1, dispose_count); | 450 CHECK_EQ(1, dispose_count); |
| 450 } | 451 } |
| 451 | 452 |
| 452 | 453 |
| 453 THREADED_TEST(ScriptMakingExternalAsciiString) { | 454 THREADED_TEST(ScriptMakingExternalAsciiString) { |
| 454 int dispose_count = 0; | 455 int dispose_count = 0; |
| 455 const char* c_source = "1 + 2 * 3"; | 456 const char* c_source = "1 + 2 * 3"; |
| 456 { | 457 { |
| 457 v8::HandleScope scope; | 458 v8::HandleScope scope; |
| 458 LocalContext env; | 459 LocalContext env; |
| 459 Local<String> source = v8_str(c_source); | 460 Local<String> source = v8_str(c_source); |
| 460 // Trigger GCs so that the newly allocated string moves to old gen. | 461 // Trigger GCs so that the newly allocated string moves to old gen. |
| 461 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now | 462 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 462 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now | 463 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 463 bool success = source->MakeExternal( | 464 bool success = source->MakeExternal( |
| 464 new TestAsciiResource(i::StrDup(c_source), &dispose_count)); | 465 new TestAsciiResource(i::StrDup(c_source), &dispose_count)); |
| 465 CHECK(success); | 466 CHECK(success); |
| 466 Local<Script> script = Script::Compile(source); | 467 Local<Script> script = Script::Compile(source); |
| 467 Local<Value> value = script->Run(); | 468 Local<Value> value = script->Run(); |
| 468 CHECK(value->IsNumber()); | 469 CHECK(value->IsNumber()); |
| 469 CHECK_EQ(7, value->Int32Value()); | 470 CHECK_EQ(7, value->Int32Value()); |
| 470 HEAP->CollectAllGarbage(false); | 471 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 471 CHECK_EQ(0, dispose_count); | 472 CHECK_EQ(0, dispose_count); |
| 472 } | 473 } |
| 473 i::Isolate::Current()->compilation_cache()->Clear(); | 474 i::Isolate::Current()->compilation_cache()->Clear(); |
| 474 HEAP->CollectAllGarbage(false); | 475 // TODO(1608): This should use kAbortIncrementalMarking. |
| 476 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 475 CHECK_EQ(1, dispose_count); | 477 CHECK_EQ(1, dispose_count); |
| 476 } | 478 } |
| 477 | 479 |
| 478 | 480 |
| 479 TEST(MakingExternalStringConditions) { | 481 TEST(MakingExternalStringConditions) { |
| 480 v8::HandleScope scope; | 482 v8::HandleScope scope; |
| 481 LocalContext env; | 483 LocalContext env; |
| 482 | 484 |
| 483 // 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. |
| 484 HEAP->CollectGarbage(i::NEW_SPACE); | 486 HEAP->CollectGarbage(i::NEW_SPACE); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 567 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
| 566 Local<String> string = | 568 Local<String> string = |
| 567 String::NewExternal(new TestResource(two_byte_string)); | 569 String::NewExternal(new TestResource(two_byte_string)); |
| 568 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 570 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
| 569 // 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. |
| 570 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now | 572 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 571 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now | 573 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 572 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); | 574 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); |
| 573 CHECK(isymbol->IsSymbol()); | 575 CHECK(isymbol->IsSymbol()); |
| 574 } | 576 } |
| 575 HEAP->CollectAllGarbage(false); | 577 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 576 HEAP->CollectAllGarbage(false); | 578 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 577 } | 579 } |
| 578 | 580 |
| 579 | 581 |
| 580 THREADED_TEST(UsingExternalAsciiString) { | 582 THREADED_TEST(UsingExternalAsciiString) { |
| 581 { | 583 { |
| 582 v8::HandleScope scope; | 584 v8::HandleScope scope; |
| 583 const char* one_byte_string = "test string"; | 585 const char* one_byte_string = "test string"; |
| 584 Local<String> string = String::NewExternal( | 586 Local<String> string = String::NewExternal( |
| 585 new TestAsciiResource(i::StrDup(one_byte_string))); | 587 new TestAsciiResource(i::StrDup(one_byte_string))); |
| 586 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); | 588 i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); |
| 587 // 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. |
| 588 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now | 590 HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 589 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now | 591 HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 590 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); | 592 i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring); |
| 591 CHECK(isymbol->IsSymbol()); | 593 CHECK(isymbol->IsSymbol()); |
| 592 } | 594 } |
| 593 HEAP->CollectAllGarbage(false); | 595 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 594 HEAP->CollectAllGarbage(false); | 596 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 595 } | 597 } |
| 596 | 598 |
| 597 | 599 |
| 598 THREADED_TEST(ScavengeExternalString) { | 600 THREADED_TEST(ScavengeExternalString) { |
| 599 int dispose_count = 0; | 601 int dispose_count = 0; |
| 600 bool in_new_space = false; | 602 bool in_new_space = false; |
| 601 { | 603 { |
| 602 v8::HandleScope scope; | 604 v8::HandleScope scope; |
| 603 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); | 605 uint16_t* two_byte_string = AsciiToTwoByteString("test string"); |
| 604 Local<String> string = | 606 Local<String> string = |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 667 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
| 666 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); | 668 TestAsciiResourceWithDisposeControl res_stack(i::StrDup(c_source), false); |
| 667 { | 669 { |
| 668 v8::HandleScope scope; | 670 v8::HandleScope scope; |
| 669 LocalContext env; | 671 LocalContext env; |
| 670 Local<String> source = String::NewExternal(&res_stack); | 672 Local<String> source = String::NewExternal(&res_stack); |
| 671 Local<Script> script = Script::Compile(source); | 673 Local<Script> script = Script::Compile(source); |
| 672 Local<Value> value = script->Run(); | 674 Local<Value> value = script->Run(); |
| 673 CHECK(value->IsNumber()); | 675 CHECK(value->IsNumber()); |
| 674 CHECK_EQ(7, value->Int32Value()); | 676 CHECK_EQ(7, value->Int32Value()); |
| 675 HEAP->CollectAllGarbage(false); | 677 HEAP->CollectAllAvailableGarbage(); |
| 676 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 678 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); |
| 677 } | 679 } |
| 678 i::Isolate::Current()->compilation_cache()->Clear(); | 680 i::Isolate::Current()->compilation_cache()->Clear(); |
| 679 HEAP->CollectAllGarbage(false); | 681 HEAP->CollectAllAvailableGarbage(); |
| 680 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 682 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
| 681 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 683 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); |
| 682 | 684 |
| 683 // Use a heap allocated external string resource allocated object. | 685 // Use a heap allocated external string resource allocated object. |
| 684 TestAsciiResourceWithDisposeControl::dispose_count = 0; | 686 TestAsciiResourceWithDisposeControl::dispose_count = 0; |
| 685 TestAsciiResourceWithDisposeControl::dispose_calls = 0; | 687 TestAsciiResourceWithDisposeControl::dispose_calls = 0; |
| 686 TestAsciiResource* res_heap = | 688 TestAsciiResource* res_heap = |
| 687 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); | 689 new TestAsciiResourceWithDisposeControl(i::StrDup(c_source), true); |
| 688 { | 690 { |
| 689 v8::HandleScope scope; | 691 v8::HandleScope scope; |
| 690 LocalContext env; | 692 LocalContext env; |
| 691 Local<String> source = String::NewExternal(res_heap); | 693 Local<String> source = String::NewExternal(res_heap); |
| 692 Local<Script> script = Script::Compile(source); | 694 Local<Script> script = Script::Compile(source); |
| 693 Local<Value> value = script->Run(); | 695 Local<Value> value = script->Run(); |
| 694 CHECK(value->IsNumber()); | 696 CHECK(value->IsNumber()); |
| 695 CHECK_EQ(7, value->Int32Value()); | 697 CHECK_EQ(7, value->Int32Value()); |
| 696 HEAP->CollectAllGarbage(false); | 698 HEAP->CollectAllAvailableGarbage(); |
| 697 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); | 699 CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count); |
| 698 } | 700 } |
| 699 i::Isolate::Current()->compilation_cache()->Clear(); | 701 i::Isolate::Current()->compilation_cache()->Clear(); |
| 700 HEAP->CollectAllGarbage(false); | 702 HEAP->CollectAllAvailableGarbage(); |
| 701 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); | 703 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls); |
| 702 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count); | 704 CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count); |
| 703 } | 705 } |
| 704 | 706 |
| 705 | 707 |
| 706 THREADED_TEST(StringConcat) { | 708 THREADED_TEST(StringConcat) { |
| 707 { | 709 { |
| 708 v8::HandleScope scope; | 710 v8::HandleScope scope; |
| 709 LocalContext env; | 711 LocalContext env; |
| 710 const char* one_byte_string_1 = "function a_times_t"; | 712 const char* one_byte_string_1 = "function a_times_t"; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 737 source = String::Concat(source, right); | 739 source = String::Concat(source, right); |
| 738 right = String::NewExternal( | 740 right = String::NewExternal( |
| 739 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); | 741 new TestResource(AsciiToTwoByteString(two_byte_extern_2))); |
| 740 source = String::Concat(source, right); | 742 source = String::Concat(source, right); |
| 741 Local<Script> script = Script::Compile(source); | 743 Local<Script> script = Script::Compile(source); |
| 742 Local<Value> value = script->Run(); | 744 Local<Value> value = script->Run(); |
| 743 CHECK(value->IsNumber()); | 745 CHECK(value->IsNumber()); |
| 744 CHECK_EQ(68, value->Int32Value()); | 746 CHECK_EQ(68, value->Int32Value()); |
| 745 } | 747 } |
| 746 i::Isolate::Current()->compilation_cache()->Clear(); | 748 i::Isolate::Current()->compilation_cache()->Clear(); |
| 747 HEAP->CollectAllGarbage(false); | 749 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 748 HEAP->CollectAllGarbage(false); | 750 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 749 } | 751 } |
| 750 | 752 |
| 751 | 753 |
| 752 THREADED_TEST(GlobalProperties) { | 754 THREADED_TEST(GlobalProperties) { |
| 753 v8::HandleScope scope; | 755 v8::HandleScope scope; |
| 754 LocalContext env; | 756 LocalContext env; |
| 755 v8::Handle<v8::Object> global = env->Global(); | 757 v8::Handle<v8::Object> global = env->Global(); |
| 756 global->Set(v8_str("pi"), v8_num(3.1415926)); | 758 global->Set(v8_str("pi"), v8_num(3.1415926)); |
| 757 Local<Value> pi = global->Get(v8_str("pi")); | 759 Local<Value> pi = global->Get(v8_str("pi")); |
| 758 CHECK_EQ(3.1415926, pi->NumberValue()); | 760 CHECK_EQ(3.1415926, pi->NumberValue()); |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1659 | 1661 |
| 1660 char* data = new char[100]; | 1662 char* data = new char[100]; |
| 1661 | 1663 |
| 1662 void* aligned = data; | 1664 void* aligned = data; |
| 1663 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); | 1665 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); |
| 1664 void* unaligned = data + 1; | 1666 void* unaligned = data + 1; |
| 1665 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); | 1667 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); |
| 1666 | 1668 |
| 1667 // Check reading and writing aligned pointers. | 1669 // Check reading and writing aligned pointers. |
| 1668 obj->SetPointerInInternalField(0, aligned); | 1670 obj->SetPointerInInternalField(0, aligned); |
| 1669 HEAP->CollectAllGarbage(false); | 1671 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1670 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); | 1672 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); |
| 1671 | 1673 |
| 1672 // Check reading and writing unaligned pointers. | 1674 // Check reading and writing unaligned pointers. |
| 1673 obj->SetPointerInInternalField(0, unaligned); | 1675 obj->SetPointerInInternalField(0, unaligned); |
| 1674 HEAP->CollectAllGarbage(false); | 1676 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1675 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); | 1677 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); |
| 1676 | 1678 |
| 1677 delete[] data; | 1679 delete[] data; |
| 1678 } | 1680 } |
| 1679 | 1681 |
| 1680 | 1682 |
| 1681 THREADED_TEST(InternalFieldsNativePointersAndExternal) { | 1683 THREADED_TEST(InternalFieldsNativePointersAndExternal) { |
| 1682 v8::HandleScope scope; | 1684 v8::HandleScope scope; |
| 1683 LocalContext env; | 1685 LocalContext env; |
| 1684 | 1686 |
| 1685 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 1687 Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
| 1686 Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); | 1688 Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); |
| 1687 instance_templ->SetInternalFieldCount(1); | 1689 instance_templ->SetInternalFieldCount(1); |
| 1688 Local<v8::Object> obj = templ->GetFunction()->NewInstance(); | 1690 Local<v8::Object> obj = templ->GetFunction()->NewInstance(); |
| 1689 CHECK_EQ(1, obj->InternalFieldCount()); | 1691 CHECK_EQ(1, obj->InternalFieldCount()); |
| 1690 CHECK(obj->GetPointerFromInternalField(0) == NULL); | 1692 CHECK(obj->GetPointerFromInternalField(0) == NULL); |
| 1691 | 1693 |
| 1692 char* data = new char[100]; | 1694 char* data = new char[100]; |
| 1693 | 1695 |
| 1694 void* aligned = data; | 1696 void* aligned = data; |
| 1695 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); | 1697 CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(aligned) & 0x1)); |
| 1696 void* unaligned = data + 1; | 1698 void* unaligned = data + 1; |
| 1697 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); | 1699 CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1)); |
| 1698 | 1700 |
| 1699 obj->SetPointerInInternalField(0, aligned); | 1701 obj->SetPointerInInternalField(0, aligned); |
| 1700 HEAP->CollectAllGarbage(false); | 1702 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1701 CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0))); | 1703 CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0))); |
| 1702 | 1704 |
| 1703 obj->SetPointerInInternalField(0, unaligned); | 1705 obj->SetPointerInInternalField(0, unaligned); |
| 1704 HEAP->CollectAllGarbage(false); | 1706 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1705 CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0))); | 1707 CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0))); |
| 1706 | 1708 |
| 1707 obj->SetInternalField(0, v8::External::Wrap(aligned)); | 1709 obj->SetInternalField(0, v8::External::Wrap(aligned)); |
| 1708 HEAP->CollectAllGarbage(false); | 1710 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1709 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); | 1711 CHECK_EQ(aligned, obj->GetPointerFromInternalField(0)); |
| 1710 | 1712 |
| 1711 obj->SetInternalField(0, v8::External::Wrap(unaligned)); | 1713 obj->SetInternalField(0, v8::External::Wrap(unaligned)); |
| 1712 HEAP->CollectAllGarbage(false); | 1714 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1713 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); | 1715 CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0)); |
| 1714 | 1716 |
| 1715 delete[] data; | 1717 delete[] data; |
| 1716 } | 1718 } |
| 1717 | 1719 |
| 1718 | 1720 |
| 1719 THREADED_TEST(IdentityHash) { | 1721 THREADED_TEST(IdentityHash) { |
| 1720 v8::HandleScope scope; | 1722 v8::HandleScope scope; |
| 1721 LocalContext env; | 1723 LocalContext env; |
| 1722 | 1724 |
| 1723 // Ensure that the test starts with an fresh heap to test whether the hash | 1725 // Ensure that the test starts with an fresh heap to test whether the hash |
| 1724 // code is based on the address. | 1726 // code is based on the address. |
| 1725 HEAP->CollectAllGarbage(false); | 1727 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1726 Local<v8::Object> obj = v8::Object::New(); | 1728 Local<v8::Object> obj = v8::Object::New(); |
| 1727 int hash = obj->GetIdentityHash(); | 1729 int hash = obj->GetIdentityHash(); |
| 1728 int hash1 = obj->GetIdentityHash(); | 1730 int hash1 = obj->GetIdentityHash(); |
| 1729 CHECK_EQ(hash, hash1); | 1731 CHECK_EQ(hash, hash1); |
| 1730 int hash2 = v8::Object::New()->GetIdentityHash(); | 1732 int hash2 = v8::Object::New()->GetIdentityHash(); |
| 1731 // Since the identity hash is essentially a random number two consecutive | 1733 // Since the identity hash is essentially a random number two consecutive |
| 1732 // objects should not be assigned the same hash code. If the test below fails | 1734 // objects should not be assigned the same hash code. If the test below fails |
| 1733 // the random number generator should be evaluated. | 1735 // the random number generator should be evaluated. |
| 1734 CHECK_NE(hash, hash2); | 1736 CHECK_NE(hash, hash2); |
| 1735 HEAP->CollectAllGarbage(false); | 1737 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1736 int hash3 = v8::Object::New()->GetIdentityHash(); | 1738 int hash3 = v8::Object::New()->GetIdentityHash(); |
| 1737 // Make sure that the identity hash is not based on the initial address of | 1739 // Make sure that the identity hash is not based on the initial address of |
| 1738 // the object alone. If the test below fails the random number generator | 1740 // the object alone. If the test below fails the random number generator |
| 1739 // should be evaluated. | 1741 // should be evaluated. |
| 1740 CHECK_NE(hash, hash3); | 1742 CHECK_NE(hash, hash3); |
| 1741 int hash4 = obj->GetIdentityHash(); | 1743 int hash4 = obj->GetIdentityHash(); |
| 1742 CHECK_EQ(hash, hash4); | 1744 CHECK_EQ(hash, hash4); |
| 1743 | 1745 |
| 1744 // Check identity hashes behaviour in the presence of JS accessors. | 1746 // Check identity hashes behaviour in the presence of JS accessors. |
| 1745 // Put a getter for 'v8::IdentityHash' on the Object's prototype: | 1747 // Put a getter for 'v8::IdentityHash' on the Object's prototype: |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1762 | 1764 |
| 1763 THREADED_TEST(HiddenProperties) { | 1765 THREADED_TEST(HiddenProperties) { |
| 1764 v8::HandleScope scope; | 1766 v8::HandleScope scope; |
| 1765 LocalContext env; | 1767 LocalContext env; |
| 1766 | 1768 |
| 1767 v8::Local<v8::Object> obj = v8::Object::New(); | 1769 v8::Local<v8::Object> obj = v8::Object::New(); |
| 1768 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); | 1770 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); |
| 1769 v8::Local<v8::String> empty = v8_str(""); | 1771 v8::Local<v8::String> empty = v8_str(""); |
| 1770 v8::Local<v8::String> prop_name = v8_str("prop_name"); | 1772 v8::Local<v8::String> prop_name = v8_str("prop_name"); |
| 1771 | 1773 |
| 1772 HEAP->CollectAllGarbage(false); | 1774 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1773 | 1775 |
| 1774 // Make sure delete of a non-existent hidden value works | 1776 // Make sure delete of a non-existent hidden value works |
| 1775 CHECK(obj->DeleteHiddenValue(key)); | 1777 CHECK(obj->DeleteHiddenValue(key)); |
| 1776 | 1778 |
| 1777 CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); | 1779 CHECK(obj->SetHiddenValue(key, v8::Integer::New(1503))); |
| 1778 CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); | 1780 CHECK_EQ(1503, obj->GetHiddenValue(key)->Int32Value()); |
| 1779 CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); | 1781 CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002))); |
| 1780 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1782 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1781 | 1783 |
| 1782 HEAP->CollectAllGarbage(false); | 1784 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1783 | 1785 |
| 1784 // Make sure we do not find the hidden property. | 1786 // Make sure we do not find the hidden property. |
| 1785 CHECK(!obj->Has(empty)); | 1787 CHECK(!obj->Has(empty)); |
| 1786 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1788 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1787 CHECK(obj->Get(empty)->IsUndefined()); | 1789 CHECK(obj->Get(empty)->IsUndefined()); |
| 1788 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1790 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1789 CHECK(obj->Set(empty, v8::Integer::New(2003))); | 1791 CHECK(obj->Set(empty, v8::Integer::New(2003))); |
| 1790 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1792 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1791 CHECK_EQ(2003, obj->Get(empty)->Int32Value()); | 1793 CHECK_EQ(2003, obj->Get(empty)->Int32Value()); |
| 1792 | 1794 |
| 1793 HEAP->CollectAllGarbage(false); | 1795 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1794 | 1796 |
| 1795 // Add another property and delete it afterwards to force the object in | 1797 // Add another property and delete it afterwards to force the object in |
| 1796 // slow case. | 1798 // slow case. |
| 1797 CHECK(obj->Set(prop_name, v8::Integer::New(2008))); | 1799 CHECK(obj->Set(prop_name, v8::Integer::New(2008))); |
| 1798 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1800 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1799 CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); | 1801 CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); |
| 1800 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1802 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1801 CHECK(obj->Delete(prop_name)); | 1803 CHECK(obj->Delete(prop_name)); |
| 1802 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); | 1804 CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value()); |
| 1803 | 1805 |
| 1804 HEAP->CollectAllGarbage(false); | 1806 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 1805 | 1807 |
| 1806 CHECK(obj->DeleteHiddenValue(key)); | 1808 CHECK(obj->DeleteHiddenValue(key)); |
| 1807 CHECK(obj->GetHiddenValue(key).IsEmpty()); | 1809 CHECK(obj->GetHiddenValue(key).IsEmpty()); |
| 1808 } | 1810 } |
| 1809 | 1811 |
| 1810 | 1812 |
| 1811 static bool interceptor_for_hidden_properties_called; | 1813 static bool interceptor_for_hidden_properties_called; |
| 1812 static v8::Handle<Value> InterceptorForHiddenProperties( | 1814 static v8::Handle<Value> InterceptorForHiddenProperties( |
| 1813 Local<String> name, const AccessorInfo& info) { | 1815 Local<String> name, const AccessorInfo& info) { |
| 1814 interceptor_for_hidden_properties_called = true; | 1816 interceptor_for_hidden_properties_called = true; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1873 { | 1875 { |
| 1874 v8::HandleScope scope; | 1876 v8::HandleScope scope; |
| 1875 Local<String> str = v8_str("str"); | 1877 Local<String> str = v8_str("str"); |
| 1876 global = v8::Persistent<String>::New(str); | 1878 global = v8::Persistent<String>::New(str); |
| 1877 } | 1879 } |
| 1878 CHECK_EQ(global->Length(), 3); | 1880 CHECK_EQ(global->Length(), 3); |
| 1879 global.Dispose(); | 1881 global.Dispose(); |
| 1880 } | 1882 } |
| 1881 | 1883 |
| 1882 | 1884 |
| 1883 static int NumberOfWeakCalls = 0; | 1885 class WeakCallCounter { |
| 1886 public: |
| 1887 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { } |
| 1888 int id() { return id_; } |
| 1889 void increment() { number_of_weak_calls_++; } |
| 1890 int NumberOfWeakCalls() { return number_of_weak_calls_; } |
| 1891 private: |
| 1892 int id_; |
| 1893 int number_of_weak_calls_; |
| 1894 }; |
| 1895 |
| 1896 |
| 1884 static void WeakPointerCallback(Persistent<Value> handle, void* id) { | 1897 static void WeakPointerCallback(Persistent<Value> handle, void* id) { |
| 1885 CHECK_EQ(reinterpret_cast<void*>(1234), id); | 1898 WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id); |
| 1886 NumberOfWeakCalls++; | 1899 CHECK_EQ(1234, counter->id()); |
| 1900 counter->increment(); |
| 1887 handle.Dispose(); | 1901 handle.Dispose(); |
| 1888 } | 1902 } |
| 1889 | 1903 |
| 1904 |
| 1890 THREADED_TEST(ApiObjectGroups) { | 1905 THREADED_TEST(ApiObjectGroups) { |
| 1891 HandleScope scope; | 1906 HandleScope scope; |
| 1892 LocalContext env; | 1907 LocalContext env; |
| 1893 | 1908 |
| 1894 NumberOfWeakCalls = 0; | |
| 1895 | |
| 1896 Persistent<Object> g1s1; | 1909 Persistent<Object> g1s1; |
| 1897 Persistent<Object> g1s2; | 1910 Persistent<Object> g1s2; |
| 1898 Persistent<Object> g1c1; | 1911 Persistent<Object> g1c1; |
| 1899 Persistent<Object> g2s1; | 1912 Persistent<Object> g2s1; |
| 1900 Persistent<Object> g2s2; | 1913 Persistent<Object> g2s2; |
| 1901 Persistent<Object> g2c1; | 1914 Persistent<Object> g2c1; |
| 1902 | 1915 |
| 1916 WeakCallCounter counter(1234); |
| 1917 |
| 1903 { | 1918 { |
| 1904 HandleScope scope; | 1919 HandleScope scope; |
| 1905 g1s1 = Persistent<Object>::New(Object::New()); | 1920 g1s1 = Persistent<Object>::New(Object::New()); |
| 1906 g1s2 = Persistent<Object>::New(Object::New()); | 1921 g1s2 = Persistent<Object>::New(Object::New()); |
| 1907 g1c1 = Persistent<Object>::New(Object::New()); | 1922 g1c1 = Persistent<Object>::New(Object::New()); |
| 1908 g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1923 g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1909 g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1924 g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1910 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1925 g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1911 | 1926 |
| 1912 g2s1 = Persistent<Object>::New(Object::New()); | 1927 g2s1 = Persistent<Object>::New(Object::New()); |
| 1913 g2s2 = Persistent<Object>::New(Object::New()); | 1928 g2s2 = Persistent<Object>::New(Object::New()); |
| 1914 g2c1 = Persistent<Object>::New(Object::New()); | 1929 g2c1 = Persistent<Object>::New(Object::New()); |
| 1915 g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1930 g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1916 g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1931 g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1917 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1932 g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1918 } | 1933 } |
| 1919 | 1934 |
| 1920 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. | 1935 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. |
| 1921 | 1936 |
| 1922 // Connect group 1 and 2, make a cycle. | 1937 // Connect group 1 and 2, make a cycle. |
| 1923 CHECK(g1s2->Set(0, g2s2)); | 1938 CHECK(g1s2->Set(0, g2s2)); |
| 1924 CHECK(g2s1->Set(0, g1s1)); | 1939 CHECK(g2s1->Set(0, g1s1)); |
| 1925 | 1940 |
| 1926 { | 1941 { |
| 1927 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1942 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 1928 Persistent<Value> g1_children[] = { g1c1 }; | 1943 Persistent<Value> g1_children[] = { g1c1 }; |
| 1929 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1944 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 1930 Persistent<Value> g2_children[] = { g2c1 }; | 1945 Persistent<Value> g2_children[] = { g2c1 }; |
| 1931 V8::AddObjectGroup(g1_objects, 2); | 1946 V8::AddObjectGroup(g1_objects, 2); |
| 1932 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1947 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 1933 V8::AddObjectGroup(g2_objects, 2); | 1948 V8::AddObjectGroup(g2_objects, 2); |
| 1934 V8::AddImplicitReferences(g2s2, g2_children, 1); | 1949 V8::AddImplicitReferences(g2s2, g2_children, 1); |
| 1935 } | 1950 } |
| 1936 // Do a full GC | 1951 // Do a single full GC. Use kMakeHeapIterableMask to ensure that |
| 1937 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 1952 // incremental garbage collection is stopped. |
| 1953 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 1938 | 1954 |
| 1939 // All object should be alive. | 1955 // All object should be alive. |
| 1940 CHECK_EQ(0, NumberOfWeakCalls); | 1956 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
| 1941 | 1957 |
| 1942 // Weaken the root. | 1958 // Weaken the root. |
| 1943 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1959 root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1944 // But make children strong roots---all the objects (except for children) | 1960 // But make children strong roots---all the objects (except for children) |
| 1945 // should be collectable now. | 1961 // should be collectable now. |
| 1946 g1c1.ClearWeak(); | 1962 g1c1.ClearWeak(); |
| 1947 g2c1.ClearWeak(); | 1963 g2c1.ClearWeak(); |
| 1948 | 1964 |
| 1949 // Groups are deleted, rebuild groups. | 1965 // Groups are deleted, rebuild groups. |
| 1950 { | 1966 { |
| 1951 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1967 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 1952 Persistent<Value> g1_children[] = { g1c1 }; | 1968 Persistent<Value> g1_children[] = { g1c1 }; |
| 1953 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1969 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 1954 Persistent<Value> g2_children[] = { g2c1 }; | 1970 Persistent<Value> g2_children[] = { g2c1 }; |
| 1955 V8::AddObjectGroup(g1_objects, 2); | 1971 V8::AddObjectGroup(g1_objects, 2); |
| 1956 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1972 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 1957 V8::AddObjectGroup(g2_objects, 2); | 1973 V8::AddObjectGroup(g2_objects, 2); |
| 1958 V8::AddImplicitReferences(g2s2, g2_children, 1); | 1974 V8::AddImplicitReferences(g2s2, g2_children, 1); |
| 1959 } | 1975 } |
| 1960 | 1976 |
| 1961 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 1977 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 1962 | 1978 |
| 1963 // All objects should be gone. 5 global handles in total. | 1979 // All objects should be gone. 5 global handles in total. |
| 1964 CHECK_EQ(5, NumberOfWeakCalls); | 1980 CHECK_EQ(5, counter.NumberOfWeakCalls()); |
| 1965 | 1981 |
| 1966 // And now make children weak again and collect them. | 1982 // And now make children weak again and collect them. |
| 1967 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1983 g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1968 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1984 g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1969 | 1985 |
| 1970 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 1986 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 1971 CHECK_EQ(7, NumberOfWeakCalls); | 1987 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
| 1972 } | 1988 } |
| 1973 | 1989 |
| 1974 | 1990 |
| 1975 THREADED_TEST(ApiObjectGroupsCycle) { | 1991 THREADED_TEST(ApiObjectGroupsCycle) { |
| 1976 HandleScope scope; | 1992 HandleScope scope; |
| 1977 LocalContext env; | 1993 LocalContext env; |
| 1978 | 1994 |
| 1979 NumberOfWeakCalls = 0; | 1995 WeakCallCounter counter(1234); |
| 1980 | 1996 |
| 1981 Persistent<Object> g1s1; | 1997 Persistent<Object> g1s1; |
| 1982 Persistent<Object> g1s2; | 1998 Persistent<Object> g1s2; |
| 1983 Persistent<Object> g2s1; | 1999 Persistent<Object> g2s1; |
| 1984 Persistent<Object> g2s2; | 2000 Persistent<Object> g2s2; |
| 1985 Persistent<Object> g3s1; | 2001 Persistent<Object> g3s1; |
| 1986 Persistent<Object> g3s2; | 2002 Persistent<Object> g3s2; |
| 1987 | 2003 |
| 1988 { | 2004 { |
| 1989 HandleScope scope; | 2005 HandleScope scope; |
| 1990 g1s1 = Persistent<Object>::New(Object::New()); | 2006 g1s1 = Persistent<Object>::New(Object::New()); |
| 1991 g1s2 = Persistent<Object>::New(Object::New()); | 2007 g1s2 = Persistent<Object>::New(Object::New()); |
| 1992 g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2008 g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1993 g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2009 g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1994 | 2010 |
| 1995 g2s1 = Persistent<Object>::New(Object::New()); | 2011 g2s1 = Persistent<Object>::New(Object::New()); |
| 1996 g2s2 = Persistent<Object>::New(Object::New()); | 2012 g2s2 = Persistent<Object>::New(Object::New()); |
| 1997 g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2013 g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1998 g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2014 g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1999 | 2015 |
| 2000 g3s1 = Persistent<Object>::New(Object::New()); | 2016 g3s1 = Persistent<Object>::New(Object::New()); |
| 2001 g3s2 = Persistent<Object>::New(Object::New()); | 2017 g3s2 = Persistent<Object>::New(Object::New()); |
| 2002 g3s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2018 g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2003 g3s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2019 g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2004 } | 2020 } |
| 2005 | 2021 |
| 2006 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. | 2022 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. |
| 2007 | 2023 |
| 2008 // Connect groups. We're building the following cycle: | 2024 // Connect groups. We're building the following cycle: |
| 2009 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other | 2025 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
| 2010 // groups. | 2026 // groups. |
| 2011 { | 2027 { |
| 2012 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2028 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 2013 Persistent<Value> g1_children[] = { g2s1 }; | 2029 Persistent<Value> g1_children[] = { g2s1 }; |
| 2014 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2030 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 2015 Persistent<Value> g2_children[] = { g3s1 }; | 2031 Persistent<Value> g2_children[] = { g3s1 }; |
| 2016 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 2032 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
| 2017 Persistent<Value> g3_children[] = { g1s1 }; | 2033 Persistent<Value> g3_children[] = { g1s1 }; |
| 2018 V8::AddObjectGroup(g1_objects, 2); | 2034 V8::AddObjectGroup(g1_objects, 2); |
| 2019 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2035 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 2020 V8::AddObjectGroup(g2_objects, 2); | 2036 V8::AddObjectGroup(g2_objects, 2); |
| 2021 V8::AddImplicitReferences(g2s1, g2_children, 1); | 2037 V8::AddImplicitReferences(g2s1, g2_children, 1); |
| 2022 V8::AddObjectGroup(g3_objects, 2); | 2038 V8::AddObjectGroup(g3_objects, 2); |
| 2023 V8::AddImplicitReferences(g3s1, g3_children, 1); | 2039 V8::AddImplicitReferences(g3s1, g3_children, 1); |
| 2024 } | 2040 } |
| 2025 // Do a full GC | 2041 // Do a single full GC |
| 2026 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2042 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 2027 | 2043 |
| 2028 // All object should be alive. | 2044 // All object should be alive. |
| 2029 CHECK_EQ(0, NumberOfWeakCalls); | 2045 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
| 2030 | 2046 |
| 2031 // Weaken the root. | 2047 // Weaken the root. |
| 2032 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2048 root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2033 | 2049 |
| 2034 // Groups are deleted, rebuild groups. | 2050 // Groups are deleted, rebuild groups. |
| 2035 { | 2051 { |
| 2036 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2052 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 2037 Persistent<Value> g1_children[] = { g2s1 }; | 2053 Persistent<Value> g1_children[] = { g2s1 }; |
| 2038 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2054 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 2039 Persistent<Value> g2_children[] = { g3s1 }; | 2055 Persistent<Value> g2_children[] = { g3s1 }; |
| 2040 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 2056 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
| 2041 Persistent<Value> g3_children[] = { g1s1 }; | 2057 Persistent<Value> g3_children[] = { g1s1 }; |
| 2042 V8::AddObjectGroup(g1_objects, 2); | 2058 V8::AddObjectGroup(g1_objects, 2); |
| 2043 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2059 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 2044 V8::AddObjectGroup(g2_objects, 2); | 2060 V8::AddObjectGroup(g2_objects, 2); |
| 2045 V8::AddImplicitReferences(g2s1, g2_children, 1); | 2061 V8::AddImplicitReferences(g2s1, g2_children, 1); |
| 2046 V8::AddObjectGroup(g3_objects, 2); | 2062 V8::AddObjectGroup(g3_objects, 2); |
| 2047 V8::AddImplicitReferences(g3s1, g3_children, 1); | 2063 V8::AddImplicitReferences(g3s1, g3_children, 1); |
| 2048 } | 2064 } |
| 2049 | 2065 |
| 2050 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2066 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 2051 | 2067 |
| 2052 // All objects should be gone. 7 global handles in total. | 2068 // All objects should be gone. 7 global handles in total. |
| 2053 CHECK_EQ(7, NumberOfWeakCalls); | 2069 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
| 2054 } | 2070 } |
| 2055 | 2071 |
| 2056 | 2072 |
| 2057 THREADED_TEST(ScriptException) { | 2073 THREADED_TEST(ScriptException) { |
| 2058 v8::HandleScope scope; | 2074 v8::HandleScope scope; |
| 2059 LocalContext env; | 2075 LocalContext env; |
| 2060 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); | 2076 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); |
| 2061 v8::TryCatch try_catch; | 2077 v8::TryCatch try_catch; |
| 2062 Local<Value> result = script->Run(); | 2078 Local<Value> result = script->Run(); |
| 2063 CHECK(result.IsEmpty()); | 2079 CHECK(result.IsEmpty()); |
| (...skipping 2706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4770 CHECK(object_a_disposed); | 4786 CHECK(object_a_disposed); |
| 4771 } | 4787 } |
| 4772 | 4788 |
| 4773 | 4789 |
| 4774 static void InvokeScavenge() { | 4790 static void InvokeScavenge() { |
| 4775 HEAP->PerformScavenge(); | 4791 HEAP->PerformScavenge(); |
| 4776 } | 4792 } |
| 4777 | 4793 |
| 4778 | 4794 |
| 4779 static void InvokeMarkSweep() { | 4795 static void InvokeMarkSweep() { |
| 4780 HEAP->CollectAllGarbage(false); | 4796 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 4781 } | 4797 } |
| 4782 | 4798 |
| 4783 | 4799 |
| 4784 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { | 4800 static void ForceScavenge(v8::Persistent<v8::Value> obj, void* data) { |
| 4785 obj.Dispose(); | 4801 obj.Dispose(); |
| 4786 obj.Clear(); | 4802 obj.Clear(); |
| 4787 *(reinterpret_cast<bool*>(data)) = true; | 4803 *(reinterpret_cast<bool*>(data)) = true; |
| 4788 InvokeScavenge(); | 4804 InvokeScavenge(); |
| 4789 } | 4805 } |
| 4790 | 4806 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4863 | 4879 |
| 4864 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { | 4880 static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) { |
| 4865 ApiTestFuzzer::Fuzz(); | 4881 ApiTestFuzzer::Fuzz(); |
| 4866 CHECK_EQ(args_fun, args.Callee()); | 4882 CHECK_EQ(args_fun, args.Callee()); |
| 4867 CHECK_EQ(3, args.Length()); | 4883 CHECK_EQ(3, args.Length()); |
| 4868 CHECK_EQ(v8::Integer::New(1), args[0]); | 4884 CHECK_EQ(v8::Integer::New(1), args[0]); |
| 4869 CHECK_EQ(v8::Integer::New(2), args[1]); | 4885 CHECK_EQ(v8::Integer::New(2), args[1]); |
| 4870 CHECK_EQ(v8::Integer::New(3), args[2]); | 4886 CHECK_EQ(v8::Integer::New(3), args[2]); |
| 4871 CHECK_EQ(v8::Undefined(), args[3]); | 4887 CHECK_EQ(v8::Undefined(), args[3]); |
| 4872 v8::HandleScope scope; | 4888 v8::HandleScope scope; |
| 4873 HEAP->CollectAllGarbage(false); | 4889 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 4874 return v8::Undefined(); | 4890 return v8::Undefined(); |
| 4875 } | 4891 } |
| 4876 | 4892 |
| 4877 | 4893 |
| 4878 THREADED_TEST(Arguments) { | 4894 THREADED_TEST(Arguments) { |
| 4879 v8::HandleScope scope; | 4895 v8::HandleScope scope; |
| 4880 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); | 4896 v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(); |
| 4881 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); | 4897 global->Set(v8_str("f"), v8::FunctionTemplate::New(ArgumentsTestCallback)); |
| 4882 LocalContext context(NULL, global); | 4898 LocalContext context(NULL, global); |
| 4883 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); | 4899 args_fun = context->Global()->Get(v8_str("f")).As<Function>(); |
| (...skipping 2964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7848 "var p = new constructor();" | 7864 "var p = new constructor();" |
| 7849 "p.hasOwnProperty('ostehaps');"); | 7865 "p.hasOwnProperty('ostehaps');"); |
| 7850 CHECK_EQ(false, value->BooleanValue()); | 7866 CHECK_EQ(false, value->BooleanValue()); |
| 7851 } | 7867 } |
| 7852 | 7868 |
| 7853 | 7869 |
| 7854 static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC( | 7870 static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC( |
| 7855 Local<String> name, | 7871 Local<String> name, |
| 7856 const AccessorInfo& info) { | 7872 const AccessorInfo& info) { |
| 7857 ApiTestFuzzer::Fuzz(); | 7873 ApiTestFuzzer::Fuzz(); |
| 7858 HEAP->CollectAllGarbage(false); | 7874 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 7859 return v8::Handle<Value>(); | 7875 return v8::Handle<Value>(); |
| 7860 } | 7876 } |
| 7861 | 7877 |
| 7862 | 7878 |
| 7863 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { | 7879 THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { |
| 7864 v8::HandleScope scope; | 7880 v8::HandleScope scope; |
| 7865 LocalContext context; | 7881 LocalContext context; |
| 7866 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 7882 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
| 7867 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); | 7883 Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); |
| 7868 instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); | 7884 instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC); |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8578 "};"); | 8594 "};"); |
| 8579 CHECK_EQ(239 * 10, value->Int32Value()); | 8595 CHECK_EQ(239 * 10, value->Int32Value()); |
| 8580 } | 8596 } |
| 8581 | 8597 |
| 8582 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, | 8598 static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name, |
| 8583 const AccessorInfo& info) { | 8599 const AccessorInfo& info) { |
| 8584 ApiTestFuzzer::Fuzz(); | 8600 ApiTestFuzzer::Fuzz(); |
| 8585 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); | 8601 int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data())); |
| 8586 ++(*call_count); | 8602 ++(*call_count); |
| 8587 if ((*call_count) % 20 == 0) { | 8603 if ((*call_count) % 20 == 0) { |
| 8588 HEAP->CollectAllGarbage(true); | 8604 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 8589 } | 8605 } |
| 8590 return v8::Handle<Value>(); | 8606 return v8::Handle<Value>(); |
| 8591 } | 8607 } |
| 8592 | 8608 |
| 8593 static v8::Handle<Value> FastApiCallback_TrivialSignature( | 8609 static v8::Handle<Value> FastApiCallback_TrivialSignature( |
| 8594 const v8::Arguments& args) { | 8610 const v8::Arguments& args) { |
| 8595 ApiTestFuzzer::Fuzz(); | 8611 ApiTestFuzzer::Fuzz(); |
| 8596 CHECK_EQ(args.This(), args.Holder()); | 8612 CHECK_EQ(args.This(), args.Holder()); |
| 8597 CHECK(args.Data()->Equals(v8_str("method_data"))); | 8613 CHECK(args.Data()->Equals(v8_str("method_data"))); |
| 8598 return v8::Integer::New(args[0]->Int32Value() + 1); | 8614 return v8::Integer::New(args[0]->Int32Value() + 1); |
| (...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9929 Local<Script> script = v8_compile("(function () {" | 9945 Local<Script> script = v8_compile("(function () {" |
| 9930 " unlock_for_a_moment();" | 9946 " unlock_for_a_moment();" |
| 9931 " return 42;" | 9947 " return 42;" |
| 9932 "})();"); | 9948 "})();"); |
| 9933 CHECK_EQ(42, script->Run()->Int32Value()); | 9949 CHECK_EQ(42, script->Run()->Int32Value()); |
| 9934 } | 9950 } |
| 9935 } | 9951 } |
| 9936 | 9952 |
| 9937 | 9953 |
| 9938 static int GetGlobalObjectsCount() { | 9954 static int GetGlobalObjectsCount() { |
| 9955 i::Isolate::Current()->heap()->EnsureHeapIsIterable(); |
| 9939 int count = 0; | 9956 int count = 0; |
| 9940 i::HeapIterator it; | 9957 i::HeapIterator it; |
| 9941 for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) | 9958 for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) |
| 9942 if (object->IsJSGlobalObject()) count++; | 9959 if (object->IsJSGlobalObject()) count++; |
| 9943 return count; | 9960 return count; |
| 9944 } | 9961 } |
| 9945 | 9962 |
| 9946 | 9963 |
| 9947 static void CheckSurvivingGlobalObjectsCount(int expected) { | 9964 static void CheckSurvivingGlobalObjectsCount(int expected) { |
| 9948 // We need to collect all garbage twice to be sure that everything | 9965 // We need to collect all garbage twice to be sure that everything |
| 9949 // has been collected. This is because inline caches are cleared in | 9966 // has been collected. This is because inline caches are cleared in |
| 9950 // the first garbage collection but some of the maps have already | 9967 // the first garbage collection but some of the maps have already |
| 9951 // been marked at that point. Therefore some of the maps are not | 9968 // been marked at that point. Therefore some of the maps are not |
| 9952 // collected until the second garbage collection. | 9969 // collected until the second garbage collection. |
| 9953 HEAP->global_context_map(); | 9970 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 9954 HEAP->CollectAllGarbage(false); | 9971 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 9955 HEAP->CollectAllGarbage(false); | |
| 9956 int count = GetGlobalObjectsCount(); | 9972 int count = GetGlobalObjectsCount(); |
| 9957 #ifdef DEBUG | 9973 #ifdef DEBUG |
| 9958 if (count != expected) HEAP->TracePathToGlobal(); | 9974 if (count != expected) HEAP->TracePathToGlobal(); |
| 9959 #endif | 9975 #endif |
| 9960 CHECK_EQ(expected, count); | 9976 CHECK_EQ(expected, count); |
| 9961 } | 9977 } |
| 9962 | 9978 |
| 9963 | 9979 |
| 9964 TEST(DontLeakGlobalObjects) { | 9980 TEST(DontLeakGlobalObjects) { |
| 9965 // Regression test for issues 1139850 and 1174891. | 9981 // Regression test for issues 1139850 and 1174891. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10014 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10030 some_object = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10015 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10031 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10016 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10032 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10017 } | 10033 } |
| 10018 // Note: order is implementation dependent alas: currently | 10034 // Note: order is implementation dependent alas: currently |
| 10019 // global handle nodes are processed by PostGarbageCollectionProcessing | 10035 // global handle nodes are processed by PostGarbageCollectionProcessing |
| 10020 // in reverse allocation order, so if second allocated handle is deleted, | 10036 // in reverse allocation order, so if second allocated handle is deleted, |
| 10021 // weak callback of the first handle would be able to 'reallocate' it. | 10037 // weak callback of the first handle would be able to 'reallocate' it. |
| 10022 handle1.MakeWeak(NULL, NewPersistentHandleCallback); | 10038 handle1.MakeWeak(NULL, NewPersistentHandleCallback); |
| 10023 handle2.Dispose(); | 10039 handle2.Dispose(); |
| 10024 HEAP->CollectAllGarbage(false); | 10040 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 10025 } | 10041 } |
| 10026 | 10042 |
| 10027 | 10043 |
| 10028 v8::Persistent<v8::Object> to_be_disposed; | 10044 v8::Persistent<v8::Object> to_be_disposed; |
| 10029 | 10045 |
| 10030 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { | 10046 void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) { |
| 10031 to_be_disposed.Dispose(); | 10047 to_be_disposed.Dispose(); |
| 10032 HEAP->CollectAllGarbage(false); | 10048 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 10033 handle.Dispose(); | 10049 handle.Dispose(); |
| 10034 } | 10050 } |
| 10035 | 10051 |
| 10036 | 10052 |
| 10037 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { | 10053 THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) { |
| 10038 LocalContext context; | 10054 LocalContext context; |
| 10039 | 10055 |
| 10040 v8::Persistent<v8::Object> handle1, handle2; | 10056 v8::Persistent<v8::Object> handle1, handle2; |
| 10041 { | 10057 { |
| 10042 v8::HandleScope scope; | 10058 v8::HandleScope scope; |
| 10043 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10059 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10044 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10060 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10045 } | 10061 } |
| 10046 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); | 10062 handle1.MakeWeak(NULL, DisposeAndForceGcCallback); |
| 10047 to_be_disposed = handle2; | 10063 to_be_disposed = handle2; |
| 10048 HEAP->CollectAllGarbage(false); | 10064 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 10049 } | 10065 } |
| 10050 | 10066 |
| 10051 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { | 10067 void DisposingCallback(v8::Persistent<v8::Value> handle, void*) { |
| 10052 handle.Dispose(); | 10068 handle.Dispose(); |
| 10053 } | 10069 } |
| 10054 | 10070 |
| 10055 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { | 10071 void HandleCreatingCallback(v8::Persistent<v8::Value> handle, void*) { |
| 10056 v8::HandleScope scope; | 10072 v8::HandleScope scope; |
| 10057 v8::Persistent<v8::Object>::New(v8::Object::New()); | 10073 v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10058 handle.Dispose(); | 10074 handle.Dispose(); |
| 10059 } | 10075 } |
| 10060 | 10076 |
| 10061 | 10077 |
| 10062 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { | 10078 THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { |
| 10063 LocalContext context; | 10079 LocalContext context; |
| 10064 | 10080 |
| 10065 v8::Persistent<v8::Object> handle1, handle2, handle3; | 10081 v8::Persistent<v8::Object> handle1, handle2, handle3; |
| 10066 { | 10082 { |
| 10067 v8::HandleScope scope; | 10083 v8::HandleScope scope; |
| 10068 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10084 handle3 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10069 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10085 handle2 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10070 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); | 10086 handle1 = v8::Persistent<v8::Object>::New(v8::Object::New()); |
| 10071 } | 10087 } |
| 10072 handle2.MakeWeak(NULL, DisposingCallback); | 10088 handle2.MakeWeak(NULL, DisposingCallback); |
| 10073 handle3.MakeWeak(NULL, HandleCreatingCallback); | 10089 handle3.MakeWeak(NULL, HandleCreatingCallback); |
| 10074 HEAP->CollectAllGarbage(false); | 10090 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 10075 } | 10091 } |
| 10076 | 10092 |
| 10077 | 10093 |
| 10078 THREADED_TEST(CheckForCrossContextObjectLiterals) { | 10094 THREADED_TEST(CheckForCrossContextObjectLiterals) { |
| 10079 v8::V8::Initialize(); | 10095 v8::V8::Initialize(); |
| 10080 | 10096 |
| 10081 const int nof = 2; | 10097 const int nof = 2; |
| 10082 const char* sources[nof] = { | 10098 const char* sources[nof] = { |
| 10083 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", | 10099 "try { [ 2, 3, 4 ].forEach(5); } catch(e) { e.toString(); }", |
| 10084 "Object()" | 10100 "Object()" |
| (...skipping 795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10880 private: | 10896 private: |
| 10881 RegExpInterruptTest* test_; | 10897 RegExpInterruptTest* test_; |
| 10882 }; | 10898 }; |
| 10883 | 10899 |
| 10884 void CollectGarbage() { | 10900 void CollectGarbage() { |
| 10885 block_->Wait(); | 10901 block_->Wait(); |
| 10886 while (gc_during_regexp_ < kRequiredGCs) { | 10902 while (gc_during_regexp_ < kRequiredGCs) { |
| 10887 { | 10903 { |
| 10888 v8::Locker lock; | 10904 v8::Locker lock; |
| 10889 // TODO(lrn): Perhaps create some garbage before collecting. | 10905 // TODO(lrn): Perhaps create some garbage before collecting. |
| 10890 HEAP->CollectAllGarbage(false); | 10906 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 10891 gc_count_++; | 10907 gc_count_++; |
| 10892 } | 10908 } |
| 10893 i::OS::Sleep(1); | 10909 i::OS::Sleep(1); |
| 10894 } | 10910 } |
| 10895 gc_success_ = true; | 10911 gc_success_ = true; |
| 10896 } | 10912 } |
| 10897 | 10913 |
| 10898 void LongRunningRegExp() { | 10914 void LongRunningRegExp() { |
| 10899 block_->Signal(); // Enable garbage collection thread on next preemption. | 10915 block_->Signal(); // Enable garbage collection thread on next preemption. |
| 10900 int rounds = 0; | 10916 int rounds = 0; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11002 } | 11018 } |
| 11003 private: | 11019 private: |
| 11004 ApplyInterruptTest* test_; | 11020 ApplyInterruptTest* test_; |
| 11005 }; | 11021 }; |
| 11006 | 11022 |
| 11007 void CollectGarbage() { | 11023 void CollectGarbage() { |
| 11008 block_->Wait(); | 11024 block_->Wait(); |
| 11009 while (gc_during_apply_ < kRequiredGCs) { | 11025 while (gc_during_apply_ < kRequiredGCs) { |
| 11010 { | 11026 { |
| 11011 v8::Locker lock; | 11027 v8::Locker lock; |
| 11012 HEAP->CollectAllGarbage(false); | 11028 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 11013 gc_count_++; | 11029 gc_count_++; |
| 11014 } | 11030 } |
| 11015 i::OS::Sleep(1); | 11031 i::OS::Sleep(1); |
| 11016 } | 11032 } |
| 11017 gc_success_ = true; | 11033 gc_success_ = true; |
| 11018 } | 11034 } |
| 11019 | 11035 |
| 11020 void LongRunningApply() { | 11036 void LongRunningApply() { |
| 11021 block_->Signal(); | 11037 block_->Signal(); |
| 11022 int rounds = 0; | 11038 int rounds = 0; |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11718 | 11734 |
| 11719 | 11735 |
| 11720 THREADED_TEST(PixelArray) { | 11736 THREADED_TEST(PixelArray) { |
| 11721 v8::HandleScope scope; | 11737 v8::HandleScope scope; |
| 11722 LocalContext context; | 11738 LocalContext context; |
| 11723 const int kElementCount = 260; | 11739 const int kElementCount = 260; |
| 11724 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); | 11740 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(kElementCount)); |
| 11725 i::Handle<i::ExternalPixelArray> pixels = | 11741 i::Handle<i::ExternalPixelArray> pixels = |
| 11726 i::Handle<i::ExternalPixelArray>::cast( | 11742 i::Handle<i::ExternalPixelArray>::cast( |
| 11727 FACTORY->NewExternalArray(kElementCount, | 11743 FACTORY->NewExternalArray(kElementCount, |
| 11728 v8::kExternalPixelArray, | 11744 v8::kExternalPixelArray, |
| 11729 pixel_data)); | 11745 pixel_data)); |
| 11730 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 11746 // Force GC to trigger verification. |
| 11747 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 11731 for (int i = 0; i < kElementCount; i++) { | 11748 for (int i = 0; i < kElementCount; i++) { |
| 11732 pixels->set(i, i % 256); | 11749 pixels->set(i, i % 256); |
| 11733 } | 11750 } |
| 11734 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 11751 // Force GC to trigger verification. |
| 11752 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 11735 for (int i = 0; i < kElementCount; i++) { | 11753 for (int i = 0; i < kElementCount; i++) { |
| 11736 CHECK_EQ(i % 256, pixels->get_scalar(i)); | 11754 CHECK_EQ(i % 256, pixels->get_scalar(i)); |
| 11737 CHECK_EQ(i % 256, pixel_data[i]); | 11755 CHECK_EQ(i % 256, pixel_data[i]); |
| 11738 } | 11756 } |
| 11739 | 11757 |
| 11740 v8::Handle<v8::Object> obj = v8::Object::New(); | 11758 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 11741 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 11759 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
| 11742 // Set the elements to be the pixels. | 11760 // Set the elements to be the pixels. |
| 11743 // jsobj->set_elements(*pixels); | 11761 // jsobj->set_elements(*pixels); |
| 11744 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); | 11762 obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount); |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12200 int64_t high) { | 12218 int64_t high) { |
| 12201 v8::HandleScope scope; | 12219 v8::HandleScope scope; |
| 12202 LocalContext context; | 12220 LocalContext context; |
| 12203 const int kElementCount = 40; | 12221 const int kElementCount = 40; |
| 12204 int element_size = ExternalArrayElementSize(array_type); | 12222 int element_size = ExternalArrayElementSize(array_type); |
| 12205 ElementType* array_data = | 12223 ElementType* array_data = |
| 12206 static_cast<ElementType*>(malloc(kElementCount * element_size)); | 12224 static_cast<ElementType*>(malloc(kElementCount * element_size)); |
| 12207 i::Handle<ExternalArrayClass> array = | 12225 i::Handle<ExternalArrayClass> array = |
| 12208 i::Handle<ExternalArrayClass>::cast( | 12226 i::Handle<ExternalArrayClass>::cast( |
| 12209 FACTORY->NewExternalArray(kElementCount, array_type, array_data)); | 12227 FACTORY->NewExternalArray(kElementCount, array_type, array_data)); |
| 12210 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 12228 // Force GC to trigger verification. |
| 12229 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12211 for (int i = 0; i < kElementCount; i++) { | 12230 for (int i = 0; i < kElementCount; i++) { |
| 12212 array->set(i, static_cast<ElementType>(i)); | 12231 array->set(i, static_cast<ElementType>(i)); |
| 12213 } | 12232 } |
| 12214 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 12233 // Force GC to trigger verification. |
| 12234 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12215 for (int i = 0; i < kElementCount; i++) { | 12235 for (int i = 0; i < kElementCount; i++) { |
| 12216 CHECK_EQ(static_cast<int64_t>(i), | 12236 CHECK_EQ(static_cast<int64_t>(i), |
| 12217 static_cast<int64_t>(array->get_scalar(i))); | 12237 static_cast<int64_t>(array->get_scalar(i))); |
| 12218 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); | 12238 CHECK_EQ(static_cast<int64_t>(i), static_cast<int64_t>(array_data[i])); |
| 12219 } | 12239 } |
| 12220 | 12240 |
| 12221 v8::Handle<v8::Object> obj = v8::Object::New(); | 12241 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 12222 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); | 12242 i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); |
| 12223 // Set the elements to be the external array. | 12243 // Set the elements to be the external array. |
| 12224 obj->SetIndexedPropertiesToExternalArrayData(array_data, | 12244 obj->SetIndexedPropertiesToExternalArrayData(array_data, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12322 result = CompileRun("var tmp_array = ext_array;" | 12342 result = CompileRun("var tmp_array = ext_array;" |
| 12323 "var sum = 0;" | 12343 "var sum = 0;" |
| 12324 "for (var i = 0; i < 8; i++) {" | 12344 "for (var i = 0; i < 8; i++) {" |
| 12325 " tmp_array[i] = i;" | 12345 " tmp_array[i] = i;" |
| 12326 " sum += tmp_array[i];" | 12346 " sum += tmp_array[i];" |
| 12327 " if (i == 4) {" | 12347 " if (i == 4) {" |
| 12328 " tmp_array = {};" | 12348 " tmp_array = {};" |
| 12329 " }" | 12349 " }" |
| 12330 "}" | 12350 "}" |
| 12331 "sum;"); | 12351 "sum;"); |
| 12332 HEAP->CollectAllGarbage(false); // Force GC to trigger verification. | 12352 // Force GC to trigger verification. |
| 12353 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 12333 CHECK_EQ(28, result->Int32Value()); | 12354 CHECK_EQ(28, result->Int32Value()); |
| 12334 | 12355 |
| 12335 // Make sure out-of-range loads do not throw. | 12356 // Make sure out-of-range loads do not throw. |
| 12336 i::OS::SNPrintF(test_buf, | 12357 i::OS::SNPrintF(test_buf, |
| 12337 "var caught_exception = false;" | 12358 "var caught_exception = false;" |
| 12338 "try {" | 12359 "try {" |
| 12339 " ext_array[%d];" | 12360 " ext_array[%d];" |
| 12340 "} catch (e) {" | 12361 "} catch (e) {" |
| 12341 " caught_exception = true;" | 12362 " caught_exception = true;" |
| 12342 "}" | 12363 "}" |
| (...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13302 Local<v8::String> obj = v8::String::New(""); | 13323 Local<v8::String> obj = v8::String::New(""); |
| 13303 context->SetData(obj); | 13324 context->SetData(obj); |
| 13304 CompileRun(source_simple); | 13325 CompileRun(source_simple); |
| 13305 context->Exit(); | 13326 context->Exit(); |
| 13306 } | 13327 } |
| 13307 context.Dispose(); | 13328 context.Dispose(); |
| 13308 for (gc_count = 1; gc_count < 10; gc_count++) { | 13329 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 13309 other_context->Enter(); | 13330 other_context->Enter(); |
| 13310 CompileRun(source_simple); | 13331 CompileRun(source_simple); |
| 13311 other_context->Exit(); | 13332 other_context->Exit(); |
| 13312 HEAP->CollectAllGarbage(false); | 13333 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 13313 if (GetGlobalObjectsCount() == 1) break; | 13334 if (GetGlobalObjectsCount() == 1) break; |
| 13314 } | 13335 } |
| 13315 CHECK_GE(2, gc_count); | 13336 CHECK_GE(2, gc_count); |
| 13316 CHECK_EQ(1, GetGlobalObjectsCount()); | 13337 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 13317 | 13338 |
| 13318 // Eval in a function creates reference from the compilation cache to the | 13339 // Eval in a function creates reference from the compilation cache to the |
| 13319 // global object. | 13340 // global object. |
| 13320 const char* source_eval = "function f(){eval('1')}; f()"; | 13341 const char* source_eval = "function f(){eval('1')}; f()"; |
| 13321 context = Context::New(); | 13342 context = Context::New(); |
| 13322 { | 13343 { |
| 13323 v8::HandleScope scope; | 13344 v8::HandleScope scope; |
| 13324 | 13345 |
| 13325 context->Enter(); | 13346 context->Enter(); |
| 13326 CompileRun(source_eval); | 13347 CompileRun(source_eval); |
| 13327 context->Exit(); | 13348 context->Exit(); |
| 13328 } | 13349 } |
| 13329 context.Dispose(); | 13350 context.Dispose(); |
| 13330 for (gc_count = 1; gc_count < 10; gc_count++) { | 13351 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 13331 other_context->Enter(); | 13352 other_context->Enter(); |
| 13332 CompileRun(source_eval); | 13353 CompileRun(source_eval); |
| 13333 other_context->Exit(); | 13354 other_context->Exit(); |
| 13334 HEAP->CollectAllGarbage(false); | 13355 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 13335 if (GetGlobalObjectsCount() == 1) break; | 13356 if (GetGlobalObjectsCount() == 1) break; |
| 13336 } | 13357 } |
| 13337 CHECK_GE(2, gc_count); | 13358 CHECK_GE(2, gc_count); |
| 13338 CHECK_EQ(1, GetGlobalObjectsCount()); | 13359 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 13339 | 13360 |
| 13340 // Looking up the line number for an exception creates reference from the | 13361 // Looking up the line number for an exception creates reference from the |
| 13341 // compilation cache to the global object. | 13362 // compilation cache to the global object. |
| 13342 const char* source_exception = "function f(){throw 1;} f()"; | 13363 const char* source_exception = "function f(){throw 1;} f()"; |
| 13343 context = Context::New(); | 13364 context = Context::New(); |
| 13344 { | 13365 { |
| 13345 v8::HandleScope scope; | 13366 v8::HandleScope scope; |
| 13346 | 13367 |
| 13347 context->Enter(); | 13368 context->Enter(); |
| 13348 v8::TryCatch try_catch; | 13369 v8::TryCatch try_catch; |
| 13349 CompileRun(source_exception); | 13370 CompileRun(source_exception); |
| 13350 CHECK(try_catch.HasCaught()); | 13371 CHECK(try_catch.HasCaught()); |
| 13351 v8::Handle<v8::Message> message = try_catch.Message(); | 13372 v8::Handle<v8::Message> message = try_catch.Message(); |
| 13352 CHECK(!message.IsEmpty()); | 13373 CHECK(!message.IsEmpty()); |
| 13353 CHECK_EQ(1, message->GetLineNumber()); | 13374 CHECK_EQ(1, message->GetLineNumber()); |
| 13354 context->Exit(); | 13375 context->Exit(); |
| 13355 } | 13376 } |
| 13356 context.Dispose(); | 13377 context.Dispose(); |
| 13357 for (gc_count = 1; gc_count < 10; gc_count++) { | 13378 for (gc_count = 1; gc_count < 10; gc_count++) { |
| 13358 other_context->Enter(); | 13379 other_context->Enter(); |
| 13359 CompileRun(source_exception); | 13380 CompileRun(source_exception); |
| 13360 other_context->Exit(); | 13381 other_context->Exit(); |
| 13361 HEAP->CollectAllGarbage(false); | 13382 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 13362 if (GetGlobalObjectsCount() == 1) break; | 13383 if (GetGlobalObjectsCount() == 1) break; |
| 13363 } | 13384 } |
| 13364 CHECK_GE(2, gc_count); | 13385 CHECK_GE(2, gc_count); |
| 13365 CHECK_EQ(1, GetGlobalObjectsCount()); | 13386 CHECK_EQ(1, GetGlobalObjectsCount()); |
| 13366 | 13387 |
| 13367 other_context.Dispose(); | 13388 other_context.Dispose(); |
| 13368 } | 13389 } |
| 13369 | 13390 |
| 13370 | 13391 |
| 13371 THREADED_TEST(ScriptOrigin) { | 13392 THREADED_TEST(ScriptOrigin) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13569 ++epilogue_call_count_second; | 13590 ++epilogue_call_count_second; |
| 13570 } | 13591 } |
| 13571 | 13592 |
| 13572 TEST(GCCallbacks) { | 13593 TEST(GCCallbacks) { |
| 13573 LocalContext context; | 13594 LocalContext context; |
| 13574 | 13595 |
| 13575 v8::V8::AddGCPrologueCallback(PrologueCallback); | 13596 v8::V8::AddGCPrologueCallback(PrologueCallback); |
| 13576 v8::V8::AddGCEpilogueCallback(EpilogueCallback); | 13597 v8::V8::AddGCEpilogueCallback(EpilogueCallback); |
| 13577 CHECK_EQ(0, prologue_call_count); | 13598 CHECK_EQ(0, prologue_call_count); |
| 13578 CHECK_EQ(0, epilogue_call_count); | 13599 CHECK_EQ(0, epilogue_call_count); |
| 13579 HEAP->CollectAllGarbage(false); | 13600 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 13580 CHECK_EQ(1, prologue_call_count); | 13601 CHECK_EQ(1, prologue_call_count); |
| 13581 CHECK_EQ(1, epilogue_call_count); | 13602 CHECK_EQ(1, epilogue_call_count); |
| 13582 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); | 13603 v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); |
| 13583 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); | 13604 v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); |
| 13584 HEAP->CollectAllGarbage(false); | 13605 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 13585 CHECK_EQ(2, prologue_call_count); | 13606 CHECK_EQ(2, prologue_call_count); |
| 13586 CHECK_EQ(2, epilogue_call_count); | 13607 CHECK_EQ(2, epilogue_call_count); |
| 13587 CHECK_EQ(1, prologue_call_count_second); | 13608 CHECK_EQ(1, prologue_call_count_second); |
| 13588 CHECK_EQ(1, epilogue_call_count_second); | 13609 CHECK_EQ(1, epilogue_call_count_second); |
| 13589 v8::V8::RemoveGCPrologueCallback(PrologueCallback); | 13610 v8::V8::RemoveGCPrologueCallback(PrologueCallback); |
| 13590 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); | 13611 v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); |
| 13591 HEAP->CollectAllGarbage(false); | 13612 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 13592 CHECK_EQ(2, prologue_call_count); | 13613 CHECK_EQ(2, prologue_call_count); |
| 13593 CHECK_EQ(2, epilogue_call_count); | 13614 CHECK_EQ(2, epilogue_call_count); |
| 13594 CHECK_EQ(2, prologue_call_count_second); | 13615 CHECK_EQ(2, prologue_call_count_second); |
| 13595 CHECK_EQ(2, epilogue_call_count_second); | 13616 CHECK_EQ(2, epilogue_call_count_second); |
| 13596 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); | 13617 v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); |
| 13597 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); | 13618 v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); |
| 13598 HEAP->CollectAllGarbage(false); | 13619 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 13599 CHECK_EQ(2, prologue_call_count); | 13620 CHECK_EQ(2, prologue_call_count); |
| 13600 CHECK_EQ(2, epilogue_call_count); | 13621 CHECK_EQ(2, epilogue_call_count); |
| 13601 CHECK_EQ(2, prologue_call_count_second); | 13622 CHECK_EQ(2, prologue_call_count_second); |
| 13602 CHECK_EQ(2, epilogue_call_count_second); | 13623 CHECK_EQ(2, epilogue_call_count_second); |
| 13603 } | 13624 } |
| 13604 | 13625 |
| 13605 | 13626 |
| 13606 THREADED_TEST(AddToJSFunctionResultCache) { | 13627 THREADED_TEST(AddToJSFunctionResultCache) { |
| 13607 i::FLAG_allow_natives_syntax = true; | 13628 i::FLAG_allow_natives_syntax = true; |
| 13608 v8::HandleScope scope; | 13629 v8::HandleScope scope; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13805 | 13826 |
| 13806 reresult = CompileRun("str2.charCodeAt(2);"); | 13827 reresult = CompileRun("str2.charCodeAt(2);"); |
| 13807 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); | 13828 CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); |
| 13808 } | 13829 } |
| 13809 | 13830 |
| 13810 | 13831 |
| 13811 // Failed access check callback that performs a GC on each invocation. | 13832 // Failed access check callback that performs a GC on each invocation. |
| 13812 void FailedAccessCheckCallbackGC(Local<v8::Object> target, | 13833 void FailedAccessCheckCallbackGC(Local<v8::Object> target, |
| 13813 v8::AccessType type, | 13834 v8::AccessType type, |
| 13814 Local<v8::Value> data) { | 13835 Local<v8::Value> data) { |
| 13815 HEAP->CollectAllGarbage(true); | 13836 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 13816 } | 13837 } |
| 13817 | 13838 |
| 13818 | 13839 |
| 13819 TEST(GCInFailedAccessCheckCallback) { | 13840 TEST(GCInFailedAccessCheckCallback) { |
| 13820 // Install a failed access check callback that performs a GC on each | 13841 // Install a failed access check callback that performs a GC on each |
| 13821 // invocation. Then force the callback to be called from va | 13842 // invocation. Then force the callback to be called from va |
| 13822 | 13843 |
| 13823 v8::V8::Initialize(); | 13844 v8::V8::Initialize(); |
| 13824 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); | 13845 v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); |
| 13825 | 13846 |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14379 ExpectBoolean("delete cell", true); | 14400 ExpectBoolean("delete cell", true); |
| 14380 ExpectString("(function() {" | 14401 ExpectString("(function() {" |
| 14381 " try {" | 14402 " try {" |
| 14382 " return readCell();" | 14403 " return readCell();" |
| 14383 " } catch(e) {" | 14404 " } catch(e) {" |
| 14384 " return e.toString();" | 14405 " return e.toString();" |
| 14385 " }" | 14406 " }" |
| 14386 "})()", | 14407 "})()", |
| 14387 "ReferenceError: cell is not defined"); | 14408 "ReferenceError: cell is not defined"); |
| 14388 CompileRun("cell = \"new_second\";"); | 14409 CompileRun("cell = \"new_second\";"); |
| 14389 HEAP->CollectAllGarbage(true); | 14410 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 14390 ExpectString("readCell()", "new_second"); | 14411 ExpectString("readCell()", "new_second"); |
| 14391 ExpectString("readCell()", "new_second"); | 14412 ExpectString("readCell()", "new_second"); |
| 14392 } | 14413 } |
| 14393 } | 14414 } |
| 14394 | 14415 |
| 14395 | 14416 |
| 14396 TEST(DontDeleteCellLoadICForceDelete) { | 14417 TEST(DontDeleteCellLoadICForceDelete) { |
| 14397 const char* function_code = | 14418 const char* function_code = |
| 14398 "function readCell() { while (true) { return cell; } }"; | 14419 "function readCell() { while (true) { return cell; } }"; |
| 14399 | 14420 |
| (...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15147 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); | 15168 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); |
| 15148 | 15169 |
| 15149 // TODO(1547): Make the following also return "i". | 15170 // TODO(1547): Make the following also return "i". |
| 15150 // Calling with environment record as base. | 15171 // Calling with environment record as base. |
| 15151 TestReceiver(o, context->Global(), "func()"); | 15172 TestReceiver(o, context->Global(), "func()"); |
| 15152 // Calling with no base. | 15173 // Calling with no base. |
| 15153 TestReceiver(o, context->Global(), "(1,func)()"); | 15174 TestReceiver(o, context->Global(), "(1,func)()"); |
| 15154 | 15175 |
| 15155 foreign_context.Dispose(); | 15176 foreign_context.Dispose(); |
| 15156 } | 15177 } |
| OLD | NEW |