gc.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #include "__virtualmath.h"
  2. #if START_GC
  3. static void gc_iterVar(Var *var);
  4. static void gc_iterLinkValue(LinkValue *value);
  5. static void gc_iterValue(Value *value);
  6. static void gc_iterHashTable(HashTable *ht);
  7. #define resetGC(gcs) ((gcs)->continue_ = false, (gcs)->link = 0)
  8. // 若(gcs)->continue_为true, 则直接返回; 若为false则自增(+1后为false), 并返回自增前的值
  9. #define gc_shouldIter(gcs) (!((gcs)->continue_))
  10. #define gc_setIterAlready(gcs) ((gcs)->continue_ = true)
  11. #define gc_needFree(gcs) ((gcs)->statement_link == 0 && (gcs)->tmp_link == 0 && (gcs)->link == 0)
  12. #define gc_needFreeValue(value) (gc_needFree(&(value)->gc_status) && (value)->gc_status.c_value == need_free)
  13. static void gc_iterLinkValue(LinkValue *value){
  14. gc_setIterAlready(&value->gc_status);
  15. gc_addLink(&value->gc_status);
  16. if (value->belong != NULL && gc_shouldIter(&value->belong->gc_status))
  17. gc_iterLinkValue(value->belong);
  18. if (gc_shouldIter(&value->value->gc_status))
  19. gc_iterValue(value->value);
  20. }
  21. static void gc_iterValue(Value *value){
  22. gc_setIterAlready(&value->gc_status);
  23. gc_addLink(&value->gc_status);
  24. for (VarList *vl = value->object.var; vl != NULL; vl = vl->next) {
  25. if (gc_shouldIter(&vl->hashtable->gc_status))
  26. gc_iterHashTable(vl->hashtable);
  27. }
  28. for (VarList *vl = value->object.out_var; vl != NULL; vl = vl->next) {
  29. if (gc_shouldIter(&vl->hashtable->gc_status))
  30. gc_iterHashTable(vl->hashtable);
  31. }
  32. for (Inherit *ih = value->object.inherit; ih != NULL; ih = ih->next) {
  33. if (gc_shouldIter(&ih->value->gc_status))
  34. gc_iterLinkValue(ih->value);
  35. }
  36. // 不重置value的c_value属性, __del__始终只执行一次
  37. switch (value->type) {
  38. case V_list:
  39. for (int i=0;i < value->data.list.size;i++) {
  40. if (gc_shouldIter(&value->data.list.list[i]->gc_status))
  41. gc_iterLinkValue(value->data.list.list[i]);
  42. }
  43. break;
  44. case V_dict:
  45. if (gc_shouldIter(&value->data.dict.dict->gc_status))
  46. gc_iterHashTable(value->data.dict.dict);
  47. break;
  48. case V_func:
  49. if (value->data.function.function_data.cls != NULL && gc_shouldIter(&value->data.function.function_data.cls->gc_status))
  50. gc_iterLinkValue(value->data.function.function_data.cls);
  51. break;
  52. default:
  53. break;
  54. }
  55. }
  56. static void gc_iterHashTable(HashTable *ht){
  57. gc_setIterAlready(&ht->gc_status);
  58. gc_addLink(&ht->gc_status);
  59. for (int i=0;i < MAX_SIZE;i++) {
  60. if (ht->hashtable[i] != NULL)
  61. gc_iterVar(ht->hashtable[i]);
  62. }
  63. }
  64. static void gc_iterVar(Var *var){
  65. gc_setIterAlready(&var->gc_status);
  66. for (PASS; var != NULL; var = var->next){
  67. gc_addLink(&var->gc_status);
  68. if (gc_shouldIter(&var->name_->gc_status))
  69. gc_iterLinkValue(var->name_);
  70. if (gc_shouldIter(&var->value->gc_status))
  71. gc_iterLinkValue(var->value);
  72. }
  73. }
  74. #define gc_resetBase(inter) do { \
  75. for (Value *value_base = (inter)->base; value_base != NULL; value_base = value_base->gc_next) \
  76. {resetGC(&value_base->gc_status);} \
  77. for (LinkValue *link_base = (inter)->link_base; link_base != NULL; link_base = link_base->gc_next) \
  78. {resetGC(&link_base->gc_status);} \
  79. for (HashTable *hash_base = (inter)->hash_base; hash_base != NULL; hash_base = hash_base->gc_next) \
  80. {resetGC(&hash_base->gc_status);} \
  81. for (Var *var_base = (inter)->base_var; var_base != NULL; var_base = var_base->gc_next) \
  82. {resetGC(&var_base->gc_status);} \
  83. } while(0)
  84. static void gc_checkBase(Inter *inter){
  85. for (Value *value_base = inter->base; value_base != NULL; value_base = value_base->gc_next)
  86. if (!gc_needFree(&value_base->gc_status) && gc_shouldIter(&value_base->gc_status))
  87. gc_iterValue(value_base);
  88. for (LinkValue *link_base = inter->link_base; link_base != NULL; link_base = link_base->gc_next)
  89. if (!gc_needFree(&link_base->gc_status) && gc_shouldIter(&link_base->gc_status))
  90. gc_iterLinkValue(link_base);
  91. for (HashTable *hash_base = inter->hash_base; hash_base != NULL; hash_base = hash_base->gc_next)
  92. if (!gc_needFree(&hash_base->gc_status) && gc_shouldIter(&hash_base->gc_status))
  93. gc_iterHashTable(hash_base);
  94. for (Var *var_base = inter->base_var; var_base != NULL; var_base = var_base->gc_next)
  95. if (!gc_needFree(&var_base->gc_status) && gc_shouldIter(&var_base->gc_status))
  96. gc_iterVar(var_base);
  97. }
  98. static void gc_checkDel(Inter *inter){
  99. for (Value *value = inter->base; value != NULL; value = value->gc_next) {
  100. if (value->gc_status.c_value == not_free) {
  101. if (needDel(value, inter)) {
  102. gc_iterValue(value); // 不需要检查是否位shouldIter, 因为他必然不是
  103. value->gc_status.c_value = run_del;
  104. } else
  105. value->gc_status.c_value = need_free;
  106. }
  107. }
  108. }
  109. void gc_runDelAll(Inter *inter){
  110. Result result;
  111. setResultCore(&result);
  112. for (Value *value = inter->base; value != NULL; value = value->gc_next) {
  113. gc_addTmpLink(&value->gc_status);
  114. if (value->gc_status.c_value != need_free && needDel(value, inter)) { // 检查value->gc_status.c_value != need_free; 是避免二次运行__del__
  115. value->gc_status.c_value = need_free;
  116. callDel(value, &result, inter, inter->var_list);
  117. if (!RUN_TYPE(result.type))
  118. printError(&result, inter, true);
  119. freeResult(&result);
  120. }
  121. gc_freeTmpLink(&value->gc_status);
  122. }
  123. }
  124. static void gc_runDel(Inter *inter, VarList *var_list){
  125. Result result;
  126. setResultCore(&result);
  127. for (Value *value = inter->base; value != NULL; value = value->gc_next) {
  128. if (value->gc_status.c_value == run_del) {
  129. value->gc_status.c_value = need_free;
  130. gc_addTmpLink(&value->gc_status);
  131. callDel(value, &result, inter, var_list);
  132. if (!RUN_TYPE(result.type))
  133. printError(&result, inter, true);
  134. gc_freeTmpLink(&value->gc_status);
  135. freeResult(&result);
  136. }
  137. }
  138. }
  139. static void gc_freeBase(Inter *inter){
  140. for (LinkValue **link_base = &inter->link_base; *link_base != NULL;)
  141. if (gc_needFree(&(*link_base)->gc_status))
  142. freeLinkValue(link_base);
  143. else
  144. link_base = &(*link_base)->gc_next;
  145. for (HashTable **hash_base = &inter->hash_base; *hash_base != NULL;)
  146. if (gc_needFree(&(*hash_base)->gc_status))
  147. freeHashTable(hash_base);
  148. else
  149. hash_base = &(*hash_base)->gc_next;
  150. for (Var **var_base = &inter->base_var; *var_base != NULL;)
  151. if (gc_needFree(&(*var_base)->gc_status))
  152. freeVar(var_base);
  153. else
  154. var_base = &(*var_base)->gc_next;
  155. for (Value **value_base = &inter->base; *value_base != NULL;)
  156. if (gc_needFreeValue(*value_base))
  157. freeValue(value_base);
  158. else
  159. value_base = &(*value_base)->gc_next;
  160. }
  161. void gc_run(Inter *inter, VarList *run_var){
  162. gc_resetBase(inter);
  163. inter->data.run_gc = 0;
  164. gc_checkBase(inter);
  165. gc_checkDel(inter);
  166. gc_freeBase(inter);
  167. gc_runDel(inter, run_var);
  168. }
  169. #endif