Skip to content

Commit 0321aca

Browse files
committed
Add vm barrier to ObjectSpace.{dump,dump_all}
1 parent ef86908 commit 0321aca

3 files changed

Lines changed: 62 additions & 20 deletions

File tree

ext/objspace/objspace_dump.c

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "ruby/io.h"
3131
#include "vm_callinfo.h"
3232
#include "vm_core.h"
33+
#include "vm_sync.h"
3334

3435
RUBY_EXTERN const char ruby_hexdigits[];
3536

@@ -776,15 +777,23 @@ static VALUE
776777
objspace_dump(VALUE os, VALUE obj, VALUE output)
777778
{
778779
struct dump_config dc = {0,};
779-
if (!RB_SPECIAL_CONST_P(obj)) {
780-
dc.cur_page_slot_size = rb_gc_obj_slot_size(obj);
781-
}
780+
VALUE result = Qnil;
781+
RB_VM_LOCK_LOCK();
782+
{
783+
rb_vm_barrier();
784+
785+
if (!RB_SPECIAL_CONST_P(obj)) {
786+
dc.cur_page_slot_size = rb_gc_obj_slot_size(obj);
787+
}
782788

783-
dump_output(&dc, output, Qnil, Qnil, Qnil);
789+
dump_output(&dc, output, Qnil, Qnil, Qnil);
784790

785-
dump_object(obj, &dc);
791+
dump_object(obj, &dc);
786792

787-
return dump_result(&dc);
793+
result = dump_result(&dc);
794+
}
795+
RB_VM_LOCK_UNLOCK();
796+
return result;
788797
}
789798

790799
static void
@@ -840,22 +849,30 @@ static VALUE
840849
objspace_dump_all(VALUE os, VALUE output, VALUE full, VALUE since, VALUE shapes)
841850
{
842851
struct dump_config dc = {0,};
843-
dump_output(&dc, output, full, since, shapes);
852+
VALUE result = Qnil;
853+
RB_VM_LOCK_LOCK();
854+
{
855+
rb_vm_barrier();
844856

845-
if (!dc.partial_dump || dc.since == 0) {
846-
/* dump roots */
847-
rb_objspace_reachable_objects_from_root(root_obj_i, &dc);
848-
if (dc.roots) dump_append(&dc, "]}\n");
849-
}
857+
dump_output(&dc, output, full, since, shapes);
850858

851-
if (RTEST(shapes)) {
852-
rb_shape_each_shape_id(shape_id_i, &dc);
853-
}
859+
if (!dc.partial_dump || dc.since == 0) {
860+
/* dump roots */
861+
rb_objspace_reachable_objects_from_root(root_obj_i, &dc);
862+
if (dc.roots) dump_append(&dc, "]}\n");
863+
}
854864

855-
/* dump all objects */
856-
rb_objspace_each_objects(heap_i, &dc);
865+
if (RTEST(shapes)) {
866+
rb_shape_each_shape_id(shape_id_i, &dc);
867+
}
857868

858-
return dump_result(&dc);
869+
/* dump all objects */
870+
rb_objspace_each_objects(heap_i, &dc);
871+
872+
result = dump_result(&dc);
873+
}
874+
RB_VM_LOCK_UNLOCK();
875+
return result;
859876
}
860877

861878
/* :nodoc: */
@@ -866,14 +883,17 @@ objspace_dump_shapes(VALUE os, VALUE output, VALUE shapes)
866883
dump_output(&dc, output, Qfalse, Qnil, shapes);
867884

868885
if (RTEST(shapes)) {
869-
rb_shape_each_shape_id(shape_id_i, &dc);
886+
rb_shape_each_shape_id(shape_id_i, &dc); // takes a barrier
870887
}
871888
return dump_result(&dc);
872889
}
873890

874891
void
875892
Init_objspace_dump(VALUE rb_mObjSpace)
876893
{
894+
#ifdef HAVE_RB_EXT_RACTOR_SAFE
895+
rb_ext_ractor_safe(true);
896+
#endif
877897
#undef rb_intern
878898
#if 0
879899
rb_mObjSpace = rb_define_module("ObjectSpace"); /* let rdoc know */

vm_sync.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,3 +291,17 @@ rb_ec_vm_lock_rec_release(const rb_execution_context_t *ec,
291291

292292
VM_ASSERT(recorded_lock_rec == rb_ec_vm_lock_rec(ec));
293293
}
294+
295+
// For extensions, to be used like: RB_VM_LOCK_LOCK()
296+
void
297+
rb_vm_lock_lock(const char *file, int line)
298+
{
299+
rb_vm_lock(file, line);
300+
}
301+
302+
303+
// for extensions, to be used like: RB_VM_LOCK_UNLOCK()
304+
void rb_vm_lock_unlock(const char *file, int line)
305+
{
306+
rb_vm_unlock(file, line);
307+
}

vm_sync.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@ NOINLINE(void rb_vm_lock_enter_body_nb(unsigned int *lev APPEND_LOCATION_ARGS));
2626
NOINLINE(void rb_vm_lock_enter_body(unsigned int *lev APPEND_LOCATION_ARGS));
2727
void rb_vm_lock_leave_body_nb(unsigned int *lev APPEND_LOCATION_ARGS);
2828
void rb_vm_lock_leave_body(unsigned int *lev APPEND_LOCATION_ARGS);
29-
void rb_vm_barrier(void);
29+
30+
// `objspace_dump.c` extension needs these
31+
RUBY_SYMBOL_EXPORT_BEGIN
32+
NOINLINE(void rb_vm_barrier(void));
33+
NOINLINE(void rb_vm_lock_lock(const char *file, int line));
34+
NOINLINE(void rb_vm_lock_unlock(const char *file, int line));
35+
RUBY_SYMBOL_EXPORT_END
36+
#define RB_VM_LOCK_LOCK() rb_vm_lock_lock(__FILE__, __LINE__)
37+
#define RB_VM_LOCK_UNLOCK() rb_vm_lock_unlock(__FILE__, __LINE__)
3038

3139
#if RUBY_DEBUG
3240
// GET_VM()

0 commit comments

Comments
 (0)