Skip to content

Commit

Permalink
Unregister PPP when no longer a PPP (iseq)
Browse files Browse the repository at this point in the history
This commit allows the GC to detect if a registered PPP is no longer a
PPP and remove it from the PPP list.  Notably, iseq becomes a PPP since
ISEQ_COMPILE_DATA_ALLOC, and stops being a PPP after
ISEQ_COMPILE_DATA_CLEAR.
  • Loading branch information
wks committed Oct 16, 2024
1 parent 8c96eaf commit 0511ec8
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 14 deletions.
2 changes: 1 addition & 1 deletion gc/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -2269,7 +2269,7 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
#if USE_MMTK
if (rb_mmtk_enabled_p()) {
rb_mmtk_maybe_register_obj_free_candidate(obj);
rb_mmtk_maybe_register_ppp(obj);
rb_mmtk_maybe_register_initial_ppp(obj);
}
#endif

Expand Down
8 changes: 4 additions & 4 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
#include "internal/mmtk_macros.h"

#if USE_MMTK
#include "internal/mmtk.h" // For mmtk_register_ppp
#include "internal/mmtk_support.h" // For rb_mmtk_register_ppp
#endif

/* Flags of RHash
Expand Down Expand Up @@ -4458,7 +4458,7 @@ rb_hash_compare_by_id(VALUE hash)

#if USE_MMTK
if (rb_mmtk_enabled_p()) {
mmtk_register_ppp((MMTk_ObjectReference)hash);
rb_mmtk_register_ppp(hash);
}
#endif

Expand Down Expand Up @@ -4486,7 +4486,7 @@ rb_ident_hash_new(void)

#if USE_MMTK
if (rb_mmtk_enabled_p()) {
mmtk_register_ppp((MMTk_ObjectReference)hash);
rb_mmtk_register_ppp(hash);
}
#endif

Expand All @@ -4501,7 +4501,7 @@ rb_ident_hash_new_with_size(st_index_t size)

#if USE_MMTK
if (rb_mmtk_enabled_p()) {
mmtk_register_ppp((MMTk_ObjectReference)hash);
rb_mmtk_register_ppp(hash);
}
#endif

Expand Down
1 change: 1 addition & 0 deletions internal/mmtk.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ typedef struct MMTk_RubyUpcalls {
void (*scan_final_jobs_roots)(void);
void (*scan_roots_in_mutator_thread)(MMTk_VMMutatorThread mutator_tls,
MMTk_VMWorkerThread worker_tls);
bool (*is_no_longer_ppp)(MMTk_ObjectReference);
void (*scan_object_ruby_style)(MMTk_ObjectReference object);
void (*call_gc_mark_children)(MMTk_ObjectReference object);
void (*call_obj_free)(MMTk_ObjectReference object);
Expand Down
3 changes: 2 additions & 1 deletion internal/mmtk_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ bool rb_mmtk_object_moved_p(VALUE obj);
VALUE rb_mmtk_maybe_forward(VALUE object);

// PPP support
void rb_mmtk_maybe_register_ppp(VALUE obj);
void rb_mmtk_register_ppp(VALUE obj);
void rb_mmtk_maybe_register_initial_ppp(VALUE obj);

// Finalization and exiting
void rb_mmtk_maybe_register_obj_free_candidate(VALUE obj);
Expand Down
17 changes: 17 additions & 0 deletions iseq.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
#include "insns.inc"
#include "insns_info.inc"

// Conditional compilation macros for MMTk.
#include "internal/mmtk_macros.h"

VALUE rb_cISeq;
static VALUE iseqw_new(const rb_iseq_t *iseq);
static const rb_iseq_t *iseqw_check(VALUE iseqw);
Expand Down Expand Up @@ -440,6 +443,20 @@ rb_iseq_mark_and_move(rb_iseq_t *iseq, bool reference_updating)
RUBY_MARK_LEAVE("iseq");
}

#if USE_MMTK
void rb_mmtk_iseq_register_ppp(rb_iseq_t *iseq)
{
WHEN_USING_MMTK({
rb_mmtk_register_ppp((VALUE)iseq);
})
}

bool rb_mmtk_iseq_is_no_longer_ppp(rb_iseq_t *iseq)
{
return !FL_TEST_RAW((VALUE)iseq, ISEQ_USE_COMPILE_DATA);
}
#endif

static size_t
param_keyword_size(const struct rb_iseq_param_keyword *pkw)
{
Expand Down
9 changes: 9 additions & 0 deletions iseq.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ struct iseq_compile_data {
#endif
};

#if USE_MMTK
void rb_mmtk_iseq_register_ppp(rb_iseq_t *iseq);
bool rb_mmtk_iseq_is_no_longer_ppp(rb_iseq_t *iseq);
#endif

static inline struct iseq_compile_data *
ISEQ_COMPILE_DATA(const rb_iseq_t *iseq)
{
Expand All @@ -152,6 +157,10 @@ ISEQ_COMPILE_DATA_ALLOC(rb_iseq_t *iseq)
{
iseq->aux.compile_data = ZALLOC(struct iseq_compile_data);
iseq->flags |= ISEQ_USE_COMPILE_DATA;

#if USE_MMTK
rb_mmtk_iseq_register_ppp(iseq);
#endif
}

static inline void
Expand Down
57 changes: 49 additions & 8 deletions mmtk_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "internal/imemo.h"
#include "internal/thread.h"
#include "internal/variable.h"
#include "iseq.h"
#include "ruby/ruby.h"
#include "ractor_core.h"
#include "vm_core.h"
Expand Down Expand Up @@ -633,16 +634,20 @@ rb_mmtk_maybe_forward(VALUE value)
// PPP support
////////////////////////////////////////////////////////////////////////////////

// Return true if an object is a PPP when allocated.
// This does not include PPP types that may become PPPs during its lifetime, such as
// - Hash (when starting to compare keys by identity)
// - iseq (since ISEQ_COMPILE_DATA_ALLOC)
static bool
rb_mmtk_is_ppp(VALUE obj) {
rb_mmtk_is_initially_ppp(VALUE obj)
{
RUBY_ASSERT(!rb_special_const_p(obj));

switch (RB_BUILTIN_TYPE(obj)) {
case T_DATA:
return true;
case T_IMEMO:
switch (imemo_type(obj)) {
case imemo_iseq:
case imemo_tmpbuf:
case imemo_ast:
case imemo_ifunc:
Expand All @@ -657,6 +662,32 @@ rb_mmtk_is_ppp(VALUE obj) {
}
}

// Return true if a registered PPP is no longer a PPP. Return false otherwise.
// The return value doesn't matter for objects that are not registered as PPP.
static bool
rb_mmtk_is_no_longer_ppp(MMTk_ObjectReference objref)
{
VALUE obj = (VALUE)objref;
RUBY_ASSERT(!rb_special_const_p(obj));

switch (RB_BUILTIN_TYPE(obj)) {
case T_IMEMO:
switch (imemo_type(obj)) {
case imemo_iseq: {
if (rb_mmtk_iseq_is_no_longer_ppp((rb_iseq_t*)obj)) {
return true;
}
}
default:
break;
}
default:
break;
}

return false;
}

static void
rb_mmtk_flush_ppp_buffer(struct rb_mmtk_values_buffer *buffer)
{
Expand All @@ -666,14 +697,23 @@ rb_mmtk_flush_ppp_buffer(struct rb_mmtk_values_buffer *buffer)
}

void
rb_mmtk_maybe_register_ppp(VALUE obj) {
rb_mmtk_register_ppp(VALUE obj)
{
RUBY_ASSERT(!rb_special_const_p(obj));

if (rb_mmtk_is_ppp(obj)) {
struct rb_mmtk_values_buffer *buffer = &rb_mmtk_mutator_local.ppp_buffer;
if (rb_mmtk_values_buffer_append(buffer, obj)) {
rb_mmtk_flush_ppp_buffer(buffer);
}
struct rb_mmtk_values_buffer *buffer = &rb_mmtk_mutator_local.ppp_buffer;
if (rb_mmtk_values_buffer_append(buffer, obj)) {
rb_mmtk_flush_ppp_buffer(buffer);
}
}

void
rb_mmtk_maybe_register_initial_ppp(VALUE obj)
{
RUBY_ASSERT(!rb_special_const_p(obj));

if (rb_mmtk_is_initially_ppp(obj)) {
rb_mmtk_register_ppp(obj);
}
}

Expand Down Expand Up @@ -1661,6 +1701,7 @@ MMTk_RubyUpcalls ruby_upcalls = {
rb_mmtk_scan_misc_roots,
rb_mmtk_scan_final_jobs_roots,
rb_mmtk_scan_roots_in_mutator_thread,
rb_mmtk_is_no_longer_ppp,
rb_mmtk_scan_object_ruby_style,
rb_mmtk_call_gc_mark_children,
rb_mmtk_call_obj_free,
Expand Down

0 comments on commit 0511ec8

Please sign in to comment.