mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 08:25:20 +08:00
Fix rb_gc_ever_multi_ractor_p to simply read the latch variable
In single-ractor mode, we don't want foreign_object_p checks to actually run (there can be no foreign objspaces). This foreign_object_p check return false if there was never a (non-main) Ractor created. Previously, rb_gc_ever_multi_ractor_p() was needlessly complex. This change should speed up marking and WB implementations in single-ractor mode.
This commit is contained in:
1 parent
6b15825df0
commit
29264f878a
2 files changed
+12
-15
Notes:
git
2026-10-26 18:30:31 +00:00
No files matched your search
@@ -1083,15 +1083,14 @@ rb_gc_init_objspaces(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Stays true once the process has gone multi-Ractor (rb_multi_ractor_p goes back to
|
||||
* false when the other Ractors finish). Used by verification that spans generation
|
||||
* state built while multiple Ractors ran. */
|
||||
/* Stays true once a second objspace has existed (rb_multi_ractor_p goes back to false
|
||||
* when the other Ractors finish, and is false for the whole window in which the creator
|
||||
* builds the child objspace). */
|
||||
static bool gc_ever_multi_ractor = false;
|
||||
|
||||
bool
|
||||
rb_gc_ever_multi_ractor_p(void)
|
||||
{
|
||||
if (!gc_ever_multi_ractor && rb_multi_ractor_p()) gc_ever_multi_ractor = true;
|
||||
return gc_ever_multi_ractor;
|
||||
}
|
||||
|
||||
@@ -1100,7 +1099,9 @@ rb_gc_ever_multi_ractor_p(void)
|
||||
void *
|
||||
rb_gc_objspace_alloc(void)
|
||||
{
|
||||
gc_ever_multi_ractor = true;
|
||||
/* The one store that ever runs is the first Ractor creation, which is by definition
|
||||
* single-Ractor and so races no reader. */
|
||||
if (!gc_ever_multi_ractor) gc_ever_multi_ractor = true;
|
||||
if (!rb_gc_impl_multi_objspace_p()) {
|
||||
/* One objspace shared by every Ractor. */
|
||||
return rb_gc_get_objspace();
|
||||
|
||||
+6
-10
@@ -1271,6 +1271,8 @@ slot_index_for_offset(size_t offset, uint64_t reciprocal)
|
||||
static inline bool
|
||||
gc_foreign_object_p(const rb_objspace_t *objspace, VALUE obj)
|
||||
{
|
||||
if (RB_LIKELY(!rb_gc_ever_multi_ractor_p())) return false;
|
||||
|
||||
return RB_UNLIKELY(GET_HEAP_OBJSPACE(obj) != objspace);
|
||||
}
|
||||
|
||||
@@ -8501,13 +8503,8 @@ rb_gc_impl_writebarrier(void *objspace_ptr, VALUE a, VALUE b)
|
||||
if (!is_incremental_marking(objspace)) {
|
||||
/* The generational barrier covers old->young edges within one objspace only.
|
||||
* NOTE: we shouldn't even check the age of `a` or `b` if they are in another
|
||||
* objspace, so check locality first. The test is rb_gc_ever_multi_ractor_p, not
|
||||
* rb_gc_multi_ractor_p: a foreign objspace exists before the process is
|
||||
* multi-Ractor (rb_gc_objspace_alloc runs while the creator is still the only
|
||||
* Ractor) and outlives the return to one (a fork parks the others in
|
||||
* zombie_objspaces). */
|
||||
if ((rb_gc_ever_multi_ractor_p() &&
|
||||
(GET_HEAP_OBJSPACE(a) != objspace || GET_HEAP_OBJSPACE(b) != objspace)) ||
|
||||
* objspace, so check locality first. */
|
||||
if (gc_foreign_object_p(objspace, a) || gc_foreign_object_p(objspace, b) ||
|
||||
!RVALUE_OLD_P(objspace, a) || RVALUE_OLD_P(objspace, b)) {
|
||||
// do nothing
|
||||
}
|
||||
@@ -8517,8 +8514,7 @@ rb_gc_impl_writebarrier(void *objspace_ptr, VALUE a, VALUE b)
|
||||
}
|
||||
else {
|
||||
// Shareable objects from different object spaces are kept alive by shareable bits
|
||||
if (rb_gc_ever_multi_ractor_p() &&
|
||||
(GET_HEAP_OBJSPACE(a) != objspace || GET_HEAP_OBJSPACE(b) != objspace)) {
|
||||
if (gc_foreign_object_p(objspace, a) || gc_foreign_object_p(objspace, b)) {
|
||||
// do nothing
|
||||
}
|
||||
else {
|
||||
@@ -8615,7 +8611,7 @@ rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj)
|
||||
|
||||
// Shareable objects from other object spaces don't need to be put on the remembered set
|
||||
// and are only collected during global GC, so not while incremental marking.
|
||||
if (RB_LIKELY(!rb_gc_ever_multi_ractor_p() || GET_HEAP_OBJSPACE(obj) == objspace)) {
|
||||
if (RB_LIKELY(!gc_foreign_object_p(objspace, obj))) {
|
||||
gc_report(1, objspace, "rb_gc_writebarrier_remember: %s\n", rb_obj_info(obj));
|
||||
if (is_incremental_marking(objspace)) {
|
||||
if (RVALUE_BLACK_P(objspace, obj)) {
|
||||
|
||||
Reference in new issue
Block a user