Commit graph

6 commits

Author SHA1 Message Date
Peter Zhu
c91ec7ba1e Remove rb_gc_impl_objspace_mark
It's not necessary for the GC implementation to call rb_gc_mark_roots
which calls back into the GC implementation's rb_gc_impl_objspace_mark.
2024-08-09 10:27:40 -04:00
Alan Wu
0ada02abe2 Put the default GC implementation back into gc.o
We discovered that having gc.o and gc_impl.o in separate translation
units diminishes codegen quality with GCC 11 on x86-64. This commit
solves that problem by including default/gc.c into gc.c, letting the
optimizer have visibility into the body of functions again in builds
not using link-time optimization, which are common.

This effectively restores things to the way they were before
[Feature #20470] from the optimizer's perspective while maintaining the
ability to build gc/default.c as a DSO.

There were a few functions duplicated across gc.c and gc/default.c.
Extract them and put them into gc/gc.h.
2024-07-26 11:44:34 -04:00
Peter Zhu
4b05d2dbb0 Make rb_gc_impl_undefine_finalizer return void 2024-07-19 08:53:32 -04:00
Peter Zhu
4b0244a1f3 Rename GC_IMPL_H macro to GC_GC_IMPL_H 2024-07-15 08:57:14 -04:00
Matt Valentine-House
f543c68e1c Provide GC.config to disable major GC collections
This feature provides a new method `GC.config` that configures internal
GC configuration variables provided by an individual GC implementation.

Implemented in this PR is the option `full_mark`: a boolean value that
will determine whether the Ruby GC is allowed to run a major collection
while the process is running.

It has the following semantics

This feature configures Ruby's GC to only run minor GC's. It's designed
to give users relying on Out of Band GC complete control over when a
major GC is run. Configuring `full_mark: false` does two main things:

* Never runs a Major GC. When the heap runs out of space during a minor
  and when a major would traditionally be run, instead we allocate more
  heap pages, and mark objspace as needing a major GC.
* Don't increment object ages. We don't promote objects during GC, this
  will cause every object to be scanned on every minor. This is an
  intentional trade-off between minor GC's doing more work every time,
  and potentially promoting objects that will then never be GC'd.

The intention behind not aging objects is that users of this feature
should use a preforking web server, or some other method of pre-warming
the oldgen (like Nakayoshi fork)before disabling Majors. That way most
objects that are going to be old will have already been promoted.

This will interleave major and minor GC collections in exactly the same
what that the Ruby GC runs in versions previously to this. This is the
default behaviour.

* This new method has the following extra semantics:
  - `GC.config` with no arguments returns a hash of the keys of the
    currently configured GC
  - `GC.config` with a key pair (eg. `GC.config(full_mark: true)` sets
    the matching config key to the corresponding value and returns the
    entire known config hash, including the new values. If the key does
    not exist, `nil` is returned

* When a minor GC is run, Ruby sets an internal status flag to determine
  whether the next GC will be a major or a minor. When `full_mark:
  false` this flag is ignored and every GC will be a minor.

  This status flag can be accessed at
  `GC.latest_gc_info(:needs_major_by)`. Any value other than `nil` means
  that the next collection would have been a major.

  Thus it's possible to use this feature to check at a predetermined
  time, whether a major GC is necessary and run one if it is. eg. After
  a request has finished processing.

  ```ruby
  if GC.latest_gc_info(:needs_major_by)
    GC.start(full_mark: true)
  end
  ```

[Feature #20443]
2024-07-12 14:43:33 +01:00
Peter Zhu
00d0ddd48a Add gc/gc_impl.h for GC implementation headers 2024-07-12 08:41:33 -04:00