浏览代码

feat: 调整Environment的析构机制

Object等GC对象最后释放
void *data在GC对象前释放
SongZihuan 3 年之前
父节点
当前提交
007faa4064
共有 5 个文件被更改,包括 27 次插入3 次删除
  1. 1 0
      src/core/__gc.h
  2. 1 0
      src/core/__object.h
  3. 4 3
      src/core/env.c
  4. 6 0
      src/core/gc.c
  5. 15 0
      src/core/object.c

+ 1 - 0
src/core/__gc.h

@@ -117,6 +117,7 @@ AFUN_CORE_NO_EXPORT GcCount gc_getObjectDataReference(af_ObjectData *obj);
 /* gc 操控函数 : gc的启动由解释器完全管理 */
 AFUN_CORE_NO_EXPORT void gc_RunGC(af_Environment *env);
 AFUN_CORE_NO_EXPORT pgc_DestructList checkAllDestruct(af_Environment *env, pgc_DestructList pdl);
+AFUN_CORE_NO_EXPORT void gc_freeAllValueData(af_Environment *env);
 AFUN_CORE_NO_EXPORT void gc_freeAllValue(af_Environment *env);
 
 /* gc 信息函数 */

+ 1 - 0
src/core/__object.h

@@ -67,6 +67,7 @@ AFUN_CORE_NO_EXPORT void freeObject(af_Object *obj, af_Environment *env);
 AFUN_CORE_NO_EXPORT af_Object *findObjectAttributesByObjectData(char *name, af_Object *visitor, af_ObjectData *od);
 
 /* ObjectData 释放函数 */
+AFUN_CORE_NO_EXPORT void freeObjectDataData(af_ObjectData *od, af_Environment *env);
 AFUN_CORE_NO_EXPORT void freeObjectData(af_ObjectData *od, af_Environment *env);
 
 /* Object 释放函数 */

+ 4 - 3
src/core/env.c

@@ -112,9 +112,10 @@ static af_Core *makeCore(enum GcRunTime grt, af_Environment *env) {
  * 因为gc_freeAllValue需要env作为参数, 故使用env作为freeCore的参数
  */
 static void freeCore(af_Environment *env) {
-    printGCByCore(env->core);
-    gc_freeAllValue(env);
     freeAllLiteralRegex(env->core->lr);
+    gc_freeAllValueData(env);  // 先释放ObjectData的void *data
+    printGCByCore(env->core);
+    gc_freeAllValue(env);  // 再完全释放Object
     free(env->core);
 }
 
@@ -842,10 +843,10 @@ void freeEnvironment(af_Environment *env) {
         res = iterDestruct(10, env);
 
     freeAllActivity(env->activity);
-    freeCore(env);
     freeEnvVarSpace(env->esv);
     freeAllTopMsgProcess(env->process);
     freeAllGuardian(env->guardian);
+    freeCore(env);  // core最后释放, 因为Object等需要最后释放
 
     if (!res)
         writeErrorLog(aFunCoreLogger, "Run iterDestruct error.");

+ 6 - 0
src/core/gc.c

@@ -391,6 +391,12 @@ pgc_DestructList checkAllDestruct(af_Environment *env, pgc_DestructList pdl) {
     return pdl;
 }
 
+void gc_freeAllValueData(af_Environment *env) {
+    for (af_ObjectData *od = env->core->gc_ObjectData; od != NULL; od = od->gc.next) {
+        freeObjectDataData(od, env);
+    }
+}
+
 void gc_freeAllValue(af_Environment *env) {
     for (af_ObjectData *od = env->core->gc_ObjectData, *next; od != NULL; od = next) {
         next = od->gc.next;

+ 15 - 0
src/core/object.c

@@ -95,6 +95,21 @@ af_Object *makeObject(char *id, bool free_api, af_ObjectAPI *api, bool allow_inh
     return obj;
 }
 
+/*
+ * 函数名: freeObjectDataData
+ * 目标: 释放ObjectData的void *data, 仅GC函数可用
+ * 对外API中, 创建对象的基本单位都是af_Object, 无法直接操控af_ObjectData
+ */
+void freeObjectDataData(af_ObjectData *od, af_Environment *env) {
+    if (od->size == 0)
+        return;
+    obj_destructData *func = findAPI("obj_destructData", od->api);
+    if (func != NULL)
+        func(od->id, od->base, od->data, env);
+    od->size = 0;
+    free(od->data);
+}
+
 /*
  * 函数名: freeObjectData
  * 目标: 释放ObjectData, 仅GC函数可用