GCConfig.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #ifndef HERMES_PUBLIC_GCCONFIG_H
  8. #define HERMES_PUBLIC_GCCONFIG_H
  9. #include "hermes/Public/CtorConfig.h"
  10. #include "hermes/Public/GCTripwireContext.h"
  11. #include "hermes/Public/MemoryEventTracker.h"
  12. #include <algorithm>
  13. #include <cassert>
  14. #include <chrono>
  15. #include <cstdint>
  16. #include <functional>
  17. #include <limits>
  18. #include <memory>
  19. #include <string>
  20. namespace hermes {
  21. namespace vm {
  22. /// A type big enough to accomodate the entire allocated address space.
  23. /// Individual allocations are always 'uint32_t', but on a 64-bit machine we
  24. /// might want to accommodate a larger total heap (or not, in which case we keep
  25. /// it 32-bit).
  26. using gcheapsize_t = uint32_t;
  27. struct GCAnalyticsEvent {
  28. std::string runtimeDescription;
  29. std::string gcKind;
  30. std::string collectionType;
  31. std::chrono::milliseconds duration;
  32. std::chrono::milliseconds cpuDuration;
  33. uint64_t preAllocated;
  34. uint64_t preSize;
  35. uint64_t postAllocated;
  36. uint64_t postSize;
  37. double survivalRatio;
  38. };
  39. /// Parameters to control a tripwire function called when the live set size
  40. /// surpasses a given threshold after collections. Check documentation in
  41. /// README.md
  42. #define GC_TRIPWIRE_FIELDS(F) \
  43. /* If the heap size is above this threshold after a collection, the tripwire \
  44. * is triggered. */ \
  45. F(constexpr, gcheapsize_t, Limit, std::numeric_limits<gcheapsize_t>::max()) \
  46. \
  47. /* The callback to call when the tripwire is considered triggered. */ \
  48. F(HERMES_NON_CONSTEXPR, \
  49. std::function<void(GCTripwireContext &)>, \
  50. Callback, \
  51. nullptr) \
  52. /* GC_TRIPWIRE_FIELDS END */
  53. _HERMES_CTORCONFIG_STRUCT(GCTripwireConfig, GC_TRIPWIRE_FIELDS, {});
  54. #undef HEAP_TRIPWIRE_FIELDS
  55. #define GC_HANDLESAN_FIELDS(F) \
  56. /* The probability with which the GC should keep moving the heap */ \
  57. /* to detect stale GC handles. */ \
  58. F(constexpr, double, SanitizeRate, 0.0) \
  59. /* Random seed to use for basis of decisions whether or not to */ \
  60. /* sanitize. A negative value will mean a seed will be chosen at */ \
  61. /* random. */ \
  62. F(constexpr, int64_t, RandomSeed, -1) \
  63. /* GC_HANDLESAN_FIELDS END */
  64. _HERMES_CTORCONFIG_STRUCT(GCSanitizeConfig, GC_HANDLESAN_FIELDS, {});
  65. #undef GC_HANDLESAN_FIELDS
  66. /// How aggressively to return unused memory to the OS.
  67. enum ReleaseUnused {
  68. kReleaseUnusedNone = 0, /// Don't try to release unused memory.
  69. kReleaseUnusedOld, /// Only old gen, on full collections.
  70. kReleaseUnusedYoungOnFull, /// Also young gen, but only on full collections.
  71. kReleaseUnusedYoungAlways /// Also young gen, also on young gen collections.
  72. };
  73. enum class GCEventKind {
  74. CollectionStart,
  75. CollectionEnd,
  76. };
  77. /// Parameters for GC Initialisation. Check documentation in README.md
  78. /// constexpr indicates that the default value is constexpr.
  79. #define GC_FIELDS(F) \
  80. /* Minimum heap size hint. */ \
  81. F(constexpr, gcheapsize_t, MinHeapSize, 0) \
  82. \
  83. /* Initial heap size hint. */ \
  84. F(constexpr, gcheapsize_t, InitHeapSize, 32 << 20) \
  85. \
  86. /* Maximum heap size hint. */ \
  87. F(constexpr, gcheapsize_t, MaxHeapSize, 512 << 20) \
  88. \
  89. /* Sizing heuristic: fraction of heap to be occupied by live data. */ \
  90. F(constexpr, double, OccupancyTarget, 0.5) \
  91. \
  92. /* Number of consecutive full collections considered to be an OOM. */ \
  93. F(constexpr, \
  94. unsigned, \
  95. EffectiveOOMThreshold, \
  96. std::numeric_limits<unsigned>::max()) \
  97. \
  98. /* Sanitizer configuration for the GC. */ \
  99. F(constexpr, GCSanitizeConfig, SanitizeConfig) \
  100. \
  101. /* Whether the GC should spread allocations across all its "spaces". */ \
  102. F(constexpr, bool, ShouldRandomizeAllocSpace, false) \
  103. \
  104. /* Whether to Keep track of GC Statistics. */ \
  105. F(constexpr, bool, ShouldRecordStats, false) \
  106. \
  107. /* How aggressively to return unused memory to the OS. */ \
  108. F(constexpr, ReleaseUnused, ShouldReleaseUnused, kReleaseUnusedOld) \
  109. \
  110. /* Name for this heap in logs. */ \
  111. F(HERMES_NON_CONSTEXPR, std::string, Name, "") \
  112. \
  113. /* Configuration for the Heap Tripwire. */ \
  114. F(HERMES_NON_CONSTEXPR, GCTripwireConfig, TripwireConfig) \
  115. \
  116. /* Whether to (initially) allocate from the young gen (true) or the */ \
  117. /* old gen (false). */ \
  118. F(constexpr, bool, AllocInYoung, true) \
  119. \
  120. /* Whether to revert, if necessary, to young-gen allocation at TTI. */ \
  121. F(constexpr, bool, RevertToYGAtTTI, false) \
  122. \
  123. /* Whether to use mprotect on GC metadata between GCs. */ \
  124. F(constexpr, bool, ProtectMetadata, false) \
  125. \
  126. /* Whether to track allocation traces starting in the Runtime ctor. */ \
  127. F(constexpr, bool, AllocationLocationTrackerFromStart, false) \
  128. \
  129. /* Pointer to the memory profiler (Memory Event Tracker). */ \
  130. F(HERMES_NON_CONSTEXPR, \
  131. std::shared_ptr<MemoryEventTracker>, \
  132. MemEventTracker, \
  133. nullptr) \
  134. \
  135. /* Callout for an analytics event. */ \
  136. F(HERMES_NON_CONSTEXPR, \
  137. std::function<void(const GCAnalyticsEvent &)>, \
  138. AnalyticsCallback, \
  139. nullptr) \
  140. \
  141. /* Called at GC events (see GCEventKind enum for the list). The */ \
  142. /* second argument contains human-readable details about the event. */ \
  143. /* NOTE: The function MUST NOT invoke any methods on the Runtime. */ \
  144. F(HERMES_NON_CONSTEXPR, \
  145. std::function<void(GCEventKind, const char *)>, \
  146. Callback, \
  147. nullptr) \
  148. /* GC_FIELDS END */
  149. _HERMES_CTORCONFIG_STRUCT(GCConfig, GC_FIELDS, {
  150. if (builder.hasMinHeapSize()) {
  151. if (builder.hasInitHeapSize()) {
  152. // If both are specified, normalize the initial size up to the minimum,
  153. // if necessary.
  154. InitHeapSize_ = std::max(MinHeapSize_, InitHeapSize_);
  155. } else {
  156. // If the minimum is set explicitly, but the initial heap size is not,
  157. // use the minimum as the initial size.
  158. InitHeapSize_ = MinHeapSize_;
  159. }
  160. }
  161. assert(InitHeapSize_ >= MinHeapSize_);
  162. // Make sure the max is at least the Init.
  163. MaxHeapSize_ = std::max(InitHeapSize_, MaxHeapSize_);
  164. });
  165. #undef GC_FIELDS
  166. } // namespace vm
  167. } // namespace hermes
  168. #endif // HERMES_PUBLIC_GCCONFIG_H