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 |