Skip to content

Conversation

goyox86
Copy link
Collaborator

@goyox86 goyox86 commented Feb 6, 2025

Solves #447

Implemented:

  • StableApiDefinition::gc_adjust_memory_usage.
  • StableApiDefinition::gc_writebarrier.
  • StableApiDefinition::gc_writebarrier_unprotect.

Note:

I have to tweak the testing macros so it would allow multiple arguments for the data_builder, in the meanwhile I just expanded the macro and tweaked it manually.

@goyox86 goyox86 force-pushed the goyox86/stable-api-gc-methods branch from deb0a59 to cf7c3d1 Compare February 6, 2025 17:19
@goyox86
Copy link
Collaborator Author

goyox86 commented Feb 6, 2025

Looking at Truffle's failure I think they don't have a C API stub for impl_gc_writebarrier, impl_gc_writebarrier_unprotect.

@goyox86 goyox86 requested a review from ianks February 7, 2025 10:12
@eregon
Copy link

eregon commented Mar 7, 2025

Sorry for the late reply, @nirvdrum pinged me today about this.

rb_gc_adjust_memory_usage() is defined on TruffleRuby so that one is fine.

For rb_gc_writebarrier() and rb_gc_writebarrier_unprotect() they are documented in https://github.com/ruby/ruby/blob/17f6a689629ec3507a79fc156833f329dc641bed/include/ruby/internal/gc.h#L660-L675
Copying it here for convenience:

/**
 * This  is  the  implementation  of  #RB_OBJ_WRITE().   People  don't  use  it
 * directly.
 *
 * @param[in]   old    An object that points to `young`.
 * @param[out]  young  An object that is referenced from `old`.
 */
void rb_gc_writebarrier(VALUE old, VALUE young);

/**
 * This is the  implementation of #RB_OBJ_WB_UNPROTECT().  People  don't use it
 * directly.
 *
 * @param[out] obj  An object that does not participate in WB.
 */
void rb_gc_writebarrier_unprotect(VALUE obj);

So those should not be called directly according to those docs, and instead RB_OBJ_WRITE/RB_OBJ_WB_UNPROTECT should be used.
RB_OBJ_WRITE is supported on TruffleRuby. Can rb-sys use/expose that instead?
If not, see https://github.com/oracle/truffleruby/blob/b3a2cec22635f55b74f350bc59a9fbcca0e4ac3e/lib/cext/include/ruby/internal/gc.h#L791-L805 i.e. TruffleRuby has an empty rb_obj_written() and so rb_gc_writebarrier() if it existed would be empty too.

RB_OBJ_WB_UNPROTECT is not yet supported on TruffleRuby, I believe because so far we have not found any extension using that (do you know any extension actually using it?).
FWIW the docs of it:

/**
 * Asserts that the passed object is  not fenced by write barriers.  Objects of
 * such  property do  not contribute  to  generational GCs.   They are  scanned
 * always.
 *
 * @param[out]  x  An object that would not be protected by the barrier.
 */
#define RB_OBJ_WB_UNPROTECT(x) rb_obj_wb_unprotect(x, __FILE__, __LINE__)

In general TruffleRuby currently never moves any native memory, and does not use a generational GC for it, so currently has no write barriers for writes in C extensions.

To be future-proof though it would be best to test if these functions exist (e.g. have_func('rb_gc_writebarrier') in extconf.rb). And if they don't then assuming they are empty are OK for write-barrier-related functions.

@eregon
Copy link

eregon commented Mar 10, 2025

Also don't hesitate to ping me and/or @andrykonchin on TruffleRuby-related issues in rb-sys.
We are happy rb-sys has truffleruby in CI now and want to help to keep it there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants