From c9c02f3fb00a5ade104bf5a9af08a959fc2eb1c9 Mon Sep 17 00:00:00 2001 From: Kevin Tew Date: Thu, 12 May 2011 05:10:20 -0600 Subject: [PATCH] duplicate and cycle detection for places_deserialize_worker --- collects/tests/racket/place-channel.rkt | 3 +- src/racket/src/place.c | 66 ++++++++++++++++++++----- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/collects/tests/racket/place-channel.rkt b/collects/tests/racket/place-channel.rkt index 4972bdaa2c..226ff6fdb9 100644 --- a/collects/tests/racket/place-channel.rkt +++ b/collects/tests/racket/place-channel.rkt @@ -236,7 +236,8 @@ (test-long (lambda (x) 3) "Listof ints") (test-long (lambda (x) #(1 2)) "Listof vectors") (test-long (lambda (x) (intern-num-sym (modulo x 1000))) "Listof symbols") - (test-long (lambda (x) #s(clown "Binky" "pie")) "Listof prefabs")) + (test-long (lambda (x) #s(clown "Binky" "pie")) "Listof prefabs") + (test-long (lambda (x) (read (open-input-string "#0=(#0# . #0#)"))) "Listof cycles")) ;(report-errs) diff --git a/src/racket/src/place.c b/src/racket/src/place.c index 97c58658d7..fab95c1e14 100644 --- a/src/racket/src/place.c +++ b/src/racket/src/place.c @@ -1665,23 +1665,27 @@ Scheme_Object *scheme_places_deep_copy_to_master(Scheme_Object *so) { } #ifdef DO_STACK_CHECK -static void places_deserialize_worker(Scheme_Object **pso); +static void places_deserialize_worker(Scheme_Object **pso, Scheme_Hash_Table **ht); static Scheme_Object *places_deserialize_worker_k(void) { Scheme_Thread *p = scheme_current_thread; - Scheme_Object *pso = (Scheme_Object **)p->ku.k.p1; + Scheme_Object *pso = (Scheme_Object *)p->ku.k.p1; + Scheme_Hash_Table*ht = (Scheme_Hash_Table *)p->ku.k.p2; p->ku.k.p1 = NULL; + p->ku.k.p2 = NULL; - places_deserialize_worker(&pso); + places_deserialize_worker(&pso, &ht); + p = scheme_current_thread; + p->ku.k.p1 = ht; return pso; } #endif -static void places_deserialize_worker(Scheme_Object **pso) +static void places_deserialize_worker(Scheme_Object **pso, Scheme_Hash_Table **ht) { Scheme_Object *so; Scheme_Object *tmp; @@ -1695,10 +1699,15 @@ static void places_deserialize_worker(Scheme_Object **pso) { # include "mzstkchk.h" { - Scheme_Thread *p = scheme_current_thread; + Scheme_Thread *p; + p = scheme_current_thread; p->ku.k.p1 = *pso; + p->ku.k.p2 = *ht; tmp = scheme_handle_stack_overflow(places_deserialize_worker_k); *pso = tmp; + p = scheme_current_thread; + *ht = p->ku.k.p1; + p->ku.k.p1 = NULL; return; } } @@ -1736,35 +1745,69 @@ static void places_deserialize_worker(Scheme_Object **pso) *pso = tmp; break; case scheme_pair_type: + if (*ht) { + if ((st = (Scheme_Structure *) scheme_hash_get(*ht, so))) + break; + else + scheme_hash_set(*ht, so, so); + } + else { + tmp = (Scheme_Object *) scheme_make_hash_table(SCHEME_hash_ptr); + *ht = (Scheme_Hash_Table *) tmp; + scheme_hash_set(*ht, so, so); + } tmp = SCHEME_CAR(so); - places_deserialize_worker(&tmp); + places_deserialize_worker(&tmp, ht); SCHEME_CAR(so) = tmp; tmp = SCHEME_CDR(so); - places_deserialize_worker(&tmp); + places_deserialize_worker(&tmp, ht); SCHEME_CDR(so) = tmp; break; case scheme_vector_type: + if (*ht) { + if ((st = (Scheme_Structure *) scheme_hash_get(*ht, so))) + break; + else + scheme_hash_set(*ht, so, so); + } + else { + tmp = (Scheme_Object *) scheme_make_hash_table(SCHEME_hash_ptr); + *ht = (Scheme_Hash_Table *) tmp; + scheme_hash_set(*ht, so, so); + } size = SCHEME_VEC_SIZE(so); for (i = 0; i num_slots; tmp = sst->prefab_key; - places_deserialize_worker(&tmp); + places_deserialize_worker(&tmp, ht); sst->prefab_key = tmp; stype = scheme_lookup_prefab_type(sst->prefab_key, size); st = (Scheme_Structure *) scheme_make_blank_prefab_struct_instance(stype); + scheme_hash_set(*ht, so, (Scheme_Object *) st); for (i = 0; i slots[i]; - places_deserialize_worker(&tmp); + places_deserialize_worker(&tmp, ht); st->slots[i] = tmp; } *pso = (Scheme_Object *) st; @@ -1808,10 +1851,11 @@ Scheme_Object *scheme_places_deserialize(Scheme_Object *so, void *msg_memory) { GC_dispose_short_message_allocator(msg_memory); } else { + Scheme_Object *ht = NULL; GC_adopt_message_allocator(msg_memory); #if !defined(SHARED_TABLES) new_so = so; - places_deserialize_worker(&new_so); + places_deserialize_worker(&new_so, (Scheme_Hash_Table **) &ht); #endif } return new_so;