Browse Source

feat: GC机制可以冻结VarList

冻结当前VarList不可达变量
如在call_fcuntion中, function的VarList和当前的VarList可能是分岔的
则需要冻结当前VarList中的变量(仅冻结function的VarList不包含的VarList)
SongZihuan 4 năm trước cách đây
mục cha
commit
544a8833b9
7 tập tin đã thay đổi với 136 bổ sung2 xóa
  1. 112 0
      gc/freeze.c
  2. 1 0
      include/__virtualmath.h
  3. 3 0
      include/gc.h
  4. 1 0
      include/grammar.h
  5. 1 2
      main.c
  6. 15 0
      src/inter.c
  7. 3 0
      src/runcall.c

+ 112 - 0
gc/freeze.c

@@ -0,0 +1,112 @@
+#include "__virtualmath.h"
+
+void gc_freezeValue(Value *value, bool is_lock);
+void gc_freezeHashTable(HashTable *ht, bool is_lock);
+void gc_freezeVarList(VarList *vl, bool is_lock);
+void gc_freezeVar(Var *var, bool is_lock);
+
+void gc_freezeLinkValue(LinkValue *value, bool is_lock){
+    if (value == NULL)
+        return;
+
+    if (is_lock)
+        gcAddTmp(&value->gc_status);
+    else
+        gcFreeTmpLink(&value->gc_status);
+
+    if (!setIterAlready(&value->gc_status)){
+        gc_freezeLinkValue(value->father, is_lock);
+        gc_freezeValue(value->value, is_lock);
+    }
+}
+
+void gc_freezeValue(Value *value, bool is_lock){
+    if (value == NULL)
+        return;
+
+    if (is_lock)
+        gcAddTmp(&value->gc_status);
+    else
+        gcFreeTmpLink(&value->gc_status);
+
+    if (setIterAlready(&value->gc_status))
+        return;
+
+    switch (value->type) {
+        case function:
+            gc_freezeVarList(value->data.function.var, is_lock);
+            break;
+        case list:
+            for (int i=0;i < value->data.list.size;i++)
+                gc_freezeLinkValue(value->data.list.list[i], is_lock);
+            break;
+        case dict:
+            gc_freezeHashTable(value->data.dict.dict, is_lock);
+            break;
+        default:
+            break;
+    }
+}
+
+void gc_freezeVarList(VarList *vl, bool is_lock){
+    while (vl != NULL) {
+        gc_freezeHashTable(vl->hashtable, is_lock);
+        vl = vl->next;
+    }
+}
+
+void gc_freezeHashTable(HashTable *ht, bool is_lock){
+    if (ht == NULL)
+        return;
+
+    if (is_lock)
+        gcAddTmp(&ht->gc_status);
+    else
+        gcFreeTmpLink(&ht->gc_status);
+
+    if (setIterAlready(&ht->gc_status))
+        return;
+
+    for (int i=0;i < MAX_SIZE;i++){
+        gc_freezeVar(ht->hashtable[i], is_lock);
+    }
+}
+
+void gc_freezeVar(Var *var, bool is_lock){
+    while (var != NULL){
+        gc_freezeLinkValue(var->name_, is_lock);
+        gc_freezeLinkValue(var->value, is_lock);
+        var = var->next;
+    }
+}
+
+void iterFreezeVarList(VarList *freeze, VarList *base, bool is_lock){
+    while (freeze != NULL){
+        VarList *tmp = base;
+        bool need_freeze = true;
+        while (tmp != NULL){
+            if (tmp->hashtable == freeze->hashtable){
+                need_freeze = false;
+                break;
+            }
+            tmp = tmp->next;
+        }
+        if (need_freeze)
+            gc_freezeHashTable(freeze->hashtable, is_lock);
+        freeze = freeze->next;
+    }
+}
+
+/**
+ * 冻结不可达的VarList的hashTable
+ * @param inter
+ * @param freeze
+ * @param base
+ * @param is_lock
+ */
+void runFREEZE(Inter *inter, VarList *freeze, VarList *base, bool is_lock){
+#if START_GC
+    gc_resetBase(inter);
+    iterFreezeVarList(freeze, base, is_lock);
+#endif
+}

