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