Chromium Code Reviews| 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/v8.h" | 5 #include "src/v8.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/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 full_codegen_bytes_generated_(0), | 136 full_codegen_bytes_generated_(0), |
| 137 crankshaft_codegen_bytes_generated_(0), | 137 crankshaft_codegen_bytes_generated_(0), |
| 138 gcs_since_last_deopt_(0), | 138 gcs_since_last_deopt_(0), |
| 139 allocation_sites_scratchpad_length_(0), | 139 allocation_sites_scratchpad_length_(0), |
| 140 promotion_queue_(this), | 140 promotion_queue_(this), |
| 141 configured_(false), | 141 configured_(false), |
| 142 external_string_table_(this), | 142 external_string_table_(this), |
| 143 chunks_queued_for_free_(NULL), | 143 chunks_queued_for_free_(NULL), |
| 144 gc_callbacks_depth_(0), | 144 gc_callbacks_depth_(0), |
| 145 deserialization_complete_(false), | 145 deserialization_complete_(false), |
| 146 concurrent_sweeping_enabled_(false) { | 146 concurrent_sweeping_enabled_(false), |
| 147 migration_failure_(false), | |
| 148 previous_migration_failure_(false) { | |
| 147 // Allow build-time customization of the max semispace size. Building | 149 // Allow build-time customization of the max semispace size. Building |
| 148 // V8 with snapshots and a non-default max semispace size is much | 150 // V8 with snapshots and a non-default max semispace size is much |
| 149 // easier if you can define it as part of the build environment. | 151 // easier if you can define it as part of the build environment. |
| 150 #if defined(V8_MAX_SEMISPACE_SIZE) | 152 #if defined(V8_MAX_SEMISPACE_SIZE) |
| 151 max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; | 153 max_semi_space_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; |
| 152 #endif | 154 #endif |
| 153 | 155 |
| 154 // Ensure old_generation_size_ is a multiple of kPageSize. | 156 // Ensure old_generation_size_ is a multiple of kPageSize. |
| 155 DCHECK(MB >= Page::kPageSize); | 157 DCHECK(MB >= Page::kPageSize); |
| 156 | 158 |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 #undef UPDATE_FRAGMENTATION_FOR_SPACE | 732 #undef UPDATE_FRAGMENTATION_FOR_SPACE |
| 731 #undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE | 733 #undef UPDATE_COUNTERS_AND_FRAGMENTATION_FOR_SPACE |
| 732 | 734 |
| 733 #ifdef DEBUG | 735 #ifdef DEBUG |
| 734 ReportStatisticsAfterGC(); | 736 ReportStatisticsAfterGC(); |
| 735 #endif // DEBUG | 737 #endif // DEBUG |
| 736 | 738 |
| 737 // Remember the last top pointer so that we can later find out | 739 // Remember the last top pointer so that we can later find out |
| 738 // whether we allocated in new space since the last GC. | 740 // whether we allocated in new space since the last GC. |
| 739 new_space_top_after_last_gc_ = new_space()->top(); | 741 new_space_top_after_last_gc_ = new_space()->top(); |
| 742 | |
| 743 if (migration_failure_) { | |
| 744 set_previous_migration_failure(true); | |
| 745 } else { | |
| 746 set_previous_migration_failure(false); | |
| 747 } | |
| 748 set_migration_failure(false); | |
| 740 } | 749 } |
| 741 | 750 |
| 742 | 751 |
| 743 void Heap::HandleGCRequest() { | 752 void Heap::HandleGCRequest() { |
| 744 if (incremental_marking()->request_type() == | 753 if (incremental_marking()->request_type() == |
| 745 IncrementalMarking::COMPLETE_MARKING) { | 754 IncrementalMarking::COMPLETE_MARKING) { |
| 746 CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt"); | 755 CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt"); |
| 747 return; | 756 return; |
| 748 } | 757 } |
| 749 DCHECK(FLAG_overapproximate_weak_closure); | 758 DCHECK(FLAG_overapproximate_weak_closure); |
| (...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1731 Object** start = &external_string_table_.old_space_strings_[0]; | 1740 Object** start = &external_string_table_.old_space_strings_[0]; |
| 1732 Object** end = start + external_string_table_.old_space_strings_.length(); | 1741 Object** end = start + external_string_table_.old_space_strings_.length(); |
| 1733 for (Object** p = start; p < end; ++p) *p = updater_func(this, p); | 1742 for (Object** p = start; p < end; ++p) *p = updater_func(this, p); |
| 1734 } | 1743 } |
| 1735 | 1744 |
| 1736 UpdateNewSpaceReferencesInExternalStringTable(updater_func); | 1745 UpdateNewSpaceReferencesInExternalStringTable(updater_func); |
| 1737 } | 1746 } |
| 1738 | 1747 |
| 1739 | 1748 |
| 1740 void Heap::ProcessAllWeakReferences(WeakObjectRetainer* retainer) { | 1749 void Heap::ProcessAllWeakReferences(WeakObjectRetainer* retainer) { |
| 1741 ProcessArrayBuffers(retainer); | 1750 ProcessArrayBuffers(retainer, false); |
| 1751 ProcessNewArrayBufferViews(retainer); | |
| 1742 ProcessNativeContexts(retainer); | 1752 ProcessNativeContexts(retainer); |
| 1743 ProcessAllocationSites(retainer); | 1753 ProcessAllocationSites(retainer); |
| 1744 } | 1754 } |
| 1745 | 1755 |
| 1746 | 1756 |
| 1747 void Heap::ProcessYoungWeakReferences(WeakObjectRetainer* retainer) { | 1757 void Heap::ProcessYoungWeakReferences(WeakObjectRetainer* retainer) { |
| 1748 ProcessArrayBuffers(retainer); | 1758 ProcessArrayBuffers(retainer, true); |
| 1759 ProcessNewArrayBufferViews(retainer); | |
| 1749 ProcessNativeContexts(retainer); | 1760 ProcessNativeContexts(retainer); |
| 1750 } | 1761 } |
| 1751 | 1762 |
| 1752 | 1763 |
| 1753 void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { | 1764 void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { |
| 1754 Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer); | 1765 Object* head = |
| 1766 VisitWeakList<Context>(this, native_contexts_list(), retainer, false); | |
| 1755 // Update the head of the list of contexts. | 1767 // Update the head of the list of contexts. |
| 1756 set_native_contexts_list(head); | 1768 set_native_contexts_list(head); |
| 1757 } | 1769 } |
| 1758 | 1770 |
| 1759 | 1771 |
| 1760 void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer) { | 1772 void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer, |
| 1761 Object* array_buffer_obj = | 1773 bool stop_after_young) { |
| 1762 VisitWeakList<JSArrayBuffer>(this, array_buffers_list(), retainer); | 1774 Object* array_buffer_obj = VisitWeakList<JSArrayBuffer>( |
| 1775 this, array_buffers_list(), retainer, stop_after_young); | |
| 1763 set_array_buffers_list(array_buffer_obj); | 1776 set_array_buffers_list(array_buffer_obj); |
| 1777 | |
| 1778 #ifdef DEBUG | |
| 1779 // Verify invariant that young array buffers come before old array buffers | |
| 1780 // in array buffers list if there was no promotion failure. | |
| 1781 Object* undefined = undefined_value(); | |
| 1782 Object* next = array_buffers_list(); | |
| 1783 bool old_objects_recorded = false; | |
| 1784 if (migration_failure()) return; | |
| 1785 while (next != undefined) { | |
| 1786 if (!old_objects_recorded) { | |
| 1787 old_objects_recorded = !InNewSpace(next); | |
| 1788 } | |
| 1789 DCHECK((InNewSpace(next) && !old_objects_recorded) || !InNewSpace(next)); | |
| 1790 next = JSArrayBuffer::cast(next)->weak_next(); | |
| 1791 } | |
| 1792 #endif | |
| 1764 } | 1793 } |
| 1765 | 1794 |
| 1766 | 1795 |
| 1796 void Heap::ProcessNewArrayBufferViews(WeakObjectRetainer* retainer) { | |
| 1797 // Retain the list of new space views. | |
| 1798 Object* typed_array_obj = VisitWeakList<JSArrayBufferView>( | |
| 1799 this, new_array_buffer_views_list_, retainer, false); | |
| 1800 set_new_array_buffer_views_list(typed_array_obj); | |
| 1801 | |
| 1802 // Some objects in the list may be in old space now. Find them | |
| 1803 // and move them to the corresponding array buffer. | |
| 1804 Object* view = VisitNewArrayBufferViewsWeakList( | |
| 1805 this, new_array_buffer_views_list_, retainer); | |
| 1806 set_new_array_buffer_views_list(view); | |
| 1807 } | |
| 1808 | |
| 1809 | |
| 1767 void Heap::TearDownArrayBuffers() { | 1810 void Heap::TearDownArrayBuffers() { |
| 1768 Object* undefined = undefined_value(); | 1811 Object* undefined = undefined_value(); |
| 1769 for (Object* o = array_buffers_list(); o != undefined;) { | 1812 for (Object* o = array_buffers_list(); o != undefined;) { |
| 1770 JSArrayBuffer* buffer = JSArrayBuffer::cast(o); | 1813 JSArrayBuffer* buffer = JSArrayBuffer::cast(o); |
| 1771 Runtime::FreeArrayBuffer(isolate(), buffer); | 1814 Runtime::FreeArrayBuffer(isolate(), buffer); |
| 1772 o = buffer->weak_next(); | 1815 o = buffer->weak_next(); |
| 1773 } | 1816 } |
| 1774 set_array_buffers_list(undefined); | 1817 set_array_buffers_list(undefined); |
| 1775 } | 1818 } |
| 1776 | 1819 |
| 1777 | 1820 |
| 1778 void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) { | 1821 void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) { |
| 1779 Object* allocation_site_obj = | 1822 Object* allocation_site_obj = VisitWeakList<AllocationSite>( |
| 1780 VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer); | 1823 this, allocation_sites_list(), retainer, false); |
| 1781 set_allocation_sites_list(allocation_site_obj); | 1824 set_allocation_sites_list(allocation_site_obj); |
| 1782 } | 1825 } |
| 1783 | 1826 |
| 1784 | 1827 |
| 1785 void Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) { | 1828 void Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) { |
| 1786 DisallowHeapAllocation no_allocation_scope; | 1829 DisallowHeapAllocation no_allocation_scope; |
| 1787 Object* cur = allocation_sites_list(); | 1830 Object* cur = allocation_sites_list(); |
| 1788 bool marked = false; | 1831 bool marked = false; |
| 1789 while (cur->IsAllocationSite()) { | 1832 while (cur->IsAllocationSite()) { |
| 1790 AllocationSite* casted = AllocationSite::cast(cur); | 1833 AllocationSite* casted = AllocationSite::cast(cur); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2182 SLOW_DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); | 2225 SLOW_DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
| 2183 SLOW_DCHECK(object->Size() == object_size); | 2226 SLOW_DCHECK(object->Size() == object_size); |
| 2184 Heap* heap = map->GetHeap(); | 2227 Heap* heap = map->GetHeap(); |
| 2185 | 2228 |
| 2186 if (!heap->ShouldBePromoted(object->address(), object_size)) { | 2229 if (!heap->ShouldBePromoted(object->address(), object_size)) { |
| 2187 // A semi-space copy may fail due to fragmentation. In that case, we | 2230 // A semi-space copy may fail due to fragmentation. In that case, we |
| 2188 // try to promote the object. | 2231 // try to promote the object. |
| 2189 if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { | 2232 if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) { |
| 2190 return; | 2233 return; |
| 2191 } | 2234 } |
| 2235 heap->set_migration_failure(false); | |
|
ulan
2015/03/10 14:56:14
Where is migration_failure set to true?
Hannes Payer (out of office)
2015/03/10 15:12:24
here. that was a manual merge conflict error.
| |
| 2192 } | 2236 } |
| 2193 | 2237 |
| 2194 if (PromoteObject<object_contents, alignment>(map, slot, object, | 2238 if (PromoteObject<object_contents, alignment>(map, slot, object, |
| 2195 object_size)) { | 2239 object_size)) { |
| 2196 return; | 2240 return; |
| 2197 } | 2241 } |
| 2198 V8::FatalProcessOutOfMemory("Scavenge promotion failed"); | 2242 V8::FatalProcessOutOfMemory("Scavenge promotion failed"); |
| 2199 } | 2243 } |
| 2200 | 2244 |
| 2201 | 2245 |
| (...skipping 3333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5535 // Create initial maps. | 5579 // Create initial maps. |
| 5536 if (!CreateInitialMaps()) return false; | 5580 if (!CreateInitialMaps()) return false; |
| 5537 CreateApiObjects(); | 5581 CreateApiObjects(); |
| 5538 | 5582 |
| 5539 // Create initial objects | 5583 // Create initial objects |
| 5540 CreateInitialObjects(); | 5584 CreateInitialObjects(); |
| 5541 CHECK_EQ(0u, gc_count_); | 5585 CHECK_EQ(0u, gc_count_); |
| 5542 | 5586 |
| 5543 set_native_contexts_list(undefined_value()); | 5587 set_native_contexts_list(undefined_value()); |
| 5544 set_array_buffers_list(undefined_value()); | 5588 set_array_buffers_list(undefined_value()); |
| 5589 set_new_array_buffer_views_list(undefined_value()); | |
| 5545 set_allocation_sites_list(undefined_value()); | 5590 set_allocation_sites_list(undefined_value()); |
| 5546 return true; | 5591 return true; |
| 5547 } | 5592 } |
| 5548 | 5593 |
| 5549 | 5594 |
| 5550 void Heap::SetStackLimits() { | 5595 void Heap::SetStackLimits() { |
| 5551 DCHECK(isolate_ != NULL); | 5596 DCHECK(isolate_ != NULL); |
| 5552 DCHECK(isolate_ == isolate()); | 5597 DCHECK(isolate_ == isolate()); |
| 5553 // On 64 bit machines, pointers are generally out of range of Smis. We write | 5598 // On 64 bit machines, pointers are generally out of range of Smis. We write |
| 5554 // something that looks like an out of range Smi to the GC. | 5599 // something that looks like an out of range Smi to the GC. |
| (...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6535 static_cast<int>(object_sizes_last_time_[index])); | 6580 static_cast<int>(object_sizes_last_time_[index])); |
| 6536 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 6581 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 6537 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 6582 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 6538 | 6583 |
| 6539 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 6584 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 6540 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 6585 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 6541 ClearObjectStats(); | 6586 ClearObjectStats(); |
| 6542 } | 6587 } |
| 6543 } | 6588 } |
| 6544 } // namespace v8::internal | 6589 } // namespace v8::internal |
| OLD | NEW |