+ 1 - 0
include/__virtualmath.h

@@ -20,5 +20,6 @@
 
 /* DEBUG */
 void printLinkValueGC(char *tag, Inter *inter);
+void printValueGC(char *tag, Inter *inter);
 void showLinkValue(struct LinkValue *base);
 #endif //VIRTUALMATH___VIRTUALMATH_H

+ 3 - 0
include/gc.h

@@ -39,6 +39,9 @@ void gc_iterHashTable(struct HashTable *ht);
 void gc_iterVar(struct Var *var);
 void gc_var_list(struct VarList *vl);
 
+void iterFreezeVarList(struct VarList *freeze, struct VarList *base, bool is_lock);
+void runFREEZE(struct Inter *inter, struct VarList *freeze, struct VarList *base, bool is_lock);
+
 void runGC(struct Inter *inter, int var_list, int link_value, int value, ...);
 
 #endif //VIRTUALMATH_GC_H

+ 1 - 0
include/grammar.h

@@ -22,5 +22,6 @@ typedef struct ParserMessage ParserMessage;
 ParserMessage *makeParserMessage(char *file_dir, char *debug);
 void freeParserMessage(ParserMessage *pm, bool self);
 void parserCommandList(ParserMessage *pm, Inter *inter, bool global, Statement *st);
+// PASERSSIGNATURE 位于__grammar
 
 #endif //VIRTUALMATH_GRAMMAR_H

+ 1 - 2
main.c

@@ -18,9 +18,8 @@ int main(int argc, char *argv[]) {
 /**
  * TODO-szh 面向对象
  * TODO-szh import语句
- * TODO-szh 检查文件是否为目录和目录是否为目录
  * TODO-szh 生成语法树
  * TODO-szh 取反符号 -
  * TODO-szh 字面量后缀
- * TODO-szh 字面量使用string处理方式
+ * TODO-szh 空参数使用 void
  */

+ 15 - 0
src/inter.c

@@ -75,6 +75,7 @@ void freeInter(Inter *inter, bool self){
     freeBase(inter, return_);
 
     printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter);
+    printValueGC("\nprintValueGC TAG : freeInter", inter);
 
     freeStatement(inter->statement);  // Statement放在Value前面释放, 因为base_value的释放需要处理gc_status
     freeVarList(inter->var_list, true);
@@ -122,6 +123,20 @@ void printLinkValueGC(char *tag, Inter *inter){
     printf("printLinkValueGC TAG : END\n");
 }
 
+void printValueGC(char *tag, Inter *inter){
+    Value *base = inter->base;
+    printf("%s\n", tag);
+    while (base != NULL) {
+        printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
+        printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
+        printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
+        printf("value = ");
+        printValue(base, stdout);
+        printf("\n-------------------------------------------\n");
+        base = base->next;
+    }
+    printf("printValueGC TAG : END\n");
+}
 
 void showLinkValue(struct LinkValue *base){
     printf("tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);

+ 3 - 0
src/runcall.c

@@ -31,11 +31,13 @@ Result callFunction(INTER_FUNCTIONSIG) {
     }
     VarList *function_var = pushVarList(function_value.value->value->data.function.var, inter);
     gcAddTmp(&function_var->hashtable->gc_status);
+    runFREEZE(inter, var_list, function_var, true);
 
     set_tmp = setParameter(st->u.call_function.parameter, function_value.value->value->data.function.pt, function_var,
                            st, CALL_INTER_FUNCTIONSIG_CORE(var_list));
     if (set_tmp.type == error_return) {
         gcAddTmp(&function_var->hashtable->gc_status);
+        runFREEZE(inter, var_list, function_var, false);
         popVarList(function_var);
         return set_tmp;
     }
@@ -44,6 +46,7 @@ Result callFunction(INTER_FUNCTIONSIG) {
     functionSafeInterStatement(&result, CALL_INTER_FUNCTIONSIG(function_value.value->value->data.function.function, function_var));
 
     gcFreeTmpLink(&function_var->hashtable->gc_status);
+    runFREEZE(inter, var_list, function_var, false);
     popVarList(function_var);
 
     freeResult(&function_value);