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 #ifndef V8_HEAP_HEAP_H_ | 5 #ifndef V8_HEAP_HEAP_H_ |
6 #define V8_HEAP_HEAP_H_ | 6 #define V8_HEAP_HEAP_H_ |
7 | 7 |
8 #include <cmath> | 8 #include <cmath> |
9 #include <map> | 9 #include <map> |
10 | 10 |
11 #include "src/allocation.h" | 11 #include "src/allocation.h" |
12 #include "src/assert-scope.h" | 12 #include "src/assert-scope.h" |
| 13 #include "src/base/flags.h" |
13 #include "src/globals.h" | 14 #include "src/globals.h" |
14 #include "src/heap/gc-idle-time-handler.h" | 15 #include "src/heap/gc-idle-time-handler.h" |
15 #include "src/heap/incremental-marking.h" | 16 #include "src/heap/incremental-marking.h" |
16 #include "src/heap/mark-compact.h" | 17 #include "src/heap/mark-compact.h" |
17 #include "src/heap/objects-visiting.h" | 18 #include "src/heap/objects-visiting.h" |
18 #include "src/heap/spaces.h" | 19 #include "src/heap/spaces.h" |
19 #include "src/heap/store-buffer.h" | 20 #include "src/heap/store-buffer.h" |
20 #include "src/list.h" | 21 #include "src/list.h" |
21 | 22 |
22 namespace v8 { | 23 namespace v8 { |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 kStringTableRootIndex, | 570 kStringTableRootIndex, |
570 | 571 |
571 #define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex, | 572 #define ROOT_INDEX_DECLARATION(type, name, camel_name) k##camel_name##RootIndex, |
572 SMI_ROOT_LIST(ROOT_INDEX_DECLARATION) | 573 SMI_ROOT_LIST(ROOT_INDEX_DECLARATION) |
573 #undef ROOT_INDEX_DECLARATION | 574 #undef ROOT_INDEX_DECLARATION |
574 kRootListLength, | 575 kRootListLength, |
575 kStrongRootListLength = kStringTableRootIndex, | 576 kStrongRootListLength = kStringTableRootIndex, |
576 kSmiRootsStart = kStringTableRootIndex + 1 | 577 kSmiRootsStart = kStringTableRootIndex + 1 |
577 }; | 578 }; |
578 | 579 |
| 580 // Flags to indicate modes for a GC run. |
| 581 enum GCFlag { |
| 582 kNoGCFlags = 0u, |
| 583 kReduceMemoryFootprintMask = 1u << 0, |
| 584 kAbortIncrementalMarkingMask = 1u << 1, |
| 585 kFinalizeIncrementalMarkingMask = 1u << 2, |
| 586 |
| 587 // Making the heap iterable requires us to abort incremental marking. |
| 588 kMakeHeapIterableMask = kAbortIncrementalMarkingMask, |
| 589 }; |
| 590 typedef base::Flags<GCFlag> GCFlags; |
| 591 |
| 592 // A GC invocation always respects the passed flags. Upon finished the current |
| 593 // cycle the previously set flags are either restored (kDontOverride), or |
| 594 // overriden with the flags indicating no special behavior (kOverride). |
| 595 enum GCFlagOverride { |
| 596 kOverride, |
| 597 kDontOverride, |
| 598 }; |
| 599 |
579 // Indicates whether live bytes adjustment is triggered | 600 // Indicates whether live bytes adjustment is triggered |
580 // - from within the GC code before sweeping started (SEQUENTIAL_TO_SWEEPER), | 601 // - from within the GC code before sweeping started (SEQUENTIAL_TO_SWEEPER), |
581 // - or from within GC (CONCURRENT_TO_SWEEPER), | 602 // - or from within GC (CONCURRENT_TO_SWEEPER), |
582 // - or mutator code (CONCURRENT_TO_SWEEPER). | 603 // - or mutator code (CONCURRENT_TO_SWEEPER). |
583 enum InvocationMode { SEQUENTIAL_TO_SWEEPER, CONCURRENT_TO_SWEEPER }; | 604 enum InvocationMode { SEQUENTIAL_TO_SWEEPER, CONCURRENT_TO_SWEEPER }; |
584 | 605 |
585 enum ScratchpadSlotMode { IGNORE_SCRATCHPAD_SLOT, RECORD_SCRATCHPAD_SLOT }; | 606 enum ScratchpadSlotMode { IGNORE_SCRATCHPAD_SLOT, RECORD_SCRATCHPAD_SLOT }; |
586 | 607 |
587 enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT }; | 608 enum HeapState { NOT_IN_GC, SCAVENGE, MARK_COMPACT }; |
588 | 609 |
589 // ObjectStats are kept in two arrays, counts and sizes. Related stats are | 610 // ObjectStats are kept in two arrays, counts and sizes. Related stats are |
590 // stored in a contiguous linear buffer. Stats groups are stored one after | 611 // stored in a contiguous linear buffer. Stats groups are stored one after |
591 // another. | 612 // another. |
592 enum { | 613 enum { |
593 FIRST_CODE_KIND_SUB_TYPE = LAST_TYPE + 1, | 614 FIRST_CODE_KIND_SUB_TYPE = LAST_TYPE + 1, |
594 FIRST_FIXED_ARRAY_SUB_TYPE = | 615 FIRST_FIXED_ARRAY_SUB_TYPE = |
595 FIRST_CODE_KIND_SUB_TYPE + Code::NUMBER_OF_KINDS, | 616 FIRST_CODE_KIND_SUB_TYPE + Code::NUMBER_OF_KINDS, |
596 FIRST_CODE_AGE_SUB_TYPE = | 617 FIRST_CODE_AGE_SUB_TYPE = |
597 FIRST_FIXED_ARRAY_SUB_TYPE + LAST_FIXED_ARRAY_SUB_TYPE + 1, | 618 FIRST_FIXED_ARRAY_SUB_TYPE + LAST_FIXED_ARRAY_SUB_TYPE + 1, |
598 OBJECT_STATS_COUNT = FIRST_CODE_AGE_SUB_TYPE + Code::kCodeAgeCount + 1 | 619 OBJECT_STATS_COUNT = FIRST_CODE_AGE_SUB_TYPE + Code::kCodeAgeCount + 1 |
599 }; | 620 }; |
600 | 621 |
| 622 class GCFlagScope { |
| 623 public: |
| 624 GCFlagScope(Heap* heap, GCFlags gc_flags, GCCallbackFlags callback_flags, |
| 625 GCFlagOverride override) |
| 626 : heap_(heap), override_(override) { |
| 627 if (override_ == kDontOverride) { |
| 628 saved_gc_flags_ = heap->current_gc_flags_; |
| 629 saved_gc_callback_flags_ = heap->current_gc_callback_flags_; |
| 630 } |
| 631 heap->set_current_gc_flags(gc_flags); |
| 632 heap->current_gc_callback_flags_ = callback_flags; |
| 633 } |
| 634 |
| 635 ~GCFlagScope() { |
| 636 if (override_ == kDontOverride) { |
| 637 heap_->set_current_gc_flags(saved_gc_flags_); |
| 638 heap_->current_gc_callback_flags_ = saved_gc_callback_flags_; |
| 639 } else { |
| 640 heap_->set_current_gc_flags(kNoGCFlags); |
| 641 heap_->current_gc_callback_flags_ = kNoGCCallbackFlags; |
| 642 } |
| 643 } |
| 644 |
| 645 private: |
| 646 Heap* heap_; |
| 647 GCFlagOverride override_; |
| 648 GCFlags saved_gc_flags_; |
| 649 GCCallbackFlags saved_gc_callback_flags_; |
| 650 }; |
| 651 |
601 // Taking this lock prevents the GC from entering a phase that relocates | 652 // Taking this lock prevents the GC from entering a phase that relocates |
602 // object references. | 653 // object references. |
603 class RelocationLock { | 654 class RelocationLock { |
604 public: | 655 public: |
605 explicit RelocationLock(Heap* heap) : heap_(heap) { | 656 explicit RelocationLock(Heap* heap) : heap_(heap) { |
606 heap_->relocation_mutex_.Lock(); | 657 heap_->relocation_mutex_.Lock(); |
607 } | 658 } |
608 | 659 |
609 ~RelocationLock() { heap_->relocation_mutex_.Unlock(); } | 660 ~RelocationLock() { heap_->relocation_mutex_.Unlock(); } |
610 | 661 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 // Strict mode arguments has no callee so it is smaller. | 744 // Strict mode arguments has no callee so it is smaller. |
694 static const int kStrictArgumentsObjectSize = | 745 static const int kStrictArgumentsObjectSize = |
695 JSObject::kHeaderSize + 1 * kPointerSize; | 746 JSObject::kHeaderSize + 1 * kPointerSize; |
696 | 747 |
697 // Indicies for direct access into argument objects. | 748 // Indicies for direct access into argument objects. |
698 static const int kArgumentsLengthIndex = 0; | 749 static const int kArgumentsLengthIndex = 0; |
699 | 750 |
700 // callee is only valid in sloppy mode. | 751 // callee is only valid in sloppy mode. |
701 static const int kArgumentsCalleeIndex = 1; | 752 static const int kArgumentsCalleeIndex = 1; |
702 | 753 |
703 static const int kNoGCFlags = 0; | |
704 static const int kReduceMemoryFootprintMask = 1; | |
705 static const int kAbortIncrementalMarkingMask = 2; | |
706 static const int kFinalizeIncrementalMarkingMask = 4; | |
707 | |
708 // Making the heap iterable requires us to abort incremental marking. | |
709 static const int kMakeHeapIterableMask = kAbortIncrementalMarkingMask; | |
710 | |
711 // The roots that have an index less than this are always in old space. | 754 // The roots that have an index less than this are always in old space. |
712 static const int kOldSpaceRoots = 0x20; | 755 static const int kOldSpaceRoots = 0x20; |
713 | 756 |
714 STATIC_ASSERT(kUndefinedValueRootIndex == | 757 STATIC_ASSERT(kUndefinedValueRootIndex == |
715 Internals::kUndefinedValueRootIndex); | 758 Internals::kUndefinedValueRootIndex); |
716 STATIC_ASSERT(kNullValueRootIndex == Internals::kNullValueRootIndex); | 759 STATIC_ASSERT(kNullValueRootIndex == Internals::kNullValueRootIndex); |
717 STATIC_ASSERT(kTrueValueRootIndex == Internals::kTrueValueRootIndex); | 760 STATIC_ASSERT(kTrueValueRootIndex == Internals::kTrueValueRootIndex); |
718 STATIC_ASSERT(kFalseValueRootIndex == Internals::kFalseValueRootIndex); | 761 STATIC_ASSERT(kFalseValueRootIndex == Internals::kFalseValueRootIndex); |
719 STATIC_ASSERT(kempty_stringRootIndex == Internals::kEmptyStringRootIndex); | 762 STATIC_ASSERT(kempty_stringRootIndex == Internals::kEmptyStringRootIndex); |
720 | 763 |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1260 bool inline_allocation_disabled() { return inline_allocation_disabled_; } | 1303 bool inline_allocation_disabled() { return inline_allocation_disabled_; } |
1261 | 1304 |
1262 // Switch whether inline bump-pointer allocation should be used. | 1305 // Switch whether inline bump-pointer allocation should be used. |
1263 void EnableInlineAllocation(); | 1306 void EnableInlineAllocation(); |
1264 void DisableInlineAllocation(); | 1307 void DisableInlineAllocation(); |
1265 | 1308 |
1266 // =========================================================================== | 1309 // =========================================================================== |
1267 // Methods triggering GCs. =================================================== | 1310 // Methods triggering GCs. =================================================== |
1268 // =========================================================================== | 1311 // =========================================================================== |
1269 | 1312 |
1270 // Performs garbage collection operation. | 1313 // Perform a garbage collection operation in a given space. |
1271 // Returns whether there is a chance that another major GC could | 1314 // Returns whether there is a chance that another major GC could |
1272 // collect more garbage. | 1315 // collect more garbage. |
1273 inline bool CollectGarbage( | 1316 inline bool CollectGarbage( |
1274 AllocationSpace space, const char* gc_reason = NULL, | 1317 AllocationSpace space, const char* gc_reason = nullptr, |
1275 const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); | 1318 const GCFlags flags = kNoGCFlags, |
| 1319 const GCCallbackFlags callback_flags = kNoGCCallbackFlags, |
| 1320 const GCFlagOverride override = kOverride); |
1276 | 1321 |
1277 // Performs a full garbage collection. If (flags & kMakeHeapIterableMask) is | 1322 inline bool CollectGarbageNewSpace(const char* gc_reason = nullptr); |
1278 // non-zero, then the slower precise sweeper is used, which leaves the heap | 1323 |
1279 // in a state where we can iterate over the heap visiting all objects. | 1324 // Performs a full garbage collection. |
1280 void CollectAllGarbage( | 1325 void CollectAllGarbage( |
1281 int flags = kFinalizeIncrementalMarkingMask, const char* gc_reason = NULL, | 1326 const char* gc_reason = nullptr, |
| 1327 const GCFlags flags = Heap::kFinalizeIncrementalMarkingMask, |
1282 const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); | 1328 const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); |
1283 | 1329 |
1284 // Last hope GC, should try to squeeze as much as possible. | 1330 // Last hope GC, should try to squeeze as much as possible. |
1285 void CollectAllAvailableGarbage(const char* gc_reason = NULL); | 1331 void CollectAllAvailableGarbage(const char* gc_reason = nullptr); |
1286 | 1332 |
1287 // Invoked when GC was requested via the stack guard. | 1333 // Invoked when GC was requested via the stack guard. |
1288 void HandleGCRequest(); | 1334 void HandleGCRequest(); |
1289 | 1335 |
1290 // =========================================================================== | 1336 // =========================================================================== |
1291 // Iterators. ================================================================ | 1337 // Iterators. ================================================================ |
1292 // =========================================================================== | 1338 // =========================================================================== |
1293 | 1339 |
1294 // Iterates over all roots in the heap. | 1340 // Iterates over all roots in the heap. |
1295 void IterateRoots(ObjectVisitor* v, VisitMode mode); | 1341 void IterateRoots(ObjectVisitor* v, VisitMode mode); |
(...skipping 28 matching lines...) Expand all Loading... |
1324 // =========================================================================== | 1370 // =========================================================================== |
1325 // Incremental marking API. ================================================== | 1371 // Incremental marking API. ================================================== |
1326 // =========================================================================== | 1372 // =========================================================================== |
1327 | 1373 |
1328 // Start incremental marking and ensure that idle time handler can perform | 1374 // Start incremental marking and ensure that idle time handler can perform |
1329 // incremental steps. | 1375 // incremental steps. |
1330 void StartIdleIncrementalMarking(); | 1376 void StartIdleIncrementalMarking(); |
1331 | 1377 |
1332 // Starts incremental marking assuming incremental marking is currently | 1378 // Starts incremental marking assuming incremental marking is currently |
1333 // stopped. | 1379 // stopped. |
1334 void StartIncrementalMarking(int gc_flags = kNoGCFlags, | 1380 void StartIncrementalMarking(const GCFlags = kNoGCFlags, |
1335 const GCCallbackFlags gc_callback_flags = | 1381 const GCCallbackFlags gc_callback_flags = |
1336 GCCallbackFlags::kNoGCCallbackFlags, | 1382 GCCallbackFlags::kNoGCCallbackFlags, |
1337 const char* reason = nullptr); | 1383 const char* reason = nullptr); |
1338 | 1384 |
1339 // Performs incremental marking steps of step_size_in_bytes as long as | 1385 // Performs incremental marking steps of step_size_in_bytes as long as |
1340 // deadline_ins_ms is not reached. step_size_in_bytes can be 0 to compute | 1386 // deadline_ins_ms is not reached. step_size_in_bytes can be 0 to compute |
1341 // an estimate increment. Returns the remaining time that cannot be used | 1387 // an estimate increment. Returns the remaining time that cannot be used |
1342 // for incremental marking anymore because a single step would exceed the | 1388 // for incremental marking anymore because a single step would exceed the |
1343 // deadline. | 1389 // deadline. |
1344 double AdvanceIncrementalMarking( | 1390 double AdvanceIncrementalMarking( |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1688 return (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE; | 1734 return (pretenure == TENURED) ? OLD_SPACE : NEW_SPACE; |
1689 } | 1735 } |
1690 | 1736 |
1691 #define ROOT_ACCESSOR(type, name, camel_name) \ | 1737 #define ROOT_ACCESSOR(type, name, camel_name) \ |
1692 inline void set_##name(type* value); | 1738 inline void set_##name(type* value); |
1693 ROOT_LIST(ROOT_ACCESSOR) | 1739 ROOT_LIST(ROOT_ACCESSOR) |
1694 #undef ROOT_ACCESSOR | 1740 #undef ROOT_ACCESSOR |
1695 | 1741 |
1696 StoreBuffer* store_buffer() { return &store_buffer_; } | 1742 StoreBuffer* store_buffer() { return &store_buffer_; } |
1697 | 1743 |
1698 void set_current_gc_flags(int flags) { | 1744 void set_current_gc_flags(GCFlags flags) { |
1699 current_gc_flags_ = flags; | 1745 current_gc_flags_ = flags; |
1700 DCHECK(!ShouldFinalizeIncrementalMarking() || | 1746 DCHECK(!ShouldFinalizeIncrementalMarking() || |
1701 !ShouldAbortIncrementalMarking()); | 1747 !ShouldAbortIncrementalMarking()); |
1702 } | 1748 } |
1703 | 1749 |
1704 inline bool ShouldReduceMemory() const { | 1750 inline bool ShouldReduceMemory() const { |
1705 return current_gc_flags_ & kReduceMemoryFootprintMask; | 1751 return current_gc_flags_ & kReduceMemoryFootprintMask; |
1706 } | 1752 } |
1707 | 1753 |
1708 inline bool ShouldAbortIncrementalMarking() const { | 1754 inline bool ShouldAbortIncrementalMarking() const { |
(...skipping 21 matching lines...) Expand all Loading... |
1730 // with the allocation memento of the object at the top | 1776 // with the allocation memento of the object at the top |
1731 void EnsureFillerObjectAtTop(); | 1777 void EnsureFillerObjectAtTop(); |
1732 | 1778 |
1733 // Ensure that we have swept all spaces in such a way that we can iterate | 1779 // Ensure that we have swept all spaces in such a way that we can iterate |
1734 // over all objects. May cause a GC. | 1780 // over all objects. May cause a GC. |
1735 void MakeHeapIterable(); | 1781 void MakeHeapIterable(); |
1736 | 1782 |
1737 // Performs garbage collection operation. | 1783 // Performs garbage collection operation. |
1738 // Returns whether there is a chance that another major GC could | 1784 // Returns whether there is a chance that another major GC could |
1739 // collect more garbage. | 1785 // collect more garbage. |
1740 bool CollectGarbage( | 1786 bool CollectGarbage(GarbageCollector collector, const char* gc_reason, |
1741 GarbageCollector collector, const char* gc_reason, | 1787 const char* collector_reason); |
1742 const char* collector_reason, | |
1743 const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); | |
1744 | 1788 |
1745 // Performs garbage collection | 1789 // Performs garbage collection |
1746 // Returns whether there is a chance another major GC could | 1790 // Returns whether there is a chance another major GC could |
1747 // collect more garbage. | 1791 // collect more garbage. |
1748 bool PerformGarbageCollection( | 1792 bool PerformGarbageCollection(GarbageCollector collector); |
1749 GarbageCollector collector, | |
1750 const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags); | |
1751 | 1793 |
1752 inline void UpdateOldSpaceLimits(); | 1794 inline void UpdateOldSpaceLimits(); |
1753 | 1795 |
1754 // Initializes a JSObject based on its map. | 1796 // Initializes a JSObject based on its map. |
1755 void InitializeJSObjectFromMap(JSObject* obj, FixedArray* properties, | 1797 void InitializeJSObjectFromMap(JSObject* obj, FixedArray* properties, |
1756 Map* map); | 1798 Map* map); |
1757 void InitializeAllocationMemento(AllocationMemento* memento, | 1799 void InitializeAllocationMemento(AllocationMemento* memento, |
1758 AllocationSite* allocation_site); | 1800 AllocationSite* allocation_site); |
1759 | 1801 |
1760 bool CreateInitialMaps(); | 1802 bool CreateInitialMaps(); |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2361 size_t ring_buffer_end_; | 2403 size_t ring_buffer_end_; |
2362 | 2404 |
2363 // Shared state read by the scavenge collector and set by ScavengeObject. | 2405 // Shared state read by the scavenge collector and set by ScavengeObject. |
2364 PromotionQueue promotion_queue_; | 2406 PromotionQueue promotion_queue_; |
2365 | 2407 |
2366 // Flag is set when the heap has been configured. The heap can be repeatedly | 2408 // Flag is set when the heap has been configured. The heap can be repeatedly |
2367 // configured through the API until it is set up. | 2409 // configured through the API until it is set up. |
2368 bool configured_; | 2410 bool configured_; |
2369 | 2411 |
2370 // Currently set GC flags that are respected by all GC components. | 2412 // Currently set GC flags that are respected by all GC components. |
2371 int current_gc_flags_; | 2413 GCFlags current_gc_flags_; |
2372 | 2414 |
2373 // Currently set GC callback flags that are used to pass information between | 2415 // Currently set GC callback flags that are used to pass information between |
2374 // the embedder and V8's GC. | 2416 // the embedder and V8's GC. |
2375 GCCallbackFlags current_gc_callback_flags_; | 2417 GCCallbackFlags current_gc_callback_flags_; |
2376 | 2418 |
2377 ExternalStringTable external_string_table_; | 2419 ExternalStringTable external_string_table_; |
2378 | 2420 |
2379 VisitorDispatchTable<ScavengingCallback> scavenging_visitors_table_; | 2421 VisitorDispatchTable<ScavengingCallback> scavenging_visitors_table_; |
2380 | 2422 |
2381 MemoryChunk* chunks_queued_for_free_; | 2423 MemoryChunk* chunks_queued_for_free_; |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2794 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. | 2836 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. |
2795 | 2837 |
2796 private: | 2838 private: |
2797 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); | 2839 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); |
2798 }; | 2840 }; |
2799 #endif // DEBUG | 2841 #endif // DEBUG |
2800 } | 2842 } |
2801 } // namespace v8::internal | 2843 } // namespace v8::internal |
2802 | 2844 |
2803 #endif // V8_HEAP_HEAP_H_ | 2845 #endif // V8_HEAP_HEAP_H_ |
OLD | NEW |