Skip to content

Commit

Permalink
Updated GC signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
sampersand committed Dec 26, 2023
1 parent fea0932 commit d756270
Show file tree
Hide file tree
Showing 2 changed files with 235 additions and 45 deletions.
33 changes: 24 additions & 9 deletions core/gc.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@
# You may obtain information about the operation of the GC through GC::Profiler.
#
module GC
# <!-- rdoc-file=gc.c -->
# internal constants
#
INTERNAL_CONSTANTS: Hash[Symbol, Integer | bool]

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

# <!--
# rdoc-file=gc.rb
# - GC.count -> Integer
Expand Down Expand Up @@ -70,7 +80,7 @@ module GC
# 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
def self.start: (?immediate_sweep: boolish, ?immediate_mark: boolish, ?full_mark: boolish) -> nil

# <!--
# rdoc-file=gc.rb
Expand Down Expand Up @@ -156,16 +166,16 @@ module GC
#
# This method is only expected to work on CRuby.
#
def self.stat: (?::Hash[Symbol, Integer] arg0) -> ::Hash[Symbol, Integer]
| (?Symbol arg0) -> Integer
def self.stat: (?Hash[Symbol, Integer]? hash) -> Hash[Symbol, Integer]
| (Symbol key) -> Integer

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

# <!--
# rdoc-file=gc.rb
Expand All @@ -183,7 +193,8 @@ module GC
# 0x02:: no immediate sweep
# 0x04:: full mark after malloc/calloc/realloc
#
def self.stress=: (Integer | TrueClass | FalseClass flag) -> (Integer | TrueClass | FalseClass)
def self.stress=: (Integer flag) -> Integer
| (bool flag) -> bool

# <!--
# rdoc-file=gc.rb
Expand All @@ -210,7 +221,11 @@ module GC
#
# GC.respond_to?(:compact)
#
def self.compact: () -> ::Hash[:considered | :moved, Hash[Symbol | Integer, Integer]]
def self.compact: () -> compact_info

# The type that `GC.compact` and related functions can return.
#
type compact_info = Hash[:considered | :moved |:moved_up | :moved_down, Hash[Symbol, Integer]]

# <!--
# rdoc-file=gc.rb
Expand All @@ -227,7 +242,7 @@ module GC
# 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]]
def self.verify_compaction_references: (?toward: :empty | untyped, ?double_heap: boolish, ?expand_heap: boolish) -> compact_info

# <!--
# rdoc-file=gc.c
Expand All @@ -251,8 +266,8 @@ module GC
# 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]
def self.latest_gc_info: (?nil) -> Hash[Symbol, untyped]
| (Hash[Symbol, untyped] hash) -> Hash[Symbol, untyped]
| (Symbol key) -> untyped

# <!--
Expand Down
247 changes: 211 additions & 36 deletions test/stdlib/GC_test.rb
Original file line number Diff line number Diff line change
@@ -1,65 +1,240 @@
require_relative "test_helper"
require_relative 'test_helper'

class GCTest < StdlibTest
target GC
class GCSingletonTest < Test::Unit::TestCase
include TestHelper

include GC
testing "singleton(::GC)"

def test_garbage_collect
garbage_collect
garbage_collect(full_mark: true)
garbage_collect(full_mark: false)
garbage_collect(immediate_mark: true)
garbage_collect(immediate_mark: false)
garbage_collect(immediate_sweep: true)
garbage_collect(immediate_sweep: false)
def test_INTERNAL_CONSTANTS
assert_const_type 'Hash[Symbol, Integer | bool]',
'GC::INTERNAL_CONSTANTS'
end

def test_OPTS
assert_const_type 'Array[String]',
'GC::OPTS'
end

def test_count
assert_send_type '() -> Integer',
GC, :count
end

def test_disable
was_disabled = GC.disable

assert_send_type '() -> bool',
GC, :disable
ensure
GC.enable unless was_disabled
end

def test_enable
was_enabled = GC.enable

assert_send_type '() -> bool',
GC, :enable
ensure
GC.disable unless was_enabled
end

def test_start
GC.start
GC.start(full_mark: true)
GC.start(full_mark: false)
GC.start(immediate_mark: true)
GC.start(immediate_mark: false)
GC.start(immediate_sweep: true)
GC.start(immediate_sweep: false)
assert_send_type '() -> nil',
GC, :start

[true, Object.new, nil].each do |immediate_sweep|
[true, Object.new, nil].each do |immediate_mark|
[true, Object.new, nil].each do |full_mark|
assert_send_type '(immediate_sweep: boolish, immediate_mark: boolish, full_mark: boolish) -> nil',
GC, :start, immediate_sweep: immediate_sweep, immediate_mark: immediate_mark, full_mark: full_mark
end
end
end
end

