00001
00002
00003
00004
00005
00006 #ifndef lint
00007 static char vcid[] = "$Id: memory.c,v 1.10 1995/07/27 19:03:24 duchier Exp $";
00008 #endif
00009
00010
00011 #include <stdlib.h>
00012 #include "extern.h"
00013 #include "print.h"
00014 #include "login.h"
00015 #include "lefun.h"
00016 #include "token.h"
00017 #include "error.h"
00018 #include "xpred.h"
00019 #include "modules.h"
00020
00021
00022
00023
00024 GENERIC mem_base;
00025 GENERIC mem_limit;
00026 GENERIC stack_pointer;
00027 GENERIC heap_pointer;
00028 GENERIC other_base;
00029
00030 GENERIC other_limit;
00031 GENERIC other_pointer;
00032
00033 static long delta;
00034
00035 #ifdef prlDEBUG
00036 static long amount_used;
00037 #endif
00038
00039 #ifdef CLIFE
00040 long pass;
00041 #else
00042 static long pass;
00043 #endif
00044
00045 #define LONELY 1
00046
00047 #ifndef OS2_PORT
00048 static struct tms last_garbage_time;
00049 #else
00050 static float last_garbage_time;
00051 #endif
00052 static float gc_time, life_time;
00053
00054
00055 int mem_size;
00056 int alloc_words;
00057
00058 #define ALIGNUP(X) { (X) = (GENERIC)( ((long) (X) + (ALIGN-1)) & ~(ALIGN-1) ); }
00059
00060
00061
00062
00063
00064 char *GetStrOption(name,def)
00065 char *name;
00066 char *def;
00067 {
00068 int i;
00069 char *result=def;
00070 int l=strlen(name);
00071
00072 for(i=1;i<arg_c;i++)
00073 if(arg_v[i][0]=='-' && (int)strlen(arg_v[i])>=l+1)
00074 if(!strncmp(arg_v[i]+1,name,l))
00075 if(arg_v[i][l+1]=='=')
00076 result=arg_v[i]+l+2;
00077 else
00078 result=arg_v[i]+l+1;
00079
00080 return result;
00081 }
00082
00083
00084
00085 int GetBoolOption(name)
00086 char *name;
00087 {
00088 char *s;
00089 s=GetStrOption(name,"off");
00090 return strcmp(s,"off");
00091 }
00092
00093
00094
00095 int GetIntOption(name,def)
00096 char *name;
00097 int def;
00098 {
00099 char *s;
00100 char buffer[40];
00101 sprintf(buffer,"%d",def);
00102 s=GetStrOption(name,buffer);
00103 return atof(s);
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 void pchoices()
00113 {
00114 ptr_choice_point c;
00115 printf("stack pointer is: %x\n",stack_pointer);
00116 for(c=choice_stack;c;c=c->next)
00117 printf("\tc=%x\ts=%x\tg=%x\tu=%x\n",c,c->stack_top,c->goal_stack,c->undo_point);
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 #ifndef GCTEST
00134 #undef assert
00135 #define assert(N)
00136 #endif
00137
00138 void print_undo_stack()
00139 {
00140 ptr_stack u=undo_stack;
00141
00142 while (u) {
00143 if (u->a<mem_base || u->a>mem_limit ||
00144 (GENERIC)u->next<mem_base || (GENERIC)u->next>mem_limit) {
00145 printf("UNDO: type:%ld a:%lx b:%lx next:%lx\n",u->type,u->a,u->b,u->next);
00146 fflush(stdout);
00147 }
00148 u=u->next;
00149 }
00150 }
00151
00152 long bounds_undo_stack()
00153
00154
00155 {
00156 ptr_stack u=undo_stack;
00157
00158 while (u) {
00159 if ( (GENERIC)u<mem_base
00160 || (GENERIC)u>mem_limit
00161 || (!VALID_ADDRESS(u->a) && !(u->type & undo_action))
00162 ) {
00163 if ((GENERIC)u<mem_base || (GENERIC)u>mem_limit) {
00164 printf("\nUNDO: u=%lx\n",(long)u);
00165 }
00166 else {
00167 printf("\nUNDO: u:%lx type:%ld a:%lx b:%lx next:%lx\n",
00168 (long)u,u->type,u->a,u->b,u->next);
00169 }
00170 fflush(stdout);
00171 return FALSE;
00172 }
00173 u=u->next;
00174 }
00175
00176 return TRUE;
00177 }
00178
00179
00180
00181
00182
00183 static void check_psi_list();
00184 static void check_resid_list();
00185 static void check_choice();
00186 static void check_undo_stack();
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 void fail_all()
00197 {
00198 output_stream=stdout;
00199 choice_stack=NULL;
00200 goal_stack=NULL;
00201 undo_stack=NULL;
00202 abort_life(TRUE);
00203
00204 stdin_cleareof();
00205 open_input_file("stdin");
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 void check_attr();
00220 void check_psi_term();
00221 void check_definition();
00222 void check_resid_block();
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 static void compress()
00233 {
00234 GENERIC addr, new_addr;
00235 long len, i;
00236
00237
00238
00239 addr=new_addr=mem_base;
00240 while (addr<=stack_pointer) {
00241 len = *(addr+delta);
00242 if (len) {
00243
00244
00245 if (len==LONELY) len=ALIGN;
00246 else if (len & (ALIGN-1)) len=len-(len & (ALIGN-1))+ALIGN;
00247
00248 assert((len & (ALIGN-1))==0);
00249 len /= sizeof(*addr);
00250 assert(len>0);
00251
00252 for (i=0; i<len; i++) {
00253 *new_addr = *addr;
00254 if (i>0) {
00255 if (*(addr+delta)>=len)
00256 assert(i>0 ? *(addr+delta)<len : TRUE);
00257 }
00258 assert(VALID_ADDRESS(new_addr));
00259 *(addr+delta) = (long)new_addr + 1;
00260 #ifdef prlDEBUG
00261 if (*(addr+delta) & 1 == 0)
00262 printf ("compress: could be a bug ...\n");
00263 #endif
00264 addr++;
00265 new_addr++;
00266 }
00267 }
00268 else
00269 addr++;
00270 }
00271 other_pointer=stack_pointer;
00272 stack_pointer=new_addr;
00273
00274
00275
00276 addr=new_addr=mem_limit;
00277 addr--;
00278
00279
00280 while (addr>=heap_pointer) {
00281 skip_addr:
00282 len= *(addr+delta);
00283 if (len) {
00284 if (len!=LONELY) {
00285
00286 if (len & (ALIGN-1)) len=len-(len & (ALIGN-1))+ALIGN;
00287 assert((len & (ALIGN-1))==0);
00288 len /= sizeof (*addr);
00289 assert(len>0);
00290
00291 } else {
00292 GENERIC a;
00293
00294 if (len & (ALIGN-1)) len=len-(len & (ALIGN-1))+ALIGN;
00295 assert((len & (ALIGN-1))==0);
00296 len /= sizeof (*addr);
00297 assert(len==1);
00298
00299
00300
00301 a=addr;
00302 do {
00303 a--;
00304 } while (a>=heap_pointer &&
00305 (*(a+delta)==0 || *(a+delta)==LONELY));
00306 if (a>=heap_pointer && *(a+delta)/sizeof(*a)+a>addr) {
00307 addr=a;
00308 goto skip_addr;
00309 }
00310 }
00311
00312
00313 addr += len;
00314 for (i=0; i<len; i++) {
00315 addr--;
00316 new_addr--;
00317 *new_addr = *addr;
00318 assert(VALID_ADDRESS(new_addr));
00319 *(addr+delta) = (long)new_addr + 1;
00320 }
00321 }
00322 addr--;
00323 }
00324 heap_pointer=new_addr;
00325 }
00326
00327
00328
00329 #define UNCHECKED(P) (! *((GENERIC)(P)+delta))
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 #ifdef CLIFE
00344 long unchecked (p, len)
00345 #else
00346 static long unchecked (p, len)
00347 #endif
00348 GENERIC *p;
00349 long len;
00350 {
00351 GENERIC addr;
00352 long result=FALSE, value;
00353
00354 assert(len>0);
00355 if ((unsigned long)*p>MAX_BUILT_INS) {
00356 #ifdef GCTEST
00357 if (!VALID_ADDRESS(*p)) {
00358 printf("p=%lx,*p=%lx\n",p,*p);
00359 }
00360 #endif
00361 assert(VALID_ADDRESS(*p));
00362 addr = *p + delta;
00363 value = *addr;
00364 switch (pass) {
00365 case 1:
00366 #ifdef GCTEST
00367 if (FALSE ) {
00368
00369 printf("len=%ld,value=%ld\n",len,value);
00370 fflush(stdout);
00371 }
00372 #endif
00373
00374 if (!value || value==LONELY) {
00375
00376 result=TRUE;
00377 *addr=len;
00378 #ifdef prlDEBUG
00379 amount_used+=len;
00380 #endif
00381 }
00382 else if (value < len && len != LONELY) {
00383 Errorline("in garbage collection, %d < %d.\n", value, len);
00384 }
00385 else if (value > len && len != LONELY) {
00386 Errorline("in garbage collection, %d > %d.\n", value, len);
00387 }
00388 break;
00389 case 2:
00390 if (value & 1) {
00391 value--;
00392 *addr=value;
00393 #ifdef prlDEBUG
00394 amount_used+=len;
00395 #endif
00396 result=TRUE;
00397 }
00398 if (!VALID_ADDRESS(value))
00399 assert(VALID_ADDRESS(value));
00400 *p = (GENERIC) value;
00401 break;
00402 }
00403 }
00404 return result;
00405 }
00406
00407
00408
00409
00410
00411
00412 static void check_string (s)
00413 GENERIC *s;
00414 {
00415 GENERIC addr;
00416 long value;
00417 long bytes;
00418
00419 if ((unsigned long) *s > MAX_BUILT_INS) {
00420 switch (pass) {
00421 case 1:
00422 bytes=strlen((char *)*s)+1;
00423
00424
00425
00426
00427
00428
00429
00430 unchecked(s, (bytes==LONELY)?bytes+1:bytes);
00431 break;
00432 case 2:
00433 addr=(*s+delta);
00434 value= *addr;
00435 if (value & 1) {
00436 value--;
00437 *s=(GENERIC)value;
00438 *addr=value;
00439 #ifdef prlDEBUG
00440 amount_used+=strlen(*s)+1;
00441 #endif
00442 }
00443 *s=(GENERIC)value;
00444 break;
00445 }
00446 }
00447 }
00448
00449
00450
00451
00452
00453 static void check_bytedata(s)
00454 GENERIC *s;
00455 {
00456 GENERIC addr;
00457 long value;
00458 if ((unsigned long) *s > MAX_BUILT_INS) {
00459 unsigned long bytes = *((unsigned long *) *s);
00460 unsigned long size = bytes + sizeof(bytes);
00461 switch (pass) {
00462 case 1:
00463 unchecked(s,size);
00464 break;
00465 case 2:
00466 addr=(*s+delta);
00467 value= *addr;
00468 if (value & 1) {
00469 value--;
00470 *s=(GENERIC) value;
00471 *addr=value;
00472 #ifdef prlDEBUG
00473 amount_used+=size;
00474 #endif
00475 }
00476 *s=(GENERIC)value;
00477 break;
00478 }
00479 }
00480 }
00481
00482
00483
00484
00485 static void check_code(c)
00486 ptr_int_list *c;
00487 {
00488 while (unchecked(c,sizeof(int_list)))
00489 c= &((*c)->next);
00490 }
00491
00492
00493
00494
00495
00496
00497 static void check_pair_list(p)
00498 ptr_pair_list *p;
00499 {
00500 while (unchecked(p,sizeof(pair_list))) {
00501 check_psi_term(&((*p)->a));
00502 check_psi_term(&((*p)->b));
00503 p= &((*p)->next);
00504 }
00505 }
00506
00507
00508
00509
00510
00511
00512
00513 static void check_triple_list(p)
00514 ptr_triple_list *p;
00515 {
00516 while (unchecked(p,sizeof(triple_list))) {
00517 check_psi_term(&((*p)->a));
00518 check_psi_term(&((*p)->b));
00519 check_definition(&((*p)->c));
00520 p= &((*p)->next);
00521 }
00522 }
00523
00524
00525
00526
00527
00528
00529 static void check_kids(c)
00530 ptr_int_list *c;
00531 {
00532 while (unchecked(c,sizeof(int_list))) {
00533 check_definition(&((*c)->value));
00534 c= &((*c)->next);
00535 }
00536 }
00537
00538
00539
00540
00541
00542
00543 static void check_operator_data(op)
00544 ptr_operator_data *op;
00545 {
00546 while (unchecked(op,sizeof(operator_data))) {
00547 op = &((*op)->next);
00548 }
00549 }
00550
00551
00552 static void check_module();
00553 void check_hash_table();
00554 static void check_keyword();
00555
00556
00557
00558
00559
00560
00561
00562 static void check_module_list(c)
00563
00564 ptr_int_list *c;
00565 {
00566 while (unchecked(c,sizeof(int_list))) {
00567 check_module(&((*c)->value));
00568 c= &((*c)->next);
00569 }
00570 }
00571
00572
00573
00574
00575
00576 static void check_module_tree(n)
00577 ptr_node *n;
00578 {
00579 if (unchecked(n,sizeof(node))) {
00580 check_module_tree(&((*n)->left));
00581 check_string(&((*n)->key));
00582 check_module(&((*n)->data));
00583 check_module_tree(&((*n)->right));
00584 }
00585 }
00586
00587
00588
00589
00590
00591
00592
00593 static void check_module(m)
00594
00595 ptr_module *m;
00596 {
00597 if(unchecked(m,sizeof(struct wl_module))) {
00598 check_string(&((*m)->module_name));
00599 check_string(&((*m)->source_file));
00600 check_module_list(&((*m)->open_modules));
00601 check_module_list(&((*m)->inherited_modules));
00602 check_hash_table((*m)->symbol_table);
00603 }
00604 }
00605
00606
00607
00608
00609
00610
00611
00612
00613 void check_hash_table(table)
00614
00615 ptr_hash_table table;
00616 {
00617 long i;
00618
00619 for(i=0;i<table->size;i++)
00620 if(table->data[i])
00621 check_keyword(&(table->data[i]));
00622 }
00623
00624
00625
00626
00627
00628
00629
00630 static void check_keyword(k)
00631
00632 ptr_keyword *k;
00633 {
00634 if(unchecked(k,sizeof(struct wl_keyword))) {
00635 check_module(&((*k)->module));
00636 check_string(&((*k)->symbol));
00637 check_string(&((*k)->combined_name));
00638 check_definition(&((*k)->definition));
00639 }
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649 void check_definition(d)
00650 ptr_definition *d;
00651 {
00652 if(unchecked(d,sizeof(definition))) {
00653
00654 check_keyword(&((*d)->keyword));
00655
00656 #ifdef prlDEBUG
00657 printf("%lx %20s %ld\n",*d,(*d)->keyword->symbol,amount_used);
00658 #endif
00659
00660 check_code(&((*d)->code));
00661 check_pair_list(&((*d)->rule));
00662 check_triple_list(&((*d)->properties));
00663
00664 if ((*d)->type==type) {
00665 check_kids(&((*d)->parents));
00666 check_kids(&((*d)->children));
00667 }
00668
00669 check_psi_term(&((*d)->global_value));
00670 check_psi_term(&((*d)->init_value));
00671
00672 check_operator_data(&((*d)->op_data));
00673
00674 #ifdef CLIFE
00675 check_block_def(&((*d)->block_def));
00676 #endif
00677 }
00678 }
00679
00680
00681
00682
00683
00684
00685 void check_definition_list()
00686
00687 {
00688 ptr_definition *d;
00689
00690 d= &first_definition;
00691
00692 while(*d) {
00693 check_definition(d);
00694 d= &((*d)->next);
00695 }
00696 }
00697
00698
00699
00700
00701
00702
00703
00704 static void check_def_code(d)
00705 ptr_definition *d;
00706 {
00707 if (unchecked(d,sizeof(definition)))
00708 check_code(&((*d)->code));
00709
00710
00711 }
00712
00713
00714
00715
00716
00717
00718
00719 static void check_def_rest(d)
00720 ptr_definition *d;
00721 {
00722 if (*d) {
00723 check_keyword(&((*d)->keyword));
00724 check_pair_list(&((*d)->rule));
00725 check_triple_list(&((*d)->properties));
00726
00727 if ((*d)->type==type) {
00728 check_kids(&((*d)->parents));
00729 check_kids(&((*d)->children));
00730 }
00731 check_operator_data(&((*d)->op_data));
00732 #ifdef CLIFE
00733 check_block_def(&((*d)->block_def));
00734 #endif
00735 }
00736 }
00737
00738
00739
00740
00741
00742
00743
00744 static void check_symbol(n)
00745 ptr_node *n;
00746 {
00747 if (unchecked(n,sizeof(node))) {
00748 check_symbol(&((*n)->left));
00749 check_string(&((*n)->key));
00750 check_keyword(&((*n)->data));
00751 check_symbol(&((*n)->right));
00752 }
00753 }
00754
00755
00756
00757
00758
00759
00760 static void check_type_disj(p)
00761 ptr_int_list *p;
00762 {
00763 while (unchecked(p,sizeof(int_list))) {
00764 check_definition(&((*p)->value));
00765 p= &((*p)->next);
00766 }
00767 }
00768
00769
00770
00771
00772
00773
00774
00775
00776 static void check_goal_stack(g)
00777 ptr_goal *g;
00778 {
00779 while (unchecked(g,sizeof(goal))) {
00780
00781 switch ((*g)->type) {
00782
00783 case fail:
00784 break;
00785
00786 case unify:
00787 case unify_noeval:
00788 check_psi_term(&((*g)->a));
00789 check_psi_term(&((*g)->b));
00790 break;
00791
00792 case prove:
00793 check_psi_term(&((*g)->a));
00794 if ((unsigned long)(*g)->b!=DEFRULES) check_pair_list(&((*g)->b));
00795 check_pair_list(&((*g)->c));
00796 break;
00797
00798 case disj:
00799 check_psi_term(&((*g)->a));
00800 check_psi_term(&((*g)->b));
00801 break;
00802
00803 case what_next:
00804
00805 break;
00806
00807 case eval:
00808 check_psi_term(&((*g)->a));
00809 check_psi_term(&((*g)->b));
00810 check_pair_list(&((*g)->c));
00811 break;
00812
00813 case load:
00814 check_psi_term(&((*g)->a));
00815 check_string(&((*g)->c));
00816 break;
00817
00818 case match:
00819 check_psi_term(&((*g)->a));
00820 check_psi_term(&((*g)->b));
00821 check_resid_block(&((*g)->c));
00822 break;
00823
00824 case general_cut:
00825
00826 if (pass==1 && (ptr_choice_point)(*g)->a>choice_stack)
00827 (*g)->a=(ptr_psi_term)choice_stack;
00828 unchecked(&((*g)->a),LONELY);
00829 break;
00830
00831 case eval_cut:
00832 check_psi_term(&((*g)->a));
00833
00834 if (pass==1 && (ptr_choice_point)(*g)->b>choice_stack)
00835 (*g)->b=(ptr_psi_term)choice_stack;
00836 unchecked(&((*g)->b),LONELY);
00837 check_resid_block(&((*g)->c));
00838 break;
00839
00840 case freeze_cut:
00841 case implies_cut:
00842 check_psi_term(&((*g)->a));
00843
00844 if (pass==1 && (ptr_choice_point)(*g)->b>choice_stack)
00845 (*g)->b=(ptr_psi_term)choice_stack;
00846 unchecked(&((*g)->b),LONELY);
00847 check_resid_block(&((*g)->c));
00848 break;
00849
00850 case type_disj:
00851 check_psi_term(&((*g)->a));
00852 check_type_disj(&((*g)->b));
00853 break;
00854
00855 case clause:
00856 check_psi_term(&((*g)->a));
00857 check_psi_term(&((*g)->b));
00858 unchecked(&((*g)->c),LONELY);
00859
00860 break;
00861
00862 case del_clause:
00863 check_psi_term(&((*g)->a));
00864 check_psi_term(&((*g)->b));
00865 unchecked(&((*g)->c),LONELY);
00866
00867 break;
00868
00869 case retract:
00870 unchecked(&((*g)->a),LONELY);
00871
00872
00873 break;
00874
00875 default:
00876 Errorline("in garbage collection, bad goal on stack.\n");
00877 }
00878
00879 g= &((*g)->next);
00880 }
00881 }
00882
00883
00884
00885
00886
00887
00888 static void check_resid(r)
00889 ptr_residuation *r;
00890 {
00891 ptr_int_list code;
00892 ptr_list *l;
00893
00894 while (unchecked(r,sizeof(residuation))) {
00895
00896 if ((*r)->sortflag)
00897 check_definition(&((*r)->bestsort));
00898 else
00899 check_code(&((*r)->bestsort));
00900
00901
00902 code = (*r)->sortflag ? ((ptr_definition)((*r)->bestsort))->code
00903 : (ptr_int_list)(*r)->bestsort;
00904
00905 if ((*r)->value) {
00906 if (code==alist->code) {
00907 l=(ptr_list *) &((*r)->value);
00908 if (l)
00909 printf("Found an old list!!\n");
00910 }
00911 else if (sub_CodeType(code,real->code))
00912 unchecked(&((*r)->value),sizeof(REAL));
00913 else if (sub_CodeType(code,quoted_string->code))
00914 check_string(&((*r)->value));
00915
00916 else if (sub_CodeType(code,sys_bytedata->code))
00917 check_bytedata(&((*r)->value));
00918 else if (sub_CodeType(code,cut->code)) {
00919 if (pass==1 && (*r)->value>(GENERIC)choice_stack)
00920 (*r)->value=(GENERIC)choice_stack;
00921 unchecked(&((*r)->value),LONELY);
00922 }
00923 else if (sub_CodeType(code,variable->code))
00924 check_string(&((*r)->value));
00925 }
00926
00927 check_goal_stack(&((*r)->goal));
00928 r= &((*r)->next);
00929 }
00930 }
00931
00932
00933
00934
00935
00936
00937 void check_resid_block(rb)
00938 ptr_resid_block *rb;
00939 {
00940 if (*rb) {
00941 if (unchecked(rb,sizeof(resid_block))) {
00942 check_goal_stack(&((*rb)->ra));
00943 check_resid_list(&((*rb)->rv));
00944
00945 unchecked(&((*rb)->md),LONELY);
00946
00947
00948 }
00949 }
00950 }
00951
00952
00953
00954
00955
00956
00957 void check_psi_term(t)
00958 ptr_psi_term *t;
00959 {
00960 ptr_list *l;
00961
00962 while (unchecked(t,sizeof(psi_term))) {
00963
00964
00965 if (pass==1 && (GENERIC)(*t)>=heap_pointer && (GENERIC)(*t)<mem_limit) {
00966 assert((*t)->resid==NULL);
00967 }
00968 check_definition(&((*t)->type));
00969 check_attr(&((*t)->attr_list));
00970
00971 if ((*t)->value) {
00972
00973 if ((*t)->type==alist) {
00974 l=(ptr_list *) &((*t)->value);
00975 if (l)
00976 printf("Found an old list!\n");
00977 }
00978 else
00979
00980 if (sub_type((*t)->type,real))
00981 unchecked(&((*t)->value),sizeof(REAL));
00982 else if (sub_type((*t)->type,quoted_string))
00983 check_string(&((*t)->value));
00984
00985 else if (sub_type((*t)->type,sys_bytedata))
00986 check_bytedata(&((*t)->value));
00987 #ifdef CLIFE
00988 else if ((*t)->type->type==block) {
00989 check_block_value(&((*t)->value));
00990 }
00991 #endif
00992 else if ((*t)->type==cut) {
00993
00994 if (pass==1 && (*t)->value>(GENERIC)choice_stack)
00995 (*t)->value=(GENERIC)choice_stack;
00996 unchecked(&((*t)->value),LONELY);
00997 }
00998 else if (sub_type((*t)->type,variable))
00999 check_string(&((*t)->value));
01000 else if ((*t)->type!=stream)
01001 Errorline("non-NULL value field in garbage collector, type='%s', value=%d.\n",
01002 (*t)->type->keyword->combined_name,
01003 (*t)->value);
01004 }
01005
01006
01007 if ((*t)->resid)
01008 check_resid(&((*t)->resid));
01009
01010 t = &((*t)->coref);
01011 }
01012 }
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 void check_attr(n)
01023 ptr_node *n;
01024 {
01025 while (unchecked(n,sizeof(node))) {
01026 check_attr(&((*n)->left));
01027 check_string(&((*n)->key));
01028 check_psi_term(&((*n)->data));
01029
01030 n = &((*n)->right);
01031
01032 }
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045 void check_gamma_code()
01046 {
01047 long i;
01048
01049 if (unchecked(&gamma_table,type_count*sizeof(ptr_definition))) {
01050 for (i=0;i<type_count;i++)
01051 check_def_code(&(gamma_table[i]));
01052 }
01053 }
01054
01055
01056
01057
01058
01059
01060 static void check_gamma_rest()
01061 {
01062 long i;
01063
01064 for (i=0;i<type_count;i++)
01065 check_def_rest(&(gamma_table[i]));
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075 static void check_undo_stack(s)
01076 ptr_stack *s;
01077 {
01078 while (unchecked(s,sizeof(stack))) {
01079
01080 switch((*s)->type) {
01081
01082 case psi_term_ptr:
01083 check_psi_term(&((*s)->b));
01084 break;
01085
01086 case resid_ptr:
01087 check_resid(&((*s)->b));
01088 break;
01089
01090 case int_ptr:
01091
01092 break;
01093
01094 case def_ptr:
01095 check_definition(&((*s)->b));
01096 break;
01097
01098 case code_ptr:
01099 check_code(&((*s)->b));
01100 break;
01101
01102 case goal_ptr:
01103 check_goal_stack(&((*s)->b));
01104 break;
01105
01106 case cut_ptr:
01107 break;
01108 #ifdef CLIFE
01109 case block_ptr:
01110 check_block_value(&((*s)->b));
01111 break;
01112
01113 #endif
01114
01115 case destroy_window:
01116 case show_window:
01117 case hide_window:
01118
01119 break;
01120 }
01121
01122 s= &((*s)->next);
01123 }
01124 }
01125
01126
01127
01128
01129
01130
01131 static void check_choice_structs(c)
01132 ptr_choice_point *c;
01133 {
01134 while(unchecked(c,sizeof(choice_point))) {
01135 c= &((*c)->next);
01136 }
01137 }
01138
01139 static void check_choice(c)
01140 ptr_choice_point *c;
01141 {
01142 while(*c) {
01143 check_undo_stack(&((*c)->undo_point));
01144 check_goal_stack(&((*c)->goal_stack));
01145 c= &((*c)->next);
01146 }
01147 }
01148
01149
01150
01151
01152
01153
01154
01155
01156 static void check_special_addresses()
01157 {
01158 ptr_choice_point c;
01159 ptr_stack p;
01160 ptr_goal g;
01161
01162 c=choice_stack;
01163 while(c) {
01164
01165 unchecked(&(c->stack_top),LONELY);
01166 c=c->next;
01167 }
01168
01169 p=undo_stack;
01170 while (p) {
01171 if (!(p->type & undo_action)) {
01172
01173 if (VALID_RANGE(p->a)) unchecked(&(p->a),LONELY);
01174 if (p->type==cut_ptr) unchecked(&(p->b),LONELY);
01175 }
01176 p=p->next;
01177 }
01178 }
01179
01180
01181
01182
01183
01184
01185
01186 static void check_psi_list(l)
01187 ptr_int_list *l;
01188 {
01189 while(unchecked(l,sizeof(int_list))) {
01190 check_psi_term(&((*l)->value));
01191 l= &((*l)->next);
01192 }
01193 }
01194
01195
01196
01197
01198
01199
01200
01201 static void check_resid_list(l)
01202 ptr_resid_list *l;
01203 {
01204 while(unchecked(l,sizeof(resid_list))) {
01205 check_psi_term(&((*l)->var));
01206 check_psi_term(&((*l)->othervar));
01207 l= &((*l)->next);
01208 }
01209 }
01210
01211
01212
01213
01214
01215
01216
01217 static void check_var(n)
01218 ptr_node *n;
01219 {
01220 if (unchecked(n,sizeof(node))) {
01221 check_var(&((*n)->left));
01222 check_string(&((*n)->key));
01223 check_psi_term(&((*n)->data));
01224 check_var(&((*n)->right));
01225 }
01226 }
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 static void check()
01246 {
01247 #ifdef prlDEBUG
01248 amount_used=0;
01249 #endif
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 check_choice_structs(&choice_stack);
01261
01262 assert((pass==1?bounds_undo_stack():TRUE));
01263 check_gamma_code();
01264
01265
01266
01267 check_gamma_rest();
01268
01269 assert((pass==1?bounds_undo_stack():TRUE));
01270
01271 check_definition(&abortsym);
01272 check_definition(&aborthooksym);
01273
01274 check_definition(&add_module1);
01275 check_definition(&add_module2);
01276 check_definition(&add_module3);
01277
01278 check_definition(&and);
01279 check_definition(&apply);
01280 check_definition(&boolean);
01281 check_definition(&boolpredsym);
01282 check_definition(&built_in);
01283 check_definition(&colonsym);
01284 check_definition(&commasym);
01285 check_definition(&comment);
01286
01287 check_definition(&constant);
01288 check_definition(&cut);
01289 check_definition(&disjunction);
01290 check_definition(&disj_nil);
01291 check_definition(&eof);
01292 check_definition(&eqsym);
01293 check_definition(&false);
01294 check_definition(&funcsym);
01295 check_definition(&functor);
01296 check_definition(&iff);
01297 check_definition(&integer);
01298 check_definition(&alist);
01299 check_definition(&life_or);
01300 check_definition(&minus_symbol);
01301 check_definition(&nil);
01302 check_definition(¬hing);
01303 check_definition(&predsym);
01304 check_definition("e);
01305 check_definition("ed_string);
01306 check_definition(&real);
01307 check_definition(&stream);
01308 check_definition(&succeed);
01309 check_definition(&such_that);
01310 check_definition(&top);
01311 check_definition(&true);
01312 check_definition(×ym);
01313 check_definition(&tracesym);
01314 check_definition(&typesym);
01315 check_definition(&variable);
01316 check_definition(&opsym);
01317 check_definition(&loadsym);
01318 check_definition(&dynamicsym);
01319 check_definition(&staticsym);
01320 check_definition(&encodesym);
01321 check_definition(&listingsym);
01322
01323 check_definition(&delay_checksym);
01324 check_definition(&eval_argsym);
01325 check_definition(&inputfilesym);
01326 check_definition(&call_handlersym);
01327 check_definition(&xf_sym);
01328 check_definition(&fx_sym);
01329 check_definition(&yf_sym);
01330 check_definition(&fy_sym);
01331 check_definition(&xfx_sym);
01332 check_definition(&xfy_sym);
01333 check_definition(&yfx_sym);
01334 check_definition(&nullsym);
01335
01336
01337 check_definition(&final_dot);
01338 check_definition(&final_question);
01339
01340 check_sys_definitions();
01341
01342 #ifdef X11
01343 check_definition(&xevent);
01344 check_definition(&xmisc_event);
01345 check_definition(&xkeyboard_event);
01346 check_definition(&xbutton_event);
01347 check_definition(&xconfigure_event);
01348 check_definition(&xmotion_event);
01349 check_definition(&xenter_event);
01350 check_definition(&xleave_event);
01351 check_definition(&xexpose_event);
01352 check_definition(&xdestroy_event);
01353 check_definition(&xdisplay);
01354 check_definition(&xdrawable);
01355 check_definition(&xwindow);
01356 check_definition(&xpixmap);
01357 check_definition(&xgc);
01358 check_definition(&xdisplaylist);
01359 #endif
01360
01361
01362
01363 check_string(&one);
01364 check_string(&two);
01365 check_string(&three);
01366 check_string(&year_attr);
01367 check_string(&month_attr);
01368 check_string(&day_attr);
01369 check_string(&hour_attr);
01370 check_string(&minute_attr);
01371 check_string(&second_attr);
01372 check_string(&weekday_attr);
01373
01374 check_psi_term(&input_state);
01375 check_psi_term(&stdin_state);
01376 check_psi_term(&error_psi_term);
01377 check_psi_term(&saved_psi_term);
01378 check_psi_term(&old_saved_psi_term);
01379 check_psi_term(&null_psi_term);
01380 check_psi_term(&old_state);
01381
01382 assert((pass==1?bounds_undo_stack():TRUE));
01383 #ifdef X11
01384 check_psi_term(&xevent_list);
01385 check_psi_term(&xevent_existing);
01386 #endif
01387
01388 check_choice(&choice_stack);
01389
01390
01391
01392
01393
01394
01395 check_definition_list();
01396
01397
01398
01399
01400
01401 check_module_tree(&module_table);
01402 check_module(&sys_module);
01403 check_module(&bi_module);
01404 check_module(&user_module);
01405 check_module(&no_module);
01406 check_module(&x_module);
01407 check_module(&syntax_module);
01408 check_module(¤t_module);
01409
01410
01411
01412
01413
01414 check_var(&var_tree);
01415
01416 check_goal_stack(&goal_stack);
01417 check_goal_stack(&aim);
01418
01419 if (TRUE ) check_resid_list(&resid_vars);
01420
01421 check_goal_stack(&resid_aim);
01422
01423 assert((pass==1?bounds_undo_stack():TRUE));
01424 check_undo_stack(&undo_stack);
01425
01426 assert((pass==1?bounds_undo_stack():TRUE));
01427 check_special_addresses();
01428
01429 assert((pass==1?bounds_undo_stack():TRUE));
01430 }
01431
01432
01433 void print_gc_info(timeflag)
01434 long timeflag;
01435 {
01436 fprintf(stderr," [%ld%% free (%ldK), %ld%% heap, %ld%% stack",
01437 (100*((unsigned long)heap_pointer-(unsigned long)stack_pointer)+mem_size/2)/mem_size,
01438 ((unsigned long)heap_pointer-(unsigned long)stack_pointer+512)/1024,
01439 (100*((unsigned long)mem_limit-(unsigned long)heap_pointer)+mem_size/2)/mem_size,
01440 (100*((unsigned long)stack_pointer-(unsigned long)mem_base)+mem_size/2)/mem_size);
01441 if (timeflag) {
01442 fprintf(stderr,", %1.3fs cpu (%ld%%)",
01443 gc_time,
01444 (unsigned long)(0.5+100*gc_time/(life_time+gc_time)));
01445 }
01446 fprintf(stderr,"]\n");
01447 }
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467 void garbage()
01468 {
01469 GENERIC addr;
01470 #ifndef OS2_PORT
01471 struct tms garbage_start_time,garbage_end_time;
01472 #else
01473 float garbage_start_time,garbage_end_time;
01474 #endif
01475 long start_number_cells, end_number_cells;
01476
01477 start_number_cells = (stack_pointer-mem_base) + (mem_limit-heap_pointer);
01478
01479 times(&garbage_start_time);
01480
01481
01482 #ifndef OS2_PORT
01483 life_time=(garbage_start_time.tms_utime - last_garbage_time.tms_utime)/60.0;
01484 #else
01485 life_time=(garbage_start_time - last_garbage_time)/60.0;
01486 #endif
01487
01488 if (verbose) {
01489 fprintf(stderr,"*** Garbage Collect ");
01490 fprintf(stderr,"\n*** Begin");
01491 print_gc_info(FALSE);
01492 fflush(stderr);
01493 }
01494
01495
01496
01497 for (addr = other_base; addr < other_limit; addr ++)
01498 *addr = 0;
01499
01500 pass=1;
01501
01502 check();
01503 #ifdef GCVERBOSE
01504 fprintf(stderr,"- Done pass 1 ");
01505 #endif
01506
01507 assert(bounds_undo_stack());
01508 compress();
01509 #ifdef GCVERBOSE
01510 fprintf(stderr,"- Done compress ");
01511 #endif
01512
01513 pass=2;
01514
01515 check();
01516 assert(bounds_undo_stack());
01517 #ifdef GCVERBOSE
01518 fprintf(stderr,"- Done pass 2\n");
01519 #endif
01520
01521 clear_copy();
01522
01523 printed_pointers=NULL;
01524 pointer_names=NULL;
01525
01526 times(&garbage_end_time);
01527 #ifndef OS2_PORT
01528 gc_time=(garbage_end_time.tms_utime - garbage_start_time.tms_utime)/60.0;
01529 #else
01530 gc_time=(garbage_end_time - garbage_start_time)/60.0;
01531 #endif
01532 garbage_time+=gc_time;
01533
01534 if (verbose) {
01535 fprintf(stderr,"*** End ");
01536 print_gc_info(TRUE);
01537 stack_info(stderr);
01538 fflush(stderr);
01539 }
01540
01541 last_garbage_time=garbage_end_time;
01542
01543 end_number_cells = (stack_pointer-mem_base) + (mem_limit-heap_pointer);
01544 assert(end_number_cells<=start_number_cells);
01545
01546 ignore_eff=FALSE;
01547
01548 }
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566 GENERIC heap_alloc (s)
01567 long s;
01568 {
01569 if (s & (ALIGN-1))
01570 s = s - (s & (ALIGN-1))+ALIGN;
01571
01572 s /= sizeof (*heap_pointer);
01573
01574 heap_pointer -= s;
01575
01576 if (stack_pointer>heap_pointer)
01577 Errorline("the heap overflowed into the stack.\n");
01578
01579 return heap_pointer;
01580 }
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590 GENERIC stack_alloc(s)
01591 long s;
01592 {
01593 GENERIC r;
01594
01595 r = stack_pointer;
01596
01597 if (s & (ALIGN-1))
01598 s = s - (s & (ALIGN-1)) + ALIGN;
01599
01600 s /= sizeof (*stack_pointer);
01601
01602 stack_pointer += s;
01603
01604 if (stack_pointer>heap_pointer)
01605 Errorline("the stack overflowed into the heap.\n");
01606
01607 return r;
01608 }
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620 void init_memory ()
01621 {
01622 alloc_words=GetIntOption("memory",ALLOC_WORDS);
01623 mem_size=alloc_words*sizeof(long);
01624
01625 mem_base = (GENERIC) malloc(mem_size);
01626 other_base = (GENERIC) malloc(mem_size);
01627
01628 if (mem_base && other_base) {
01629
01630 ALIGNUP(mem_base);
01631 stack_pointer = mem_base;
01632
01633 mem_limit=mem_base+alloc_words-2;
01634 ALIGNUP(mem_limit);
01635 heap_pointer = mem_limit;
01636
01637 ALIGNUP(other_base);
01638 other_pointer = other_base;
01639
01640 other_limit=other_base+alloc_words-2;
01641 ALIGNUP(other_limit);
01642
01643 delta = other_base - mem_base;
01644 buffer = (char *) malloc (PRINT_BUFFER);
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658 }
01659 else
01660 Errorline("Wild_life could not allocate sufficient memory to run.\n\n");
01661 }
01662
01663
01664
01665
01666
01667
01668
01669
01670 long memory_check ()
01671 {
01672 long success=TRUE;
01673
01674 if (heap_pointer-stack_pointer < GC_THRESHOLD) {
01675 if(verbose) fprintf(stderr,"\n");
01676 garbage();
01677
01678 if (heap_pointer-stack_pointer < GC_THRESHOLD+GC_THRESHOLD/10) {
01679 fprintf(stderr,"*********************\n");
01680 fprintf(stderr,"*** OUT OF MEMORY ***\n");
01681 fprintf(stderr,"*********************\n");
01682 fail_all();
01683 success=FALSE;
01684 }
01685 }
01686 return success;
01687 }
01688
01689
01690