Skip to content

Commit 69db488

Browse files
committed
Assert valid object reference in write barrier
Added a feature to assert the source and the target objects are valid object references in write barriers. It is controlled by a macro so that it can be enabled in release build, too.
1 parent 68d95d7 commit 69db488

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

Diff for: compile.c

+9
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
#include "insns.inc"
4949
#include "insns_info.inc"
5050

51+
// conditional compilation macros for MMTk
52+
#include "internal/mmtk_macros.h"
53+
5154
#define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG))
5255
#define FIXNUM_OR(n, i) ((n)|INT2FIX(i))
5356

@@ -5420,7 +5423,13 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
54205423
ci = ci_flag_set(iseq, ci, VM_CALL_ARGS_SPLAT_MUT);
54215424
}
54225425
OPERAND_AT(iobj, 0) = (VALUE)ci;
5426+
WHEN_USING_MMTK2({
5427+
// iobj is not a heap object, so it is technically incorrect to use it as the
5428+
// argument to the write barrier.
5429+
rb_gc_writebarrier_remember((VALUE)iseq);
5430+
}, {
54235431
RB_OBJ_WRITTEN(iseq, Qundef, iobj);
5432+
});
54245433

54255434
/* Given: h[*a], h[*b, 1] = ary
54265435
* h[*a] uses splatarray false and does not set VM_CALL_ARGS_SPLAT_MUT,

Diff for: gc/default.c

+31
Original file line numberDiff line numberDiff line change
@@ -6913,6 +6913,21 @@ void
69136913
rb_gc_impl_writebarrier(void *objspace_ptr, VALUE a, VALUE b)
69146914
{
69156915
#if USE_MMTK
6916+
// Define the MMTK_WB_ASSERT_VO macro in the compiler command line to enable the assertions.
6917+
// Whenever writing an object field using the write barrier, it will assert the source object
6918+
// and the new value are valid objects.
6919+
#ifdef MMTK_WB_ASSERT_VO
6920+
if (rb_mmtk_enabled_p()) {
6921+
if (!rb_mmtk_is_valid_objref(a)) {
6922+
rb_bug("a is not MMTk object: %p", (void*)a);
6923+
}
6924+
if (!SPECIAL_CONST_P(b)) {
6925+
if (!rb_mmtk_is_valid_objref(b)) {
6926+
rb_bug("b is not MMTk object: %p", (void*)b);
6927+
}
6928+
}
6929+
}
6930+
#endif
69166931
if (rb_mmtk_enabled_p() && rb_mmtk_use_barrier) {
69176932
mmtk_object_reference_write_post(GET_THREAD()->mutator, (MMTk_ObjectReference)a);
69186933
return;
@@ -6958,6 +6973,14 @@ void
69586973
rb_gc_impl_writebarrier_unprotect(void *objspace_ptr, VALUE obj)
69596974
{
69606975
#if USE_MMTK
6976+
// Define the MMTK_WB_ASSERT_VO macro in the compiler command line to enable the assertions.
6977+
#ifdef MMTK_WB_ASSERT_VO
6978+
if (rb_mmtk_enabled_p()) {
6979+
if (!rb_mmtk_is_valid_objref(obj)) {
6980+
rb_bug("Attempted to unprotect invalid objref: %p", (void*)obj);
6981+
}
6982+
}
6983+
#endif
69616984
if (rb_mmtk_enabled_p()) {
69626985
mmtk_register_wb_unprotected_object((MMTk_ObjectReference)obj);
69636986
return;
@@ -7013,6 +7036,14 @@ void
70137036
rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj)
70147037
{
70157038
#if USE_MMTK
7039+
// Define the MMTK_WB_ASSERT_VO macro in the compiler command line to enable the assertions.
7040+
#ifdef MMTK_WB_ASSERT_VO
7041+
if (rb_mmtk_enabled_p()) {
7042+
if (!rb_mmtk_is_valid_objref(obj)) {
7043+
rb_bug("Attempt to remember invalid invalid objref: %p", (void*)obj);
7044+
}
7045+
}
7046+
#endif
70167047
if (rb_mmtk_enabled_p() && rb_mmtk_use_barrier) {
70177048
mmtk_object_reference_write_post(GET_THREAD()->mutator, (MMTk_ObjectReference)obj);
70187049
return;

Diff for: internal/mmtk_support.h

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ bool rb_mmtk_is_mmtk_worker(void);
121121
bool rb_mmtk_is_mutator(void);
122122
void rb_mmtk_assert_mmtk_worker(void);
123123
void rb_mmtk_assert_mutator(void);
124+
bool rb_mmtk_is_valid_objref(VALUE obj);
125+
124126

125127
// Vanilla GC timing
126128
void rb_mmtk_gc_probe(bool enter);

Diff for: mmtk_support.c

+6
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,12 @@ rb_mmtk_panic_if_multiple_ractor(const char *msg)
13531353
}
13541354
}
13551355

1356+
bool
1357+
rb_mmtk_is_valid_objref(VALUE obj)
1358+
{
1359+
return obj != 0 && obj % sizeof(VALUE) == 0 && mmtk_is_mmtk_object((MMTk_Address)obj);
1360+
}
1361+
13561362
////////////////////////////////////////////////////////////////////////////////
13571363
// Vanilla GC timing
13581364
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)