def test_stat
assert_send_type '() -> Hash[Symbol, Integer]',
GC, :stat
assert_send_type '(Hash[Symbol, Integer]) -> Hash[Symbol, Integer]',
GC, :stat, {}
assert_send_type '(nil) -> Hash[Symbol, Integer]',
GC, :stat, nil
assert_send_type '(Symbol) -> Integer',
GC, :stat, :count
end

def test_stress_and_stress=
old_stress = GC.stress

assert_send_type '() -> (Integer | bool)',
GC, :stress
assert_send_type '(Integer) -> Integer',
GC, :stress=, 0
assert_send_type '() -> (Integer | bool)',
GC, :stress
[true, false].each do |bool|
assert_send_type '(bool) -> bool',
GC, :stress=, bool
end
ensure
GC.stress = old_stress
end

def test_total_time
assert_send_type '() -> Integer',
GC, :total_time
end

def test_compact
GC.compact
assert_send_type '() -> GC::compact_info',
GC, :compact
end

def test_verify_compaction_references
GC.verify_compaction_references
assert_send_type '() -> GC::compact_info',
GC, :verify_compaction_references
end

def test_verify_internal_consistency
GC.verify_internal_consistency
assert_send_type '() -> nil',
GC, :verify_internal_consistency
end

def test_latest_gc_info
GC.latest_gc_info
GC.latest_gc_info({})
GC.latest_gc_info(:state)
assert_send_type '() -> Hash[Symbol, untyped]',
GC, :latest_gc_info
assert_send_type '(nil) -> Hash[Symbol, untyped]',
GC, :latest_gc_info, nil
assert_send_type '(Hash[Symbol, untyped]) -> Hash[Symbol, untyped]',
GC, :latest_gc_info, {}

assert_send_type '(Symbol) -> untyped',
GC, :latest_gc_info, :major_by
end

def test_auto_compact
assert_send_type '() -> bool',
GC, :auto_compact
end

def test_auto_compact=
old = GC.auto_compact

[true, nil, Object.new, 1r].each do |obj|
assert_send_type '[T] (T) -> T',
GC, :auto_compact=, obj
end
ensure
GC.auto_compact = old
end

def test_latest_compact_info
assert_send_type '() -> GC::compact_info',
GC, :latest_compact_info
end

def test_set_stress
GC.stress = 0
GC.stress = true
GC.stress = false
def test_measure_total_time
assert_send_type '() -> bool',
GC, :measure_total_time
end

def test_measure_total_time=
old = GC.measure_total_time

[true, nil, Object.new, 1r].each do |obj|
assert_send_type '[T] (T) -> T',
GC, :measure_total_time=, obj
end
ensure
GC.measure_total_time = old
end
end

class GCIncludeTest < Test::Unit::TestCase
include TypeAssertions

class GCSingletonTest < Test::Unit::TestCase
include TestHelper
testing '::GC'

testing "singleton(::GC)"
class Foo
extend GC
end

def test_garbage_collect
assert_send_type '() -> nil',
Foo, :garbage_collect

[true, Object.new, nil].each do |immediate_sweep|
[true, Object.new, nil].each do |immediate_mark|
[true, Object.new, nil].each do |full_mark|
assert_send_type '(immediate_sweep: boolish, immediate_mark: boolish, full_mark: boolish) -> nil',
Foo, :garbage_collect, immediate_sweep: immediate_sweep, immediate_mark: immediate_mark, full_mark: full_mark
end
end
end
end
end

class GC_ProfilerSingletonTest < Test::Unit::TestCase
include TypeAssertions

testing 'singleton(::GC::Profiler)'

def test_clear
assert_send_type '() -> nil',
GC::Profiler, :clear
end

def test_enabled?
assert_send_type '() -> bool',
GC::Profiler, :enabled?
end

def test_enable_and_disable
was_enabled = GC::Profiler.enabled?

assert_send_type '() -> nil',
GC::Profiler, :enable
assert_send_type '() -> nil',
GC::Profiler, :disable
ensure
GC::Profiler.enable if was_enabled
end

def test_raw_data
was_enabled = GC::Profiler.enabled?
GC::Profiler.disable

assert_send_type '() -> nil',
GC::Profiler, :raw_data

GC::Profiler.enable
GC.start
assert_send_type '() -> Array[Hash[Symbol, untyped]]',
GC::Profiler, :raw_data
ensure
GC::Profiler.enable if was_enabled
end

def test_report
old_stdout = $stdout
$stdout = Object.new.tap { def _1.write(*) end }

assert_send_type '() -> nil',
GC::Profiler, :report

assert_send_type '(_Writer) -> nil',
GC::Profiler, :report, Writer.new
ensure
$stdout = old_stdout
end

def test_result
assert_send_type '() -> String',
GC::Profiler, :result
end

def test_total_time
assert_send_type(
"() -> Integer",
GC, :total_time
)
assert_send_type '() -> Float',
GC::Profiler, :total_time
end
end

0 comments on commit d756270

Please sign in to comment.