diff --git a/racket/src/racket/src/mzmarksrc.c b/racket/src/racket/src/mzmarksrc.c index a4bf998059..c2c222894c 100644 --- a/racket/src/racket/src/mzmarksrc.c +++ b/racket/src/racket/src/mzmarksrc.c @@ -1592,7 +1592,8 @@ place_async_channel_val { gcMARK2(pac->msg_chains, gc); gcMARK2(pac->wakeup_signal, gc); - /* mark master-allocated objects within each messages: */ + /* mark master-allocated objects within each messages; the + raw pairs that form the list are embedded in each message block */ j = pac->out; sz = pac->size; for (i = pac->count; i--; ) { diff --git a/racket/src/racket/src/place.c b/racket/src/racket/src/place.c index e60f5baa5c..f76094ae6d 100644 --- a/racket/src/racket/src/place.c +++ b/racket/src/racket/src/place.c @@ -3012,11 +3012,12 @@ Scheme_Place_Async_Channel *place_async_channel_create() { #endif ch = GC_master_malloc_tagged(sizeof(Scheme_Place_Async_Channel)); + ch->so.type = scheme_place_async_channel_type; + msgs = GC_master_malloc(sizeof(Scheme_Object*) * 8); msg_memory = GC_master_malloc(sizeof(void*) * 8); msg_chains = GC_master_malloc(sizeof(Scheme_Object*) * 8); - ch->so.type = scheme_place_async_channel_type; ch->in = 0; ch->out = 0; ch->count = 0; @@ -3186,6 +3187,8 @@ static void place_async_send(Scheme_Place_Async_Channel *ch, Scheme_Object *uo) int cnt; o = places_serialize(uo, &msg_memory, &master_chain, &invalid_object); + /* uo needs to stay live until `master_chain` is registered in `ch` */ + if (!o) { if (invalid_object) { scheme_contract_error("place-channel-put", @@ -3245,6 +3248,9 @@ static void place_async_send(Scheme_Place_Async_Channel *ch, Scheme_Object *uo) maybe_report_message_size(ch); } + /* make sure `uo` is treated as live until here: */ + if (!uo) scheme_signal_error("?"); + { intptr_t msg_size; msg_size = GC_message_allocator_size(msg_memory); diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index be48d6a773..b534d466b8 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -4114,7 +4114,7 @@ typedef struct Scheme_Place_Async_Channel { #endif Scheme_Object **msgs; void **msg_memory; - Scheme_Object **msg_chains; + Scheme_Object **msg_chains; /* lists embedded in message blocks; specially traversed during GC */ intptr_t mem_size; intptr_t reported_size; /* size reported to master GC; avoid reporting too often */ void *wakeup_signal;