#define HANDLE_PTR(ptr,obj) do { \
void *__old = *(ptr); \
SGEN_OBJECT_LAYOUT_STATISTICS_MARK_BITMAP ((obj), (ptr)); \
+ binary_protocol_scan_process_reference ((obj), (ptr), __old); \
if (__old && FOLLOW_OBJECT (__old)) { \
void *__copy; \
PREFETCH_DYNAMIC_HEAP (__old); \
#undef HANDLE_PTR
#define HANDLE_PTR(ptr,obj) do { \
void *__old = *(ptr); \
+ binary_protocol_scan_process_reference ((obj), (ptr), __old); \
if (__old) { \
gboolean __still_in_nursery = COPY_OR_MARK_FUNCTION_NAME ((ptr), __old, queue); \
if (G_UNLIKELY (__still_in_nursery && !sgen_ptr_in_nursery ((ptr)) && !SGEN_OBJECT_IS_CEMENTED (*(ptr)))) { \
#define HANDLE_PTR(ptr,obj) do { \
void *__old = *(ptr); \
SGEN_OBJECT_LAYOUT_STATISTICS_MARK_BITMAP ((obj), (ptr)); \
+ binary_protocol_scan_process_reference ((obj), (ptr), __old); \
if (__old) { \
SERIAL_COPY_OBJECT_FROM_OBJ ((ptr), queue); \
SGEN_COND_LOG (9, __old != *(ptr), "Overwrote field at %p with %p (was: %p)", (ptr), *(ptr), __old); \
protocol_entry (SGEN_PROTOCOL_SCAN_VTYPE_BEGIN, &entry, sizeof (SGenProtocolScanVTypeBegin));
}
+void
+binary_protocol_scan_process_reference (gpointer obj, gpointer ptr, gpointer value)
+{
+ SGenProtocolScanProcessReference entry = { obj, ptr, value };
+ protocol_entry (SGEN_PROTOCOL_SCAN_PROCESS_REFERENCE, &entry, sizeof (SGenProtocolScanProcessReference));
+}
+
void
binary_protocol_wbarrier (gpointer ptr, gpointer value, gpointer value_vtable)
{
SGEN_PROTOCOL_MARK,
SGEN_PROTOCOL_SCAN_BEGIN,
SGEN_PROTOCOL_SCAN_VTYPE_BEGIN,
+ SGEN_PROTOCOL_SCAN_PROCESS_REFERENCE,
SGEN_PROTOCOL_WBARRIER,
SGEN_PROTOCOL_GLOBAL_REMSET,
SGEN_PROTOCOL_PTR_UPDATE,
int size;
} SGenProtocolScanVTypeBegin;
+typedef struct {
+ gpointer obj;
+ gpointer ptr;
+ gpointer value;
+} SGenProtocolScanProcessReference;
+
typedef struct {
gpointer ptr;
gpointer value;
void binary_protocol_mark (gpointer obj, gpointer vtable, int size) MONO_INTERNAL;
void binary_protocol_scan_begin (gpointer obj, gpointer vtable, int size) MONO_INTERNAL;
void binary_protocol_scan_vtype_begin (gpointer start, int size) MONO_INTERNAL;
+void binary_protocol_scan_process_reference (gpointer obj, gpointer ptr, gpointer value) MONO_INTERNAL;
void binary_protocol_wbarrier (gpointer ptr, gpointer value, gpointer value_vtable) MONO_INTERNAL;
void binary_protocol_global_remset (gpointer ptr, gpointer value, gpointer value_vtable) MONO_INTERNAL;
void binary_protocol_ptr_update (gpointer ptr, gpointer old_value, gpointer new_value, gpointer vtable, int size) MONO_INTERNAL;
#define binary_protocol_mark(obj, vtable, size)
#define binary_protocol_scan_begin(obj, vtable, size)
#define binary_protocol_scan_vtype_begin(obj, size)
+#define binary_protocol_scan_process_reference(obj, ptr, value)
#define binary_protocol_wbarrier(ptr, value, value_vtable)
#define binary_protocol_global_remset(ptr, value, value_vtable)
#define binary_protocol_ptr_update(ptr, old_value, new_value, vtable, size)
case SGEN_PROTOCOL_MARK: size = sizeof (SGenProtocolMark); break;
case SGEN_PROTOCOL_SCAN_BEGIN: size = sizeof (SGenProtocolScanBegin); break;
case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: size = sizeof (SGenProtocolScanVTypeBegin); break;
+ case SGEN_PROTOCOL_SCAN_PROCESS_REFERENCE: size = sizeof (SGenProtocolScanProcessReference); break;
case SGEN_PROTOCOL_WBARRIER: size = sizeof (SGenProtocolWBarrier); break;
case SGEN_PROTOCOL_GLOBAL_REMSET: size = sizeof (SGenProtocolGlobalRemset); break;
case SGEN_PROTOCOL_PTR_UPDATE: size = sizeof (SGenProtocolPtrUpdate); break;
printf ("scan_vtype_begin obj %p size %d\n", entry->obj, entry->size);
break;
}
+ case SGEN_PROTOCOL_SCAN_PROCESS_REFERENCE: {
+ SGenProtocolScanProcessReference *entry = data;
+ printf ("scan_process_reference obj %p ptr %p value %p\n", entry->obj, entry->ptr, entry->value);
+ break;
+ }
case SGEN_PROTOCOL_WBARRIER: {
SGenProtocolWBarrier *entry = data;
printf ("wbarrier ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
SGenProtocolScanVTypeBegin *entry = data;
return matches_interval (ptr, entry->obj, entry->size);
}
+ case SGEN_PROTOCOL_SCAN_PROCESS_REFERENCE: {
+ SGenProtocolScanProcessReference *entry = data;
+ return ptr == entry->obj || ptr == entry->ptr || ptr == entry->value;
+ }
case SGEN_PROTOCOL_WBARRIER: {
SGenProtocolWBarrier *entry = data;
return ptr == entry->ptr || ptr == entry->value;