Wild Life: memory.c Source File

Wild Life 2.29

- Main Page
- Data Structures
- Files

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Macros
memory.c
Go to the documentation of this file.
1 /* Copyright 1991 Digital Equipment Corporation.
2 ** All Rights Reserved.
3 *****************************************************************/
4 /* $Id: memory.c,v 1.10 1995/07/27 19:03:24 duchier Exp $ */
5
6 #include "defs.h"
7
8 static long delta;
9
10 #ifdef prlDEBUG
11 static long amount_used;
12 #endif
13
14 #ifdef CLIFE
15 long pass;
16 #else
17 static long pass;
18 #endif /* CLIFE */
19
20 #define LONELY 1
21
22 static struct tms last_garbage_time;
23 static float gc_time, life_time;
24
25
26
27 // #define ALIGNUP(X) { (X) = (GENERIC)( ((long) (X) + (ALIGN-1)) & ~(ALIGN-1) ); }
28
29
30
31 /************* STUFF FOR PARSING COMMAND LINE ARGS ************************/
32
33 char *GetStrOption(name,def)
34 char *name;
35 char *def;
36 {
37 int i;
38 char *result=def;
39 int l=strlen(name);
40
41 for(i=1;i<arg_c;i++)
42 if(arg_v[i][0]=='-' && (int)strlen(arg_v[i])>=l+1)
43 if(!strncmp(arg_v[i]+1,name,l))
44 if(arg_v[i][l+1]=='=')
45 result=arg_v[i]+l+2;
46 else
47 result=arg_v[i]+l+1;
48
49 return result;
50 }
51
52
53
54 int GetBoolOption(name)
55 char *name;
56 {
57 char *s;
58 s=GetStrOption(name,"off");
59 return strcmp(s,"off");
60 }
61
62
63
64 int GetIntOption(name,def)
65 char *name;
66 int def;
67 {
68 char *s;
69 char buffer_loc[40];
70 (void)snprintf(buffer_loc,40,"%d",def);
71 s=GetStrOption(name,buffer_loc);
72 return atof(s);
73 }
74
75 /****************************************************************************/
76
77
78
79
80
81 void pchoices() /* RM: Oct 28 1993 For debugging. */
82 {
83 ptr_choice_point c;
84 printf("stack pointer is: %lx\n",(unsigned long)stack_pointer);
85 for(c=choice_stack;c;c=c->next)
86 printf("\tc=%lx\ts=%lx\tg=%lx\tu=%lx\n",(unsigned long)c,(unsigned long)c->stack_top,(unsigned long)c->goal_stack,(unsigned long)c->undo_point);
87 }
88
89
90
91
92 /****************************************************************************/
93
94 /* GC sanity checks */
95
96 /* Keep for release versions, unless the garbage collector is very robust */
97 /* #define GCTEST */
98
99 /* Remove for release versions */
100 /* #define GCVERBOSE */
101
102 #ifndef GCTEST
103 #undef assert
104 #define assert(N)
105 #endif
106
107 void print_undo_stack()
108 {
109 ptr_stack u=undo_stack;
110
111 while (u) {
112 if ((GENERIC)u->aaaa_3<mem_base || (GENERIC)u->aaaa_3>mem_limit ||
113 (GENERIC)u->next<mem_base || (GENERIC)u->next>mem_limit) {
114 printf("UNDO: type:%ld a:%lx b:%lx next:%lx\n",u->type,(unsigned long)u->aaaa_3,(unsigned long)u->bbbb_3,(unsigned long)u->next);
115 (void)fflush(stdout);
116 }
117 u=u->next;
118 }
119 }
120
121 long bounds_undo_stack()
122 /* Address field in undo_stack is within range */
123 /* The only valid address outside this range is that of xevent_state */
124 {
125 ptr_stack u=undo_stack;
126
127 while (u) {
128 if ( (GENERIC)u<mem_base
129 || (GENERIC)u>mem_limit
130 || (!VALID_ADDRESS(u->aaaa_3) && !(u->type & undo_action))
131 ) {
132 if ((GENERIC)u<mem_base || (GENERIC)u>mem_limit) {
133 printf("\nUNDO: u=%lx\n",(long)u);
134 }
135 else {
136 printf("\nUNDO: u:%lx type:%ld a:%lx b:%lx next:%lx\n",
137 (unsigned long)u,(unsigned long)u->type,(unsigned long)u->aaaa_3,(unsigned long)u->bbbb_3,(unsigned long)u->next);
138 }
139 (void)fflush(stdout);
140 return FALSE;
141 }
142 u=u->next;
143 }
144
145 return TRUE;
146 }
147
148
149 /****************************************************************************/
150
151 /* Forward declarations */
152 static void check_psi_list();
153 static void check_resid_list(); /* 21.9 */
154 static void check_choice();
155 static void check_undo_stack();
156
157
158
159
160 /******** FAIL_ALL()
161 This routines provokes a total failure, in case of a bad error
162 (out of memory, abort, etc...).
163 All goals are abandoned.
164 */
165 void fail_all()
166 {
167 output_stream=stdout;
168 choice_stack=NULL;
169 goal_stack=NULL;
170 undo_stack=NULL;
171 (void)abort_life(TRUE);
172 /* printf("\n*** Abort\n"); */
173 stdin_cleareof();
174 (void)open_input_file("stdin");
175 }
176
177
178
179
180 /******************************************************************************
181
182 GARBAGE COLLECTING.
183
184 */
185
186
187
188 /* RM: Jan 29 1993 Replaced with PVR's version of 26.1 */
189
190 /******** COMPRESS()
191 This routine compresses the memory contents and
192 calculates the new addresses. First the Stack is compressed, bottom up.
193 Secondly the Heap is compressed, top down.
194 */
195 static void compress()
196 {
197 GENERIC addr, new_addr;
198 long len, i;
199
200 /* Compressing the stack: */
201
202 addr=new_addr=mem_base;
203 while (addr<=stack_pointer) {
204 len = *(addr+delta);
205 if (len) {
206 /* There are lots of these: */
207 /* if (len==LONELY) printf("Isolated LONELY at %lx\n",addr); */
208 if (len==LONELY) len=ALIGN;
209 else if (len & (ALIGN-1)) len=len-(len & (ALIGN-1))+ALIGN;
210 /* if (len & (ALIGN-1)) len=len-(len & (ALIGN-1))+ALIGN; 12.6 */
211 assert((len & (ALIGN-1))==0);
212 len /= sizeof(*addr);
213 assert(len>0);
214
215 for (i=0; i<len; i++) {
216 *new_addr = *addr;
217 if (i>0) {
218 if (*(addr+delta)>=len)
219 assert(i>0 ? *(addr+delta)<len : TRUE);
220 }
221 assert(VALID_ADDRESS(new_addr));
222 *(addr+delta) = (long)new_addr + 1; /* Set low bit */
223 #ifdef prlDEBUG
224 if (*(addr+delta) & 1 == 0)
225 printf ("compress: could be a bug ...\n");
226 #endif
227 addr++;
228 new_addr++;
229 }
230 }
231 else
232 addr++;
233 }
234 other_pointer=stack_pointer; /* 10.6 this var. is unused */
235 stack_pointer=new_addr;
236
237 /* Compressing the heap: */
238
239 addr=new_addr=mem_limit;
240 addr--; /* PVR fix: adding this statement avoids accessing beyond */
241 /* the memory's edge, which causes a segmentation fault on*/
242 /* SPARC. */
243 while (addr>=heap_pointer) {
244 skip_addr:
245 len= *(addr+delta);
246 if (len) {
247 if (len!=LONELY) {
248
249 if (len & (ALIGN-1)) len=len-(len & (ALIGN-1))+ALIGN;
250 assert((len & (ALIGN-1))==0);
251 len /= sizeof (*addr);
252 assert(len>0);
253
254 } else { /* len==LONELY */
255 GENERIC a;
256
257 if (len & (ALIGN-1)) len=len-(len & (ALIGN-1))+ALIGN;
258 assert((len & (ALIGN-1))==0);
259 len /= sizeof (*addr);
260 assert(len==1);
261
262 /* Check if the LONELY field is actually part of a block. */
263 /* If so, skip to the beginning of the block. */
264 a=addr;
265 do {
266 a--;
267 } while (a>=heap_pointer &&
268 (*(a+delta)==0 || *(a+delta)==LONELY));
269 if (a>=heap_pointer && *(a+delta)/sizeof(*a)+a>addr) {
270 addr=a;
271 goto skip_addr;
272 }
273 }
274
275 /* Move a block or an isolated LONELY field. */
276 addr += len;
277 for (i=0; i<len; i++) {
278 addr--;
279 new_addr--;
280 *new_addr = *addr;
281 assert(VALID_ADDRESS(new_addr));
282 *(addr+delta) = (long)new_addr + 1;
283 }
284 }
285 addr--;
286 }
287 heap_pointer=new_addr;
288 }
289
290
291
292 #define UNCHECKED(P) (! *((GENERIC)(P)+delta))
293
294 /******** UNCHECKED(p,l)
295 P is a pointer to a structure L bytes in length.
296 If L=LONELY then that means that P is a pointer to a sub-field of a
297 structure.
298 The function returns TRUE if the structure has not been yet thoroughly
299 explored, otherwise FALSE.
300 If this is the second pass then it translates P to its new value
301 (as calculated by COMPRESS).
302 */
303
304
305
306 #ifdef CLIFE
307 long unchecked (p, len)
308 #else
309 static long unchecked (p, len)
310 #endif /* CLIFE */
311 GENERIC *p;
312 long len;
313 {
314 GENERIC addr;
315 long result=FALSE, value;
316
317 assert(len>0);
318 if ((unsigned long)*p>MAX_BUILT_INS) {
319 #ifdef GCTEST
320 if (!VALID_ADDRESS(*p)) {
321 printf("p=%lx,*p=%lx\n",p,*p);
322 }
323 #endif
324 assert(VALID_ADDRESS(*p));
325 addr = *p + delta;
326 value = *addr;
327 switch (pass) {
328 case 1:
329 #ifdef GCTEST
330 if (FALSE /* len>100 || value>100 13.8 */) {
331 /* This does in fact happen */
332 printf("len=%ld,value=%ld\n",len,value);
333 fflush(stdout);
334 }
335 #endif
336 /* if (!value) */
337 if (!value || value==LONELY) {
338 /* Pointer not yet explored */
339 result=TRUE;
340 *addr=len;
341 #ifdef prlDEBUG
342 amount_used+=len;
343 #endif
344 }
345 else if (value < len && len != LONELY) {
346 Errorline("in garbage collection, %d < %d.\n", value, len);
347 }
348 else if (value > len && len != LONELY) {
349 Errorline("in garbage collection, %d > %d.\n", value, len);
350 }
351 break;
352 case 2:
353 if (value & 1) { /* If low bit set */
354 value--; /* Reset low bit */
355 *addr=value;
356 #ifdef prlDEBUG
357 amount_used+=len;
358 #endif
359 result=TRUE;
360 }
361 if (!VALID_ADDRESS(value))
362 assert(VALID_ADDRESS(value));
363 *p = (GENERIC) value;
364 break;
365 }
366 }
367 return result;
368 }
369
370
371
372 /******** CHECK_STRING(s)
373 Claim the memory used by the string S.
374 */
375 static void check_string (s)
376 GENERIC *s;
377 {
378 GENERIC addr;
379 long value;
380 long bytes;
381
382 if ((unsigned long) *s > MAX_BUILT_INS) {
383 switch (pass) {
384 case 1:
385 bytes=strlen((char *)*s)+1;
386 /* if (bytes==LONELY) {
387 fprintf(stderr,"Caught an empty string!\n");
388 fflush(stderr);
389 } */
390 /* Make sure there's no conflict with LONELY (this occurs for an */
391 /* empty string, which still needs a single byte of storage). */
392 /* This does occasionally happen. */
393 (void)unchecked(s, (bytes==LONELY)?bytes+1:bytes);
394 break;
395 case 2:
396 addr=(*s+delta);
397 value= *addr;
398 if (value & 1) { /* If low bit set */
399 value--;
400 *s=(GENERIC)value;
401 *addr=value;
402 #ifdef prlDEBUG
403 amount_used+=strlen(*s)+1;
404 #endif
405 }
406 *s=(GENERIC)value;
407 break;
408 }
409 }
410 }
411
412 /* DENYS: BYTEDATA */
413 /******** CHECK_BYTEDATA(s)
414 Claim the memory used by a block of bytes
415 */
416 static void check_bytedata(s)
417 GENERIC *s;
418 {
419 GENERIC addr;
420 long value;
421 if ((unsigned long) *s > MAX_BUILT_INS) {
422 unsigned long bytes = *((unsigned long *) *s);
423 unsigned long size = bytes + sizeof(bytes);
424 switch (pass) {
425 case 1:
426 (void)unchecked(s,size);
427 break;
428 case 2:
429 addr=(*s+delta);
430 value= *addr;
431 if (value & 1) {
432 value--;
433 *s=(GENERIC) value;
434 *addr=value;
435 #ifdef prlDEBUG
436 amount_used+=size;
437 #endif
438 }
439 *s=(GENERIC)value;
440 break;
441 }
442 }
443 }
444
445 /******** CHECK_CODE(c)
446 Claim the memory used by a type code (=list of integers).
447 */
448 static void check_code(c)
449 ptr_int_list *c;
450 {
451 while (unchecked(c,sizeof(int_list)))
452 c= &((*c)->next);
453 }
454
455
456
457 /******** CHECK_PAIR_LIST
458 Checks a list of <GOAL,BODY> pairs.
459 */
460 static void check_pair_list(p)
461 ptr_pair_list *p;
462 {
463 while (unchecked(p,sizeof(pair_list))) {
464 check_psi_term(&((*p)->aaaa_2));
465 check_psi_term(&((*p)->bbbb_2));
466 p= &((*p)->next);
467 }
468 }
469
470
471
472
473 /******** CHECK_TRIPLE_LIST
474 Checks a list of <GOAL,BODY,DEF> triples.
475 */
476 static void check_triple_list(p)
477 ptr_triple_list *p;
478 {
479 while (unchecked(p,sizeof(triple_list))) {
480 check_psi_term(&((*p)->aaaa_4));
481 check_psi_term(&((*p)->bbbb_4));
482 check_definition(&((*p)->cccc_4));
483 p= &((*p)->next);
484 }
485 }
486
487
488
489 /******** CHECK_KIDS(c)
490 Check a list of parents or children of a given type.
491 */
492 static void check_kids(c)
493 ptr_int_list *c;
494 {
495 while (unchecked(c,sizeof(int_list))) {
496 check_definition((ptr_definition *)&((*c)->value_1));
497 c= &((*c)->next);
498 }
499 }
500
501
502
503 /******** CHECK_OPERATOR_DATA(op)
504 Explore a list of operator declarations.
505 */
506 static void check_operator_data(op)
507 ptr_operator_data *op;
508 {
509 while (unchecked(op,sizeof(operator_data))) {
510 op = &((*op)->next);
511 }
512 }
513
514
515 static void check_module();
516 void check_hash_table(); /* RM: Feb 3 1993 */
517 static void check_keyword(); /* RM: Jan 12 1993 */
518
519
520
521 /******** CHECK_MODULE_LIST(c)
522 Check a list of modules.
523 */
524
525 static void check_module_list(c) /* RM: Jan 12 1993 */
526
527 ptr_int_list *c;
528 {
529 while (unchecked(c,sizeof(int_list))) {
530 check_module(&((*c)->value_1));
531 c= &((*c)->next);
532 }
533 }
534
535
536 /******** CHECK_MODULE_TREE
537 This goes through the module table, checking all nodes.
538 */
539 static void check_module_tree(n) /* RM: Jan 13 1993 */
540 ptr_node *n;
541 {
542 if (unchecked(n,sizeof(node))) {
543 check_module_tree(&((*n)->left));
544 check_string(&((*n)->key));
545 check_module(&((*n)->data));
546 check_module_tree(&((*n)->right));
547 }
548 }
549
550
551
552 /******** CHECK_MODULE(m)
553 Checks a module.
554 */
555
556 static void check_module(m) /* RM: Jan 12 1993 */
557
558 ptr_module *m;
559 {
560 if(unchecked(m,sizeof(struct wl_module))) {
561 check_string(&((*m)->module_name));
562 check_string(&((*m)->source_file));
563 check_module_list(&((*m)->open_modules));
564 check_module_list(&((*m)->inherited_modules));
565 check_hash_table((*m)->symbol_table);
566 }
567 }
568
569
570
571 /******** CHECK_HASH_TABLE(table)
572 Check a hash table of keywords. The actual table is not stored within LIFE
573 memory.
574 */
575
576 void check_hash_table(table) /* RM: Feb 3 1993 */
577
578 ptr_hash_table table;
579 {
580 long i;
581
582 for(i=0;i<table->size;i++)
583 if(table->data[i])
584 check_keyword(&(table->data[i]));
585 }
586
587
588
589 /******** CHECK_KEYWORD(k)
590 Checks a keyword.
591 */
592
593 static void check_keyword(k) /* RM: Jan 12 1993 */
594
595 ptr_keyword *k;
596 {
597 if(unchecked(k,sizeof(struct wl_keyword))) {
598 check_module(&((*k)->module));
599 check_string(&((*k)->symbol));
600 check_string(&((*k)->combined_name));
601 check_definition(&((*k)->definition));
602 }
603 }
604
605
606
607 /******** CHECK_DEFINITION
608 This goes through the type tree which contains the parents and children lists
609 for all types, and the attributed code. The code field is not checked as
610 this has been done separately by CHECK_GAMMA.
611 */
612 void check_definition(d)
613 ptr_definition *d;
614 {
615 if(unchecked(d,sizeof(definition))) {
616
617 check_keyword(&((*d)->keyword)); /* RM: Jan 12 1993 */
618
619 #ifdef prlDEBUG
620 printf("%lx %20s %ld\n",*d,(*d)->keyword->symbol,amount_used);
621 #endif
622
623 check_code(&((*d)->code));
624 check_pair_list(&((*d)->rule));
625 check_triple_list(&((*d)->properties));
626
627 if ((*d)->type_def==(def_type)type_it) {
628 check_kids(&((*d)->parents));
629 check_kids(&((*d)->children));
630 }
631
632 check_psi_term(&((*d)->global_value)); /* RM: Feb 9 1993 */
633 check_psi_term(&((*d)->init_value)); /* RM: Mar 23 1993 */
634
635 check_operator_data(&((*d)->op_data)); /* PVR 5.6 */
636
637 #ifdef CLIFE
638 check_block_def(&((*d)->block_def)); /* RM: Jan 27 1993 */
639 #endif /* CLIFE */
640 }
641 }
642
643
644
645 /******** CHECK_DEFINITION_LIST
646 This checks the entire list of definitions.
647 */
648 void check_definition_list() /* RM: Feb 15 1993 */
649
650 {
651 ptr_definition *d;
652
653 d= &first_definition;
654
655 while(*d) {
656 check_definition(d);
657 d= &((*d)->next);
658 }
659 }
660
661
662
663 /******** CHECK_DEF_CODE(d)
664 This routine checks the CODE field in a definition.
665 It may only be invoked by CHECK_GAMMA.
666 */
667 static void check_def_code(d)
668 ptr_definition *d;
669 {
670 if (unchecked(d,sizeof(definition)))
671 check_code(&((*d)->code));
672 /* p = &((*d)->properties); */
673 /* check_def_prop(p); */
674 }
675
676
677
678 /******** CHECK_DEF_REST(d)
679 This routine checks the other fields in a definition.
680 It may only be invoked by CHECK_GAMMA_REST.
681 */
682 static void check_def_rest(d)
683 ptr_definition *d;
684 {
685 if (*d) {
686 check_keyword(&((*d)->keyword)); /* RM: Jan 12 1993 */
687 check_pair_list(&((*d)->rule));
688 check_triple_list(&((*d)->properties));
689
690 if ((*d)->type_def==(def_type)type_it) {
691 check_kids(&((*d)->parents));
692 check_kids(&((*d)->children));
693 }
694 check_operator_data(&((*d)->op_data)); /* PVR 5.6 */
695 #ifdef CLIFE
696 check_block_def(&((*d)->block_def)); /*CB 25/01/93 */
697 #endif /* CLIFE */
698 }
699 }
700
701
702
703 /******** CHECK_SYMBOL
704 This goes through the symbol table, checking all nodes, symbols, strings
705 and definitions not contained in the type table.
706 */
707 static void check_symbol(n)
708 ptr_node *n;
709 {
710 if (unchecked(n,sizeof(node))) {
711 check_symbol(&((*n)->left));
712 check_string(&((*n)->key));
713 check_keyword(&((*n)->data)); /* RM: Jan 12 1993 */
714 check_symbol(&((*n)->right));
715 }
716 }
717
718
719
720 /******** CHECK_TYPE_DISJ
721 Checks the list of definitions appearing in a type disjunction.
722 */
723 static void check_type_disj(p)
724 ptr_int_list *p;
725 {
726 while (unchecked(p,sizeof(int_list))) {
727 check_definition((struct wl_definition **)&((*p)->value_1));
728 p= &((*p)->next);
729 }
730 }
731
732
733
734 /******** CHECK_GOAL_STACK
735 Check the goal_stack. This is quite complicated as each type of goal (prove,
736 unify, eval, eval_cut etc...) gives its own meanings to the three other
737 fields (A,B and C) present in each goal.
738 */
739 static void check_goal_stack(g)
740 ptr_goal *g;
741 {
742 while (unchecked(g,sizeof(goal))) {
743
744 switch ((*g)->type) {
745
746 case fail:
747 break;
748
749 case unify:
750 case unify_noeval: /* PVR 5.6 */
751 check_psi_term(&((*g)->aaaa_1));
752 check_psi_term(&((*g)->bbbb_1));
753 break;
754
755 case prove:
756 check_psi_term(&((*g)->aaaa_1));
757 if ((unsigned long)(*g)->bbbb_1!=DEFRULES) check_pair_list(&((*g)->bbbb_1));
758 check_pair_list(&((*g)->cccc_1));
759 break;
760
761 case disj:
762 check_psi_term(&((*g)->aaaa_1));
763 check_psi_term(&((*g)->bbbb_1));
764 break;
765
766 case what_next:
767 /* check_choice(&((*g)->bbbb_1)); */
768 break;
769
770 case eval:
771 check_psi_term(&((*g)->aaaa_1));
772 check_psi_term(&((*g)->bbbb_1));
773 check_pair_list(&((*g)->cccc_1));
774 break;
775
776 case load:
777 check_psi_term(&((*g)->aaaa_1));
778 check_string(&((*g)->cccc_1));
779 break;
780
781 case match:
782 check_psi_term(&((*g)->aaaa_1));
783 check_psi_term(&((*g)->bbbb_1));
784 check_resid_block((struct wl_resid_block **)&((*g)->cccc_1));
785 break;
786
787 case general_cut:
788 /* assert((GENERIC)(*g)->aaaa_3 <= (GENERIC)choice_stack); 12.7 17.7 */
789 if (pass==1 && (ptr_choice_point)(*g)->aaaa_1>choice_stack)
790 (*g)->aaaa_1=(ptr_psi_term)choice_stack;
791 (void)unchecked(&((*g)->aaaa_1),LONELY);
792 break;
793
794 case eval_cut:
795 check_psi_term(&((*g)->aaaa_1));
796 /* assert((GENERIC)(*g)->bbbb_1 <= (GENERIC)choice_stack); 12.7 17.7 */
797 if (pass==1 && (ptr_choice_point)(*g)->bbbb_1>choice_stack)
798 (*g)->bbbb_1=(ptr_psi_term)choice_stack;
799 (void)unchecked(&((*g)->bbbb_1),LONELY);
800 check_resid_block((struct wl_resid_block **)&((*g)->cccc_1));
801 break;
802
803 case freeze_cut:
804 case implies_cut:
805 check_psi_term(&((*g)->aaaa_1));
806 /* assert((GENERIC)(*g)->bbbb_1 <= (GENERIC)choice_stack); 12.7 17.7 */
807 if (pass==1 && (ptr_choice_point)(*g)->bbbb_1>choice_stack)
808 (*g)->bbbb_1=(ptr_psi_term)choice_stack;
809 (void)unchecked(&((*g)->bbbb_1),LONELY);
810 check_resid_block((struct wl_resid_block **)&((*g)->cccc_1));
811 break;
812
813 case type_disj:
814 check_psi_term(&((*g)->aaaa_1));
815 check_type_disj(&((*g)->bbbb_1));
816 break;
817
818 case clause:
819 check_psi_term(&((*g)->aaaa_1));
820 check_psi_term(&((*g)->bbbb_1));
821 (void)unchecked(&((*g)->cccc_1),LONELY);
822 /* check_pair_list((*g)->cccc_1); */ /* 6.8 */
823 break;
824
825 case del_clause:
826 check_psi_term(&((*g)->aaaa_1));
827 check_psi_term(&((*g)->bbbb_1));
828 (void)unchecked(&((*g)->cccc_1),LONELY);
829 /* check_pair_list((*g)->cccc_1); */ /* 6.8 */
830 break;
831
832 case retract:
833 (void)unchecked(&((*g)->aaaa_1),LONELY);
834 /* check_pair_list((*g)->aaaa_1); */ /* 6.8 */
835 /*PVR*/ /* check_choice(&((*g)->bbbb_1)); 9.6 */
836 break;
837
838 default:
839 Errorline("in garbage collection, bad goal on stack.\n");
840 }
841
842 g= &((*g)->next);
843 }
844 }
845
846
847
848 /******** CHECK_RESID(r)
849 Explore a list of residuations.
850 */
851 static void check_resid(r)
852 ptr_residuation *r;
853 {
854 ptr_int_list code;
855 ptr_list *l;
856
857 while (unchecked(r,sizeof(residuation))) {
858
859 if ((*r)->sortflag) /* 22.9 */
860 check_definition((struct wl_definition **)&((*r)->bestsort));
861 else
862 check_code(&((*r)->bestsort)); /* 21.9 */
863
864 /* Handling of the value field (6.10) */
865 code = (*r)->sortflag ? ((ptr_definition)((*r)->bestsort))->code
866 : (ptr_int_list)(*r)->bestsort;
867 /* Copied (almost) verbatim from check_psi_term: */
868 if ((*r)->value_2) {
869 if (code==alist->code) { /* RM: Dec 15 1992 Will be removed */
870 l=(ptr_list *) &((*r)->value_2);
871 if (l)
872 printf("Found an old list!!\n");
873 }
874 else if (sub_CodeType(code,real->code))
875 (void)unchecked(&((*r)->value_2),sizeof(REAL));
876 else if (sub_CodeType(code,quoted_string->code))
877 check_string(&((*r)->value_2));
878 /* DENYS: BYTEDATA */
879 else if (sub_CodeType(code,sys_bytedata->code))
880 check_bytedata(&((*r)->value_2));
881 else if (sub_CodeType(code,cut->code)) {
882 if (pass==1 && (*r)->value_2>(GENERIC)choice_stack)
883 (*r)->value_2=(GENERIC)choice_stack;
884 (void)unchecked(&((*r)->value_2),LONELY);
885 }
886 else if (sub_CodeType(code,variable->code)) /* 8.8 */
887 check_string(&((*r)->value_2));
888 }
889
890 check_goal_stack(&((*r)->goal));
891 r= &((*r)->next);
892 }
893 }
894
895
896
897 /******** CHECK_RESID_BLOCK(rb)
898 Explore a residuation block.
899 */
900 void check_resid_block(rb)
901 ptr_resid_block *rb;
902 {
903 if (*rb) {
904 if (unchecked(rb,sizeof(resid_block))) {
905 check_goal_stack(&((*rb)->ra));
906 check_resid_list(&((*rb)->rv)); /* 21.9 */
907 /* unchecked(&((*rb)->rl),LONELY); 12.6 */ /* 10.6 */
908 (void)unchecked(&((*rb)->md),LONELY); /* 10.6 */
909 /* check_goal_stack(&((*rb)->rl)); 10.6 */
910 /* check_psi_term(&((*rb)->md)); 10.6 */
911 }
912 }
913 }
914
915
916
917 /******** CHECK_PSI_TERM(t)
918 Explore a psi_term.
919 */
920 void check_psi_term(t)
921 ptr_psi_term *t;
922 {
923 ptr_list *l;
924
925 while (unchecked(t,sizeof(psi_term))) {
926
927 /* A psi-term on the heap has no residuation list. */
928 if (pass==1 && (GENERIC)(*t)>=heap_pointer && (GENERIC)(*t)<mem_limit) {
929 assert((*t)->resid==NULL);
930 }
931 check_definition(&((*t)->type));
932 check_attr(&((*t)->attr_list));
933
934 if ((*t)->value_3) {
935
936 if ((*t)->type==alist) { /* RM: Dec 15 1992 Should be removed */
937 l=(ptr_list *) &((*t)->value_3);
938 if (l)
939 printf("Found an old list!\n");
940 }
941 else
942
943 if (sub_type((*t)->type,real))
944 (void)unchecked(&((*t)->value_3),sizeof(REAL));
945 else if (sub_type((*t)->type,quoted_string))
946 check_string(&((*t)->value_3));
947 /* DENYS: BYTEDATA */
948 else if (sub_type((*t)->type,sys_bytedata))
949 check_bytedata(&((*t)->value_3));
950 #ifdef CLIFE
951 else if ((*t)->type->type==block) { /* RM: Jan 27 1993 */
952 check_block_value(&((*t)->value_3));
953 }
954 #endif /* CLIFE */
955 else if ((*t)->type==cut) { /* RM: Oct 28 1993 */
956 /* assert((*t)->value_3 <= (GENERIC)choice_stack); 12.7 17.7 */
957 if (pass==1 && (*t)->value_3>(GENERIC)choice_stack)
958 (*t)->value_3=(GENERIC)choice_stack;
959 (void)unchecked(&((*t)->value_3),LONELY);
960 }
961 else if (sub_type((*t)->type,variable)) /* 8.8 */
962 check_string(&((*t)->value_3));
963 else if ((*t)->type!=stream)
964 Errorline("non-NULL value field in garbage collector, type='%s', value=%d.\n",
965 (*t)->type->keyword->combined_name,
966 (*t)->value_3);
967 }
968
969 /* check_psi_term(&((*t)->coref)); 9.6 */
970 if ((*t)->resid)
971 check_resid(&((*t)->resid));
972
973 t = &((*t)->coref);
974 }
975 }
976
977
978
979 /******** CHECK_ATTR(attribute-tree)
980 Check an attribute tree.
981 (Could improve this by randomly picking left or right subtree
982 for last call optimization. This would never overflow, even on
983 very skewed attribute trees.)
984 */
985 void check_attr(n)
986 ptr_node *n;
987 {
988 while (unchecked(n,sizeof(node))) {
989 check_attr(&((*n)->left));
990 check_string(&((*n)->key));
991 check_psi_term((struct wl_psi_term **)&((*n)->data));
992
993 n = &((*n)->right);
994 /* check_attr(&((*n)->right)); 9.6 */
995 }
996 }
997
998
999
1000 /******** CHECK_GAMMA_CODE()
1001 Check and update the code
1002 reversing table. In this part, only the codes are checked in
1003 the definitions, this is vital because these codes are used
1004 later to distinguish between the various data types and to
1005 determine the type of the VALUE field in psi_terms. Misunderstanding this
1006 caused a lot of bugs in the GC.
1007 */
1008 void check_gamma_code()
1009 {
1010 long i;
1011
1012 if (unchecked(&gamma_table,type_count*sizeof(ptr_definition))) {
1013 for (i=0;i<type_count;i++)
1014 check_def_code(&(gamma_table[i]));
1015 }
1016 }
1017
1018
1019
1020 /******** CHECK_GAMMA_REST()
1021 Check and update the code reversing table.
1022 */
1023 static void check_gamma_rest()
1024 {
1025 long i;
1026
1027 for (i=0;i<type_count;i++)
1028 check_def_rest(&(gamma_table[i]));
1029 }
1030
1031
1032
1033 /******** CHECK_UNDO_STACK()
1034 This looks after checking the addresses of objects pointed to in the trail.
1035 The type of the pointer to be restored on backtracking is known, which
1036 allows the structure it is referring to to be accordingly checked.
1037 */
1038 static void check_undo_stack(s)
1039 ptr_stack *s;
1040 {
1041 while (unchecked(s,sizeof(stack))) {
1042
1043 switch((*s)->type) {
1044
1045 case psi_term_ptr:
1046 check_psi_term((struct wl_psi_term **)&((*s)->bbbb_3));
1047 break;
1048
1049 case resid_ptr:
1050 check_resid(&((*s)->bbbb_3));
1051 break;
1052
1053 case int_ptr:
1054 /* int_ptr's are used to trail time_stamps, so they can get large. */
1055 break;
1056
1057 case def_ptr:
1058 check_definition((struct wl_definition **)&((*s)->bbbb_3));
1059 break;
1060
1061 case code_ptr:
1062 check_code(&((*s)->bbbb_3));
1063 break;
1064
1065 case goal_ptr:
1066 check_goal_stack(&((*s)->bbbb_3));
1067 break;
1068
1069 case cut_ptr: /* 22.9 */
1070 break;
1071 #ifdef CLIFE
1072 case block_ptr: /* CB: Jan 28 1993 */
1073 check_block_value(&((*s)->bbbb_3));
1074 break;
1075
1076 #endif /* CLIFE */
1077 /* All undo actions here */
1078 case destroy_window:
1079 case show_window:
1080 case hide_window:
1081 /* No pointers to follow */
1082 break;
1083 }
1084
1085 s= &((*s)->next);
1086 }
1087 }
1088
1089
1090
1091 /******** CHECK_CHOICE(c)
1092 This routine checks all choice points.
1093 */
1094 static void check_choice_structs(c)
1095 ptr_choice_point *c;
1096 {
1097 while(unchecked(c,sizeof(choice_point))) {
1098 c= &((*c)->next);
1099 }
1100 }
1101
1102 static void check_choice(c)
1103 ptr_choice_point *c;
1104 {
1105 while(*c) {
1106 check_undo_stack(&((*c)->undo_point)); /* 17.7 */
1107 check_goal_stack(&((*c)->goal_stack));
1108 c= &((*c)->next);
1109 }
1110 }
1111
1112
1113
1114 /******** CHECK_SPECIAL_ADDRESSES
1115 Here we check all the addresses which do not point to a whole data structure,
1116 but to something within, for example a field such as VALUE which might
1117 have been modified in a PSI_TERM structure. These are the LONELY addresses.
1118 */
1119 static void check_special_addresses()
1120 {
1121 ptr_choice_point c;
1122 ptr_stack p;
1123 // ptr_goal g;
1124
1125 c=choice_stack;
1126 while(c) {
1127 /* unchecked(&(c->undo_point),LONELY); 17.7 */
1128 (void)unchecked(&(c->stack_top),LONELY);
1129 c=c->next;
1130 }
1131
1132 p=undo_stack;
1133 while (p) {
1134 if (!(p->type & undo_action)) {
1135 /* Only update an address if it's within the Life data space! */
1136 if (VALID_RANGE(p->aaaa_3)) (void)unchecked(&(p->aaaa_3),LONELY);
1137 if (p->type==cut_ptr) (void)unchecked(&(p->bbbb_3),LONELY); /* 22.9 */
1138 }
1139 p=p->next;
1140 }
1141 }
1142
1143
1144
1145 /******** CHECK_PSI_LIST
1146 Update all the values in the list of residuation variables, which is a list
1147 of psi_terms.
1148 */
1149 static void check_psi_list(l)
1150 ptr_int_list *l;
1151 {
1152 while(unchecked(l,sizeof(int_list))) {
1153 check_psi_term((struct wl_psi_term **)&((*l)->value_1));
1154 l= &((*l)->next);
1155 }
1156 }
1157
1158
1159
1160 /******** CHECK_RESID_LIST
1161 Update all the values in the list of residuation variables, which is a list
1162 of pairs of psi_terms.
1163 */
1164 static void check_resid_list(l)
1165 ptr_resid_list *l;
1166 {
1167 while(unchecked(l,sizeof(resid_list))) {
1168 check_psi_term(&((*l)->var));
1169 check_psi_term(&((*l)->othervar));
1170 l= &((*l)->next);
1171 }
1172 }
1173
1174
1175
1176 /******** CHECK_VAR(t)
1177 Go through the VARiable tree.
1178 (This could be made tail recursive.)
1179 */
1180 static void check_var(n)
1181 ptr_node *n;
1182 {
1183 if (unchecked(n,sizeof(node))) {
1184 check_var(&((*n)->left));
1185 check_string(&((*n)->key));
1186 check_psi_term((struct wl_psi_term **)&((*n)->data));
1187 check_var(&((*n)->right));
1188 }
1189 }
1190
1191
1192
1193 /******** CHECK
1194 This routine checks all pointers and psi_terms to find out which memory cells
1195 must be preserved and which can be discarded.
1196
1197 This routine explores all known structures. It is vital that it should visit
1198 them all exactly once. It thus creates a map of what is used in memory, which
1199 COMPRESS uses to compact the memory and recalculate the addresses.
1200 Exploration of these structures should be done in exactly the same order
1201 in both passes. If it is the second pass, pointers are assigned their new
1202 values.
1203
1204 A crucial property of this routine: In pass 2, a global variable (i.e. a
1205 root for GC) must be updated before it is accessed. E.g. don't use the
1206 variable goal_stack before updating it.
1207 */
1208 static void check()
1209 {
1210 #ifdef prlDEBUG
1211 amount_used=0;
1212 #endif
1213
1214 /* First of all, get all the codes right so that data type-checking remains
1215 coherent.
1216
1217 Kids and Parents cannot be checked because the built-in types have codes
1218 which might have been moved.
1219 */
1220 /* print_undo_stack(); */
1221
1222
1223 check_choice_structs(&choice_stack); /* RM: Oct 28 1993 */
1224
1225 assert((pass==1?bounds_undo_stack():TRUE));
1226 check_gamma_code();
1227
1228 /* Now, check the rest of the definitions and all global roots */
1229
1230 check_gamma_rest();
1231
1232 assert((pass==1?bounds_undo_stack():TRUE));
1233
1234 check_definition(&abortsym); /* 26.1 */
1235 check_definition(&aborthooksym); /* 26.1 */
1236
1237 check_definition(&add_module1); /* RM: Mar 12 1993 */
1238 check_definition(&add_module2);
1239 check_definition(&add_module3);
1240
1241 check_definition(&and);
1242 check_definition(&apply);
1243 check_definition(&boolean);
1244 check_definition(&boolpredsym);
1245 check_definition(&built_in);
1246 check_definition(&colonsym);
1247 check_definition(&commasym);
1248 check_definition(&comment);
1249 /* check_definition(&conjunction); 19.8 */
1250 check_definition(&constant);
1251 check_definition(&cut);
1252 check_definition(&disjunction);
1253 check_definition(&disj_nil); /* RM: Feb 16 1993 */
1254 check_definition(&eof);
1255 check_definition(&eqsym);
1256 check_definition(&lf_false);
1257 check_definition(&funcsym);
1258 check_definition(&functor);
1259 check_definition(&iff);
1260 check_definition(&integer);
1261 check_definition(&alist);
1262 check_definition(&life_or); /* RM: Apr 6 1993 */
1263 check_definition(&minus_symbol); /* RM: Jun 21 1993 */
1264 check_definition(&nil); /* RM: Dec 9 1992 */
1265 check_definition(&nothing);
1266 check_definition(&predsym);
1267 check_definition(&quote);
1268 check_definition(&quoted_string);
1269 check_definition(&real);
1270 check_definition(&stream);
1271 check_definition(&succeed);
1272 check_definition(&such_that);
1273 check_definition(&top);
1274 check_definition(&lf_true);
1275 check_definition(&timesym);
1276 check_definition(&tracesym); /* 26.1 */
1277 check_definition(&typesym);
1278 check_definition(&variable);
1279 check_definition(&opsym);
1280 check_definition(&loadsym);
1281 check_definition(&dynamicsym);
1282 check_definition(&staticsym);
1283 check_definition(&encodesym);
1284 check_definition(&listingsym);
1285 /* check_definition(&provesym); */
1286 check_definition(&delay_checksym);
1287 check_definition(&eval_argsym);
1288 check_definition(&inputfilesym);
1289 check_definition(&call_handlersym);
1290 check_definition(&xf_sym);
1291 check_definition(&fx_sym);
1292 check_definition(&yf_sym);
1293 check_definition(&fy_sym);
1294 check_definition(&xfx_sym);
1295 check_definition(&xfy_sym);
1296 check_definition(&yfx_sym);
1297 check_definition(&nullsym);
1298
1299 /* RM: Jul 7 1993 */
1300 check_definition(&final_dot);
1301 check_definition(&final_question);
1302
1303 check_sys_definitions();
1304
1305 #ifdef X11
1306 check_definition(&xevent);
1307 check_definition(&xmisc_event);
1308 check_definition(&xkeyboard_event);
1309 check_definition(&xbutton_event);
1310 check_definition(&xconfigure_event);
1311 check_definition(&xmotion_event);
1312 check_definition(&xenter_event);
1313 check_definition(&xleave_event);
1314 check_definition(&xexpose_event);
1315 check_definition(&xdestroy_event);
1316 check_definition(&xdisplay);
1317 check_definition(&xdrawable);
1318 check_definition(&xwindow);
1319 check_definition(&xpixmap);
1320 check_definition(&xgc);
1321 check_definition(&xdisplaylist);
1322 #endif
1323
1324 /* check_psi_term(&empty_list); 5.8 */
1325
1326 check_string(&one);
1327 check_string(&two);
1328 check_string(&three);
1329 check_string(&year_attr);
1330 check_string(&month_attr);
1331 check_string(&day_attr);
1332 check_string(&hour_attr);
1333 check_string(&minute_attr);
1334 check_string(&second_attr);
1335 check_string(&weekday_attr);
1336
1337 check_psi_term(&input_state);
1338 check_psi_term(&stdin_state);
1339 check_psi_term(&error_psi_term);
1340 check_psi_term(&saved_psi_term);
1341 check_psi_term(&old_saved_psi_term);
1342 check_psi_term(&null_psi_term);
1343 check_psi_term(&old_state); /* RM: Feb 17 1993 */
1344
1345 assert((pass==1?bounds_undo_stack():TRUE));
1346 #ifdef X11
1347 check_psi_term(&xevent_list);
1348 check_psi_term(&xevent_existing);
1349 #endif
1350
1351 check_choice(&choice_stack);
1352 /* check_choice(&prompt_choice_stack); 12.7 */
1353
1354
1355 /* RM: Feb 3 1993 */
1356 /* check_symbol(&symbol_table); */
1357 /* check_definition(&first_definition); */
1358 check_definition_list(); /* RM: Feb 15 1993 */
1359
1360
1361 /*** MODULES ***/
1362 /* RM: Jan 13 1993 */
1363
1364 check_module_tree(&module_table);
1365 check_module(&sys_module);
1366 check_module(&bi_module);
1367 check_module(&user_module); /* RM: Jan 27 1993 */
1368 check_module(&no_module);
1369 check_module(&x_module);
1370 check_module(&syntax_module);
1371 check_module(&current_module);
1372
1373 /*** End ***/
1374
1375
1376
1377 check_var(&var_tree);
1378
1379 check_goal_stack(&goal_stack);
1380 check_goal_stack(&aim); /* 7.10 */
1381
1382 if (TRUE /*resid_aim 10.6 */) check_resid_list(&resid_vars); /* 21.9 */
1383
1384 check_goal_stack(&resid_aim);
1385
1386 assert((pass==1?bounds_undo_stack():TRUE));
1387 check_undo_stack(&undo_stack);
1388
1389 assert((pass==1?bounds_undo_stack():TRUE));
1390 check_special_addresses();
1391
1392 assert((pass==1?bounds_undo_stack():TRUE));
1393 }
1394
1395
1396 void print_gc_info(timeflag)
1397 long timeflag;
1398 {
1399 fprintf(stderr," [%ld%% free (%ldK), %ld%% heap, %ld%% stack",
1400 (100*((unsigned long)heap_pointer-(unsigned long)stack_pointer)+mem_size/2)/mem_size,
1401 ((unsigned long)heap_pointer-(unsigned long)stack_pointer+512)/1024,
1402 (100*((unsigned long)mem_limit-(unsigned long)heap_pointer)+mem_size/2)/mem_size,
1403 (100*((unsigned long)stack_pointer-(unsigned long)mem_base)+mem_size/2)/mem_size);
1404 if (timeflag) {
1405 fprintf(stderr,", %1.3fs cpu (%ld%%)",
1406 gc_time,
1407 (unsigned long)(0.5+100*gc_time/(life_time+gc_time)));
1408 }
1409 fprintf(stderr,"]\n");
1410 }
1411
1412
1413 /******** GARBAGE()
1414 The garbage collector.
1415 This routine is called whenever memory is getting low.
1416 It returns TRUE if insufficient memory was freed to allow
1417 the interpreter to carry on working.
1418
1419 This is a half-space GC, it first explores all known structures, then
1420 compresses the heap and the stack, then during the second pass assigns
1421 all the new addresses.
1422
1423 Bugs will appear if the collector is called during parsing or other
1424 such routines which are 'unsafe'. In order to avoid this problem, before
1425 one of these routines is invoked the program will check to see whether
1426 there is enough memory available to work, and will call the GC if not
1427 (this is a fix, because it is not possible to determine in advance
1428 what the size of a psi_term read by the parser will be).
1429 */
1430 void garbage()
1431 {
1432 GENERIC addr;
1433 struct tms garbage_start_time,garbage_end_time;
1434 long start_number_cells, end_number_cells;
1435
1436 start_number_cells = (stack_pointer-mem_base) + (mem_limit-heap_pointer);
1437
1438 (void)times(&garbage_start_time);
1439
1440 /* Time elapsed since last garbage collection */
1441 life_time=(garbage_start_time.tms_utime - last_garbage_time.tms_utime)/60.0;
1442
1443
1444 if (verbose) {
1445 fprintf(stderr,"*** Garbage Collect "); /* RM: Jan 26 1993 */
1446 fprintf(stderr,"\n*** Begin");
1447 print_gc_info(FALSE);
1448 (void)fflush(stderr);
1449 }
1450
1451
1452 /* reset the other base */
1453 for (addr = other_base; addr < other_limit; addr ++)
1454 *addr = 0;
1455
1456 pass=1;
1457
1458 check();
1459 #ifdef GCVERBOSE
1460 fprintf(stderr,"- Done pass 1 ");
1461 #endif
1462
1463 assert(bounds_undo_stack());
1464 compress();
1465 #ifdef GCVERBOSE
1466 fprintf(stderr,"- Done compress ");
1467 #endif
1468
1469 pass=2;
1470
1471 check();
1472 assert(bounds_undo_stack());
1473 #ifdef GCVERBOSE
1474 fprintf(stderr,"- Done pass 2\n");
1475 #endif
1476
1477 clear_copy();
1478
1479 printed_pointers=NULL;
1480 pointer_names=NULL;
1481
1482 (void)times(&garbage_end_time);
1483 gc_time=(garbage_end_time.tms_utime - garbage_start_time.tms_utime)/60.0;
1484 garbage_time+=gc_time;
1485
1486 if (verbose) {
1487 fprintf(stderr,"*** End ");
1488 print_gc_info(TRUE); /* RM: Jan 26 1993 */
1489 stack_info(stderr);
1490 (void)fflush(stderr);
1491 }
1492
1493 last_garbage_time=garbage_end_time;
1494
1495 end_number_cells = (stack_pointer-mem_base) + (mem_limit-heap_pointer);
1496 assert(end_number_cells<=start_number_cells);
1497
1498 ignore_eff=FALSE;
1499
1500 }
1501
1502
1503
1504 /****************************************************************************
1505
1506 MEMORY ALLOCATION ROUTINES.
1507
1508 */
1509
1510
1511
1512 /******** HEAP_ALLOC(s)
1513 This returns a pointer to S bytes of memory in the heap.
1514 Alignment is taken into account in the following manner:
1515 the macro ALIGN is supposed to be a power of 2 and the pointer returned
1516 is a multiple of ALIGN.
1517 */
1518 GENERIC heap_alloc (s)
1519 long s;
1520 {
1521 if (s & (ALIGN-1))
1522 s = s - (s & (ALIGN-1))+ALIGN;
1523 /* assert(s % sizeof(*heap_pointer) == 0); */
1524 s /= sizeof (*heap_pointer);
1525
1526 heap_pointer -= s;
1527
1528 if (stack_pointer>heap_pointer)
1529 Errorline("the heap overflowed into the stack.\n");
1530
1531 return heap_pointer;
1532 }
1533
1534
1535
1536 /******** STACK_ALLOC(s)
1537 This returns a pointer to S bytes of memory in the stack.
1538 Alignment is taken into account in the following manner:
1539 the macro ALIGN is supposed to be a power of 2 and the pointer returned
1540 is a multiple of ALIGN.
1541 */
1542 GENERIC stack_alloc(s)
1543 long s;
1544 {
1545 GENERIC r;
1546
1547 r = stack_pointer;
1548
1549 if (s & (ALIGN-1))
1550 s = s - (s & (ALIGN-1)) + ALIGN;
1551 /* assert(s % sizeof(*stack_pointer) == 0); */
1552 s /= sizeof (*stack_pointer);
1553
1554 stack_pointer += s;
1555
1556 if (stack_pointer>heap_pointer)
1557 Errorline("the stack overflowed into the heap.\n");
1558
1559 return r;
1560 }
1561
1562
1563
1564 /******** INIT_MEMORY()
1565 Get two big blocks of memory to work in.
1566 The second is only used for the half-space garbage collector.
1567 The start and end addresses of the blocks are re-aligned correctly.
1568 to allocate.
1569 */
1570
1571
1572 void init_memory ()
1573 {
1574 alloc_words=GetIntOption("memory",ALLOC_WORDS);
1575 mem_size=alloc_words*sizeof(long);
1576
1577 mem_base = (GENERIC) malloc(mem_size);
1578 other_base = (GENERIC) malloc(mem_size);
1579
1580 if (mem_base && other_base) {
1581 /* Rewrote some rather poor code... RM: Mar 1 1994 */
1582 ALIGNUP(mem_base);
1583 stack_pointer = mem_base;
1584
1585 mem_limit=mem_base+alloc_words-2;
1586 ALIGNUP(mem_limit);
1587 heap_pointer = mem_limit;
1588
1589 ALIGNUP(other_base);
1590 other_pointer = other_base;
1591
1592 other_limit=other_base+alloc_words-2;
1593 ALIGNUP(other_limit);
1594
1595 delta = other_base - mem_base;
1596 buffer = (char *) malloc (PRINT_BUFFER); /* The printing buffer */
1597
1598 /* RM: Oct 22 1993 */
1599 /* Fill the memory with rubbish data */
1600 /*
1601 {
1602 int i;
1603
1604 for(i=0;i<alloc_words;i++) {
1605 mem_base[i]= -1234;
1606 other_base[i]= -1234;
1607 }
1608 }
1609 */
1610 }
1611 else
1612 Errorline("Wild_life could not allocate sufficient memory to run.\n\n");
1613 }
1614
1615
1616
1617 /******** MEMORY_CHECK()
1618 This function tests to see whether enough memory is available to allow
1619 execution to continue. It causes a garbage collection if not, and if that
1620 fails to release enough memory it returns FALSE.
1621 */
1622 long memory_check ()
1623 {
1624 long success=TRUE;
1625
1626 if (heap_pointer-stack_pointer < GC_THRESHOLD) {
1627 if(verbose) fprintf(stderr,"\n"); /* RM: Feb 1 1993 */
1628 garbage();
1629 /* Abort if didn't recover at least GC_THRESHOLD/10 of memory */
1630 if (heap_pointer-stack_pointer < GC_THRESHOLD+GC_THRESHOLD/10) {
1631 fprintf(stderr,"*********************\n");
1632 fprintf(stderr,"*** OUT OF MEMORY ***\n");
1633 fprintf(stderr,"*********************\n");
1634 fail_all();
1635 success=FALSE;
1636 }
1637 }
1638 return success;
1639 }
1640
1641
1642
VALID_ADDRESS
#define VALID_ADDRESS(A)
Definition: def_macro.h:132
prove
#define prove
Definition: def_const.h:273
encodesym
ptr_definition encodesym
Definition: def_glob.h:116
check_hash_table
void check_hash_table()
check_type_disj
static void check_type_disj(ptr_int_list *p)
Definition: memory.c:723
such_that
ptr_definition such_that
Definition: def_glob.h:105
boolpredsym
ptr_definition boolpredsym
Definition: def_glob.h:74
check_undo_stack
static void check_undo_stack()
printed_pointers
ptr_node printed_pointers
Definition: def_glob.h:28
abortsym
ptr_definition abortsym
Definition: def_glob.h:64
memory_check
long memory_check()
Definition: memory.c:1622
timesym
ptr_definition timesym
Definition: def_glob.h:108
stack_alloc
GENERIC stack_alloc(long s)
Definition: memory.c:1542
check_resid_list
static void check_resid_list()
check_bytedata
static void check_bytedata(GENERIC *s)
Definition: memory.c:416
check
static void check()
Definition: memory.c:1208
xfy_sym
ptr_definition xfy_sym
Definition: def_glob.h:127
staticsym
ptr_definition staticsym
Definition: def_glob.h:115
clear_copy
void clear_copy()
Definition: copy.c:52
stdin_state
ptr_psi_term stdin_state
Definition: def_glob.h:200
check_resid
static void check_resid(ptr_residuation *r)
Definition: memory.c:851
wl_choice_point
Definition: def_struct.h:231
wl_hash_table
Definition: def_struct.h:111
loadsym
ptr_definition loadsym
Definition: def_glob.h:113
wl_operator_data
Definition: def_struct.h:46
goal_stack
ptr_goal goal_stack
Definition: def_glob.h:50
show_window
#define show_window
Definition: def_const.h:184
mem_limit
GENERIC mem_limit
Definition: def_glob.h:13
current_module
ptr_module current_module
Definition: def_glob.h:161
dynamicsym
ptr_definition dynamicsym
Definition: def_glob.h:114
opsym
ptr_definition opsym
Definition: def_glob.h:112
type_count
long type_count
Definition: def_glob.h:46
comment
ptr_definition comment
Definition: def_glob.h:80
xdisplaylist
ptr_definition xdisplaylist
Definition: def_glob.h:211
gc_time
static float gc_time
Definition: memory.c:23
VALID_RANGE
#define VALID_RANGE(A)
Definition: def_macro.h:122
def_ptr
#define def_ptr
Definition: def_const.h:173
stream
ptr_definition stream
Definition: def_glob.h:103
wl_goal
Definition: def_struct.h:222
fail_all
void fail_all()
Definition: memory.c:165
xevent_list
ptr_psi_term xevent_list
Definition: def_glob.h:208
check_goal_stack
static void check_goal_stack(ptr_goal *g)
Definition: memory.c:739
xbutton_event
ptr_definition xbutton_event
Definition: def_glob.h:211
alloc_words
int alloc_words
Definition: def_glob.h:10
listingsym
ptr_definition listingsym
Definition: def_glob.h:117
check_operator_data
static void check_operator_data(ptr_operator_data *op)
Definition: memory.c:506
old_state
ptr_psi_term old_state
Definition: def_glob.h:142
verbose
long verbose
Definition: def_glob.h:273
two
char * two
Definition: def_glob.h:251
wl_stack::bbbb_3
GENERIC * bbbb_3
Definition: def_struct.h:218
commasym
ptr_definition commasym
Definition: def_glob.h:79
delta
static long delta
Definition: memory.c:8
wl_module
Definition: def_struct.h:74
general_cut
#define general_cut
Definition: def_const.h:282
null_psi_term
ptr_psi_term null_psi_term
Definition: def_glob.h:140
mem_size
int mem_size
Definition: def_glob.h:9
check_string
static void check_string(GENERIC *s)
Definition: memory.c:375
implies_cut
#define implies_cut
Definition: def_const.h:281
defs.h
wl_psi_term
Definition: def_struct.h:161
fy_sym
ptr_definition fy_sym
Definition: def_glob.h:125
check_special_addresses
static void check_special_addresses()
Definition: memory.c:1119
wl_stack
Definition: def_struct.h:215
DEFRULES
#define DEFRULES
Definition: def_const.h:138
pass
static long pass
Definition: memory.c:17
destroy_window
#define destroy_window
Definition: def_const.h:183
wl_triple_list
Definition: def_struct.h:195
aborthooksym
ptr_definition aborthooksym
Definition: def_glob.h:65
xexpose_event
ptr_definition xexpose_event
Definition: def_glob.h:211
constant
ptr_definition constant
Definition: def_glob.h:82
wl_choice_point::stack_top
GENERIC stack_top
Definition: def_struct.h:236
wl_residuation
Definition: def_struct.h:152
wl_pair_list
Definition: def_struct.h:188
user_module
ptr_module user_module
Definition: def_glob.h:156
check_pair_list
static void check_pair_list(ptr_pair_list *p)
Definition: memory.c:460
other_base
GENERIC other_base
Definition: def_glob.h:19
top
ptr_definition top
Definition: def_glob.h:106
cut_ptr
#define cut_ptr
Definition: def_const.h:176
NULL
#define NULL
Definition: def_const.h:203
var_tree
ptr_node var_tree
Definition: def_glob.h:26
input_state
ptr_psi_term input_state
Definition: def_glob.h:199
other_pointer
GENERIC other_pointer
Definition: def_glob.h:21
quote
ptr_definition quote
Definition: def_glob.h:100
ignore_eff
long ignore_eff
Definition: def_glob.h:151
check_module
static void check_module()
heap_alloc
GENERIC heap_alloc(long s)
Definition: memory.c:1518
three
char * three
Definition: def_glob.h:252
apply
ptr_definition apply
Definition: def_glob.h:72
xgc
ptr_definition xgc
Definition: def_glob.h:211
resid_aim
ptr_goal resid_aim
Definition: def_glob.h:220
wl_choice_point::next
ptr_choice_point next
Definition: def_struct.h:235
REAL
#define REAL
Definition: def_const.h:72
xmotion_event
ptr_definition xmotion_event
Definition: def_glob.h:211
unchecked
static long unchecked(GENERIC *p, long len)
Definition: memory.c:309
resid_vars
ptr_resid_list resid_vars
Definition: def_glob.h:221
ptr_list
struct wl_list * ptr_list
Definition: def_struct.h:38
xmisc_event
ptr_definition xmisc_event
Definition: def_glob.h:211
abort_life
long abort_life(int nlflag)
Definition: built_ins.c:2124
eval
#define eval
Definition: def_const.h:278
pointer_names
ptr_node pointer_names
Definition: def_glob.h:29
minus_symbol
ptr_definition minus_symbol
Definition: def_glob.h:96
check_symbol
static void check_symbol(ptr_node *n)
Definition: memory.c:707
check_choice
static void check_choice()
xfx_sym
ptr_definition xfx_sym
Definition: def_glob.h:126
sub_type
long sub_type(ptr_definition t1, ptr_definition t2)
Definition: types.c:1544
check_definition
void check_definition(ptr_definition *d)
Definition: memory.c:612
wl_int_list
Definition: def_struct.h:53
print_gc_info
void print_gc_info(long timeflag)
Definition: memory.c:1396
type_it
#define type_it
Definition: def_const.h:363
add_module3
ptr_definition add_module3
Definition: def_glob.h:69
hide_window
#define hide_window
Definition: def_const.h:185
undo_stack
ptr_stack undo_stack
Definition: def_glob.h:53
check_kids
static void check_kids(ptr_int_list *c)
Definition: memory.c:492
Errorline
void Errorline(char *format,...)
Definition: error.c:414
yf_sym
ptr_definition yf_sym
Definition: def_glob.h:124
check_def_code
static void check_def_code(ptr_definition *d)
Definition: memory.c:667
disj_nil
ptr_definition disj_nil
Definition: def_glob.h:85
nullsym
ptr_definition nullsym
Definition: def_glob.h:129
real
ptr_definition real
Definition: def_glob.h:102
buffer
char * buffer
Definition: def_glob.h:175
alist
ptr_definition alist
Definition: def_glob.h:94
check_resid_block
void check_resid_block(ptr_resid_block *rb)
Definition: memory.c:900
check_choice_structs
static void check_choice_structs(ptr_choice_point *c)
Definition: memory.c:1094
wl_stack::type
type_ptr type
Definition: def_struct.h:216
functor
ptr_definition functor
Definition: def_glob.h:91
eqsym
ptr_definition eqsym
Definition: def_glob.h:87
freeze_cut
#define freeze_cut
Definition: def_const.h:280
eof
ptr_definition eof
Definition: def_glob.h:86
xkeyboard_event
ptr_definition xkeyboard_event
Definition: def_glob.h:211
TRUE
#define TRUE
Definition: def_const.h:127
xwindow
ptr_definition xwindow
Definition: def_glob.h:211
name
char * name
Definition: def_glob.h:325
first_definition
ptr_definition first_definition
Definition: def_glob.h:3
ALIGNUP
#define ALIGNUP(X)
Definition: def_macro.h:294
error_psi_term
ptr_psi_term error_psi_term
Definition: def_glob.h:23
gamma_table
ptr_definition * gamma_table
Definition: def_glob.h:309
what_next
#define what_next
Definition: def_const.h:277
built_in
ptr_definition built_in
Definition: def_glob.h:75
integer
ptr_definition integer
Definition: def_glob.h:93
PRINT_BUFFER
#define PRINT_BUFFER
Definition: def_const.h:106
match
#define match
Definition: def_const.h:283
life_time
static float life_time
Definition: memory.c:23
lf_true
ptr_definition lf_true
Definition: def_glob.h:107
iff
ptr_definition iff
Definition: def_glob.h:92
final_dot
ptr_definition final_dot
Definition: def_glob.h:137
FALSE
#define FALSE
Definition: def_const.h:128
wl_resid_list
Definition: def_struct.h:59
arg_c
int arg_c
Definition: def_glob.h:5
check_triple_list
static void check_triple_list(ptr_triple_list *p)
Definition: memory.c:476
code_ptr
#define code_ptr
Definition: def_const.h:174
quoted_string
ptr_definition quoted_string
Definition: def_glob.h:101
mem_base
GENERIC mem_base
Definition: def_glob.h:11
succeed
ptr_definition succeed
Definition: def_glob.h:104
print_undo_stack
void print_undo_stack()
Definition: memory.c:107
clause
#define clause
Definition: def_const.h:285
ptr_definition
struct wl_definition * ptr_definition
Definition: def_struct.h:31
wl_keyword
Definition: def_struct.h:89
arg_v
char * arg_v[10]
Definition: def_glob.h:6
and
ptr_definition and
Definition: def_glob.h:71
module_table
ptr_node module_table
Definition: def_glob.h:160
check_psi_term
void check_psi_term(ptr_psi_term *t)
Definition: memory.c:920
check_module_list
static void check_module_list(ptr_int_list *c)
Definition: memory.c:525
lf_false
ptr_definition lf_false
Definition: def_glob.h:89
syntax_module
ptr_module syntax_module
Definition: def_glob.h:159
fail
#define fail
Definition: def_const.h:272
aim
ptr_goal aim
Definition: def_glob.h:49
weekday_attr
char * weekday_attr
Definition: def_glob.h:259
disjunction
ptr_definition disjunction
Definition: def_glob.h:84
heap_pointer
GENERIC heap_pointer
Definition: def_glob.h:12
wl_resid_block
Definition: def_struct.h:246
xpixmap
ptr_definition xpixmap
Definition: def_glob.h:211
one
char * one
Definition: def_glob.h:250
retract
#define retract
Definition: def_const.h:287
check_code
static void check_code(ptr_int_list *c)
Definition: memory.c:448
xenter_event
ptr_definition xenter_event
Definition: def_glob.h:211
xevent
ptr_definition xevent
Definition: def_glob.h:211
unify
#define unify
Definition: def_const.h:274
init_memory
void init_memory()
Definition: memory.c:1572
wl_stack::aaaa_3
GENERIC * aaaa_3
Definition: def_struct.h:217
add_module2
ptr_definition add_module2
Definition: def_glob.h:68
GetBoolOption
int GetBoolOption(char *name)
Definition: memory.c:54
life_or
ptr_definition life_or
Definition: def_glob.h:95
delay_checksym
ptr_definition delay_checksym
Definition: def_glob.h:118
load
#define load
Definition: def_const.h:288
check_definition_list
void check_definition_list()
Definition: memory.c:648
yfx_sym
ptr_definition yfx_sym
Definition: def_glob.h:128
wl_definition
Definition: def_struct.h:121
compress
static void compress()
Definition: memory.c:195
final_question
ptr_definition final_question
Definition: def_glob.h:138
GetStrOption
char * GetStrOption(char *name, char *def)
Definition: memory.c:33
saved_psi_term
ptr_psi_term saved_psi_term
Definition: def_glob.h:194
sys_module
ptr_module sys_module
Definition: def_glob.h:162
unify_noeval
#define unify_noeval
Definition: def_const.h:275
garbage
void garbage()
Definition: memory.c:1430
sys_bytedata
ptr_definition sys_bytedata
Definition: def_glob.h:336
add_module1
ptr_definition add_module1
Definition: def_glob.h:67
tracesym
ptr_definition tracesym
Definition: def_glob.h:109
xdisplay
ptr_definition xdisplay
Definition: def_glob.h:211
del_clause
#define del_clause
Definition: def_const.h:286
eval_cut
#define eval_cut
Definition: def_const.h:279
check_gamma_code
void check_gamma_code()
Definition: memory.c:1008
check_var
static void check_var(ptr_node *n)
Definition: memory.c:1180
ptr_psi_term
struct wl_psi_term * ptr_psi_term
Definition: def_struct.h:34
stack_info
void stack_info(FILE *outfile)
Definition: error.c:58
fx_sym
ptr_definition fx_sym
Definition: def_glob.h:123
sub_CodeType
long sub_CodeType(ptr_int_list c1, ptr_int_list c2)
Definition: types.c:1522
undo_action
#define undo_action
Definition: def_const.h:188
minute_attr
char * minute_attr
Definition: def_glob.h:257
cut
ptr_definition cut
Definition: def_glob.h:83
GC_THRESHOLD
#define GC_THRESHOLD
Definition: def_const.h:65
x_module
ptr_module x_module
Definition: def_glob.h:158
other_limit
GENERIC other_limit
Definition: def_glob.h:20
xdestroy_event
ptr_definition xdestroy_event
Definition: def_glob.h:211
output_stream
FILE * output_stream
Definition: def_glob.h:41
check_module_tree
static void check_module_tree(ptr_node *n)
Definition: memory.c:539
disj
#define disj
Definition: def_const.h:276
MAX_BUILT_INS
#define MAX_BUILT_INS
Definition: def_const.h:82
nothing
ptr_definition nothing
Definition: def_glob.h:98
nil
ptr_definition nil
Definition: def_glob.h:97
year_attr
char * year_attr
Definition: def_glob.h:253
no_module
ptr_module no_module
Definition: def_glob.h:157
stack_pointer
GENERIC stack_pointer
Definition: def_glob.h:14
GetIntOption
int GetIntOption(char *name, int def)
Definition: memory.c:64
pchoices
void pchoices()
Definition: memory.c:81
wl_definition::code
ptr_int_list code
Definition: def_struct.h:129
second_attr
char * second_attr
Definition: def_glob.h:258
xleave_event
ptr_definition xleave_event
Definition: def_glob.h:211
day_attr
char * day_attr
Definition: def_glob.h:255
check_psi_list
static void check_psi_list()
type_disj
#define type_disj
Definition: def_const.h:284
check_gamma_rest
static void check_gamma_rest()
Definition: memory.c:1023
bi_module
ptr_module bi_module
Definition: def_glob.h:155
garbage_time
float garbage_time
Definition: def_glob.h:16
predsym
ptr_definition predsym
Definition: def_glob.h:99
LONELY
#define LONELY
Definition: memory.c:20
wl_node
Definition: def_struct.h:181
hour_attr
char * hour_attr
Definition: def_glob.h:256
check_sys_definitions
void check_sys_definitions()
Definition: sys.c:1740
xconfigure_event
ptr_definition xconfigure_event
Definition: def_glob.h:211
stdin_cleareof
void stdin_cleareof()
Definition: token.c:42
GENERIC
unsigned long * GENERIC
Definition: def_struct.h:17
xevent_existing
ptr_psi_term xevent_existing
Definition: def_glob.h:208
resid_ptr
#define resid_ptr
Definition: def_const.h:171
xf_sym
ptr_definition xf_sym
Definition: def_glob.h:122
check_keyword
static void check_keyword()
bounds_undo_stack
long bounds_undo_stack()
Definition: memory.c:121
check_attr
void check_attr(ptr_node *n)
Definition: memory.c:985
ALIGN
#define ALIGN
Definition: def_const.h:31
goal_ptr
#define goal_ptr
Definition: def_const.h:175
colonsym
ptr_definition colonsym
Definition: def_glob.h:78
inputfilesym
ptr_definition inputfilesym
Definition: def_glob.h:120
variable
ptr_definition variable
Definition: def_glob.h:111
wl_stack::next
ptr_stack next
Definition: def_struct.h:219
open_input_file
long open_input_file(char *file)
Definition: token.c:504
last_garbage_time
static struct tms last_garbage_time
Definition: memory.c:22
check_def_rest
static void check_def_rest(ptr_definition *d)
Definition: memory.c:682
call_handlersym
ptr_definition call_handlersym
Definition: def_glob.h:121
choice_stack
ptr_choice_point choice_stack
Definition: def_glob.h:51
old_saved_psi_term
ptr_psi_term old_saved_psi_term
Definition: def_glob.h:195
eval_argsym
ptr_definition eval_argsym
Definition: def_glob.h:119
funcsym
ptr_definition funcsym
Definition: def_glob.h:90
month_attr
char * month_attr
Definition: def_glob.h:254
typesym
ptr_definition typesym
Definition: def_glob.h:110
assert
#define assert(N)
Definition: memory.c:104
xdrawable
ptr_definition xdrawable
Definition: def_glob.h:211
psi_term_ptr
#define psi_term_ptr
Definition: def_const.h:170
int_ptr
#define int_ptr
Definition: def_const.h:172