diff options
| author | Keith Packard <keithp@keithp.com> | 2017-12-17 22:22:50 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-12-17 22:22:50 -0800 | 
| commit | e1a6b3bf458f311d832aea7eec34935d42f8efed (patch) | |
| tree | 7141f7e4ae75f23969722f75517f4c39cb623263 | |
| parent | 9d1131da911f7220ac8b6cb7ba5a0afd3deef657 (diff) | |
altos/scheme: Use memory manager mark code to note recursive print
This flags any object being printed and checks before recursing to
avoid infinite loops.
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | src/scheme/ao_scheme.h | 15 | ||||
| -rw-r--r-- | src/scheme/ao_scheme_cons.c | 19 | ||||
| -rw-r--r-- | src/scheme/ao_scheme_frame.c | 1 | ||||
| -rw-r--r-- | src/scheme/ao_scheme_mem.c | 56 | ||||
| -rw-r--r-- | src/scheme/ao_scheme_vector.c | 28 | 
5 files changed, 99 insertions, 20 deletions
| diff --git a/src/scheme/ao_scheme.h b/src/scheme/ao_scheme.h index 48d0149b..cc7f8f1d 100644 --- a/src/scheme/ao_scheme.h +++ b/src/scheme/ao_scheme.h @@ -555,6 +555,21 @@ ao_scheme_move_memory(const struct ao_scheme_type *type, void **ref);  void *  ao_scheme_alloc(int size); +/* Marks an object as being printed, returns 1 if it was already marked */ +int +ao_scheme_print_mark_addr(void *addr); + +int +ao_scheme_print_mark_poly(ao_poly poly); + +/* Notes that printing has started */ +void +ao_scheme_print_start(void); + +/* Notes that printing has ended */ +void +ao_scheme_print_stop(void); +  #define AO_SCHEME_COLLECT_FULL		1  #define AO_SCHEME_COLLECT_INCREMENTAL	0 diff --git a/src/scheme/ao_scheme_cons.c b/src/scheme/ao_scheme_cons.c index 912100a9..0b3cbf80 100644 --- a/src/scheme/ao_scheme_cons.c +++ b/src/scheme/ao_scheme_cons.c @@ -181,16 +181,17 @@ ao_scheme_cons_write(ao_poly c)  	ao_poly			cdr;  	int			first = 1; +	ao_scheme_print_start();  	printf("(");  	while (cons) {  		if (!first)  			printf(" "); -		ao_scheme_poly_write(cons->car); -		cdr = cons->cdr; -		if (cdr == c) { -			printf(" ..."); +		if (ao_scheme_print_mark_addr(cons)) { +			printf("...");  			break;  		} +		ao_scheme_poly_write(cons->car); +		cdr = cons->cdr;  		if (ao_scheme_poly_type(cdr) == AO_SCHEME_CONS) {  			cons = ao_scheme_poly_cons(cdr);  			first = 0; @@ -201,6 +202,7 @@ ao_scheme_cons_write(ao_poly c)  		}  	}  	printf(")"); +	ao_scheme_print_stop();  }  void @@ -209,13 +211,15 @@ ao_scheme_cons_display(ao_poly c)  	struct ao_scheme_cons	*cons = ao_scheme_poly_cons(c);  	ao_poly			cdr; +	ao_scheme_print_start();  	while (cons) { -		ao_scheme_poly_display(cons->car); -		cdr = cons->cdr; -		if (cdr == c) { +		if (ao_scheme_print_mark_addr(cons)) {  			printf("...");  			break;  		} +		ao_scheme_poly_display(cons->car); + +		cdr = cons->cdr;  		if (ao_scheme_poly_type(cdr) == AO_SCHEME_CONS)  			cons = ao_scheme_poly_cons(cdr);  		else { @@ -223,6 +227,7 @@ ao_scheme_cons_display(ao_poly c)  			cons = NULL;  		}  	} +	ao_scheme_print_stop();  }  int diff --git a/src/scheme/ao_scheme_frame.c b/src/scheme/ao_scheme_frame.c index 7f521863..3f4c9157 100644 --- a/src/scheme/ao_scheme_frame.c +++ b/src/scheme/ao_scheme_frame.c @@ -41,7 +41,6 @@ frame_vals_mark(void *addr)  			  ao_scheme_poly_atom(v->atom)->name,  			  MDBG_OFFSET(ao_scheme_ref(v->atom)),  			  MDBG_OFFSET(ao_scheme_ref(v->val)), f); -		MDBG_DO(ao_scheme_poly_write(v->val));  		MDBG_DO(printf("\n"));  	}  } diff --git a/src/scheme/ao_scheme_mem.c b/src/scheme/ao_scheme_mem.c index e7e89b89..c7d6b1f8 100644 --- a/src/scheme/ao_scheme_mem.c +++ b/src/scheme/ao_scheme_mem.c @@ -280,6 +280,10 @@ static const void ** const ao_scheme_cache[] = {  #define AO_SCHEME_BUSY_SIZE	((AO_SCHEME_POOL + 31) / 32) +static int	ao_scheme_printing, ao_scheme_print_cleared; +#if DBG_MEM +static int	ao_scheme_collecting; +#endif  static uint8_t	ao_scheme_busy[AO_SCHEME_BUSY_SIZE];  static uint8_t	ao_scheme_cons_note[AO_SCHEME_BUSY_SIZE];  static uint8_t	ao_scheme_cons_last[AO_SCHEME_BUSY_SIZE]; @@ -550,6 +554,7 @@ ao_scheme_collect(uint8_t style)  	MDBG_MOVE("collect %d\n", ao_scheme_collects[style]);  #endif  	MDBG_DO(ao_scheme_frame_write(ao_scheme_frame_poly(ao_scheme_frame_global))); +	MDBG_DO(++ao_scheme_collecting);  	ao_scheme_reset_stack(); @@ -681,6 +686,7 @@ ao_scheme_collect(uint8_t style)  #if DBG_MEM_STACK  	fprintf(stderr, "max collect stack depth %lu\n", mem_collect_max_depth);  #endif +	MDBG_DO(--ao_scheme_collecting);  	return AO_SCHEME_POOL - ao_scheme_top;  } @@ -1021,3 +1027,53 @@ ao_scheme_frame_fetch(int id)  	save_frame[id] = NULL;  	return frame;  } + +int +ao_scheme_print_mark_addr(void *addr) +{ +	int	offset; + +#if DBG_MEM +	if (ao_scheme_collecting) +		ao_scheme_abort(); +#endif + +	if (!AO_SCHEME_IS_POOL(addr)) +		return 1; + +	if (!ao_scheme_print_cleared) { +		ao_scheme_print_cleared = 1; +		memset(ao_scheme_busy, '\0', sizeof (ao_scheme_busy)); +	} +	offset = pool_offset(addr); +	if (busy(ao_scheme_busy, offset)) +		return 1; +	mark(ao_scheme_busy, offset); +	return 0; +} + +int +ao_scheme_print_mark_poly(ao_poly p) +{ +	uint8_t type = ao_scheme_poly_base_type(p); + +	if (type == AO_SCHEME_INT) +		return 1; +	return ao_scheme_print_mark_addr(ao_scheme_ref(p)); +} + +/* Notes that printing has started */ +void +ao_scheme_print_start(void) +{ +	ao_scheme_printing++; +} + +/* Notes that printing has ended */ +void +ao_scheme_print_stop(void) +{ +	ao_scheme_printing--; +	if (ao_scheme_printing == 0) +		ao_scheme_print_cleared = 0; +} diff --git a/src/scheme/ao_scheme_vector.c b/src/scheme/ao_scheme_vector.c index a4127f64..ff2067e2 100644 --- a/src/scheme/ao_scheme_vector.c +++ b/src/scheme/ao_scheme_vector.c @@ -78,16 +78,19 @@ ao_scheme_vector_write(ao_poly v)  	struct ao_scheme_vector	*vector = ao_scheme_poly_vector(v);  	unsigned int i; -	printf("#("); -	for (i = 0; i < vector->length; i++) { -		if (i != 0) -			printf(" "); -		if (vector->vals[i] == v) -			printf ("..."); -		else +	ao_scheme_print_start(); +	if (ao_scheme_print_mark_addr(vector)) +		printf ("..."); +	else { +		printf("#("); +		for (i = 0; i < vector->length; i++) { +			if (i != 0) +				printf(" ");  			ao_scheme_poly_write(vector->vals[i]); +		} +		printf(")");  	} -	printf(")"); +	ao_scheme_print_stop();  }  void @@ -96,10 +99,11 @@ ao_scheme_vector_display(ao_poly v)  	struct ao_scheme_vector *vector = ao_scheme_poly_vector(v);  	unsigned int i; -	for (i = 0; i < vector->length; i++) { -		if (vector->vals[i] == v) -			printf("..."); -		else +	ao_scheme_print_start(); +	if (ao_scheme_print_mark_addr(vector)) +		printf ("..."); +	else { +		for (i = 0; i < vector->length; i++)  			ao_scheme_poly_display(vector->vals[i]);  	}  } | 
