| 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(true); | 
| 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 | 
|---|