+static gboolean
+is_vtable_match (gpointer ptr, int type, void *data)
+{
+ switch (TYPE (type)) {
+ case SGEN_PROTOCOL_ALLOC:
+ case SGEN_PROTOCOL_ALLOC_PINNED:
+ case SGEN_PROTOCOL_ALLOC_DEGRADED: {
+ SGenProtocolAlloc *entry = data;
+ return ptr == entry->vtable;
+ }
+ case SGEN_PROTOCOL_COPY: {
+ SGenProtocolCopy *entry = data;
+ return ptr == entry->vtable;
+ }
+ case SGEN_PROTOCOL_PIN: {
+ SGenProtocolPin *entry = data;
+ return ptr == entry->vtable;
+ }
+ case SGEN_PROTOCOL_SCAN_BEGIN: {
+ SGenProtocolScanBegin *entry = data;
+ return ptr == entry->vtable;
+ }
+ case SGEN_PROTOCOL_WBARRIER: {
+ SGenProtocolWBarrier *entry = data;
+ return ptr == entry->value_vtable;
+ }
+ case SGEN_PROTOCOL_GLOBAL_REMSET: {
+ SGenProtocolGlobalRemset *entry = data;
+ return ptr == entry->value_vtable;
+ }
+ case SGEN_PROTOCOL_PTR_UPDATE: {
+ SGenProtocolPtrUpdate *entry = data;
+ return ptr == entry->vtable;
+ }
+ case SGEN_PROTOCOL_CLEANUP: {
+ SGenProtocolCleanup *entry = data;
+ return ptr == entry->vtable;
+ }
+ case SGEN_PROTOCOL_MISSING_REMSET: {
+ SGenProtocolMissingRemset *entry = data;
+ return ptr == entry->obj_vtable || ptr == entry->value_vtable;
+ }
+ case SGEN_PROTOCOL_CEMENT: {
+ SGenProtocolCement *entry = data;
+ return ptr == entry->vtable;
+ }
+ default:
+ return FALSE;
+ }
+}
+