OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/heap/heap.h" | 5 #include "src/heap/heap.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 | 1462 |
1463 isolate_->compilation_cache()->MarkCompactPrologue(); | 1463 isolate_->compilation_cache()->MarkCompactPrologue(); |
1464 | 1464 |
1465 CompletelyClearInstanceofCache(); | 1465 CompletelyClearInstanceofCache(); |
1466 | 1466 |
1467 FlushNumberStringCache(); | 1467 FlushNumberStringCache(); |
1468 ClearNormalizedMapCaches(); | 1468 ClearNormalizedMapCaches(); |
1469 } | 1469 } |
1470 | 1470 |
1471 | 1471 |
| 1472 #ifdef VERIFY_HEAP |
| 1473 // Visitor class to verify pointers in code or data space do not point into |
| 1474 // new space. |
| 1475 class VerifyNonPointerSpacePointersVisitor : public ObjectVisitor { |
| 1476 public: |
| 1477 explicit VerifyNonPointerSpacePointersVisitor(Heap* heap) : heap_(heap) {} |
| 1478 |
| 1479 void VisitPointers(Object** start, Object** end) override { |
| 1480 for (Object** current = start; current < end; current++) { |
| 1481 if ((*current)->IsHeapObject()) { |
| 1482 CHECK(!heap_->InNewSpace(HeapObject::cast(*current))); |
| 1483 } |
| 1484 } |
| 1485 } |
| 1486 |
| 1487 private: |
| 1488 Heap* heap_; |
| 1489 }; |
| 1490 |
| 1491 |
| 1492 static void VerifyNonPointerSpacePointers(Heap* heap) { |
| 1493 // Verify that there are no pointers to new space in spaces where we |
| 1494 // do not expect them. |
| 1495 VerifyNonPointerSpacePointersVisitor v(heap); |
| 1496 HeapObjectIterator code_it(heap->code_space()); |
| 1497 for (HeapObject* object = code_it.Next(); object != NULL; |
| 1498 object = code_it.Next()) |
| 1499 object->Iterate(&v); |
| 1500 } |
| 1501 #endif // VERIFY_HEAP |
| 1502 |
| 1503 |
1472 void Heap::CheckNewSpaceExpansionCriteria() { | 1504 void Heap::CheckNewSpaceExpansionCriteria() { |
1473 if (FLAG_experimental_new_space_growth_heuristic) { | 1505 if (FLAG_experimental_new_space_growth_heuristic) { |
1474 if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && | 1506 if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && |
1475 survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) { | 1507 survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) { |
1476 // Grow the size of new space if there is room to grow, and more than 10% | 1508 // Grow the size of new space if there is room to grow, and more than 10% |
1477 // have survived the last scavenge. | 1509 // have survived the last scavenge. |
1478 new_space_.Grow(); | 1510 new_space_.Grow(); |
1479 survived_since_last_expansion_ = 0; | 1511 survived_since_last_expansion_ = 0; |
1480 } | 1512 } |
1481 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && | 1513 } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() && |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 // sweep collection by failing allocations. There is no sense in trying to | 1606 // sweep collection by failing allocations. There is no sense in trying to |
1575 // trigger one during scavenge: scavenges allocation should always succeed. | 1607 // trigger one during scavenge: scavenges allocation should always succeed. |
1576 AlwaysAllocateScope scope(isolate()); | 1608 AlwaysAllocateScope scope(isolate()); |
1577 | 1609 |
1578 // Bump-pointer allocations done during scavenge are not real allocations. | 1610 // Bump-pointer allocations done during scavenge are not real allocations. |
1579 // Pause the inline allocation steps. | 1611 // Pause the inline allocation steps. |
1580 PauseAllocationObserversScope pause_observers(this); | 1612 PauseAllocationObserversScope pause_observers(this); |
1581 | 1613 |
1582 mark_compact_collector()->sweeper().EnsureNewSpaceCompleted(); | 1614 mark_compact_collector()->sweeper().EnsureNewSpaceCompleted(); |
1583 | 1615 |
| 1616 #ifdef VERIFY_HEAP |
| 1617 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(this); |
| 1618 #endif |
| 1619 |
1584 gc_state_ = SCAVENGE; | 1620 gc_state_ = SCAVENGE; |
1585 | 1621 |
1586 // Implements Cheney's copying algorithm | 1622 // Implements Cheney's copying algorithm |
1587 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1623 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
1588 | 1624 |
1589 // Used for updating survived_since_last_expansion_ at function end. | 1625 // Used for updating survived_since_last_expansion_ at function end. |
1590 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); | 1626 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); |
1591 | 1627 |
1592 scavenge_collector_->SelectScavengingVisitorsTable(); | 1628 scavenge_collector_->SelectScavengingVisitorsTable(); |
1593 | 1629 |
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2816 set_cleared_optimized_code_map(*cleared_optimized_code_map); | 2852 set_cleared_optimized_code_map(*cleared_optimized_code_map); |
2817 } | 2853 } |
2818 | 2854 |
2819 set_detached_contexts(empty_fixed_array()); | 2855 set_detached_contexts(empty_fixed_array()); |
2820 set_retained_maps(ArrayList::cast(empty_fixed_array())); | 2856 set_retained_maps(ArrayList::cast(empty_fixed_array())); |
2821 | 2857 |
2822 set_weak_object_to_code_table( | 2858 set_weak_object_to_code_table( |
2823 *WeakHashTable::New(isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY, | 2859 *WeakHashTable::New(isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY, |
2824 TENURED)); | 2860 TENURED)); |
2825 | 2861 |
2826 set_weak_new_space_object_to_code_list( | |
2827 ArrayList::cast(*(factory->NewFixedArray(16, TENURED)))); | |
2828 weak_new_space_object_to_code_list()->SetLength(0); | |
2829 | |
2830 set_script_list(Smi::FromInt(0)); | 2862 set_script_list(Smi::FromInt(0)); |
2831 | 2863 |
2832 Handle<SeededNumberDictionary> slow_element_dictionary = | 2864 Handle<SeededNumberDictionary> slow_element_dictionary = |
2833 SeededNumberDictionary::New(isolate(), 0, TENURED); | 2865 SeededNumberDictionary::New(isolate(), 0, TENURED); |
2834 slow_element_dictionary->set_requires_slow_elements(); | 2866 slow_element_dictionary->set_requires_slow_elements(); |
2835 set_empty_slow_element_dictionary(*slow_element_dictionary); | 2867 set_empty_slow_element_dictionary(*slow_element_dictionary); |
2836 | 2868 |
2837 set_materialized_objects(*factory->NewFixedArray(0, TENURED)); | 2869 set_materialized_objects(*factory->NewFixedArray(0, TENURED)); |
2838 | 2870 |
2839 // Handling of script id generation is in Heap::NextScriptId(). | 2871 // Handling of script id generation is in Heap::NextScriptId(). |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2879 | 2911 |
2880 // Initialize descriptor cache. | 2912 // Initialize descriptor cache. |
2881 isolate_->descriptor_lookup_cache()->Clear(); | 2913 isolate_->descriptor_lookup_cache()->Clear(); |
2882 | 2914 |
2883 // Initialize compilation cache. | 2915 // Initialize compilation cache. |
2884 isolate_->compilation_cache()->Clear(); | 2916 isolate_->compilation_cache()->Clear(); |
2885 | 2917 |
2886 CreateFixedStubs(); | 2918 CreateFixedStubs(); |
2887 } | 2919 } |
2888 | 2920 |
| 2921 |
2889 bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) { | 2922 bool Heap::RootCanBeWrittenAfterInitialization(Heap::RootListIndex root_index) { |
2890 switch (root_index) { | 2923 switch (root_index) { |
2891 case kNumberStringCacheRootIndex: | 2924 case kNumberStringCacheRootIndex: |
2892 case kInstanceofCacheFunctionRootIndex: | 2925 case kInstanceofCacheFunctionRootIndex: |
2893 case kInstanceofCacheMapRootIndex: | 2926 case kInstanceofCacheMapRootIndex: |
2894 case kInstanceofCacheAnswerRootIndex: | 2927 case kInstanceofCacheAnswerRootIndex: |
2895 case kCodeStubsRootIndex: | 2928 case kCodeStubsRootIndex: |
2896 case kEmptyScriptRootIndex: | 2929 case kEmptyScriptRootIndex: |
2897 case kSymbolRegistryRootIndex: | 2930 case kSymbolRegistryRootIndex: |
2898 case kScriptListRootIndex: | 2931 case kScriptListRootIndex: |
2899 case kMaterializedObjectsRootIndex: | 2932 case kMaterializedObjectsRootIndex: |
2900 case kMicrotaskQueueRootIndex: | 2933 case kMicrotaskQueueRootIndex: |
2901 case kDetachedContextsRootIndex: | 2934 case kDetachedContextsRootIndex: |
2902 case kWeakObjectToCodeTableRootIndex: | 2935 case kWeakObjectToCodeTableRootIndex: |
2903 case kWeakNewSpaceObjectToCodeListRootIndex: | |
2904 case kRetainedMapsRootIndex: | 2936 case kRetainedMapsRootIndex: |
2905 case kNoScriptSharedFunctionInfosRootIndex: | 2937 case kNoScriptSharedFunctionInfosRootIndex: |
2906 case kWeakStackTraceListRootIndex: | 2938 case kWeakStackTraceListRootIndex: |
2907 case kSerializedTemplatesRootIndex: | 2939 case kSerializedTemplatesRootIndex: |
2908 // Smi values | 2940 // Smi values |
2909 #define SMI_ENTRY(type, name, Name) case k##Name##RootIndex: | 2941 #define SMI_ENTRY(type, name, Name) case k##Name##RootIndex: |
2910 SMI_ROOT_LIST(SMI_ENTRY) | 2942 SMI_ROOT_LIST(SMI_ENTRY) |
2911 #undef SMI_ENTRY | 2943 #undef SMI_ENTRY |
2912 // String table | 2944 // String table |
2913 case kStringTableRootIndex: | 2945 case kStringTableRootIndex: |
(...skipping 2611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5525 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { | 5557 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { |
5526 if (gc_epilogue_callbacks_[i].callback == callback) { | 5558 if (gc_epilogue_callbacks_[i].callback == callback) { |
5527 gc_epilogue_callbacks_.Remove(i); | 5559 gc_epilogue_callbacks_.Remove(i); |
5528 return; | 5560 return; |
5529 } | 5561 } |
5530 } | 5562 } |
5531 UNREACHABLE(); | 5563 UNREACHABLE(); |
5532 } | 5564 } |
5533 | 5565 |
5534 // TODO(ishell): Find a better place for this. | 5566 // TODO(ishell): Find a better place for this. |
5535 void Heap::AddWeakNewSpaceObjectToCodeDependency(Handle<HeapObject> obj, | |
5536 Handle<WeakCell> code) { | |
5537 DCHECK(InNewSpace(*obj)); | |
5538 DCHECK(!InNewSpace(*code)); | |
5539 Handle<ArrayList> list(weak_new_space_object_to_code_list(), isolate()); | |
5540 list = ArrayList::Add(list, isolate()->factory()->NewWeakCell(obj), code); | |
5541 if (*list != weak_new_space_object_to_code_list()) { | |
5542 set_weak_new_space_object_to_code_list(*list); | |
5543 } | |
5544 } | |
5545 | |
5546 // TODO(ishell): Find a better place for this. | |
5547 void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, | 5567 void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, |
5548 Handle<DependentCode> dep) { | 5568 Handle<DependentCode> dep) { |
5549 DCHECK(!InNewSpace(*obj)); | 5569 DCHECK(!InNewSpace(*obj)); |
5550 DCHECK(!InNewSpace(*dep)); | 5570 DCHECK(!InNewSpace(*dep)); |
5551 Handle<WeakHashTable> table(weak_object_to_code_table(), isolate()); | 5571 Handle<WeakHashTable> table(weak_object_to_code_table(), isolate()); |
5552 table = WeakHashTable::Put(table, obj, dep); | 5572 table = WeakHashTable::Put(table, obj, dep); |
5553 if (*table != weak_object_to_code_table()) | 5573 if (*table != weak_object_to_code_table()) |
5554 set_weak_object_to_code_table(*table); | 5574 set_weak_object_to_code_table(*table); |
5555 DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj)); | 5575 DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj)); |
5556 } | 5576 } |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5683 void Heap::ClearRecordedSlotRange(Address start, Address end) { | 5703 void Heap::ClearRecordedSlotRange(Address start, Address end) { |
5684 Page* page = Page::FromAddress(start); | 5704 Page* page = Page::FromAddress(start); |
5685 if (!page->InNewSpace()) { | 5705 if (!page->InNewSpace()) { |
5686 store_buffer()->MoveEntriesToRememberedSet(); | 5706 store_buffer()->MoveEntriesToRememberedSet(); |
5687 DCHECK_EQ(page->owner()->identity(), OLD_SPACE); | 5707 DCHECK_EQ(page->owner()->identity(), OLD_SPACE); |
5688 RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end); | 5708 RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end); |
5689 RememberedSet<OLD_TO_OLD>::RemoveRange(page, start, end); | 5709 RememberedSet<OLD_TO_OLD>::RemoveRange(page, start, end); |
5690 } | 5710 } |
5691 } | 5711 } |
5692 | 5712 |
5693 void Heap::RecordWriteIntoCodeSlow(Code* host, RelocInfo* rinfo, | |
5694 Object* value) { | |
5695 DCHECK(InNewSpace(value)); | |
5696 Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host)); | |
5697 RelocInfo::Mode rmode = rinfo->rmode(); | |
5698 Address addr = rinfo->pc(); | |
5699 SlotType slot_type = SlotTypeForRelocInfoMode(rmode); | |
5700 if (rinfo->IsInConstantPool()) { | |
5701 addr = rinfo->constant_pool_entry_address(); | |
5702 if (RelocInfo::IsCodeTarget(rmode)) { | |
5703 slot_type = CODE_ENTRY_SLOT; | |
5704 } else { | |
5705 DCHECK(RelocInfo::IsEmbeddedObject(rmode)); | |
5706 slot_type = OBJECT_SLOT; | |
5707 } | |
5708 } | |
5709 RememberedSet<OLD_TO_NEW>::InsertTyped( | |
5710 source_page, reinterpret_cast<Address>(host), slot_type, addr); | |
5711 } | |
5712 | |
5713 Space* AllSpaces::next() { | 5713 Space* AllSpaces::next() { |
5714 switch (counter_++) { | 5714 switch (counter_++) { |
5715 case NEW_SPACE: | 5715 case NEW_SPACE: |
5716 return heap_->new_space(); | 5716 return heap_->new_space(); |
5717 case OLD_SPACE: | 5717 case OLD_SPACE: |
5718 return heap_->old_space(); | 5718 return heap_->old_space(); |
5719 case CODE_SPACE: | 5719 case CODE_SPACE: |
5720 return heap_->code_space(); | 5720 return heap_->code_space(); |
5721 case MAP_SPACE: | 5721 case MAP_SPACE: |
5722 return heap_->map_space(); | 5722 return heap_->map_space(); |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6372 } | 6372 } |
6373 | 6373 |
6374 | 6374 |
6375 // static | 6375 // static |
6376 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6376 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6377 return StaticVisitorBase::GetVisitorId(map); | 6377 return StaticVisitorBase::GetVisitorId(map); |
6378 } | 6378 } |
6379 | 6379 |
6380 } // namespace internal | 6380 } // namespace internal |
6381 } // namespace v8 | 6381 } // namespace v8 |
OLD | NEW |