# <!-- rdoc-file=gc.rb -->
# The GC module provides an interface to Ruby's mark and sweep garbage
# collection mechanism.
#
# Some of the underlying methods are also available via the ObjectSpace module.
#
# You may obtain information about the operation of the GC through GC::Profiler.
#
module GC
  # <!--
  #   rdoc-file=gc.rb
  #   - GC.count -> Integer
  # -->
  # The number of times GC occurred.
  #
  # It returns the number of times GC occurred since the process started.
  #
  def self.count: () -> Integer

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.disable    -> true or false
  # -->
  # Disables garbage collection, returning `true` if garbage collection was
  # already disabled.
  #
  #     GC.disable   #=> false
  #     GC.disable   #=> true
  #
  def self.disable: () -> bool

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.enable    -> true or false
  # -->
  # Enables garbage collection, returning `true` if garbage collection was
  # previously disabled.
  #
  #     GC.disable   #=> false
  #     GC.enable    #=> true
  #     GC.enable    #=> false
  #
  def self.enable: () -> bool

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.start                     -> nil
  #   - ObjectSpace.garbage_collect  -> nil
  #   - include GC; garbage_collect  -> nil
  #   - GC.start(full_mark: true, immediate_sweep: true)           -> nil
  #   - ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true) -> nil
  #   - include GC; garbage_collect(full_mark: true, immediate_sweep: true) -> nil
  # -->
  # Initiates garbage collection, even if manually disabled.
  #
  # This method is defined with keyword arguments that default to true:
  #
  #     def GC.start(full_mark: true, immediate_sweep: true); end
  #
  # Use full_mark: false to perform a minor GC. Use immediate_sweep: false to
  # defer sweeping (use lazy sweep).
  #
  # Note: These keyword arguments are implementation and version dependent. They
  # are not guaranteed to be future-compatible, and may be ignored if the
  # underlying implementation does not support them.
  #
  def self.start: (?immediate_sweep: boolish immediate_sweep, ?immediate_mark: boolish immediate_mark, ?full_mark: boolish full_mark) -> nil

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.stat -> Hash
  #   - GC.stat(hash) -> Hash
  #   - GC.stat(:key) -> Numeric
  # -->
  # Returns a Hash containing information about the GC.
  #
  # The contents of the hash are implementation specific and may change in the
  # future without notice.
  #
  # The hash includes information about internal statistics about GC such as:
  #
  # count
  # :   The total number of garbage collections ran since application start (count
  #     includes both minor and major garbage collections)
  # heap_allocated_pages
  # :   The total number of `:heap_eden_pages` + `:heap_tomb_pages`
  # heap_sorted_length
  # :   The number of pages that can fit into the buffer that holds references to
  #     all pages
  # heap_allocatable_pages
  # :   The total number of pages the application could allocate without
  #     additional GC
  # heap_available_slots
  # :   The total number of slots in all `:heap_allocated_pages`
  # heap_live_slots
  # :   The total number of slots which contain live objects
  # heap_free_slots
  # :   The total number of slots which do not contain live objects
  # heap_final_slots
  # :   The total number of slots with pending finalizers to be run
  # heap_marked_slots
  # :   The total number of objects marked in the last GC
  # heap_eden_pages
  # :   The total number of pages which contain at least one live slot
  # heap_tomb_pages
  # :   The total number of pages which do not contain any live slots
  # total_allocated_pages
  # :   The cumulative number of pages allocated since application start
  # total_freed_pages
  # :   The cumulative number of pages freed since application start
  # total_allocated_objects
  # :   The cumulative number of objects allocated since application start
  # total_freed_objects
  # :   The cumulative number of objects freed since application start
  # malloc_increase_bytes
  # :   Amount of memory allocated on the heap for objects. Decreased by any GC
  # malloc_increase_bytes_limit
  # :   When `:malloc_increase_bytes` crosses this limit, GC is triggered
  # minor_gc_count
  # :   The total number of minor garbage collections run since process start
  # major_gc_count
  # :   The total number of major garbage collections run since process start
  # remembered_wb_unprotected_objects
  # :   The total number of objects without write barriers
  # remembered_wb_unprotected_objects_limit
  # :   When `:remembered_wb_unprotected_objects` crosses this limit, major GC is
  #     triggered
  # old_objects
  # :   Number of live, old objects which have survived at least 3 garbage
  #     collections
  # old_objects_limit
  # :   When `:old_objects` crosses this limit, major GC is triggered
  # oldmalloc_increase_bytes
  # :   Amount of memory allocated on the heap for objects. Decreased by major GC
  # oldmalloc_increase_bytes_limit
  # :   When `:old_malloc_increase_bytes` crosses this limit, major GC is
  #     triggered
  #
  #
  # If the optional argument, hash, is given, it is overwritten and returned. This
  # is intended to avoid probe effect.
  #
  # This method is only expected to work on CRuby.
  #
  def self.stat: (?::Hash[Symbol, Integer] arg0) -> ::Hash[Symbol, Integer]
               | (?Symbol arg0) -> Integer

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.stress            -> integer, true or false
  # -->
  # Returns current status of GC stress mode.
  #
  def self.stress: () -> (Integer | TrueClass | FalseClass)

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.stress = flag          -> flag
  # -->
  # Updates the GC stress mode.
  #
  # When stress mode is enabled, the GC is invoked at every GC opportunity: all
  # memory and object allocations.
  #
  # Enabling stress mode will degrade performance, it is only for debugging.
  #
  # flag can be true, false, or an integer bit-ORed following flags.
  #     0x01:: no major GC
  #     0x02:: no immediate sweep
  #     0x04:: full mark after malloc/calloc/realloc
  #
  def self.stress=: (Integer | TrueClass | FalseClass flag) -> (Integer | TrueClass | FalseClass)

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.total_time -> int
  # -->
  # Return measured GC total time in nano seconds.
  #
  def self.total_time: () -> Integer

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.compact
  # -->
  # This function compacts objects together in Ruby's heap.  It eliminates unused
  # space (or fragmentation) in the heap by moving objects in to that unused
  # space.  This function returns a hash which contains statistics about which
  # objects were moved.  See `GC.latest_gc_info` for details about compaction
  # statistics.
  #
  # This method is implementation specific and not expected to be implemented in
  # any implementation besides MRI.
  #
  def self.compact: () -> ::Hash[:considered | :moved, Hash[Symbol | Integer, Integer]]

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
  # -->
  # Verify compaction reference consistency.
  #
  # This method is implementation specific.  During compaction, objects that were
  # moved are replaced with T_MOVED objects.  No object should have a reference to
  # a T_MOVED object after compaction.
  #
  # This function doubles the heap to ensure room to move all objects, compacts
  # the heap to make sure everything moves, updates all references, then performs
  # a full GC.  If any object contains a reference to a T_MOVED object, that
  # object should be pushed on the mark stack, and will make a SEGV.
  #
  def self.verify_compaction_references: () -> ::Hash[:considered | :moved, Hash[Symbol | Integer, Integer]]

  # <!--
  #   rdoc-file=gc.c
  #   - GC.verify_internal_consistency                  -> nil
  # -->
  # Verify internal consistency.
  #
  # This method is implementation specific. Now this method checks generational
  # consistency if RGenGC is supported.
  #
  def self.verify_internal_consistency: () -> nil

  # <!--
  #   rdoc-file=gc.c
  #   - verify_transient_heap_internal_consistency()
  # -->
  #
  def self.verify_transient_heap_internal_consistency: () -> nil

  # <!--
  #   rdoc-file=gc.rb
  #   - GC.latest_gc_info -> {:gc_by=>:newobj}
  #   - GC.latest_gc_info(hash) -> hash
  #   - GC.latest_gc_info(:major_by) -> :malloc
  # -->
  # Returns information about the most recent garbage collection.
  #
  # If the optional argument, hash, is given, it is overwritten and returned. This
  # is intended to avoid probe effect.
  #
  def self.latest_gc_info: () -> ::Hash[::Symbol, untyped]
                         | [K] (?Hash[K, untyped] hash) -> ::Hash[::Symbol | K, untyped]
                         | (Symbol key) -> untyped

  # <!--
  #   rdoc-file=gc.rb
  #   - garbage_collect(full_mark: true, immediate_mark: true, immediate_sweep: true)
  # -->
  #
  def garbage_collect: (?immediate_sweep: boolish immediate_sweep, ?immediate_mark: boolish immediate_mark, ?full_mark: boolish full_mark) -> nil
