# <!-- 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
  #   - start(full_mark: true, immediate_mark: true, immediate_sweep: true)
  # -->
  # Initiates garbage collection, even if manually disabled.
  #
  # The `full_mark` keyword argument determines whether or not to perform a major
  # garbage collection cycle. When set to `true`, a major garbage collection cycle
  # is ran, meaning all objects are marked. When set to `false`, a minor garbage
  # collection cycle is ran, meaning only young objects are marked.
  #
  # The `immediate_mark` keyword argument determines whether or not to perform
  # incremental marking. When set to `true`, marking is completed during the call
  # to this method. When set to `false`, marking is performed in steps that is
  # interleaved with future Ruby code execution, so marking might not be completed
  # during this method call. Note that if `full_mark` is `false` then marking will
  # always be immediate, regardless of the value of `immediate_mark`.
  #
  # The `immedate_sweep` keyword argument determines whether or not to defer
  # sweeping (using lazy sweep). When set to `true`, sweeping is performed in
  # steps that is interleaved with future Ruby code execution, so sweeping might
  # not be completed during this method call. When set to `false`, sweeping is
  # completed during the call to this method.
  #
  # 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)
  # time
  # :   The total time spent in garbage collections (in milliseconds)
  # 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
  # compact_count
  # :   The total number of compactions run since process start
  # read_barrier_faults
  # :   The total number of times the read barrier was triggered during compaction
  # total_moved_objects
  # :   The total number of objects compaction has moved
  # 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.c
  #   - 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.
  #
  # To test whether GC compaction is supported, use the idiom:
  #
  #     GC.respond_to?(:compact)
  #
  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 expands 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.rb
  #   - GC.latest_gc_info -> hash
  #   - 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 in the garbage collector.
#
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
