OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 Map::Normalize(map, KEEP_INOBJECT_PROPERTIES, "testing"); | 641 Map::Normalize(map, KEEP_INOBJECT_PROPERTIES, "testing"); |
642 JSObject::MigrateToMap(object, normalized_map); | 642 JSObject::MigrateToMap(object, normalized_map); |
643 CHECK(!object->HasFastProperties()); | 643 CHECK(!object->HasFastProperties()); |
644 CHECK(object->map()->HasFastPointerLayout()); | 644 CHECK(object->map()->HasFastPointerLayout()); |
645 | 645 |
646 // Trigger GCs and heap verification. | 646 // Trigger GCs and heap verification. |
647 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 647 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
648 } | 648 } |
649 | 649 |
650 | 650 |
| 651 TEST(DoScavenge) { |
| 652 CcTest::InitializeVM(); |
| 653 Isolate* isolate = CcTest::i_isolate(); |
| 654 Factory* factory = isolate->factory(); |
| 655 v8::HandleScope scope(CcTest::isolate()); |
| 656 |
| 657 CompileRun( |
| 658 "function A() {" |
| 659 " this.x = 42.5;" |
| 660 " this.o = {};" |
| 661 "};" |
| 662 "var o = new A();"); |
| 663 |
| 664 Handle<String> obj_name = factory->InternalizeUtf8String("o"); |
| 665 |
| 666 Handle<Object> obj_value = |
| 667 Object::GetProperty(isolate->global_object(), obj_name).ToHandleChecked(); |
| 668 CHECK(obj_value->IsJSObject()); |
| 669 Handle<JSObject> obj = Handle<JSObject>::cast(obj_value); |
| 670 |
| 671 { |
| 672 // Ensure the object is properly set up. |
| 673 Map* map = obj->map(); |
| 674 DescriptorArray* descriptors = map->instance_descriptors(); |
| 675 CHECK(map->NumberOfOwnDescriptors() == 2); |
| 676 CHECK(descriptors->GetDetails(0).representation().IsDouble()); |
| 677 CHECK(descriptors->GetDetails(1).representation().IsHeapObject()); |
| 678 FieldIndex field_index = FieldIndex::ForDescriptor(map, 0); |
| 679 CHECK(field_index.is_inobject() && field_index.is_double()); |
| 680 CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index)); |
| 681 CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index)); |
| 682 } |
| 683 CHECK(isolate->heap()->new_space()->Contains(*obj)); |
| 684 |
| 685 // Trigger GCs so that the newly allocated object moves to old gen. |
| 686 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now |
| 687 |
| 688 // Create temp object in the new space. |
| 689 Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED); |
| 690 CHECK(isolate->heap()->new_space()->Contains(*temp)); |
| 691 |
| 692 // Construct a double value that looks like a pointer to the new space object |
| 693 // and store it into the obj. |
| 694 Address fake_object = reinterpret_cast<Address>(*temp) + kPointerSize; |
| 695 double boom_value = bit_cast<double>(fake_object); |
| 696 |
| 697 FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0); |
| 698 Handle<HeapNumber> boom_number = factory->NewHeapNumber(boom_value, MUTABLE); |
| 699 obj->FastPropertyAtPut(field_index, *boom_number); |
| 700 |
| 701 // Now the object moves to old gen and it has a double field that looks like |
| 702 // a pointer to a from semi-space. |
| 703 CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now |
| 704 |
| 705 CHECK(isolate->heap()->old_pointer_space()->Contains(*obj)); |
| 706 |
| 707 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index)); |
| 708 } |
| 709 |
| 710 |
651 TEST(StoreBufferScanOnScavenge) { | 711 TEST(StoreBufferScanOnScavenge) { |
652 CcTest::InitializeVM(); | 712 CcTest::InitializeVM(); |
653 Isolate* isolate = CcTest::i_isolate(); | 713 Isolate* isolate = CcTest::i_isolate(); |
654 Factory* factory = isolate->factory(); | 714 Factory* factory = isolate->factory(); |
655 v8::HandleScope scope(CcTest::isolate()); | 715 v8::HandleScope scope(CcTest::isolate()); |
656 | 716 |
657 CompileRun( | 717 CompileRun( |
658 "function A() {" | 718 "function A() {" |
659 " this.x = 42.5;" | 719 " this.x = 42.5;" |
660 " this.o = {};" | 720 " this.o = {};" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); | 765 MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address()); |
706 chunk->set_scan_on_scavenge(true); | 766 chunk->set_scan_on_scavenge(true); |
707 | 767 |
708 // Trigger GCs and force evacuation. Should not crash there. | 768 // Trigger GCs and force evacuation. Should not crash there. |
709 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 769 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
710 | 770 |
711 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index)); | 771 CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index)); |
712 } | 772 } |
713 | 773 |
714 #endif | 774 #endif |
OLD | NEW |