end

# <!-- rdoc-file=gc.c -->
# internal constants
#
GC::INTERNAL_CONSTANTS: Hash[Symbol, Integer]

# <!-- rdoc-file=gc.c -->
# GC build options
#
GC::OPTS: Array[String]

# <!-- rdoc-file=gc.c -->
# The GC profiler provides access to information on GC runs including time,
# length and object space size.
#
# Example:
#
#     GC::Profiler.enable
#
#     require 'rdoc/rdoc'
#
#     GC::Profiler.report
#
#     GC::Profiler.disable
#
# See also GC.count, GC.malloc_allocated_size and GC.malloc_allocations
#
module GC::Profiler
  # <!--
  #   rdoc-file=gc.c
  #   - GC::Profiler.clear          -> nil
  # -->
  # Clears the GC profiler data.
  #
  def self.clear: () -> void

  # <!--
  #   rdoc-file=gc.c
  #   - GC::Profiler.disable      -> nil
  # -->
  # Stops the GC profiler.
  #
  def self.disable: () -> void

  # <!--
  #   rdoc-file=gc.c
  #   - GC::Profiler.enable       -> nil
  # -->
  # Starts the GC profiler.
  #
  def self.enable: () -> void

  # <!--
  #   rdoc-file=gc.c
  #   - GC::Profiler.enabled?     -> true or false
  # -->
  # The current status of GC profile mode.
  #
  def self.enabled?: () -> bool

  # <!--
  #   rdoc-file=gc.c
  #   - GC::Profiler.raw_data    -> [Hash, ...]
  # -->
  # Returns an Array of individual raw profile data Hashes ordered from earliest
  # to latest by `:GC_INVOKE_TIME`.
  #
  # For example:
  #
  #     [
  #       {
  #          :GC_TIME=>1.3000000000000858e-05,
  #          :GC_INVOKE_TIME=>0.010634999999999999,
  #          :HEAP_USE_SIZE=>289640,
  #          :HEAP_TOTAL_SIZE=>588960,
  #          :HEAP_TOTAL_OBJECTS=>14724,
  #          :GC_IS_MARKED=>false
  #       },
  #       # ...
  #     ]
  #
  # The keys mean:
  #
  # `:GC_TIME`
  # :   Time elapsed in seconds for this GC run
  # `:GC_INVOKE_TIME`
  # :   Time elapsed in seconds from startup to when the GC was invoked
  # `:HEAP_USE_SIZE`
  # :   Total bytes of heap used
  # `:HEAP_TOTAL_SIZE`
  # :   Total size of heap in bytes
  # `:HEAP_TOTAL_OBJECTS`
  # :   Total number of objects
  # `:GC_IS_MARKED`
  # :   Returns `true` if the GC is in mark phase
  #
  #
  # If ruby was built with `GC_PROFILE_MORE_DETAIL`, you will also have access to
  # the following hash keys:
  #
  # `:GC_MARK_TIME`
  # `:GC_SWEEP_TIME`
  # `:ALLOCATE_INCREASE`
  # `:ALLOCATE_LIMIT`
  # `:HEAP_USE_PAGES`
  # `:HEAP_LIVE_OBJECTS`
  # `:HEAP_FREE_OBJECTS`
  # `:HAVE_FINALIZE`
  # :
  #
  def self.raw_data: () -> ::Array[::Hash[Symbol, untyped]]

  # <!--
  #   rdoc-file=gc.c
  #   - GC::Profiler.report
  #   - GC::Profiler.report(io)
  # -->
  # Writes the GC::Profiler.result to `$stdout` or the given IO object.
  #
  def self.report: (?IO io) -> void

  # <!--
  #   rdoc-file=gc.c
  #   - GC::Profiler.result  -> String
  # -->
  # Returns a profile data report such as:
  #
  #     GC 1 invokes.
  #     Index    Invoke Time(sec)       Use Size(byte)     Total Size(byte)         Total Object                    GC time(ms)
  #         1               0.012               159240               212940                10647         0.00000000000001530000
  #
  def self.result: () -> String

  # <!--
  #   rdoc-file=gc.c
  #   - GC::Profiler.total_time  -> float
  # -->
  # The total time used for garbage collection in seconds
  #
  def self.total_time: () -> Float
end
