Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* tp_obj tp_track(TP,tp_obj v) { return v; }
  2.    void tp_grey(TP,tp_obj v) { }
  3.    void tp_full(TP) { }
  4.    void tp_gc_init(TP) { }
  5.    void tp_gc_deinit(TP) { }
  6.    void tp_delete(TP,tp_obj v) { }*/
  7.  
  8. void tp_grey(TP,tp_obj v) {
  9.     if (v.type < TP_STRING || (!v.gci.data) || *v.gci.data) { return; }
  10.     *v.gci.data = 1;
  11.     if (v.type == TP_STRING || v.type == TP_DATA) {
  12.         _tp_list_appendx(tp,tp->black,v);
  13.         return;
  14.     }
  15.     _tp_list_appendx(tp,tp->grey,v);
  16. }
  17.  
  18. void tp_follow(TP,tp_obj v) {
  19.     int type = v.type;
  20.     if (type == TP_LIST) {
  21.         int n;
  22.         for (n=0; n<v.list.val->len; n++) {
  23.             tp_grey(tp,v.list.val->items[n]);
  24.         }
  25.     }
  26.     if (type == TP_DICT) {
  27.         int i;
  28.         for (i=0; i<v.dict.val->len; i++) {
  29.             int n = _tp_dict_next(tp,v.dict.val);
  30.             tp_grey(tp,v.dict.val->items[n].key);
  31.             tp_grey(tp,v.dict.val->items[n].val);
  32.         }
  33.     }
  34.     if (type == TP_FNC) {
  35.         tp_grey(tp,v.fnc.info->self);
  36.         tp_grey(tp,v.fnc.info->globals);
  37.     }
  38. }
  39.  
  40. void tp_reset(TP) {
  41.     int n;
  42.     _tp_list *tmp;
  43.     for (n=0; n<tp->black->len; n++) {
  44.         *tp->black->items[n].gci.data = 0;
  45.     }
  46.     tmp = tp->white;
  47.     tp->white = tp->black;
  48.     tp->black = tmp;
  49. }
  50.  
  51. void tp_gc_init(TP) {
  52.     tp->white = _tp_list_new();
  53.     tp->strings = _tp_dict_new();
  54.     tp->grey = _tp_list_new();
  55.     tp->black = _tp_list_new();
  56.     tp->steps = 0;
  57. }
  58.  
  59. void tp_gc_deinit(TP) {
  60.     _tp_list_free(tp->white);
  61.     _tp_dict_free(tp->strings);
  62.     _tp_list_free(tp->grey);
  63.     _tp_list_free(tp->black);
  64. }
  65.  
  66. void tp_delete(TP,tp_obj v) {
  67.     int type = v.type;
  68.     if (type == TP_LIST) {
  69.         _tp_list_free(v.list.val);
  70.         return;
  71.     } else if (type == TP_DICT) {
  72.         _tp_dict_free(v.dict.val);
  73.         return;
  74.     } else if (type == TP_STRING) {
  75.         tp_free(v.string.info);
  76.         return;
  77.     } else if (type == TP_DATA) {
  78.         if (v.data.info->free) {
  79.             v.data.info->free(tp,v);
  80.         }
  81.         tp_free(v.data.info);
  82.         return;
  83.     } else if (type == TP_FNC) {
  84.         tp_free(v.fnc.info);
  85.         return;
  86.     }
  87.     tp_raise(,"tp_delete(%s)",TP_CSTR(v));
  88. }
  89.  
  90. void tp_collect(TP) {
  91.     int n;
  92.     for (n=0; n<tp->white->len; n++) {
  93.         tp_obj r = tp->white->items[n];
  94.         if (*r.gci.data) { continue; }
  95.         if (r.type == TP_STRING) {
  96.             /*this can't be moved into tp_delete, because tp_delete is
  97.                also used by tp_track_s to delete redundant strings*/
  98.             _tp_dict_del(tp,tp->strings,r,"tp_collect");
  99.         }
  100.         tp_delete(tp,r);
  101.     }
  102.     tp->white->len = 0;
  103.     tp_reset(tp);
  104. }
  105.  
  106. void _tp_gcinc(TP) {
  107.     tp_obj v;
  108.     if (!tp->grey->len) {
  109.         return;
  110.     }
  111.     v = _tp_list_pop(tp,tp->grey,tp->grey->len-1,"_tp_gcinc");
  112.     tp_follow(tp,v);
  113.     _tp_list_appendx(tp,tp->black,v);
  114. }
  115.  
  116. void tp_full(TP) {
  117.     while (tp->grey->len) {
  118.         _tp_gcinc(tp);
  119.     }
  120.     tp_collect(tp);
  121.     tp_follow(tp,tp->root);
  122. }
  123.  
  124. void tp_gcinc(TP) {
  125.     tp->steps += 1;
  126.     if (tp->steps < TP_GCMAX || tp->grey->len > 0) {
  127.         _tp_gcinc(tp); _tp_gcinc(tp);
  128.     }
  129.     if (tp->steps < TP_GCMAX || tp->grey->len > 0) { return; }
  130.     tp->steps = 0;
  131.     tp_full(tp);
  132.     return;
  133. }
  134.  
  135. tp_obj tp_track(TP,tp_obj v) {
  136.     if (v.type == TP_STRING) {
  137.         int i = _tp_dict_find(tp,tp->strings,v);
  138.         if (i != -1) {
  139.             tp_delete(tp,v);
  140.             v = tp->strings->items[i].key;
  141.             tp_grey(tp,v);
  142.             return v;
  143.         }
  144.         _tp_dict_setx(tp,tp->strings,v,tp_True);
  145.     }
  146.     tp_gcinc(tp);
  147.     tp_grey(tp,v);
  148.     return v;
  149. }
  150.  
  151. /**/
  152.  
  153.