V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
heap.h
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
3 // found in the LICENSE file.
4 
5 #ifndef V8_HEAP_HEAP_H_
6 #define V8_HEAP_HEAP_H_
7 
8 #include <cmath>
9 #include <map>
10 #include <unordered_map>
11 #include <unordered_set>
12 #include <vector>
13 
14 // Clients of this interface shouldn't depend on lots of heap internals.
15 // Do not include anything from src/heap here!
16 #include "include/v8-internal.h"
17 #include "include/v8.h"
18 #include "src/accessors.h"
19 #include "src/allocation.h"
20 #include "src/assert-scope.h"
21 #include "src/base/atomic-utils.h"
22 #include "src/globals.h"
23 #include "src/heap-symbols.h"
24 #include "src/objects.h"
25 #include "src/objects/fixed-array.h"
26 #include "src/objects/heap-object.h"
27 #include "src/objects/smi.h"
28 #include "src/objects/string-table.h"
29 #include "src/visitors.h"
30 
31 namespace v8 {
32 
33 namespace debug {
34 typedef void (*OutOfMemoryCallback)(void* data);
35 } // namespace debug
36 
37 namespace internal {
38 
39 namespace heap {
40 class HeapTester;
41 class TestMemoryAllocatorScope;
42 } // namespace heap
43 
44 class AllocationMemento;
45 class ObjectBoilerplateDescription;
46 class BytecodeArray;
47 class CodeDataContainer;
48 class DeoptimizationData;
49 class HandlerTable;
50 class IncrementalMarking;
51 class JSArrayBuffer;
52 class ExternalString;
53 using v8::MemoryPressureLevel;
54 
55 class AllocationObserver;
56 class ArrayBufferCollector;
57 class ArrayBufferTracker;
58 class CodeLargeObjectSpace;
59 class ConcurrentMarking;
60 class GCIdleTimeAction;
61 class GCIdleTimeHandler;
62 class GCIdleTimeHeapState;
63 class GCTracer;
64 class HeapController;
65 class HeapObjectAllocationTracker;
66 class HeapObjectPtr;
67 class HeapObjectsFilter;
68 class HeapStats;
69 class HistogramTimer;
70 class Isolate;
71 class JSWeakFactory;
72 class LocalEmbedderHeapTracer;
73 class MemoryAllocator;
74 class MemoryReducer;
75 class MinorMarkCompactCollector;
76 class ObjectIterator;
77 class ObjectStats;
78 class Page;
79 class PagedSpace;
80 class RootVisitor;
81 class ScavengeJob;
82 class Scavenger;
83 class ScavengerCollector;
84 class Space;
85 class StoreBuffer;
86 class StressScavengeObserver;
87 class TimedHistogram;
88 class TracePossibleWrapperReporter;
89 class WeakObjectRetainer;
90 
91 enum ArrayStorageAllocationMode {
92  DONT_INITIALIZE_ARRAY_ELEMENTS,
93  INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE
94 };
95 
96 enum class ClearRecordedSlots { kYes, kNo };
97 
98 enum class ClearFreedMemoryMode { kClearFreedMemory, kDontClearFreedMemory };
99 
100 enum ExternalBackingStoreType { kArrayBuffer, kExternalString, kNumTypes };
101 
102 enum class FixedArrayVisitationMode { kRegular, kIncremental };
103 
104 enum class TraceRetainingPathMode { kEnabled, kDisabled };
105 
106 enum class RetainingPathOption { kDefault, kTrackEphemeronPath };
107 
108 enum class GarbageCollectionReason {
109  kUnknown = 0,
110  kAllocationFailure = 1,
111  kAllocationLimit = 2,
112  kContextDisposal = 3,
113  kCountersExtension = 4,
114  kDebugger = 5,
115  kDeserializer = 6,
116  kExternalMemoryPressure = 7,
117  kFinalizeMarkingViaStackGuard = 8,
118  kFinalizeMarkingViaTask = 9,
119  kFullHashtable = 10,
120  kHeapProfiler = 11,
121  kIdleTask = 12,
122  kLastResort = 13,
123  kLowMemoryNotification = 14,
124  kMakeHeapIterable = 15,
125  kMemoryPressure = 16,
126  kMemoryReducer = 17,
127  kRuntime = 18,
128  kSamplingProfiler = 19,
129  kSnapshotCreator = 20,
130  kTesting = 21,
131  kExternalFinalize = 22
132  // If you add new items here, then update the incremental_marking_reason,
133  // mark_compact_reason, and scavenge_reason counters in counters.h.
134  // Also update src/tools/metrics/histograms/histograms.xml in chromium.
135 };
136 
137 enum class YoungGenerationHandling {
138  kRegularScavenge = 0,
139  kFastPromotionDuringScavenge = 1,
140  // Histogram::InspectConstructionArguments in chromium requires us to have at
141  // least three buckets.
142  kUnusedBucket = 2,
143  // If you add new items here, then update the young_generation_handling in
144  // counters.h.
145  // Also update src/tools/metrics/histograms/histograms.xml in chromium.
146 };
147 
149  public:
150  static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) {
151  return AllocationResult(space);
152  }
153 
154  // Implicit constructor from Object*.
155  // TODO(3770): This constructor should go away eventually, replaced by
156  // the ObjectPtr alternative below.
157  AllocationResult(Object* object) // NOLINT
158  : object_(ObjectPtr(object->ptr())) {
159  // AllocationResults can't return Smis, which are used to represent
160  // failure and the space to retry in.
161  CHECK(!object->IsSmi());
162  }
163 
164  AllocationResult(ObjectPtr object) // NOLINT
165  : object_(object) {
166  // AllocationResults can't return Smis, which are used to represent
167  // failure and the space to retry in.
168  CHECK(!object->IsSmi());
169  }
170 
171  AllocationResult() : object_(Smi::FromInt(NEW_SPACE)) {}
172 
173  inline bool IsRetry() { return object_->IsSmi(); }
174  inline HeapObject* ToObjectChecked();
175  inline AllocationSpace RetrySpace();
176 
177  template <typename T, typename = typename std::enable_if<
178  std::is_base_of<Object, T>::value>::type>
179  bool To(T** obj) {
180  if (IsRetry()) return false;
181  *obj = T::cast(object_);
182  return true;
183  }
184 
185  template <typename T, typename = typename std::enable_if<
186  std::is_base_of<ObjectPtr, T>::value>::type>
187  bool To(T* obj) {
188  if (IsRetry()) return false;
189  *obj = T::cast(object_);
190  return true;
191  }
192 
193  private:
194  explicit AllocationResult(AllocationSpace space)
195  : object_(Smi::FromInt(static_cast<int>(space))) {}
196 
197  ObjectPtr object_;
198 };
199 
200 STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize);
201 
202 #ifdef DEBUG
203 struct CommentStatistic {
204  const char* comment;
205  int size;
206  int count;
207  void Clear() {
208  comment = nullptr;
209  size = 0;
210  count = 0;
211  }
212  // Must be small, since an iteration is used for lookup.
213  static const int kMaxComments = 64;
214 };
215 #endif
216 
217 class Heap {
218  public:
219  enum FindMementoMode { kForRuntime, kForGC };
220 
221  enum HeapState {
222  NOT_IN_GC,
223  SCAVENGE,
224  MARK_COMPACT,
225  MINOR_MARK_COMPACT,
226  TEAR_DOWN
227  };
228 
229  using PretenuringFeedbackMap = std::unordered_map<AllocationSite*, size_t>;
230 
231  // Taking this mutex prevents the GC from entering a phase that relocates
232  // object references.
233  base::Mutex* relocation_mutex() { return &relocation_mutex_; }
234 
235  // Support for partial snapshots. After calling this we have a linear
236  // space to write objects in each space.
237  struct Chunk {
238  uint32_t size;
239  Address start;
240  Address end;
241  };
242  typedef std::vector<Chunk> Reservation;
243 
244  static const int kInitalOldGenerationLimitFactor = 2;
245 
246 #if V8_OS_ANDROID
247  // Don't apply pointer multiplier on Android since it has no swap space and
248  // should instead adapt it's heap size based on available physical memory.
249  static const int kPointerMultiplier = 1;
250 #else
251  static const int kPointerMultiplier = i::kPointerSize / 4;
252 #endif
253 
254  // Semi-space size needs to be a multiple of page size.
255  static const size_t kMinSemiSpaceSizeInKB =
256  1 * kPointerMultiplier * ((1 << kPageSizeBits) / KB);
257  static const size_t kMaxSemiSpaceSizeInKB =
258  16 * kPointerMultiplier * ((1 << kPageSizeBits) / KB);
259 
260  static const int kTraceRingBufferSize = 512;
261  static const int kStacktraceBufferSize = 512;
262 
263  static const int kNoGCFlags = 0;
264  static const int kReduceMemoryFootprintMask = 1;
265 
266  // The minimum size of a HeapObject on the heap.
267  static const int kMinObjectSizeInTaggedWords = 2;
268 
269  static const int kMinPromotedPercentForFastPromotionMode = 90;
270 
271  STATIC_ASSERT(static_cast<int>(RootIndex::kUndefinedValue) ==
272  Internals::kUndefinedValueRootIndex);
273  STATIC_ASSERT(static_cast<int>(RootIndex::kTheHoleValue) ==
274  Internals::kTheHoleValueRootIndex);
275  STATIC_ASSERT(static_cast<int>(RootIndex::kNullValue) ==
276  Internals::kNullValueRootIndex);
277  STATIC_ASSERT(static_cast<int>(RootIndex::kTrueValue) ==
278  Internals::kTrueValueRootIndex);
279  STATIC_ASSERT(static_cast<int>(RootIndex::kFalseValue) ==
280  Internals::kFalseValueRootIndex);
281  STATIC_ASSERT(static_cast<int>(RootIndex::kempty_string) ==
282  Internals::kEmptyStringRootIndex);
283 
284  // Calculates the maximum amount of filler that could be required by the
285  // given alignment.
286  static int GetMaximumFillToAlign(AllocationAlignment alignment);
287  // Calculates the actual amount of filler required for a given address at the
288  // given alignment.
289  static int GetFillToAlign(Address address, AllocationAlignment alignment);
290 
291  void FatalProcessOutOfMemory(const char* location);
292 
293  // Checks whether the space is valid.
294  static bool IsValidAllocationSpace(AllocationSpace space);
295 
296  // Zapping is needed for verify heap, and always done in debug builds.
297  static inline bool ShouldZapGarbage() {
298 #ifdef DEBUG
299  return true;
300 #else
301 #ifdef VERIFY_HEAP
302  return FLAG_verify_heap;
303 #else
304  return false;
305 #endif
306 #endif
307  }
308 
309  static uintptr_t ZapValue() {
310  return FLAG_clear_free_memory ? kClearedFreeMemoryValue : kZapValue;
311  }
312 
313  static inline bool IsYoungGenerationCollector(GarbageCollector collector) {
314  return collector == SCAVENGER || collector == MINOR_MARK_COMPACTOR;
315  }
316 
317  static inline GarbageCollector YoungGenerationCollector() {
318 #if ENABLE_MINOR_MC
319  return (FLAG_minor_mc) ? MINOR_MARK_COMPACTOR : SCAVENGER;
320 #else
321  return SCAVENGER;
322 #endif // ENABLE_MINOR_MC
323  }
324 
325  static inline const char* CollectorName(GarbageCollector collector) {
326  switch (collector) {
327  case SCAVENGER:
328  return "Scavenger";
329  case MARK_COMPACTOR:
330  return "Mark-Compact";
331  case MINOR_MARK_COMPACTOR:
332  return "Minor Mark-Compact";
333  }
334  return "Unknown collector";
335  }
336 
337  // Copy block of memory from src to dst. Size of block should be aligned
338  // by pointer size.
339  static inline void CopyBlock(Address dst, Address src, int byte_size);
340 
341  V8_EXPORT_PRIVATE static void WriteBarrierForCodeSlow(Code host);
342  V8_EXPORT_PRIVATE static void GenerationalBarrierSlow(HeapObject* object,
343  Address slot,
344  HeapObject* value);
345  V8_EXPORT_PRIVATE static void GenerationalBarrierForElementsSlow(
346  Heap* heap, FixedArray array, int offset, int length);
347  V8_EXPORT_PRIVATE static void GenerationalBarrierForCodeSlow(
348  Code host, RelocInfo* rinfo, HeapObject* value);
349  V8_EXPORT_PRIVATE static void MarkingBarrierSlow(HeapObject* object,
350  Address slot,
351  HeapObject* value);
352  V8_EXPORT_PRIVATE static void MarkingBarrierForElementsSlow(
353  Heap* heap, HeapObject* object);
354  V8_EXPORT_PRIVATE static void MarkingBarrierForCodeSlow(Code host,
355  RelocInfo* rinfo,
356  HeapObject* value);
357  V8_EXPORT_PRIVATE static bool PageFlagsAreConsistent(HeapObject* object);
358 
359  // Notifies the heap that is ok to start marking or other activities that
360  // should not happen during deserialization.
361  void NotifyDeserializationComplete();
362 
363  inline Address* NewSpaceAllocationTopAddress();
364  inline Address* NewSpaceAllocationLimitAddress();
365  inline Address* OldSpaceAllocationTopAddress();
366  inline Address* OldSpaceAllocationLimitAddress();
367 
368  // Move len elements within a given array from src_index index to dst_index
369  // index.
370  void MoveElements(FixedArray array, int dst_index, int src_index, int len,
371  WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
372 
373  // Initialize a filler object to keep the ability to iterate over the heap
374  // when introducing gaps within pages. If slots could have been recorded in
375  // the freed area, then pass ClearRecordedSlots::kYes as the mode. Otherwise,
376  // pass ClearRecordedSlots::kNo. If the memory after the object header of
377  // the filler should be cleared, pass in kClearFreedMemory. The default is
378  // kDontClearFreedMemory.
379  V8_EXPORT_PRIVATE HeapObject* CreateFillerObjectAt(
380  Address addr, int size, ClearRecordedSlots clear_slots_mode,
381  ClearFreedMemoryMode clear_memory_mode =
382  ClearFreedMemoryMode::kDontClearFreedMemory);
383 
384  template <typename T>
385  void CreateFillerForArray(T object, int elements_to_trim, int bytes_to_trim);
386 
387  bool CanMoveObjectStart(HeapObject* object);
388 
389  bool IsImmovable(HeapObject* object);
390 
391  bool IsLargeObject(HeapObject* object);
392  inline bool IsWithinLargeObject(Address address);
393 
394  bool IsInYoungGeneration(HeapObject* object);
395 
396  // Trim the given array from the left. Note that this relocates the object
397  // start and hence is only valid if there is only a single reference to it.
398  FixedArrayBase LeftTrimFixedArray(FixedArrayBase obj, int elements_to_trim);
399 
400  // Trim the given array from the right.
401  void RightTrimFixedArray(FixedArrayBase obj, int elements_to_trim);
402  void RightTrimWeakFixedArray(WeakFixedArray* obj, int elements_to_trim);
403 
404  // Converts the given boolean condition to JavaScript boolean value.
405  inline Oddball* ToBoolean(bool condition);
406 
407  // Notify the heap that a context has been disposed.
408  int NotifyContextDisposed(bool dependant_context);
409 
410  void set_native_contexts_list(Object* object) {
411  native_contexts_list_ = object;
412  }
413  Object* native_contexts_list() const { return native_contexts_list_; }
414 
415  void set_allocation_sites_list(Object* object) {
416  allocation_sites_list_ = object;
417  }
418  Object* allocation_sites_list() { return allocation_sites_list_; }
419 
420  // Used in CreateAllocationSiteStub and the (de)serializer.
421  Address allocation_sites_list_address() {
422  return reinterpret_cast<Address>(&allocation_sites_list_);
423  }
424 
425  // Traverse all the allocaions_sites [nested_site and weak_next] in the list
426  // and foreach call the visitor
427  void ForeachAllocationSite(
428  Object* list, const std::function<void(AllocationSite*)>& visitor);
429 
430  // Number of mark-sweeps.
431  int ms_count() const { return ms_count_; }
432 
433  // Checks whether the given object is allowed to be migrated from it's
434  // current space into the given destination space. Used for debugging.
435  bool AllowedToBeMigrated(HeapObject* object, AllocationSpace dest);
436 
437  void CheckHandleCount();
438 
439  // Number of "runtime allocations" done so far.
440  uint32_t allocations_count() { return allocations_count_; }
441 
442  // Print short heap statistics.
443  void PrintShortHeapStatistics();
444 
445  bool write_protect_code_memory() const { return write_protect_code_memory_; }
446 
447  uintptr_t code_space_memory_modification_scope_depth() {
448  return code_space_memory_modification_scope_depth_;
449  }
450 
451  void increment_code_space_memory_modification_scope_depth() {
452  code_space_memory_modification_scope_depth_++;
453  }
454 
455  void decrement_code_space_memory_modification_scope_depth() {
456  code_space_memory_modification_scope_depth_--;
457  }
458 
459  void UnprotectAndRegisterMemoryChunk(MemoryChunk* chunk);
460  void UnprotectAndRegisterMemoryChunk(HeapObject* object);
461  void UnregisterUnprotectedMemoryChunk(MemoryChunk* chunk);
462  V8_EXPORT_PRIVATE void ProtectUnprotectedMemoryChunks();
463 
464  void EnableUnprotectedMemoryChunksRegistry() {
465  unprotected_memory_chunks_registry_enabled_ = true;
466  }
467 
468  void DisableUnprotectedMemoryChunksRegistry() {
469  unprotected_memory_chunks_registry_enabled_ = false;
470  }
471 
472  bool unprotected_memory_chunks_registry_enabled() {
473  return unprotected_memory_chunks_registry_enabled_;
474  }
475 
476  inline HeapState gc_state() { return gc_state_; }
477  void SetGCState(HeapState state);
478  bool IsTearingDown() const { return gc_state_ == TEAR_DOWN; }
479 
480  inline bool IsInGCPostProcessing() { return gc_post_processing_depth_ > 0; }
481 
482  // If an object has an AllocationMemento trailing it, return it, otherwise
483  // return nullptr;
484  template <FindMementoMode mode>
485  inline AllocationMemento* FindAllocationMemento(Map map, HeapObject* object);
486 
487  // Returns false if not able to reserve.
488  bool ReserveSpace(Reservation* reservations, std::vector<Address>* maps);
489 
490  //
491  // Support for the API.
492  //
493 
494  void CreateApiObjects();
495 
496  // Implements the corresponding V8 API function.
497  bool IdleNotification(double deadline_in_seconds);
498  bool IdleNotification(int idle_time_in_ms);
499 
500  void MemoryPressureNotification(MemoryPressureLevel level,
501  bool is_isolate_locked);
502  void CheckMemoryPressure();
503 
504  void AddNearHeapLimitCallback(v8::NearHeapLimitCallback, void* data);
505  void RemoveNearHeapLimitCallback(v8::NearHeapLimitCallback callback,
506  size_t heap_limit);
507 
508  double MonotonicallyIncreasingTimeInMs();
509 
510  void RecordStats(HeapStats* stats, bool take_snapshot = false);
511 
512  // Check new space expansion criteria and expand semispaces if it was hit.
513  void CheckNewSpaceExpansionCriteria();
514 
515  void VisitExternalResources(v8::ExternalResourceVisitor* visitor);
516 
517  // An object should be promoted if the object has survived a
518  // scavenge operation.
519  inline bool ShouldBePromoted(Address old_address);
520 
521  void IncrementDeferredCount(v8::Isolate::UseCounterFeature feature);
522 
523  inline uint64_t HashSeed();
524 
525  inline int NextScriptId();
526  inline int NextDebuggingId();
527  inline int GetNextTemplateSerialNumber();
528 
529  void SetSerializedObjects(FixedArray objects);
530  void SetSerializedGlobalProxySizes(FixedArray sizes);
531 
532  // For post mortem debugging.
533  void RememberUnmappedPage(Address page, bool compacted);
534 
535  int64_t external_memory_hard_limit() { return MaxOldGenerationSize() / 2; }
536 
537  V8_INLINE int64_t external_memory();
538  V8_INLINE void update_external_memory(int64_t delta);
539  V8_INLINE void update_external_memory_concurrently_freed(intptr_t freed);
540  V8_INLINE void account_external_memory_concurrently_freed();
541 
542  size_t backing_store_bytes() const { return backing_store_bytes_; }
543 
544  void CompactWeakArrayLists(PretenureFlag pretenure);
545 
546  void AddRetainedMap(Handle<Map> map);
547 
548  // This event is triggered after successful allocation of a new object made
549  // by runtime. Allocations of target space for object evacuation do not
550  // trigger the event. In order to track ALL allocations one must turn off
551  // FLAG_inline_new.
552  inline void OnAllocationEvent(HeapObject* object, int size_in_bytes);
553 
554  // This event is triggered after object is moved to a new place.
555  inline void OnMoveEvent(HeapObject* target, HeapObject* source,
556  int size_in_bytes);
557 
558  inline bool CanAllocateInReadOnlySpace();
559  bool deserialization_complete() const { return deserialization_complete_; }
560 
561  bool HasLowAllocationRate();
562  bool HasHighFragmentation();
563  bool HasHighFragmentation(size_t used, size_t committed);
564 
565  void ActivateMemoryReducerIfNeeded();
566 
567  bool ShouldOptimizeForMemoryUsage();
568 
569  bool HighMemoryPressure() {
570  return memory_pressure_level_ != MemoryPressureLevel::kNone;
571  }
572 
573  void RestoreHeapLimit(size_t heap_limit) {
574  // Do not set the limit lower than the live size + some slack.
575  size_t min_limit = SizeOfObjects() + SizeOfObjects() / 4;
576  max_old_generation_size_ =
577  Min(max_old_generation_size_, Max(heap_limit, min_limit));
578  }
579 
580  // ===========================================================================
581  // Initialization. ===========================================================
582  // ===========================================================================
583 
584  // Configure heap sizes
585  // max_semi_space_size_in_kb: maximum semi-space size in KB
586  // max_old_generation_size_in_mb: maximum old generation size in MB
587  // code_range_size_in_mb: code range size in MB
588  void ConfigureHeap(size_t max_semi_space_size_in_kb,
589  size_t max_old_generation_size_in_mb,
590  size_t code_range_size_in_mb);
591  void ConfigureHeapDefault();
592 
593  // Prepares the heap, setting up memory areas that are needed in the isolate
594  // without actually creating any objects.
595  void SetUp();
596 
597  // (Re-)Initialize hash seed from flag or RNG.
598  void InitializeHashSeed();
599 
600  // Bootstraps the object heap with the core set of objects required to run.
601  // Returns whether it succeeded.
602  bool CreateHeapObjects();
603 
604  // Create ObjectStats if live_object_stats_ or dead_object_stats_ are nullptr.
605  void CreateObjectStats();
606 
607  // Sets the TearDown state, so no new GC tasks get posted.
608  void StartTearDown();
609 
610  // Destroys all memory allocated by the heap.
611  void TearDown();
612 
613  // Returns whether SetUp has been called.
614  bool HasBeenSetUp();
615 
616  // ===========================================================================
617  // Getters for spaces. =======================================================
618  // ===========================================================================
619 
620  inline Address NewSpaceTop();
621 
622  NewSpace* new_space() { return new_space_; }
623  OldSpace* old_space() { return old_space_; }
624  CodeSpace* code_space() { return code_space_; }
625  MapSpace* map_space() { return map_space_; }
626  LargeObjectSpace* lo_space() { return lo_space_; }
627  CodeLargeObjectSpace* code_lo_space() { return code_lo_space_; }
628  NewLargeObjectSpace* new_lo_space() { return new_lo_space_; }
629  ReadOnlySpace* read_only_space() { return read_only_space_; }
630 
631  inline PagedSpace* paged_space(int idx);
632  inline Space* space(int idx);
633 
634  // Returns name of the space.
635  const char* GetSpaceName(int idx);
636 
637  // ===========================================================================
638  // Getters to other components. ==============================================
639  // ===========================================================================
640 
641  GCTracer* tracer() { return tracer_; }
642 
643  MemoryAllocator* memory_allocator() { return memory_allocator_; }
644 
645  inline Isolate* isolate();
646 
647  MarkCompactCollector* mark_compact_collector() {
648  return mark_compact_collector_;
649  }
650 
651  MinorMarkCompactCollector* minor_mark_compact_collector() {
652  return minor_mark_compact_collector_;
653  }
654 
655  ArrayBufferCollector* array_buffer_collector() {
656  return array_buffer_collector_;
657  }
658 
659  // ===========================================================================
660  // Root set access. ==========================================================
661  // ===========================================================================
662 
663  // Shortcut to the roots table stored in the Isolate.
664  V8_INLINE RootsTable& roots_table();
665 
666 // Heap root getters.
667 #define ROOT_ACCESSOR(type, name, CamelName) inline type name();
668  MUTABLE_ROOT_LIST(ROOT_ACCESSOR)
669 #undef ROOT_ACCESSOR
670 
671  // Sets the stub_cache_ (only used when expanding the dictionary).
672  V8_INLINE void SetRootCodeStubs(SimpleNumberDictionary value);
673  V8_INLINE void SetRootMaterializedObjects(FixedArray objects);
674  V8_INLINE void SetRootScriptList(Object* value);
675  V8_INLINE void SetRootStringTable(StringTable value);
676  V8_INLINE void SetRootNoScriptSharedFunctionInfos(Object* value);
677  V8_INLINE void SetMessageListeners(TemplateList value);
678 
679  // Set the stack limit in the roots table. Some architectures generate
680  // code that looks here, because it is faster than loading from the static
681  // jslimit_/real_jslimit_ variable in the StackGuard.
682  void SetStackLimits();
683 
684  // The stack limit is thread-dependent. To be able to reproduce the same
685  // snapshot blob, we need to reset it before serializing.
686  void ClearStackLimits();
687 
688  void RegisterStrongRoots(ObjectSlot start, ObjectSlot end);
689  void UnregisterStrongRoots(ObjectSlot start);
690 
691  void SetBuiltinsConstantsTable(FixedArray cache);
692 
693  // A full copy of the interpreter entry trampoline, used as a template to
694  // create copies of the builtin at runtime. The copies are used to create
695  // better profiling information for ticks in bytecode execution. Note that
696  // this is always a copy of the full builtin, i.e. not the off-heap
697  // trampoline.
698  // See also: FLAG_interpreted_frames_native_stack.
699  void SetInterpreterEntryTrampolineForProfiling(Code code);
700 
701  // Add weak_factory into the dirty_js_weak_factories list.
702  void AddDirtyJSWeakFactory(
703  JSWeakFactory* weak_factory,
704  std::function<void(HeapObject* object, ObjectSlot slot, Object* target)>
705  gc_notify_updated_slot);
706 
707  void AddKeepDuringJobTarget(Handle<JSReceiver> target);
708  void ClearKeepDuringJobSet();
709 
710  // ===========================================================================
711  // Inline allocation. ========================================================
712  // ===========================================================================
713 
714  // Indicates whether inline bump-pointer allocation has been disabled.
715  bool inline_allocation_disabled() { return inline_allocation_disabled_; }
716 
717  // Switch whether inline bump-pointer allocation should be used.
718  void EnableInlineAllocation();
719  void DisableInlineAllocation();
720 
721  // ===========================================================================
722  // Methods triggering GCs. ===================================================
723  // ===========================================================================
724 
725  // Performs garbage collection operation.
726  // Returns whether there is a chance that another major GC could
727  // collect more garbage.
728  V8_EXPORT_PRIVATE bool CollectGarbage(
729  AllocationSpace space, GarbageCollectionReason gc_reason,
730  const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags);
731 
732  // Performs a full garbage collection.
733  V8_EXPORT_PRIVATE void CollectAllGarbage(
734  int flags, GarbageCollectionReason gc_reason,
735  const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags);
736 
737  // Last hope GC, should try to squeeze as much as possible.
738  void CollectAllAvailableGarbage(GarbageCollectionReason gc_reason);
739 
740  // Precise garbage collection that potentially finalizes already running
741  // incremental marking before performing an atomic garbage collection.
742  // Only use if absolutely necessary or in tests to avoid floating garbage!
743  void PreciseCollectAllGarbage(
744  int flags, GarbageCollectionReason gc_reason,
745  const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags);
746 
747  // Reports and external memory pressure event, either performs a major GC or
748  // completes incremental marking in order to free external resources.
749  void ReportExternalMemoryPressure();
750 
751  typedef v8::Isolate::GetExternallyAllocatedMemoryInBytesCallback
752  GetExternallyAllocatedMemoryInBytesCallback;
753 
754  void SetGetExternallyAllocatedMemoryInBytesCallback(
755  GetExternallyAllocatedMemoryInBytesCallback callback) {
756  external_memory_callback_ = callback;
757  }
758 
759  // Invoked when GC was requested via the stack guard.
760  void HandleGCRequest();
761 
762  // ===========================================================================
763  // Builtins. =================================================================
764  // ===========================================================================
765 
766  Code builtin(int index);
767  Address builtin_address(int index);
768  void set_builtin(int index, Code builtin);
769 
770  // ===========================================================================
771  // Iterators. ================================================================
772  // ===========================================================================
773 
774  // None of these methods iterate over the read-only roots. To do this use
775  // ReadOnlyRoots::Iterate. Read-only root iteration is not necessary for
776  // garbage collection and is usually only performed as part of
777  // (de)serialization or heap verification.
778 
779  // Iterates over the strong roots and the weak roots.
780  void IterateRoots(RootVisitor* v, VisitMode mode);
781  // Iterates over the strong roots.
782  void IterateStrongRoots(RootVisitor* v, VisitMode mode);
783  // Iterates over entries in the smi roots list. Only interesting to the
784  // serializer/deserializer, since GC does not care about smis.
785  void IterateSmiRoots(RootVisitor* v);
786  // Iterates over weak string tables.
787  void IterateWeakRoots(RootVisitor* v, VisitMode mode);
788  // Iterates over weak global handles.
789  void IterateWeakGlobalHandles(RootVisitor* v);
790  // Iterates over builtins.
791  void IterateBuiltins(RootVisitor* v);
792 
793  // ===========================================================================
794  // Store buffer API. =========================================================
795  // ===========================================================================
796 
797  // Used for query incremental marking status in generated code.
798  Address* IsMarkingFlagAddress() {
799  return reinterpret_cast<Address*>(&is_marking_flag_);
800  }
801 
802  void SetIsMarkingFlag(uint8_t flag) { is_marking_flag_ = flag; }
803 
804  Address* store_buffer_top_address();
805  static intptr_t store_buffer_mask_constant();
806  static Address store_buffer_overflow_function_address();
807 
808  void ClearRecordedSlot(HeapObject* object, ObjectSlot slot);
809  void ClearRecordedSlotRange(Address start, Address end);
810 
811 #ifdef DEBUG
812  void VerifyClearedSlot(HeapObject* object, ObjectSlot slot);
813 #endif
814 
815  // ===========================================================================
816  // Incremental marking API. ==================================================
817  // ===========================================================================
818 
819  int GCFlagsForIncrementalMarking() {
820  return ShouldOptimizeForMemoryUsage() ? kReduceMemoryFootprintMask
821  : kNoGCFlags;
822  }
823 
824  // Start incremental marking and ensure that idle time handler can perform
825  // incremental steps.
826  void StartIdleIncrementalMarking(
827  GarbageCollectionReason gc_reason,
828  GCCallbackFlags gc_callback_flags = GCCallbackFlags::kNoGCCallbackFlags);
829 
830  // Starts incremental marking assuming incremental marking is currently
831  // stopped.
832  void StartIncrementalMarking(
833  int gc_flags, GarbageCollectionReason gc_reason,
834  GCCallbackFlags gc_callback_flags = GCCallbackFlags::kNoGCCallbackFlags);
835 
836  void StartIncrementalMarkingIfAllocationLimitIsReached(
837  int gc_flags,
838  GCCallbackFlags gc_callback_flags = GCCallbackFlags::kNoGCCallbackFlags);
839 
840  void FinalizeIncrementalMarkingIfComplete(GarbageCollectionReason gc_reason);
841  // Synchronously finalizes incremental marking.
842  void FinalizeIncrementalMarkingAtomically(GarbageCollectionReason gc_reason);
843 
844  void RegisterDeserializedObjectsForBlackAllocation(
845  Reservation* reservations, const std::vector<HeapObject*>& large_objects,
846  const std::vector<Address>& maps);
847 
848  IncrementalMarking* incremental_marking() { return incremental_marking_; }
849 
850  // ===========================================================================
851  // Concurrent marking API. ===================================================
852  // ===========================================================================
853 
854  ConcurrentMarking* concurrent_marking() { return concurrent_marking_; }
855 
856  // The runtime uses this function to notify potentially unsafe object layout
857  // changes that require special synchronization with the concurrent marker.
858  // The old size is the size of the object before layout change.
859  void NotifyObjectLayoutChange(HeapObject* object, int old_size,
860  const DisallowHeapAllocation&);
861 
862 #ifdef VERIFY_HEAP
863  // This function checks that either
864  // - the map transition is safe,
865  // - or it was communicated to GC using NotifyObjectLayoutChange.
866  void VerifyObjectLayoutChange(HeapObject* object, Map new_map);
867 #endif
868 
869  // ===========================================================================
870  // Deoptimization support API. ===============================================
871  // ===========================================================================
872 
873  // Setters for code offsets of well-known deoptimization targets.
874  void SetArgumentsAdaptorDeoptPCOffset(int pc_offset);
875  void SetConstructStubCreateDeoptPCOffset(int pc_offset);
876  void SetConstructStubInvokeDeoptPCOffset(int pc_offset);
877  void SetInterpreterEntryReturnPCOffset(int pc_offset);
878 
879  // Invalidates references in the given {code} object that are referenced
880  // transitively from the deoptimization data. Mutates write-protected code.
881  void InvalidateCodeDeoptimizationData(Code code);
882 
883  void DeoptMarkedAllocationSites();
884 
885  bool DeoptMaybeTenuredAllocationSites();
886 
887  // ===========================================================================
888  // Embedder heap tracer support. =============================================
889  // ===========================================================================
890 
891  LocalEmbedderHeapTracer* local_embedder_heap_tracer() const {
892  return local_embedder_heap_tracer_;
893  }
894 
895  void SetEmbedderHeapTracer(EmbedderHeapTracer* tracer);
896  EmbedderHeapTracer* GetEmbedderHeapTracer() const;
897 
898  void RegisterExternallyReferencedObject(Address* location);
899  void SetEmbedderStackStateForNextFinalizaton(
900  EmbedderHeapTracer::EmbedderStackState stack_state);
901 
902  // ===========================================================================
903  // External string table API. ================================================
904  // ===========================================================================
905 
906  // Registers an external string.
907  inline void RegisterExternalString(String string);
908 
909  // Called when a string's resource is changed. The size of the payload is sent
910  // as argument of the method.
911  inline void UpdateExternalString(String string, size_t old_payload,
912  size_t new_payload);
913 
914  // Finalizes an external string by deleting the associated external
915  // data and clearing the resource pointer.
916  inline void FinalizeExternalString(String string);
917 
918  static String UpdateNewSpaceReferenceInExternalStringTableEntry(
919  Heap* heap, ObjectSlot pointer);
920 
921  // ===========================================================================
922  // Methods checking/returning the space of a given object/address. ===========
923  // ===========================================================================
924 
925  // Returns whether the object resides in new space.
926  static inline bool InNewSpace(Object* object);
927  static inline bool InNewSpace(MaybeObject object);
928  static inline bool InNewSpace(HeapObject* heap_object);
929  static inline bool InNewSpace(HeapObjectPtr heap_object);
930  static inline bool InFromSpace(Object* object);
931  static inline bool InFromSpace(MaybeObject object);
932  static inline bool InFromSpace(HeapObject* heap_object);
933  static inline bool InToSpace(Object* object);
934  static inline bool InToSpace(MaybeObject object);
935  static inline bool InToSpace(HeapObject* heap_object);
936  static inline bool InToSpace(HeapObjectPtr heap_object);
937 
938  // Returns whether the object resides in old space.
939  inline bool InOldSpace(Object* object);
940 
941  // Returns whether the object resides in read-only space.
942  inline bool InReadOnlySpace(Object* object);
943 
944  // Checks whether an address/object in the heap (including auxiliary
945  // area and unused area).
946  bool Contains(HeapObject* value);
947 
948  // Checks whether an address/object in a space.
949  // Currently used by tests, serialization and heap verification only.
950  bool InSpace(HeapObject* value, AllocationSpace space);
951 
952  // Slow methods that can be used for verification as they can also be used
953  // with off-heap Addresses.
954  bool InSpaceSlow(Address addr, AllocationSpace space);
955 
956  // Find the heap which owns this HeapObject. Should never be called for
957  // objects in RO space.
958  static inline Heap* FromWritableHeapObject(const HeapObject* obj);
959  // This takes a HeapObjectPtr* (as opposed to a plain HeapObjectPtr)
960  // to keep the WRITE_BARRIER macro syntax-compatible to the HeapObject*
961  // version above.
962  // TODO(3770): This should probably take a HeapObjectPtr eventually.
963  static inline Heap* FromWritableHeapObject(const HeapObjectPtr* obj);
964 
965  // ===========================================================================
966  // Object statistics tracking. ===============================================
967  // ===========================================================================
968 
969  // Returns the number of buckets used by object statistics tracking during a
970  // major GC. Note that the following methods fail gracefully when the bounds
971  // are exceeded though.
972  size_t NumberOfTrackedHeapObjectTypes();
973 
974  // Returns object statistics about count and size at the last major GC.
975  // Objects are being grouped into buckets that roughly resemble existing
976  // instance types.
977  size_t ObjectCountAtLastGC(size_t index);
978  size_t ObjectSizeAtLastGC(size_t index);
979 
980  // Retrieves names of buckets used by object statistics tracking.
981  bool GetObjectTypeName(size_t index, const char** object_type,
982  const char** object_sub_type);
983 
984  // The total number of native contexts object on the heap.
985  size_t NumberOfNativeContexts();
986  // The total number of native contexts that were detached but were not
987  // garbage collected yet.
988  size_t NumberOfDetachedContexts();
989 
990  // ===========================================================================
991  // Code statistics. ==========================================================
992  // ===========================================================================
993 
994  // Collect code (Code and BytecodeArray objects) statistics.
995  void CollectCodeStatistics();
996 
997  // ===========================================================================
998  // GC statistics. ============================================================
999  // ===========================================================================
1000 
1001  // Returns the maximum amount of memory reserved for the heap.
1002  size_t MaxReserved();
1003  size_t MaxSemiSpaceSize() { return max_semi_space_size_; }
1004  size_t InitialSemiSpaceSize() { return initial_semispace_size_; }
1005  size_t MaxOldGenerationSize() { return max_old_generation_size_; }
1006 
1007  V8_EXPORT_PRIVATE static size_t ComputeMaxOldGenerationSize(
1008  uint64_t physical_memory);
1009 
1010  static size_t ComputeMaxSemiSpaceSize(uint64_t physical_memory) {
1011  const uint64_t min_physical_memory = 512 * MB;
1012  const uint64_t max_physical_memory = 3 * static_cast<uint64_t>(GB);
1013 
1014  uint64_t capped_physical_memory =
1015  Max(Min(physical_memory, max_physical_memory), min_physical_memory);
1016  // linearly scale max semi-space size: (X-A)/(B-A)*(D-C)+C
1017  size_t semi_space_size_in_kb =
1018  static_cast<size_t>(((capped_physical_memory - min_physical_memory) *
1019  (kMaxSemiSpaceSizeInKB - kMinSemiSpaceSizeInKB)) /
1020  (max_physical_memory - min_physical_memory) +
1021  kMinSemiSpaceSizeInKB);
1022  return RoundUp(semi_space_size_in_kb, (1 << kPageSizeBits) / KB);
1023  }
1024 
1025  // Returns the capacity of the heap in bytes w/o growing. Heap grows when
1026  // more spaces are needed until it reaches the limit.
1027  size_t Capacity();
1028 
1029  // Returns the capacity of the old generation.
1030  size_t OldGenerationCapacity();
1031 
1032  // Returns the amount of memory currently held alive by the unmapper.
1033  size_t CommittedMemoryOfUnmapper();
1034 
1035  // Returns the amount of memory currently committed for the heap.
1036  size_t CommittedMemory();
1037 
1038  // Returns the amount of memory currently committed for the old space.
1039  size_t CommittedOldGenerationMemory();
1040 
1041  // Returns the amount of executable memory currently committed for the heap.
1042  size_t CommittedMemoryExecutable();
1043 
1044  // Returns the amount of phyical memory currently committed for the heap.
1045  size_t CommittedPhysicalMemory();
1046 
1047  // Returns the maximum amount of memory ever committed for the heap.
1048  size_t MaximumCommittedMemory() { return maximum_committed_; }
1049 
1050  // Updates the maximum committed memory for the heap. Should be called
1051  // whenever a space grows.
1052  void UpdateMaximumCommitted();
1053 
1054  // Returns the available bytes in space w/o growing.
1055  // Heap doesn't guarantee that it can allocate an object that requires
1056  // all available bytes. Check MaxHeapObjectSize() instead.
1057  size_t Available();
1058 
1059  // Returns of size of all objects residing in the heap.
1060  size_t SizeOfObjects();
1061 
1062  void UpdateSurvivalStatistics(int start_new_space_size);
1063 
1064  inline void IncrementPromotedObjectsSize(size_t object_size) {
1065  promoted_objects_size_ += object_size;
1066  }
1067  inline size_t promoted_objects_size() { return promoted_objects_size_; }
1068 
1069  inline void IncrementSemiSpaceCopiedObjectSize(size_t object_size) {
1070  semi_space_copied_object_size_ += object_size;
1071  }
1072  inline size_t semi_space_copied_object_size() {
1073  return semi_space_copied_object_size_;
1074  }
1075 
1076  inline size_t SurvivedNewSpaceObjectSize() {
1077  return promoted_objects_size_ + semi_space_copied_object_size_;
1078  }
1079 
1080  inline void IncrementNodesDiedInNewSpace() { nodes_died_in_new_space_++; }
1081 
1082  inline void IncrementNodesCopiedInNewSpace() { nodes_copied_in_new_space_++; }
1083 
1084  inline void IncrementNodesPromoted() { nodes_promoted_++; }
1085 
1086  inline void IncrementYoungSurvivorsCounter(size_t survived) {
1087  survived_last_scavenge_ = survived;
1088  survived_since_last_expansion_ += survived;
1089  }
1090 
1091  inline uint64_t OldGenerationObjectsAndPromotedExternalMemorySize() {
1092  return OldGenerationSizeOfObjects() + PromotedExternalMemorySize();
1093  }
1094 
1095  inline void UpdateNewSpaceAllocationCounter();
1096 
1097  inline size_t NewSpaceAllocationCounter();
1098 
1099  // This should be used only for testing.
1100  void set_new_space_allocation_counter(size_t new_value) {
1101  new_space_allocation_counter_ = new_value;
1102  }
1103 
1104  void UpdateOldGenerationAllocationCounter() {
1105  old_generation_allocation_counter_at_last_gc_ =
1106  OldGenerationAllocationCounter();
1107  old_generation_size_at_last_gc_ = 0;
1108  }
1109 
1110  size_t OldGenerationAllocationCounter() {
1111  return old_generation_allocation_counter_at_last_gc_ +
1112  PromotedSinceLastGC();
1113  }
1114 
1115  // This should be used only for testing.
1116  void set_old_generation_allocation_counter_at_last_gc(size_t new_value) {
1117  old_generation_allocation_counter_at_last_gc_ = new_value;
1118  }
1119 
1120  size_t PromotedSinceLastGC() {
1121  size_t old_generation_size = OldGenerationSizeOfObjects();
1122  DCHECK_GE(old_generation_size, old_generation_size_at_last_gc_);
1123  return old_generation_size - old_generation_size_at_last_gc_;
1124  }
1125 
1126  // This is called by the sweeper when it discovers more free space
1127  // than expected at the end of the preceding GC.
1128  void NotifyRefinedOldGenerationSize(size_t decreased_bytes) {
1129  if (old_generation_size_at_last_gc_ != 0) {
1130  // OldGenerationSizeOfObjects() is now smaller by |decreased_bytes|.
1131  // Adjust old_generation_size_at_last_gc_ too, so that PromotedSinceLastGC
1132  // continues to increase monotonically, rather than decreasing here.
1133  DCHECK_GE(old_generation_size_at_last_gc_, decreased_bytes);
1134  old_generation_size_at_last_gc_ -= decreased_bytes;
1135  }
1136  }
1137 
1138  int gc_count() const { return gc_count_; }
1139 
1140  // Returns the size of objects residing in non-new spaces.
1141  // Excludes external memory held by those objects.
1142  size_t OldGenerationSizeOfObjects();
1143 
1144  // ===========================================================================
1145  // Prologue/epilogue callback methods.========================================
1146  // ===========================================================================
1147 
1148  void AddGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
1149  GCType gc_type_filter, void* data);
1150  void RemoveGCPrologueCallback(v8::Isolate::GCCallbackWithData callback,
1151  void* data);
1152 
1153  void AddGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
1154  GCType gc_type_filter, void* data);
1155  void RemoveGCEpilogueCallback(v8::Isolate::GCCallbackWithData callback,
1156  void* data);
1157 
1158  void CallGCPrologueCallbacks(GCType gc_type, GCCallbackFlags flags);
1159  void CallGCEpilogueCallbacks(GCType gc_type, GCCallbackFlags flags);
1160 
1161  // ===========================================================================
1162  // Allocation methods. =======================================================
1163  // ===========================================================================
1164 
1165  // Creates a filler object and returns a heap object immediately after it.
1166  V8_WARN_UNUSED_RESULT HeapObject* PrecedeWithFiller(HeapObject* object,
1167  int filler_size);
1168 
1169  // Creates a filler object if needed for alignment and returns a heap object
1170  // immediately after it. If any space is left after the returned object,
1171  // another filler object is created so the over allocated memory is iterable.
1172  V8_WARN_UNUSED_RESULT HeapObject* AlignWithFiller(
1173  HeapObject* object, int object_size, int allocation_size,
1174  AllocationAlignment alignment);
1175 
1176  // ===========================================================================
1177  // ArrayBuffer tracking. =====================================================
1178  // ===========================================================================
1179 
1180  // TODO(gc): API usability: encapsulate mutation of JSArrayBuffer::is_external
1181  // in the registration/unregistration APIs. Consider dropping the "New" from
1182  // "RegisterNewArrayBuffer" because one can re-register a previously
1183  // unregistered buffer, too, and the name is confusing.
1184  void RegisterNewArrayBuffer(JSArrayBuffer* buffer);
1185  void UnregisterArrayBuffer(JSArrayBuffer* buffer);
1186 
1187  // ===========================================================================
1188  // Allocation site tracking. =================================================
1189  // ===========================================================================
1190 
1191  // Updates the AllocationSite of a given {object}. The entry (including the
1192  // count) is cached on the local pretenuring feedback.
1193  inline void UpdateAllocationSite(
1194  Map map, HeapObject* object,
1195  PretenuringFeedbackMap* pretenuring_feedback);
1196 
1197  // Merges local pretenuring feedback into the global one. Note that this
1198  // method needs to be called after evacuation, as allocation sites may be
1199  // evacuated and this method resolves forward pointers accordingly.
1200  void MergeAllocationSitePretenuringFeedback(
1201  const PretenuringFeedbackMap& local_pretenuring_feedback);
1202 
1203  // ===========================================================================
1204  // Allocation tracking. ======================================================
1205  // ===========================================================================
1206 
1207  // Adds {new_space_observer} to new space and {observer} to any other space.
1208  void AddAllocationObserversToAllSpaces(
1209  AllocationObserver* observer, AllocationObserver* new_space_observer);
1210 
1211  // Removes {new_space_observer} from new space and {observer} from any other
1212  // space.
1213  void RemoveAllocationObserversFromAllSpaces(
1214  AllocationObserver* observer, AllocationObserver* new_space_observer);
1215 
1216  bool allocation_step_in_progress() { return allocation_step_in_progress_; }
1217  void set_allocation_step_in_progress(bool val) {
1218  allocation_step_in_progress_ = val;
1219  }
1220 
1221  // ===========================================================================
1222  // Heap object allocation tracking. ==========================================
1223  // ===========================================================================
1224 
1225  void AddHeapObjectAllocationTracker(HeapObjectAllocationTracker* tracker);
1226  void RemoveHeapObjectAllocationTracker(HeapObjectAllocationTracker* tracker);
1227  bool has_heap_object_allocation_tracker() const {
1228  return !allocation_trackers_.empty();
1229  }
1230 
1231  // ===========================================================================
1232  // Retaining path tracking. ==================================================
1233  // ===========================================================================
1234 
1235  // Adds the given object to the weak table of retaining path targets.
1236  // On each GC if the marker discovers the object, it will print the retaining
1237  // path. This requires --track-retaining-path flag.
1238  void AddRetainingPathTarget(Handle<HeapObject> object,
1239  RetainingPathOption option);
1240 
1241  // ===========================================================================
1242  // Stack frame support. ======================================================
1243  // ===========================================================================
1244 
1245  // Returns the Code object for a given interior pointer.
1246  Code GcSafeFindCodeForInnerPointer(Address inner_pointer);
1247 
1248  // Returns true if {addr} is contained within {code} and false otherwise.
1249  // Mostly useful for debugging.
1250  bool GcSafeCodeContains(Code code, Address addr);
1251 
1252 // =============================================================================
1253 #ifdef VERIFY_HEAP
1254  // Verify the heap is in its normal state before or after a GC.
1255  void Verify();
1256  void VerifyRememberedSetFor(HeapObject* object);
1257 #endif
1258 
1259 #ifdef V8_ENABLE_ALLOCATION_TIMEOUT
1260  void set_allocation_timeout(int timeout) { allocation_timeout_ = timeout; }
1261 #endif
1262 
1263 #ifdef DEBUG
1264  void VerifyCountersAfterSweeping();
1265  void VerifyCountersBeforeConcurrentSweeping();
1266 
1267  void Print();
1268  void PrintHandles();
1269 
1270  // Report code statistics.
1271  void ReportCodeStatistics(const char* title);
1272 #endif
1273  void* GetRandomMmapAddr() {
1274  void* result = v8::internal::GetRandomMmapAddr();
1275 #if V8_TARGET_ARCH_X64
1276 #if V8_OS_MACOSX
1277  // The Darwin kernel [as of macOS 10.12.5] does not clean up page
1278  // directory entries [PDE] created from mmap or mach_vm_allocate, even
1279  // after the region is destroyed. Using a virtual address space that is
1280  // too large causes a leak of about 1 wired [can never be paged out] page
1281  // per call to mmap(). The page is only reclaimed when the process is
1282  // killed. Confine the hint to a 32-bit section of the virtual address
1283  // space. See crbug.com/700928.
1284  uintptr_t offset =
1285  reinterpret_cast<uintptr_t>(v8::internal::GetRandomMmapAddr()) &
1286  kMmapRegionMask;
1287  result = reinterpret_cast<void*>(mmap_region_base_ + offset);
1288 #endif // V8_OS_MACOSX
1289 #endif // V8_TARGET_ARCH_X64
1290  return result;
1291  }
1292 
1293  static const char* GarbageCollectionReasonToString(
1294  GarbageCollectionReason gc_reason);
1295 
1296  // Calculates the nof entries for the full sized number to string cache.
1297  inline int MaxNumberToStringCacheSize() const;
1298 
1299  private:
1300  class SkipStoreBufferScope;
1301 
1302  typedef String (*ExternalStringTableUpdaterCallback)(Heap* heap,
1303  ObjectSlot pointer);
1304 
1305  // External strings table is a place where all external strings are
1306  // registered. We need to keep track of such strings to properly
1307  // finalize them.
1308  class ExternalStringTable {
1309  public:
1310  explicit ExternalStringTable(Heap* heap) : heap_(heap) {}
1311 
1312  // Registers an external string.
1313  inline void AddString(String string);
1314  bool Contains(String string);
1315 
1316  void IterateAll(RootVisitor* v);
1317  void IterateNewSpaceStrings(RootVisitor* v);
1318  void PromoteAllNewSpaceStrings();
1319 
1320  // Restores internal invariant and gets rid of collected strings. Must be
1321  // called after each Iterate*() that modified the strings.
1322  void CleanUpAll();
1323  void CleanUpNewSpaceStrings();
1324 
1325  // Finalize all registered external strings and clear tables.
1326  void TearDown();
1327 
1328  void UpdateNewSpaceReferences(
1329  Heap::ExternalStringTableUpdaterCallback updater_func);
1330  void UpdateReferences(
1331  Heap::ExternalStringTableUpdaterCallback updater_func);
1332 
1333  private:
1334  void Verify();
1335  void VerifyNewSpace();
1336 
1337  Heap* const heap_;
1338 
1339  // To speed up scavenge collections new space string are kept
1340  // separate from old space strings.
1341  std::vector<Object*> new_space_strings_;
1342  std::vector<Object*> old_space_strings_;
1343 
1344  DISALLOW_COPY_AND_ASSIGN(ExternalStringTable);
1345  };
1346 
1347  struct StrongRootsList;
1348 
1349  struct StringTypeTable {
1350  InstanceType type;
1351  int size;
1352  RootIndex index;
1353  };
1354 
1355  struct ConstantStringTable {
1356  const char* contents;
1357  RootIndex index;
1358  };
1359 
1360  struct StructTable {
1361  InstanceType type;
1362  int size;
1363  RootIndex index;
1364  };
1365 
1366  struct GCCallbackTuple {
1367  GCCallbackTuple(v8::Isolate::GCCallbackWithData callback, GCType gc_type,
1368  void* data)
1369  : callback(callback), gc_type(gc_type), data(data) {}
1370 
1371  bool operator==(const GCCallbackTuple& other) const;
1372  GCCallbackTuple& operator=(const GCCallbackTuple& other);
1373 
1374  v8::Isolate::GCCallbackWithData callback;
1375  GCType gc_type;
1376  void* data;
1377  };
1378 
1379  static const int kInitialStringTableSize = StringTable::kMinCapacity;
1380  static const int kInitialEvalCacheSize = 64;
1381  static const int kInitialNumberStringCacheSize = 256;
1382 
1383  static const int kRememberedUnmappedPages = 128;
1384 
1385  static const StringTypeTable string_type_table[];
1386  static const ConstantStringTable constant_string_table[];
1387  static const StructTable struct_table[];
1388 
1389  static const int kYoungSurvivalRateHighThreshold = 90;
1390  static const int kYoungSurvivalRateAllowedDeviation = 15;
1391  static const int kOldSurvivalRateLowThreshold = 10;
1392 
1393  static const int kMaxMarkCompactsInIdleRound = 7;
1394  static const int kIdleScavengeThreshold = 5;
1395 
1396  static const int kInitialFeedbackCapacity = 256;
1397 
1398  Heap();
1399 
1400  // Selects the proper allocation space based on the pretenuring decision.
1401  static AllocationSpace SelectSpace(PretenureFlag pretenure) {
1402  switch (pretenure) {
1403  case TENURED_READ_ONLY:
1404  return RO_SPACE;
1405  case TENURED:
1406  return OLD_SPACE;
1407  case NOT_TENURED:
1408  return NEW_SPACE;
1409  default:
1410  UNREACHABLE();
1411  }
1412  }
1413 
1414  static size_t DefaultGetExternallyAllocatedMemoryInBytesCallback() {
1415  return 0;
1416  }
1417 
1418 #define ROOT_ACCESSOR(type, name, CamelName) inline void set_##name(type value);
1419  ROOT_LIST(ROOT_ACCESSOR)
1420 #undef ROOT_ACCESSOR
1421 
1422  StoreBuffer* store_buffer() { return store_buffer_; }
1423 
1424  void set_current_gc_flags(int flags) {
1425  current_gc_flags_ = flags;
1426  }
1427 
1428  inline bool ShouldReduceMemory() const {
1429  return (current_gc_flags_ & kReduceMemoryFootprintMask) != 0;
1430  }
1431 
1432  int NumberOfScavengeTasks();
1433 
1434  // Checks whether a global GC is necessary
1435  GarbageCollector SelectGarbageCollector(AllocationSpace space,
1436  const char** reason);
1437 
1438  // Make sure there is a filler value behind the top of the new space
1439  // so that the GC does not confuse some unintialized/stale memory
1440  // with the allocation memento of the object at the top
1441  void EnsureFillerObjectAtTop();
1442 
1443  // Ensure that we have swept all spaces in such a way that we can iterate
1444  // over all objects. May cause a GC.
1445  void MakeHeapIterable();
1446 
1447  // Performs garbage collection
1448  // Returns whether there is a chance another major GC could
1449  // collect more garbage.
1450  bool PerformGarbageCollection(
1451  GarbageCollector collector,
1452  const GCCallbackFlags gc_callback_flags = kNoGCCallbackFlags);
1453 
1454  inline void UpdateOldSpaceLimits();
1455 
1456  bool CreateInitialMaps();
1457  void CreateInternalAccessorInfoObjects();
1458  void CreateInitialObjects();
1459 
1460  // These five Create*EntryStub functions are here and forced to not be inlined
1461  // because of a gcc-4.4 bug that assigns wrong vtable entries.
1462  V8_NOINLINE void CreateJSEntryStub();
1463  V8_NOINLINE void CreateJSConstructEntryStub();
1464  V8_NOINLINE void CreateJSRunMicrotasksEntryStub();
1465 
1466  void CreateFixedStubs();
1467 
1468  // Commits from space if it is uncommitted.
1469  void EnsureFromSpaceIsCommitted();
1470 
1471  // Uncommit unused semi space.
1472  bool UncommitFromSpace();
1473 
1474  // Fill in bogus values in from space
1475  void ZapFromSpace();
1476 
1477  // Zaps the memory of a code object.
1478  void ZapCodeObject(Address start_address, int size_in_bytes);
1479 
1480  // Deopts all code that contains allocation instruction which are tenured or
1481  // not tenured. Moreover it clears the pretenuring allocation site statistics.
1482  void ResetAllAllocationSitesDependentCode(PretenureFlag flag);
1483 
1484  // Evaluates local pretenuring for the old space and calls
1485  // ResetAllTenuredAllocationSitesDependentCode if too many objects died in
1486  // the old space.
1487  void EvaluateOldSpaceLocalPretenuring(uint64_t size_of_objects_before_gc);
1488 
1489  // Record statistics after garbage collection.
1490  void ReportStatisticsAfterGC();
1491 
1492  // Flush the number to string cache.
1493  void FlushNumberStringCache();
1494 
1495  void ConfigureInitialOldGenerationSize();
1496 
1497  bool HasLowYoungGenerationAllocationRate();
1498  bool HasLowOldGenerationAllocationRate();
1499  double YoungGenerationMutatorUtilization();
1500  double OldGenerationMutatorUtilization();
1501 
1502  void ReduceNewSpaceSize();
1503 
1504  GCIdleTimeHeapState ComputeHeapState();
1505 
1506  bool PerformIdleTimeAction(GCIdleTimeAction action,
1507  GCIdleTimeHeapState heap_state,
1508  double deadline_in_ms);
1509 
1510  void IdleNotificationEpilogue(GCIdleTimeAction action,
1511  GCIdleTimeHeapState heap_state, double start_ms,
1512  double deadline_in_ms);
1513 
1514  int NextAllocationTimeout(int current_timeout = 0);
1515  inline void UpdateAllocationsHash(HeapObject* object);
1516  inline void UpdateAllocationsHash(uint32_t value);
1517  void PrintAllocationsHash();
1518 
1519  void PrintMaxMarkingLimitReached();
1520  void PrintMaxNewSpaceSizeReached();
1521 
1522  int NextStressMarkingLimit();
1523 
1524  void AddToRingBuffer(const char* string);
1525  void GetFromRingBuffer(char* buffer);
1526 
1527  void CompactRetainedMaps(WeakArrayList* retained_maps);
1528 
1529  void CollectGarbageOnMemoryPressure();
1530 
1531  void EagerlyFreeExternalMemory();
1532 
1533  bool InvokeNearHeapLimitCallback();
1534 
1535  void ComputeFastPromotionMode();
1536 
1537  // Attempt to over-approximate the weak closure by marking object groups and
1538  // implicit references from global handles, but don't atomically complete
1539  // marking. If we continue to mark incrementally, we might have marked
1540  // objects that die later.
1541  void FinalizeIncrementalMarkingIncrementally(
1542  GarbageCollectionReason gc_reason);
1543 
1544  // Returns the timer used for a given GC type.
1545  // - GCScavenger: young generation GC
1546  // - GCCompactor: full GC
1547  // - GCFinalzeMC: finalization of incremental full GC
1548  // - GCFinalizeMCReduceMemory: finalization of incremental full GC with
1549  // memory reduction
1550  TimedHistogram* GCTypeTimer(GarbageCollector collector);
1551  TimedHistogram* GCTypePriorityTimer(GarbageCollector collector);
1552 
1553  // ===========================================================================
1554  // Pretenuring. ==============================================================
1555  // ===========================================================================
1556 
1557  // Pretenuring decisions are made based on feedback collected during new space
1558  // evacuation. Note that between feedback collection and calling this method
1559  // object in old space must not move.
1560  void ProcessPretenuringFeedback();
1561 
1562  // Removes an entry from the global pretenuring storage.
1563  void RemoveAllocationSitePretenuringFeedback(AllocationSite* site);
1564 
1565  // ===========================================================================
1566  // Actual GC. ================================================================
1567  // ===========================================================================
1568 
1569  // Code that should be run before and after each GC. Includes some
1570  // reporting/verification activities when compiled with DEBUG set.
1571  void GarbageCollectionPrologue();
1572  void GarbageCollectionEpilogue();
1573 
1574  // Performs a major collection in the whole heap.
1575  void MarkCompact();
1576  // Performs a minor collection of just the young generation.
1577  void MinorMarkCompact();
1578 
1579  // Code to be run before and after mark-compact.
1580  void MarkCompactPrologue();
1581  void MarkCompactEpilogue();
1582 
1583  // Performs a minor collection in new generation.
1584  void Scavenge();
1585  void EvacuateYoungGeneration();
1586 
1587  void UpdateNewSpaceReferencesInExternalStringTable(
1588  ExternalStringTableUpdaterCallback updater_func);
1589 
1590  void UpdateReferencesInExternalStringTable(
1591  ExternalStringTableUpdaterCallback updater_func);
1592 
1593  void ProcessAllWeakReferences(WeakObjectRetainer* retainer);
1594  void ProcessYoungWeakReferences(WeakObjectRetainer* retainer);
1595  void ProcessNativeContexts(WeakObjectRetainer* retainer);
1596  void ProcessAllocationSites(WeakObjectRetainer* retainer);
1597  void ProcessWeakListRoots(WeakObjectRetainer* retainer);
1598 
1599  // ===========================================================================
1600  // GC statistics. ============================================================
1601  // ===========================================================================
1602 
1603  inline size_t OldGenerationSpaceAvailable() {
1604  if (old_generation_allocation_limit_ <=
1605  OldGenerationObjectsAndPromotedExternalMemorySize())
1606  return 0;
1607  return old_generation_allocation_limit_ -
1608  static_cast<size_t>(
1609  OldGenerationObjectsAndPromotedExternalMemorySize());
1610  }
1611 
1612  // We allow incremental marking to overshoot the allocation limit for
1613  // performace reasons. If the overshoot is too large then we are more
1614  // eager to finalize incremental marking.
1615  inline bool AllocationLimitOvershotByLargeMargin() {
1616  // This guards against too eager finalization in small heaps.
1617  // The number is chosen based on v8.browsing_mobile on Nexus 7v2.
1618  size_t kMarginForSmallHeaps = 32u * MB;
1619  if (old_generation_allocation_limit_ >=
1620  OldGenerationObjectsAndPromotedExternalMemorySize())
1621  return false;
1622  uint64_t overshoot = OldGenerationObjectsAndPromotedExternalMemorySize() -
1623  old_generation_allocation_limit_;
1624  // Overshoot margin is 50% of allocation limit or half-way to the max heap
1625  // with special handling of small heaps.
1626  uint64_t margin =
1627  Min(Max(old_generation_allocation_limit_ / 2, kMarginForSmallHeaps),
1628  (max_old_generation_size_ - old_generation_allocation_limit_) / 2);
1629  return overshoot >= margin;
1630  }
1631 
1632  void UpdateTotalGCTime(double duration);
1633 
1634  bool MaximumSizeScavenge() { return maximum_size_scavenges_ > 0; }
1635 
1636  bool IsIneffectiveMarkCompact(size_t old_generation_size,
1637  double mutator_utilization);
1638  void CheckIneffectiveMarkCompact(size_t old_generation_size,
1639  double mutator_utilization);
1640 
1641  inline void IncrementExternalBackingStoreBytes(ExternalBackingStoreType type,
1642  size_t amount);
1643 
1644  inline void DecrementExternalBackingStoreBytes(ExternalBackingStoreType type,
1645  size_t amount);
1646 
1647  // ===========================================================================
1648  // Growing strategy. =========================================================
1649  // ===========================================================================
1650 
1651  HeapController* heap_controller() { return heap_controller_; }
1652  MemoryReducer* memory_reducer() { return memory_reducer_; }
1653 
1654  // For some webpages RAIL mode does not switch from PERFORMANCE_LOAD.
1655  // This constant limits the effect of load RAIL mode on GC.
1656  // The value is arbitrary and chosen as the largest load time observed in
1657  // v8 browsing benchmarks.
1658  static const int kMaxLoadTimeMs = 7000;
1659 
1660  bool ShouldOptimizeForLoadTime();
1661 
1662  size_t old_generation_allocation_limit() const {
1663  return old_generation_allocation_limit_;
1664  }
1665 
1666  bool always_allocate() { return always_allocate_scope_count_ != 0; }
1667 
1668  bool CanExpandOldGeneration(size_t size);
1669 
1670  bool ShouldExpandOldGenerationOnSlowAllocation();
1671 
1672  enum class HeapGrowingMode { kSlow, kConservative, kMinimal, kDefault };
1673 
1674  HeapGrowingMode CurrentHeapGrowingMode();
1675 
1676  enum class IncrementalMarkingLimit { kNoLimit, kSoftLimit, kHardLimit };
1677  IncrementalMarkingLimit IncrementalMarkingLimitReached();
1678 
1679  // ===========================================================================
1680  // Idle notification. ========================================================
1681  // ===========================================================================
1682 
1683  bool RecentIdleNotificationHappened();
1684  void ScheduleIdleScavengeIfNeeded(int bytes_allocated);
1685 
1686  // ===========================================================================
1687  // HeapIterator helpers. =====================================================
1688  // ===========================================================================
1689 
1690  void heap_iterator_start() { heap_iterator_depth_++; }
1691 
1692  void heap_iterator_end() { heap_iterator_depth_--; }
1693 
1694  bool in_heap_iterator() { return heap_iterator_depth_ > 0; }
1695 
1696  // ===========================================================================
1697  // Allocation methods. =======================================================
1698  // ===========================================================================
1699 
1700  // Allocates a JS Map in the heap.
1701  V8_WARN_UNUSED_RESULT AllocationResult
1702  AllocateMap(InstanceType instance_type, int instance_size,
1703  ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
1704  int inobject_properties = 0);
1705 
1706  // Allocate an uninitialized object. The memory is non-executable if the
1707  // hardware and OS allow. This is the single choke-point for allocations
1708  // performed by the runtime and should not be bypassed (to extend this to
1709  // inlined allocations, use the Heap::DisableInlineAllocation() support).
1710  V8_WARN_UNUSED_RESULT inline AllocationResult AllocateRaw(
1711  int size_in_bytes, AllocationSpace space,
1712  AllocationAlignment aligment = kWordAligned);
1713 
1714  // This method will try to perform an allocation of a given size in a given
1715  // space. If the allocation fails, a regular full garbage collection is
1716  // triggered and the allocation is retried. This is performed multiple times.
1717  // If after that retry procedure the allocation still fails nullptr is
1718  // returned.
1719  HeapObject* AllocateRawWithLightRetry(
1720  int size, AllocationSpace space,
1721  AllocationAlignment alignment = kWordAligned);
1722 
1723  // This method will try to perform an allocation of a given size in a given
1724  // space. If the allocation fails, a regular full garbage collection is
1725  // triggered and the allocation is retried. This is performed multiple times.
1726  // If after that retry procedure the allocation still fails a "hammer"
1727  // garbage collection is triggered which tries to significantly reduce memory.
1728  // If the allocation still fails after that a fatal error is thrown.
1729  HeapObject* AllocateRawWithRetryOrFail(
1730  int size, AllocationSpace space,
1731  AllocationAlignment alignment = kWordAligned);
1732  HeapObject* AllocateRawCodeInLargeObjectSpace(int size);
1733 
1734  // Allocates a heap object based on the map.
1735  V8_WARN_UNUSED_RESULT AllocationResult Allocate(Map map,
1736  AllocationSpace space);
1737 
1738  // Takes a code object and checks if it is on memory which is not subject to
1739  // compaction. This method will return a new code object on an immovable
1740  // memory location if the original code object was movable.
1741  HeapObject* EnsureImmovableCode(HeapObject* heap_object, int object_size);
1742 
1743  // Allocates a partial map for bootstrapping.
1744  V8_WARN_UNUSED_RESULT AllocationResult
1745  AllocatePartialMap(InstanceType instance_type, int instance_size);
1746 
1747  void FinalizePartialMap(Map map);
1748 
1749  // Allocate empty fixed typed array of given type.
1750  V8_WARN_UNUSED_RESULT AllocationResult
1751  AllocateEmptyFixedTypedArray(ExternalArrayType array_type);
1752 
1753  void set_force_oom(bool value) { force_oom_ = value; }
1754 
1755  // ===========================================================================
1756  // Retaining path tracing ====================================================
1757  // ===========================================================================
1758 
1759  void AddRetainer(HeapObject* retainer, HeapObject* object);
1760  void AddEphemeronRetainer(HeapObject* retainer, HeapObject* object);
1761  void AddRetainingRoot(Root root, HeapObject* object);
1762  // Returns true if the given object is a target of retaining path tracking.
1763  // Stores the option corresponding to the object in the provided *option.
1764  bool IsRetainingPathTarget(HeapObject* object, RetainingPathOption* option);
1765  void PrintRetainingPath(HeapObject* object, RetainingPathOption option);
1766 
1767 #ifdef DEBUG
1768  void IncrementObjectCounters();
1769 #endif // DEBUG
1770 
1771  // The amount of memory that has been freed concurrently.
1772  std::atomic<intptr_t> external_memory_concurrently_freed_{0};
1773 
1774  // This can be calculated directly from a pointer to the heap; however, it is
1775  // more expedient to get at the isolate directly from within Heap methods.
1776  Isolate* isolate_ = nullptr;
1777 
1778  size_t code_range_size_ = 0;
1779  size_t max_semi_space_size_ = 8 * (kPointerSize / 4) * MB;
1780  size_t initial_semispace_size_ = kMinSemiSpaceSizeInKB * KB;
1781  size_t max_old_generation_size_ = 700ul * (kPointerSize / 4) * MB;
1782  size_t initial_max_old_generation_size_;
1783  size_t initial_old_generation_size_;
1784  bool old_generation_size_configured_ = false;
1785  size_t maximum_committed_ = 0;
1786 
1787  // Backing store bytes (array buffers and external strings).
1788  std::atomic<size_t> backing_store_bytes_{0};
1789 
1790  // For keeping track of how much data has survived
1791  // scavenge since last new space expansion.
1792  size_t survived_since_last_expansion_ = 0;
1793 
1794  // ... and since the last scavenge.
1795  size_t survived_last_scavenge_ = 0;
1796 
1797  // This is not the depth of nested AlwaysAllocateScope's but rather a single
1798  // count, as scopes can be acquired from multiple tasks (read: threads).
1799  std::atomic<size_t> always_allocate_scope_count_{0};
1800 
1801  // Stores the memory pressure level that set by MemoryPressureNotification
1802  // and reset by a mark-compact garbage collection.
1803  std::atomic<MemoryPressureLevel> memory_pressure_level_;
1804 
1805  std::vector<std::pair<v8::NearHeapLimitCallback, void*> >
1806  near_heap_limit_callbacks_;
1807 
1808  // For keeping track of context disposals.
1809  int contexts_disposed_ = 0;
1810 
1811  // The length of the retained_maps array at the time of context disposal.
1812  // This separates maps in the retained_maps array that were created before
1813  // and after context disposal.
1814  int number_of_disposed_maps_ = 0;
1815 
1816  NewSpace* new_space_ = nullptr;
1817  OldSpace* old_space_ = nullptr;
1818  CodeSpace* code_space_ = nullptr;
1819  MapSpace* map_space_ = nullptr;
1820  LargeObjectSpace* lo_space_ = nullptr;
1821  CodeLargeObjectSpace* code_lo_space_ = nullptr;
1822  NewLargeObjectSpace* new_lo_space_ = nullptr;
1823  ReadOnlySpace* read_only_space_ = nullptr;
1824  // Map from the space id to the space.
1825  Space* space_[LAST_SPACE + 1];
1826 
1827  // Determines whether code space is write-protected. This is essentially a
1828  // race-free copy of the {FLAG_write_protect_code_memory} flag.
1829  bool write_protect_code_memory_ = false;
1830 
1831  // Holds the number of open CodeSpaceMemoryModificationScopes.
1832  uintptr_t code_space_memory_modification_scope_depth_ = 0;
1833 
1834  HeapState gc_state_ = NOT_IN_GC;
1835 
1836  int gc_post_processing_depth_ = 0;
1837 
1838  // Returns the amount of external memory registered since last global gc.
1839  uint64_t PromotedExternalMemorySize();
1840 
1841  // How many "runtime allocations" happened.
1842  uint32_t allocations_count_ = 0;
1843 
1844  // Running hash over allocations performed.
1845  uint32_t raw_allocations_hash_ = 0;
1846 
1847  // Starts marking when stress_marking_percentage_% of the marking start limit
1848  // is reached.
1849  int stress_marking_percentage_ = 0;
1850 
1851  // Observer that causes more frequent checks for reached incremental marking
1852  // limit.
1853  AllocationObserver* stress_marking_observer_ = nullptr;
1854 
1855  // Observer that can cause early scavenge start.
1856  StressScavengeObserver* stress_scavenge_observer_ = nullptr;
1857 
1858  bool allocation_step_in_progress_ = false;
1859 
1860  // The maximum percent of the marking limit reached wihout causing marking.
1861  // This is tracked when specyfing --fuzzer-gc-analysis.
1862  double max_marking_limit_reached_ = 0.0;
1863 
1864  // How many mark-sweep collections happened.
1865  unsigned int ms_count_ = 0;
1866 
1867  // How many gc happened.
1868  unsigned int gc_count_ = 0;
1869 
1870  // The number of Mark-Compact garbage collections that are considered as
1871  // ineffective. See IsIneffectiveMarkCompact() predicate.
1872  int consecutive_ineffective_mark_compacts_ = 0;
1873 
1874  static const uintptr_t kMmapRegionMask = 0xFFFFFFFFu;
1875  uintptr_t mmap_region_base_ = 0;
1876 
1877  // For post mortem debugging.
1878  int remembered_unmapped_pages_index_ = 0;
1879  Address remembered_unmapped_pages_[kRememberedUnmappedPages];
1880 
1881  // Limit that triggers a global GC on the next (normally caused) GC. This
1882  // is checked when we have already decided to do a GC to help determine
1883  // which collector to invoke, before expanding a paged space in the old
1884  // generation and on every allocation in large object space.
1885  size_t old_generation_allocation_limit_;
1886 
1887  // Indicates that inline bump-pointer allocation has been globally disabled
1888  // for all spaces. This is used to disable allocations in generated code.
1889  bool inline_allocation_disabled_ = false;
1890 
1891  // Weak list heads, threaded through the objects.
1892  // List heads are initialized lazily and contain the undefined_value at start.
1893  Object* native_contexts_list_;
1894  Object* allocation_sites_list_;
1895 
1896  std::vector<GCCallbackTuple> gc_epilogue_callbacks_;
1897  std::vector<GCCallbackTuple> gc_prologue_callbacks_;
1898 
1899  GetExternallyAllocatedMemoryInBytesCallback external_memory_callback_;
1900 
1901  int deferred_counters_[v8::Isolate::kUseCounterFeatureCount];
1902 
1903  size_t promoted_objects_size_ = 0;
1904  double promotion_ratio_ = 0.0;
1905  double promotion_rate_ = 0.0;
1906  size_t semi_space_copied_object_size_ = 0;
1907  size_t previous_semi_space_copied_object_size_ = 0;
1908  double semi_space_copied_rate_ = 0.0;
1909  int nodes_died_in_new_space_ = 0;
1910  int nodes_copied_in_new_space_ = 0;
1911  int nodes_promoted_ = 0;
1912 
1913  // This is the pretenuring trigger for allocation sites that are in maybe
1914  // tenure state. When we switched to the maximum new space size we deoptimize
1915  // the code that belongs to the allocation site and derive the lifetime
1916  // of the allocation site.
1917  unsigned int maximum_size_scavenges_ = 0;
1918 
1919  // Total time spent in GC.
1920  double total_gc_time_ms_;
1921 
1922  // Last time an idle notification happened.
1923  double last_idle_notification_time_ = 0.0;
1924 
1925  // Last time a garbage collection happened.
1926  double last_gc_time_ = 0.0;
1927 
1928  GCTracer* tracer_ = nullptr;
1929  MarkCompactCollector* mark_compact_collector_ = nullptr;
1930  MinorMarkCompactCollector* minor_mark_compact_collector_ = nullptr;
1931  ScavengerCollector* scavenger_collector_ = nullptr;
1932  ArrayBufferCollector* array_buffer_collector_ = nullptr;
1933  MemoryAllocator* memory_allocator_ = nullptr;
1934  StoreBuffer* store_buffer_ = nullptr;
1935  HeapController* heap_controller_ = nullptr;
1936  IncrementalMarking* incremental_marking_ = nullptr;
1937  ConcurrentMarking* concurrent_marking_ = nullptr;
1938  GCIdleTimeHandler* gc_idle_time_handler_ = nullptr;
1939  MemoryReducer* memory_reducer_ = nullptr;
1940  ObjectStats* live_object_stats_ = nullptr;
1941  ObjectStats* dead_object_stats_ = nullptr;
1942  ScavengeJob* scavenge_job_ = nullptr;
1943  AllocationObserver* idle_scavenge_observer_ = nullptr;
1944  LocalEmbedderHeapTracer* local_embedder_heap_tracer_ = nullptr;
1945  StrongRootsList* strong_roots_list_ = nullptr;
1946 
1947  // This counter is increased before each GC and never reset.
1948  // To account for the bytes allocated since the last GC, use the
1949  // NewSpaceAllocationCounter() function.
1950  size_t new_space_allocation_counter_ = 0;
1951 
1952  // This counter is increased before each GC and never reset. To
1953  // account for the bytes allocated since the last GC, use the
1954  // OldGenerationAllocationCounter() function.
1955  size_t old_generation_allocation_counter_at_last_gc_ = 0;
1956 
1957  // The size of objects in old generation after the last MarkCompact GC.
1958  size_t old_generation_size_at_last_gc_ = 0;
1959 
1960  // The feedback storage is used to store allocation sites (keys) and how often
1961  // they have been visited (values) by finding a memento behind an object. The
1962  // storage is only alive temporary during a GC. The invariant is that all
1963  // pointers in this map are already fixed, i.e., they do not point to
1964  // forwarding pointers.
1965  PretenuringFeedbackMap global_pretenuring_feedback_;
1966 
1967  char trace_ring_buffer_[kTraceRingBufferSize];
1968 
1969  // Used as boolean.
1970  uint8_t is_marking_flag_ = 0;
1971 
1972  // If it's not full then the data is from 0 to ring_buffer_end_. If it's
1973  // full then the data is from ring_buffer_end_ to the end of the buffer and
1974  // from 0 to ring_buffer_end_.
1975  bool ring_buffer_full_ = false;
1976  size_t ring_buffer_end_ = 0;
1977 
1978  // Flag is set when the heap has been configured. The heap can be repeatedly
1979  // configured through the API until it is set up.
1980  bool configured_ = false;
1981 
1982  // Currently set GC flags that are respected by all GC components.
1983  int current_gc_flags_ = Heap::kNoGCFlags;
1984 
1985  // Currently set GC callback flags that are used to pass information between
1986  // the embedder and V8's GC.
1987  GCCallbackFlags current_gc_callback_flags_;
1988 
1989  ExternalStringTable external_string_table_;
1990 
1991  base::Mutex relocation_mutex_;
1992 
1993  int gc_callbacks_depth_ = 0;
1994 
1995  bool deserialization_complete_ = false;
1996 
1997  // The depth of HeapIterator nestings.
1998  int heap_iterator_depth_ = 0;
1999 
2000  bool fast_promotion_mode_ = false;
2001 
2002  // Used for testing purposes.
2003  bool force_oom_ = false;
2004  bool delay_sweeper_tasks_for_testing_ = false;
2005 
2006  HeapObject* pending_layout_change_object_ = nullptr;
2007 
2008  base::Mutex unprotected_memory_chunks_mutex_;
2009  std::unordered_set<MemoryChunk*> unprotected_memory_chunks_;
2010  bool unprotected_memory_chunks_registry_enabled_ = false;
2011 
2012 #ifdef V8_ENABLE_ALLOCATION_TIMEOUT
2013  // If the --gc-interval flag is set to a positive value, this
2014  // variable holds the value indicating the number of allocations
2015  // remain until the next failure and garbage collection.
2016  int allocation_timeout_ = 0;
2017 #endif // V8_ENABLE_ALLOCATION_TIMEOUT
2018 
2019  std::map<HeapObject*, HeapObject*> retainer_;
2020  std::map<HeapObject*, Root> retaining_root_;
2021  // If an object is retained by an ephemeron, then the retaining key of the
2022  // ephemeron is stored in this map.
2023  std::map<HeapObject*, HeapObject*> ephemeron_retainer_;
2024  // For each index inthe retaining_path_targets_ array this map
2025  // stores the option of the corresponding target.
2026  std::map<int, RetainingPathOption> retaining_path_target_option_;
2027 
2028  std::vector<HeapObjectAllocationTracker*> allocation_trackers_;
2029 
2030  // Classes in "heap" can be friends.
2031  friend class AlwaysAllocateScope;
2032  friend class ArrayBufferCollector;
2033  friend class ConcurrentMarking;
2034  friend class EphemeronHashTableMarkingTask;
2035  friend class GCCallbacksScope;
2036  friend class GCTracer;
2037  friend class MemoryController;
2038  friend class HeapIterator;
2039  friend class IdleScavengeObserver;
2040  friend class IncrementalMarking;
2041  friend class IncrementalMarkingJob;
2042  friend class LargeObjectSpace;
2043  template <FixedArrayVisitationMode fixed_array_mode,
2044  TraceRetainingPathMode retaining_path_mode, typename MarkingState>
2045  friend class MarkingVisitor;
2046  friend class MarkCompactCollector;
2047  friend class MarkCompactCollectorBase;
2048  friend class MinorMarkCompactCollector;
2049  friend class NewSpace;
2050  friend class ObjectStatsCollector;
2051  friend class Page;
2052  friend class PagedSpace;
2053  friend class ReadOnlyRoots;
2054  friend class Scavenger;
2055  friend class ScavengerCollector;
2056  friend class Space;
2057  friend class StoreBuffer;
2058  friend class Sweeper;
2059  friend class heap::TestMemoryAllocatorScope;
2060 
2061  // The allocator interface.
2062  friend class Factory;
2063 
2064  // The Isolate constructs us.
2065  friend class Isolate;
2066 
2067  // Used in cctest.
2068  friend class heap::HeapTester;
2069 
2070  FRIEND_TEST(HeapControllerTest, OldGenerationAllocationLimit);
2071  FRIEND_TEST(HeapTest, ExternalLimitDefault);
2072  FRIEND_TEST(HeapTest, ExternalLimitStaysAboveDefaultForExplicitHandling);
2073  DISALLOW_COPY_AND_ASSIGN(Heap);
2074 };
2075 
2076 
2077 class HeapStats {
2078  public:
2079  static const int kStartMarker = 0xDECADE00;
2080  static const int kEndMarker = 0xDECADE01;
2081 
2082  intptr_t* start_marker; // 0
2083  size_t* ro_space_size; // 1
2084  size_t* ro_space_capacity; // 2
2085  size_t* new_space_size; // 3
2086  size_t* new_space_capacity; // 4
2087  size_t* old_space_size; // 5
2088  size_t* old_space_capacity; // 6
2089  size_t* code_space_size; // 7
2090  size_t* code_space_capacity; // 8
2091  size_t* map_space_size; // 9
2092  size_t* map_space_capacity; // 10
2093  size_t* lo_space_size; // 11
2094  size_t* code_lo_space_size; // 12
2095  size_t* global_handle_count; // 13
2096  size_t* weak_global_handle_count; // 14
2097  size_t* pending_global_handle_count; // 15
2098  size_t* near_death_global_handle_count; // 16
2099  size_t* free_global_handle_count; // 17
2100  size_t* memory_allocator_size; // 18
2101  size_t* memory_allocator_capacity; // 19
2102  size_t* malloced_memory; // 20
2103  size_t* malloced_peak_memory; // 21
2104  size_t* objects_per_type; // 22
2105  size_t* size_per_type; // 23
2106  int* os_error; // 24
2107  char* last_few_messages; // 25
2108  char* js_stacktrace; // 26
2109  intptr_t* end_marker; // 27
2110 };
2111 
2112 
2114  public:
2115  explicit inline AlwaysAllocateScope(Isolate* isolate);
2116  inline ~AlwaysAllocateScope();
2117 
2118  private:
2119  Heap* heap_;
2120 };
2121 
2122 // The CodeSpaceMemoryModificationScope can only be used by the main thread.
2124  public:
2125  explicit inline CodeSpaceMemoryModificationScope(Heap* heap);
2127 
2128  private:
2129  Heap* heap_;
2130 };
2131 
2132 // The CodePageCollectionMemoryModificationScope can only be used by the main
2133 // thread. It will not be enabled if a CodeSpaceMemoryModificationScope is
2134 // already active.
2136  public:
2137  explicit inline CodePageCollectionMemoryModificationScope(Heap* heap);
2139 
2140  private:
2141  Heap* heap_;
2142 };
2143 
2144 // The CodePageMemoryModificationScope does not check if tansitions to
2145 // writeable and back to executable are actually allowed, i.e. the MemoryChunk
2146 // was registered to be executable. It can be used by concurrent threads.
2148  public:
2149  explicit inline CodePageMemoryModificationScope(MemoryChunk* chunk);
2151 
2152  private:
2153  MemoryChunk* chunk_;
2154  bool scope_active_;
2155 
2156  // Disallow any GCs inside this scope, as a relocation of the underlying
2157  // object would change the {MemoryChunk} that this scope targets.
2158  DISALLOW_HEAP_ALLOCATION(no_heap_allocation_);
2159 };
2160 
2161 // Visitor class to verify interior pointers in spaces that do not contain
2162 // or care about intergenerational references. All heap object pointers have to
2163 // point into the heap to a location that has a map pointer at its first word.
2164 // Caveat: Heap::Contains is an approximation because it can return true for
2165 // objects in a heap space but above the allocation pointer.
2167  public:
2168  explicit VerifyPointersVisitor(Heap* heap) : heap_(heap) {}
2169  void VisitPointers(HeapObject* host, ObjectSlot start,
2170  ObjectSlot end) override;
2171  void VisitPointers(HeapObject* host, MaybeObjectSlot start,
2172  MaybeObjectSlot end) override;
2173  void VisitRootPointers(Root root, const char* description, ObjectSlot start,
2174  ObjectSlot end) override;
2175 
2176  protected:
2177  virtual void VerifyPointers(HeapObject* host, MaybeObjectSlot start,
2178  MaybeObjectSlot end);
2179 
2180  Heap* heap_;
2181 };
2182 
2183 
2184 // Verify that all objects are Smis.
2186  public:
2187  void VisitRootPointers(Root root, const char* description, ObjectSlot start,
2188  ObjectSlot end) override;
2189 };
2190 
2191 // Space iterator for iterating over all the paged spaces of the heap: Map
2192 // space, old space, code space and optionally read only space. Returns each
2193 // space in turn, and null when it is done.
2194 class V8_EXPORT_PRIVATE PagedSpaces {
2195  public:
2196  enum class SpacesSpecifier { kSweepablePagedSpaces, kAllPagedSpaces };
2197 
2198  explicit PagedSpaces(Heap* heap, SpacesSpecifier specifier =
2199  SpacesSpecifier::kSweepablePagedSpaces)
2200  : heap_(heap),
2201  counter_(specifier == SpacesSpecifier::kAllPagedSpaces ? RO_SPACE
2202  : OLD_SPACE) {}
2203  PagedSpace* next();
2204 
2205  private:
2206  Heap* heap_;
2207  int counter_;
2208 };
2209 
2210 
2211 class SpaceIterator : public Malloced {
2212  public:
2213  explicit SpaceIterator(Heap* heap);
2214  virtual ~SpaceIterator();
2215 
2216  bool has_next();
2217  Space* next();
2218 
2219  private:
2220  Heap* heap_;
2221  int current_space_; // from enum AllocationSpace.
2222 };
2223 
2224 
2225 // A HeapIterator provides iteration over the whole heap. It
2226 // aggregates the specific iterators for the different spaces as
2227 // these can only iterate over one space only.
2228 //
2229 // HeapIterator ensures there is no allocation during its lifetime
2230 // (using an embedded DisallowHeapAllocation instance).
2231 //
2232 // HeapIterator can skip free list nodes (that is, de-allocated heap
2233 // objects that still remain in the heap). As implementation of free
2234 // nodes filtering uses GC marks, it can't be used during MS/MC GC
2235 // phases. Also, it is forbidden to interrupt iteration in this mode,
2236 // as this will leave heap objects marked (and thus, unusable).
2238  public:
2239  enum HeapObjectsFiltering { kNoFiltering, kFilterUnreachable };
2240 
2241  explicit HeapIterator(Heap* heap,
2242  HeapObjectsFiltering filtering = kNoFiltering);
2243  ~HeapIterator();
2244 
2245  HeapObject* next();
2246 
2247  private:
2248  HeapObject* NextObject();
2249 
2250  DISALLOW_HEAP_ALLOCATION(no_heap_allocation_);
2251 
2252  Heap* heap_;
2253  HeapObjectsFiltering filtering_;
2254  HeapObjectsFilter* filter_;
2255  // Space iterator for iterating all the spaces.
2256  SpaceIterator* space_iterator_;
2257  // Object iterator for the space currently being iterated.
2258  std::unique_ptr<ObjectIterator> object_iterator_;
2259 };
2260 
2261 // Abstract base class for checking whether a weak object should be retained.
2263  public:
2264  virtual ~WeakObjectRetainer() = default;
2265 
2266  // Return whether this object should be retained. If nullptr is returned the
2267  // object has no references. Otherwise the address of the retained object
2268  // should be returned as in some GC situations the object has been moved.
2269  virtual Object* RetainAs(Object* object) = 0;
2270 };
2271 
2272 // -----------------------------------------------------------------------------
2273 // Allows observation of allocations.
2275  public:
2276  explicit AllocationObserver(intptr_t step_size)
2277  : step_size_(step_size), bytes_to_next_step_(step_size) {
2278  DCHECK_LE(kPointerSize, step_size);
2279  }
2280  virtual ~AllocationObserver() = default;
2281 
2282  // Called each time the observed space does an allocation step. This may be
2283  // more frequently than the step_size we are monitoring (e.g. when there are
2284  // multiple observers, or when page or space boundary is encountered.)
2285  void AllocationStep(int bytes_allocated, Address soon_object, size_t size);
2286 
2287  protected:
2288  intptr_t step_size() const { return step_size_; }
2289  intptr_t bytes_to_next_step() const { return bytes_to_next_step_; }
2290 
2291  // Pure virtual method provided by the subclasses that gets called when at
2292  // least step_size bytes have been allocated. soon_object is the address just
2293  // allocated (but not yet initialized.) size is the size of the object as
2294  // requested (i.e. w/o the alignment fillers). Some complexities to be aware
2295  // of:
2296  // 1) soon_object will be nullptr in cases where we end up observing an
2297  // allocation that happens to be a filler space (e.g. page boundaries.)
2298  // 2) size is the requested size at the time of allocation. Right-trimming
2299  // may change the object size dynamically.
2300  // 3) soon_object may actually be the first object in an allocation-folding
2301  // group. In such a case size is the size of the group rather than the
2302  // first object.
2303  virtual void Step(int bytes_allocated, Address soon_object, size_t size) = 0;
2304 
2305  // Subclasses can override this method to make step size dynamic.
2306  virtual intptr_t GetNextStepSize() { return step_size_; }
2307 
2308  intptr_t step_size_;
2309  intptr_t bytes_to_next_step_;
2310 
2311  private:
2312  friend class Space;
2313  DISALLOW_COPY_AND_ASSIGN(AllocationObserver);
2314 };
2315 
2316 V8_EXPORT_PRIVATE const char* AllocationSpaceName(AllocationSpace space);
2317 
2318 // -----------------------------------------------------------------------------
2319 // Allows observation of heap object allocations.
2321  public:
2322  virtual void AllocationEvent(Address addr, int size) = 0;
2323  virtual void MoveEvent(Address from, Address to, int size) {}
2324  virtual void UpdateObjectSizeEvent(Address addr, int size) {}
2325  virtual ~HeapObjectAllocationTracker() = default;
2326 };
2327 
2328 } // namespace internal
2329 } // namespace v8
2330 
2331 #endif // V8_HEAP_HEAP_H_
Definition: libplatform.h:13