/[gcl]/gcl/o/sgbc.c
ViewVC logotype

Diff of /gcl/o/sgbc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9 by camm, Sat Feb 15 00:38:28 2003 UTC revision 1.9.4.1 by camm, Fri Aug 29 20:42:00 2003 UTC
# Line 887  sgc_contblock_sweep_phase(void) { Line 887  sgc_contblock_sweep_phase(void) {
887      e = pagetochar(j);      e = pagetochar(j);
888      for (p = s;  p < e;) {      for (p = s;  p < e;) {
889        if (get_mark_bit((int *)p)) {        if (get_mark_bit((int *)p)) {
890          p += PTR_ALIGN;          /* SGC cont pages: cont blocks must be no smaller than
891               sizeof(struct contblock), and must not have a sweep
892               granularity greater than this amount (e.g. CPTR_ALIGN) if
893               contblock leaks are to be avoided.  Used to be aligned at
894               PTR_ALIGN. CM 20030827 */
895            p += CPTR_ALIGN;
896          continue;          continue;
897        }        }
898        q = p + PTR_ALIGN;        q = p + CPTR_ALIGN;
899        while (q < e) {        while (q < e) {
900          if (!get_mark_bit((int *)q)) {          if (!get_mark_bit((int *)q)) {
901            q += PTR_ALIGN;            q += CPTR_ALIGN;
902            continue;            continue;
903          }          }
904          break;          break;
905        }        }
906        insert_contblock(p, q - p);        insert_contblock(p, q - p);
907        p = q + PTR_ALIGN;        p = q + CPTR_ALIGN;
908      }      }
909      i = j + 1;      i = j + 1;
910    }    }
# Line 961  sgc_count_type(int t) { Line 966  sgc_count_type(int t) {
966    return count;    return count;
967  }  }
968    
969    #ifdef SGC_CONT_DEBUG
970    void
971    overlap_check(struct contblock *t1,struct contblock *t2) {
972    
973      struct contblock *p;
974    
975      for (;t1;t1=t1->cb_link) {
976    
977        if (!inheap(t1)) {
978          fprintf(stderr,"%p not in heap\n",t1);
979          exit(1);
980        }
981    
982        for (p=t2;p;p=p->cb_link) {
983    
984          if (!inheap(p)) {
985            fprintf(stderr,"%p not in heap\n",t1);
986            exit(1);
987          }
988    
989          if ((p<=t1 && (void *)p+p->cb_size>(void *)t1) ||
990              (t1<=p && (void *)t1+t1->cb_size>(void *)p)) {
991            fprintf(stderr,"Overlap %u %p  %u %p\n",t1->cb_size,t1,p->cb_size,p);
992            exit(1);
993          }
994          
995          if (p==p->cb_link) {
996            fprintf(stderr,"circle detected at %p\n",p);
997            exit(1);
998          }
999    
1000        }
1001            
1002        if (t1==t1->cb_link) {
1003          fprintf(stderr,"circle detected at %p\n",t1);
1004          exit(1);
1005        }
1006    
1007      }
1008    
1009    }
1010    
1011    void
1012    tcc(struct contblock *t) {
1013    
1014      for (;t;t=t->cb_link) {
1015    
1016        if (!inheap(t)) {
1017          fprintf(stderr,"%p not in heap\n",t);
1018          break;
1019        }
1020    
1021        fprintf(stderr,"%u at %p\n",t->cb_size,t);
1022    
1023        if (t==t->cb_link) {
1024          fprintf(stderr,"circle detected at %p\n",t);
1025          break;
1026        }
1027    
1028      }
1029    
1030    }
1031    
1032    #endif    
1033    
1034  int  int
1035  sgc_start(void) {  sgc_start(void) {
1036    
# Line 985  sgc_start(void) { Line 1055  sgc_start(void) {
1055      {      {
1056        int maxp=0;        int maxp=0;
1057        int j;        int j;
1058        int minfree = tm->tm_sgc_minfree;        /* SGC cont pages: This used to be simply set to tm_sgc_minfree,
1059             which is a definite bug, as minfree could then be zero,
1060             leading this type to claim SGC pages not of its type as
1061             specified in type_map.  CM 20030827*/
1062          int minfree = tm->tm_sgc_minfree > 0 ? tm->tm_sgc_minfree : 1 ;
1063        int count;        int count;
1064        bzero(free_map,npages*sizeof(short));        bzero(free_map,npages*sizeof(short));
1065        f = tm->tm_free;        f = tm->tm_free;
# Line 1031  sgc_start(void) { Line 1105  sgc_start(void) {
1105            goto FIND_FREE_PAGES;              goto FIND_FREE_PAGES;  
1106        }        }
1107      }      }
1108    
1109    /* SGC cont pages: Here we implement the contblock page division into
1110       SGC and non-SGC types.  Unlike the other types, we need *whole*
1111       free pages for contblock SGC, as there is no psersistent data
1112       element (e.g. .m) on an allocated block itself which can indicate
1113       its live status.  If anything on a page which is to be marked
1114       read-only points to a live object on an SGC cont page, it will
1115       never be marked and will be erroneously swept.  It is also possible
1116       for dead objects to unnecessarily mark dead regions on SGC pages
1117       and delay sweeping until the pointing type is GC'ed if SGC is
1118       turned off for the pointing type, e.g. tm_sgc=0. (This was so by
1119       default for a number of types, including bignums, and has now been
1120       corrected in init_alloc in alloc.c.) We can't get around this
1121       AFAICT, as old data on (writable) SGC pages must be marked lest it
1122       is lost, and (old) data on now writable non-SGC pages might point
1123       to live regions on SGC pages, yet might not themselves be reachable
1124       from the mark origin through an unbroken chain of writable pages.
1125       In any case, the possibility of a lot of garbage marks on contblock
1126       pages, especially when the blocks are small as in bignums, makes
1127       necessary the sweeping of minimal contblocks to prevent leaks. CM
1128       20030827 */
1129      {
1130    
1131        void *p=NULL;
1132        unsigned i,j,k,count;
1133        struct contblock *new_cb_pointer=NULL,*tmp_cb_pointer=NULL,**cbpp;
1134        
1135        tm=tm_of(t_contiguous);
1136        
1137        /* SGC cont pages:  First count whole free pages available.  CM 20030827 */
1138        for (cbpp=&cb_pointer,count=0;*cbpp;cbpp=&(*cbpp)->cb_link) {
1139          p=PAGE_ROUND_UP((void *)(*cbpp));
1140          k=p-((void *)(*cbpp));
1141          if ((*cbpp)->cb_size<k || (*cbpp)->cb_size-k<PAGESIZE)
1142            continue;
1143          i=((*cbpp)->cb_size-k)/PAGESIZE;
1144          count+=i;
1145        }
1146        count=tm->tm_sgc>count ? tm->tm_sgc - count : 0;
1147        
1148        if (count>0) {
1149          /* SGC cont pages: allocate more if necessary, dumping possible
1150             GBC freed pages onto the old contblock list.  CM 20030827*/
1151          int z=count+1;
1152          void *p1=alloc_contblock(z*PAGESIZE);
1153          p=PAGE_ROUND_UP(p1);
1154          if (p>p1) {
1155            z--;
1156            insert_contblock(p1,p-p1);
1157            insert_contblock(p+z*PAGESIZE,PAGESIZE-(p-p1));
1158          }
1159          tmp_cb_pointer=cb_pointer;
1160          cb_pointer=new_cb_pointer;
1161          /* SGC cont pages: add new pages to new contblock list. p is not
1162             already on any list as ensured by alloc_contblock.  CM
1163             20030827 */
1164          insert_contblock(p,PAGESIZE*z);
1165          new_cb_pointer=cb_pointer;
1166          cb_pointer=tmp_cb_pointer;
1167          for (i=0;i<z;i++)
1168            sgc_type_map[page(p)+i]|= SGC_PAGE_FLAG;
1169        }
1170    
1171        for (cbpp=&cb_pointer;*cbpp;) {
1172          p=PAGE_ROUND_UP((void *)(*cbpp));
1173          k=p-((void *)(*cbpp));
1174          if ((*cbpp)->cb_size<k || (*cbpp)->cb_size-k<PAGESIZE) {
1175            cbpp=&(*cbpp)->cb_link;
1176            continue;
1177          }
1178          i=((*cbpp)->cb_size-k)/PAGESIZE;
1179          i*=PAGESIZE;
1180          j=(*cbpp)->cb_size-i-k;
1181          /* SGC contblock pages:  remove this block from old list CM 20030827 */
1182          *cbpp=(*cbpp)->cb_link;
1183          /* SGC contblock pages:  add fragments old list CM 20030827 */
1184          if (k) {
1185            ncb--;
1186            insert_contblock(p-k,k);
1187          }
1188          if (j) {
1189            ncb--;
1190            insert_contblock(p+i,j);
1191          }
1192          tmp_cb_pointer=cb_pointer;
1193          cb_pointer=new_cb_pointer;
1194          /* SGC contblock pages: add whole pages to new list, p p-k, and
1195             p+i are guaranteed to be distinct when used. CM 20030827 */
1196          insert_contblock(p,i);
1197          new_cb_pointer=cb_pointer;
1198          cb_pointer=tmp_cb_pointer;
1199          i/=PAGESIZE;
1200          for (j=0;j<i;j++)
1201            sgc_type_map[page(p)+j]|= SGC_PAGE_FLAG;
1202        }
1203    
1204        /* SGC contblock pages: switch to new free SGC contblock list. CM
1205           20030827 */
1206        old_cb_pointer=cb_pointer;
1207        cb_pointer=new_cb_pointer;
1208    
1209    #ifdef SGC_CONT_DEBUG
1210        overlap_check(old_cb_pointer,cb_pointer);
1211    #endif
1212    
1213      }
1214    
1215    /* Now  allocate the sgc relblock.   We do this as the tail    /* Now  allocate the sgc relblock.   We do this as the tail
1216       end of the ordinary rb.     */         end of the ordinary rb.     */  
1217    {    {
# Line 1117  sgc_quit(void) { Line 1298  sgc_quit(void) {
1298      return 0;      return 0;
1299    sgc_enabled=0;    sgc_enabled=0;
1300    rb_start = old_rb_start;    rb_start = old_rb_start;
1301    
1302      /* SGC cont pages: restore contblocks, each tmp_cb_pointer coming
1303         from the new list is guaranteed not to be on the old. Need to
1304         grab 'next' before insert_contblock writes is.  CM 20030827 */
1305      {
1306    
1307        struct contblock *tmp_cb_pointer,*next;
1308        if (old_cb_pointer) {
1309    #ifdef SGC_CONT_DEBUG
1310          overlap_check(old_cb_pointer,cb_pointer);
1311    #endif
1312          tmp_cb_pointer=cb_pointer;
1313          cb_pointer=old_cb_pointer;
1314          for (;tmp_cb_pointer;  tmp_cb_pointer=next) {
1315            next=tmp_cb_pointer->cb_link;
1316            insert_contblock((void *)tmp_cb_pointer,tmp_cb_pointer->cb_size);
1317          }
1318        }
1319      }
1320    
1321    for (i= t_start; i < t_contiguous ; i++)    for (i= t_start; i < t_contiguous ; i++)
1322      if (TM_BASE_TYPE_P(i)) {      if (TM_BASE_TYPE_P(i)) {
1323        tm=tm_of(i);        tm=tm_of(i);

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.9.4.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26