mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-15 17:02:53 +08:00
fix args_foreach handler
add PikaGC class add gc.onMarkObj add GC DUMP support gcdump() improve gcdump
This commit is contained in:
parent
e58095c2eb
commit
ca65efd1fa
@ -134,6 +134,10 @@ class SysObj:
|
||||
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||
def clear(): ...
|
||||
|
||||
@staticmethod
|
||||
@PIKA_C_MACRO_IF("PIKA_GC_MARK_SWEEP_ENABLE")
|
||||
def gcdump(): ...
|
||||
|
||||
|
||||
@PIKA_C_MACRO_IF("0")
|
||||
class RangeObj:
|
||||
|
@ -531,8 +531,8 @@ PikaObj* PikaStdLib_SysObj_open(PikaObj* self, char* path, char* mode) {
|
||||
}
|
||||
|
||||
/* __dir_each */
|
||||
int32_t __dir_each(Arg* argEach, Args* context) {
|
||||
PikaObj* list = args_getPtr(context, "list");
|
||||
int32_t __dir_each(Arg* argEach, void* context) {
|
||||
PikaObj* list = args_getPtr((Args*)context, "list");
|
||||
if (argType_isCallable(arg_getType(argEach))) {
|
||||
char name_buff[PIKA_LINE_BUFF_SIZE] = {0};
|
||||
char* method_name =
|
||||
@ -670,3 +670,7 @@ void PikaStdLib_SysObj_reboot(PikaObj* self) {
|
||||
void PikaStdLib_SysObj_clear(PikaObj* self) {
|
||||
pika_platform_clear();
|
||||
}
|
||||
|
||||
void PikaStdLib_SysObj_gcdump(PikaObj *self){
|
||||
pikaGC_markDump();
|
||||
}
|
||||
|
2
port/linux/.vscode/launch.json
vendored
2
port/linux/.vscode/launch.json
vendored
@ -11,7 +11,7 @@
|
||||
"program": "${workspaceFolder}/build/test/pikascript_test",
|
||||
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
|
||||
"args": [
|
||||
"--gtest_filter=pikaui.*"
|
||||
// "--gtest_filter=pikaui.*"
|
||||
// "--gtest_filter=parser.for_in_split"
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
|
@ -134,6 +134,10 @@ class SysObj:
|
||||
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
|
||||
def clear(): ...
|
||||
|
||||
@staticmethod
|
||||
@PIKA_C_MACRO_IF("PIKA_GC_MARK_SWEEP_ENABLE")
|
||||
def gcdump(): ...
|
||||
|
||||
|
||||
@PIKA_C_MACRO_IF("0")
|
||||
class RangeObj:
|
||||
|
@ -531,8 +531,8 @@ PikaObj* PikaStdLib_SysObj_open(PikaObj* self, char* path, char* mode) {
|
||||
}
|
||||
|
||||
/* __dir_each */
|
||||
int32_t __dir_each(Arg* argEach, Args* context) {
|
||||
PikaObj* list = args_getPtr(context, "list");
|
||||
int32_t __dir_each(Arg* argEach, void* context) {
|
||||
PikaObj* list = args_getPtr((Args*)context, "list");
|
||||
if (argType_isCallable(arg_getType(argEach))) {
|
||||
char name_buff[PIKA_LINE_BUFF_SIZE] = {0};
|
||||
char* method_name =
|
||||
@ -670,3 +670,7 @@ void PikaStdLib_SysObj_reboot(PikaObj* self) {
|
||||
void PikaStdLib_SysObj_clear(PikaObj* self) {
|
||||
pika_platform_clear();
|
||||
}
|
||||
|
||||
void PikaStdLib_SysObj_gcdump(PikaObj *self){
|
||||
pikaGC_markDump();
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ int LibObj_staticLinkFile(LibObj* self, char* input_file_name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t __foreach_handler_listModules(Arg* argEach, Args* context) {
|
||||
static int32_t __foreach_handler_listModules(Arg* argEach, void* context) {
|
||||
if (arg_isObject(argEach)) {
|
||||
PikaObj* module_obj = arg_getPtr(argEach);
|
||||
pika_platform_printf("%s\r\n", obj_getStr(module_obj, "name"));
|
||||
@ -312,8 +312,8 @@ void LibObj_listModules(LibObj* self) {
|
||||
args_foreach(self->list, __foreach_handler_listModules, NULL);
|
||||
}
|
||||
|
||||
static int32_t __foreach_handler_libWriteBytecode(Arg* argEach, Args* context) {
|
||||
FILE* out_file = args_getPtr(context, "out_file");
|
||||
static int32_t __foreach_handler_libWriteBytecode(Arg* argEach, void* context) {
|
||||
FILE* out_file = args_getPtr((Args*)context, "out_file");
|
||||
if (arg_isObject(argEach)) {
|
||||
PikaObj* module_obj = arg_getPtr(argEach);
|
||||
char* bytecode = obj_getPtr(module_obj, "bytecode");
|
||||
@ -327,8 +327,9 @@ static int32_t __foreach_handler_libWriteBytecode(Arg* argEach, Args* context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t __foreach_handler_libWriteIndex(Arg* argEach, Args* context) {
|
||||
FILE* out_file = args_getPtr(context, "out_file");
|
||||
static int32_t __foreach_handler_libWriteIndex(Arg* argEach, void* context) {
|
||||
Args* args = context;
|
||||
FILE* out_file = args_getPtr(args, "out_file");
|
||||
Args buffs = {0};
|
||||
if (arg_isObject(argEach)) {
|
||||
PikaObj* module_obj = arg_getPtr(argEach);
|
||||
@ -348,21 +349,22 @@ static int32_t __foreach_handler_libWriteIndex(Arg* argEach, Args* context) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t __foreach_handler_libSumSize(Arg* argEach, Args* context) {
|
||||
static int32_t __foreach_handler_libSumSize(Arg* argEach, void* context) {
|
||||
Args* args = context;
|
||||
if (arg_isObject(argEach)) {
|
||||
PikaObj* module_obj = arg_getPtr(argEach);
|
||||
uint32_t bytecode_size = obj_getBytesSize(module_obj, "buff");
|
||||
bytecode_size = aline_by(bytecode_size, sizeof(uint32_t));
|
||||
args_setInt(context, "sum_size",
|
||||
args_getInt(context, "sum_size") + bytecode_size);
|
||||
args_setInt(args, "sum_size",
|
||||
args_getInt(args, "sum_size") + bytecode_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t __foreach_handler_getModuleNum(Arg* argEach, Args* context) {
|
||||
static int32_t __foreach_handler_getModuleNum(Arg* argEach, void* context) {
|
||||
Args* args = (Args*)context;
|
||||
if (arg_isObject(argEach)) {
|
||||
args_setInt(context, "module_num",
|
||||
args_getInt(context, "module_num") + 1);
|
||||
args_setInt(args, "module_num", args_getInt(args, "module_num") + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -496,15 +498,15 @@ PIKA_RES _loadModuleDataWithName(uint8_t* library_bytes,
|
||||
/**
|
||||
* @brief 打开 .pack 文件,并返回这个pack 文件的library_bytes
|
||||
*
|
||||
* @param pikafs_FILE** fp pikafs_FILE 二级文件指针,提供了文件加载内存中的地址以及大小等信息
|
||||
* @param pikafs_FILE** fp pikafs_FILE
|
||||
* 二级文件指针,提供了文件加载内存中的地址以及大小等信息
|
||||
* @param Arg** f_arg
|
||||
* @param char* pack_name pack 文件的名字
|
||||
* @return PIKA_RES_OK when success, otherwise failed;
|
||||
* @note if failed *fp if freed
|
||||
*
|
||||
*
|
||||
*/
|
||||
PIKA_RES _getPack_libraryBytes(pikafs_FILE** fp, Arg** f_arg, char* pack_name) {
|
||||
|
||||
if (NULL == pack_name) {
|
||||
return PIKA_RES_ERR_INVALID_PTR;
|
||||
}
|
||||
@ -518,7 +520,8 @@ PIKA_RES _getPack_libraryBytes(pikafs_FILE** fp, Arg** f_arg, char* pack_name) {
|
||||
|
||||
*f_arg = arg_loadFile(NULL, pack_name);
|
||||
if (NULL == *f_arg) {
|
||||
pika_platform_printf("Error: Could not load file \'%s\'\r\n", pack_name);
|
||||
pika_platform_printf("Error: Could not load file \'%s\'\r\n",
|
||||
pack_name);
|
||||
pikaFree(*fp, sizeof(pikafs_FILE));
|
||||
// fp == NULL;
|
||||
return PIKA_RES_ERR_IO_ERROR;
|
||||
@ -543,7 +546,7 @@ int LibObj_loadLibrary(LibObj* self, uint8_t* library_bytes) {
|
||||
return PIKA_RES_OK;
|
||||
}
|
||||
|
||||
int32_t __foreach_handler_printModule(Arg* argEach, Args* context) {
|
||||
int32_t __foreach_handler_printModule(Arg* argEach, void* context) {
|
||||
if (arg_isObject(argEach)) {
|
||||
PikaObj* module_obj = arg_getPtr(argEach);
|
||||
char* module_name = obj_getStr(module_obj, "name");
|
||||
@ -578,13 +581,12 @@ int LibObj_loadLibraryFile(LibObj* self, char* lib_file_name) {
|
||||
|
||||
/**
|
||||
* @brief unpack *.pack file to Specified path
|
||||
*
|
||||
*
|
||||
* @param pack_name the name of *.pack file
|
||||
* @param out_path output path
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
PIKA_RES LibObj_unpackFileToPath(char* pack_name, char* out_path) {
|
||||
|
||||
PIKA_RES stat = PIKA_RES_OK;
|
||||
Arg* file_arg = NULL;
|
||||
uint8_t* library_bytes = NULL;
|
||||
@ -593,8 +595,7 @@ PIKA_RES LibObj_unpackFileToPath(char* pack_name, char* out_path) {
|
||||
stat = _getPack_libraryBytes(&fptr, &file_arg, pack_name);
|
||||
if (PIKA_RES_OK == stat) {
|
||||
library_bytes = arg_getBytes(file_arg);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return stat;
|
||||
}
|
||||
|
||||
@ -603,7 +604,7 @@ PIKA_RES LibObj_unpackFileToPath(char* pack_name, char* out_path) {
|
||||
return (PIKA_RES)module_num;
|
||||
}
|
||||
|
||||
Args buffs = { 0 };
|
||||
Args buffs = {0};
|
||||
char* output_file_path = NULL;
|
||||
FILE* new_fp = NULL;
|
||||
|
||||
@ -612,15 +613,15 @@ PIKA_RES LibObj_unpackFileToPath(char* pack_name, char* out_path) {
|
||||
uint8_t* addr = NULL;
|
||||
size_t size = 0;
|
||||
_loadModuleDataWithIndex(library_bytes, module_num, i, &name, &addr,
|
||||
&size);
|
||||
&size);
|
||||
output_file_path = strsPathJoin(&buffs, out_path, name);
|
||||
new_fp = pika_platform_fopen(output_file_path, "wb+");
|
||||
if (NULL != new_fp) {
|
||||
pika_platform_fwrite(addr, size, 1, new_fp);
|
||||
pika_platform_fclose(new_fp);
|
||||
pika_platform_printf("extract %s to %s\r\n", name, output_file_path);
|
||||
}
|
||||
else {
|
||||
pika_platform_printf("extract %s to %s\r\n", name,
|
||||
output_file_path);
|
||||
} else {
|
||||
pika_platform_printf("can't open %s\r\n", output_file_path);
|
||||
break;
|
||||
}
|
||||
@ -872,7 +873,7 @@ exit:
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t __foreach_handler_printStates(Arg* argEach, Args* context) {
|
||||
int32_t __foreach_handler_printStates(Arg* argEach, void* context) {
|
||||
if (arg_isObject(argEach)) {
|
||||
PikaObj* module_obj = arg_getPtr(argEach);
|
||||
pika_platform_printf("%s: %s\r\n", obj_getStr(module_obj, "name"),
|
||||
@ -885,17 +886,17 @@ void pikaMaker_printStates(PikaMaker* self) {
|
||||
args_foreach(self->list, __foreach_handler_printStates, NULL);
|
||||
}
|
||||
|
||||
int32_t __foreach_handler_getFirstNocompiled(Arg* argEach, Args* context) {
|
||||
int32_t __foreach_handler_getFirstNocompiled(Arg* argEach, void* context) {
|
||||
if (arg_isObject(argEach)) {
|
||||
PikaObj* module_obj = arg_getPtr(argEach);
|
||||
char* state = obj_getStr(module_obj, "state");
|
||||
if (args_isArgExist(context, "res")) {
|
||||
if (args_isArgExist((Args*)context, "res")) {
|
||||
/* already get method */
|
||||
return 0;
|
||||
}
|
||||
if (strEqu("nocompiled", state)) {
|
||||
/* push module */
|
||||
args_setStr(context, "res", obj_getStr(module_obj, "name"));
|
||||
args_setStr((Args*)context, "res", obj_getStr(module_obj, "name"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -947,11 +948,11 @@ PIKA_RES pikaMaker_compileModuleWithDepends(PikaMaker* self,
|
||||
return PIKA_RES_OK;
|
||||
}
|
||||
|
||||
int32_t __foreach_handler_linkCompiledModules(Arg* argEach, Args* context) {
|
||||
int32_t __foreach_handler_linkCompiledModules(Arg* argEach, void* context) {
|
||||
Args buffs = {0};
|
||||
if (arg_isObject(argEach)) {
|
||||
LibObj* lib = args_getPtr(context, "@lib");
|
||||
PikaMaker* maker = args_getPtr(context, "__maker");
|
||||
LibObj* lib = args_getPtr((Args*)context, "@lib");
|
||||
PikaMaker* maker = args_getPtr((Args*)context, "__maker");
|
||||
PikaObj* module_obj = arg_getPtr(argEach);
|
||||
char* module_name = obj_getStr(module_obj, "name");
|
||||
char* state = obj_getStr(module_obj, "state");
|
||||
@ -1057,8 +1058,7 @@ pikafs_FILE* pikafs_fopen_pack(char* pack_name, char* file_name) {
|
||||
stat = _getPack_libraryBytes(&f, &file_arg, pack_name);
|
||||
if (PIKA_RES_OK == stat) {
|
||||
library_bytes = arg_getBytes(file_arg);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
156
src/PikaObj.c
156
src/PikaObj.c
@ -57,6 +57,9 @@ PikaObj* New_PikaStdData_List(Args* args);
|
||||
PikaObj* New_PikaStdData_Tuple(Args* args);
|
||||
void _mem_cache_deinit(void);
|
||||
void _VMEvent_deinit(void);
|
||||
void pikaGC_markObj(PikaGC* gc, PikaObj* self);
|
||||
void _pikaGC_mark(PikaGC* gc);
|
||||
void obj_dump(PikaObj* self);
|
||||
|
||||
static enum shellCTRL __obj_shellLineHandler_REPL(PikaObj* self,
|
||||
char* input_line,
|
||||
@ -134,7 +137,7 @@ static int32_t obj_deinit_no_del(PikaObj* self) {
|
||||
#endif
|
||||
extern volatile PikaObj* __pikaMain;
|
||||
/* remove self from gc chain */
|
||||
pikaGC_remove(self);
|
||||
obj_removeGcChain(self);
|
||||
/* free the pointer */
|
||||
pikaFree(self, sizeof(PikaObj));
|
||||
if (self == (PikaObj*)__pikaMain) {
|
||||
@ -144,7 +147,7 @@ static int32_t obj_deinit_no_del(PikaObj* self) {
|
||||
}
|
||||
|
||||
int obj_GC(PikaObj* self) {
|
||||
if (!pikaGC_checkAlive(self)) {
|
||||
if (!obj_checkAlive(self)) {
|
||||
return 0;
|
||||
}
|
||||
obj_refcntDec(self);
|
||||
@ -287,7 +290,7 @@ PIKA_BOOL obj_getBool(PikaObj* self, char* argPath) {
|
||||
}
|
||||
|
||||
Arg* obj_getArg(PikaObj* self, char* argPath) {
|
||||
pika_assert(pikaGC_checkAlive(self));
|
||||
pika_assert(obj_checkAlive(self));
|
||||
PIKA_BOOL is_temp = PIKA_FALSE;
|
||||
PikaObj* obj = obj_getHostObjWithIsTemp(self, argPath, &is_temp);
|
||||
if (NULL == obj) {
|
||||
@ -335,11 +338,30 @@ size_t obj_loadBytes(PikaObj* self, char* argPath, uint8_t* out_buff) {
|
||||
return size_mem;
|
||||
}
|
||||
|
||||
void obj_setName(PikaObj* self, char* name) {
|
||||
#if !PIKA_KERNAL_DEBUG_ENABLE
|
||||
return;
|
||||
#else
|
||||
if (strEqu(name, "self")) {
|
||||
return;
|
||||
}
|
||||
if (NULL != self->aName) {
|
||||
if (!strstr(self->name, name)) {
|
||||
self->aName = arg_strAppend(self->aName, "|");
|
||||
self->aName = arg_strAppend(self->aName, name);
|
||||
}
|
||||
} else {
|
||||
self->aName = arg_newStr(name);
|
||||
}
|
||||
self->name = arg_getStr(self->aName);
|
||||
#endif
|
||||
}
|
||||
|
||||
static PIKA_RES _obj_setArg(PikaObj* self,
|
||||
char* argPath,
|
||||
Arg* arg,
|
||||
uint8_t is_copy) {
|
||||
pika_assert(pikaGC_checkAlive(self));
|
||||
pika_assert(obj_checkAlive(self));
|
||||
/* setArg would copy arg */
|
||||
PikaObj* host = obj_getHostObj(self, argPath);
|
||||
PikaObj* oNew = NULL;
|
||||
@ -359,24 +381,20 @@ static PIKA_RES _obj_setArg(PikaObj* self,
|
||||
if (arg_isObject(aNew)) {
|
||||
oNew = arg_getPtr(aNew);
|
||||
bNew = PIKA_TRUE;
|
||||
pika_assert(pikaGC_checkAlive(oNew));
|
||||
pika_assert(obj_checkAlive(oNew));
|
||||
#if PIKA_KERNAL_DEBUG_ENABLE
|
||||
if (host != oNew) {
|
||||
/* skip self ref */
|
||||
oNew->parent = host;
|
||||
}
|
||||
if (NULL != oNew->aName) {
|
||||
arg_deinit(oNew->aName);
|
||||
}
|
||||
oNew->aName = arg_newStr(sArgName);
|
||||
oNew->name = arg_getStr(oNew->aName);
|
||||
#endif
|
||||
obj_setName(oNew, sArgName);
|
||||
}
|
||||
args_setArg(host->list, aNew);
|
||||
/* enable mark sweep to collect this object */
|
||||
if (bNew) {
|
||||
/* only enable mark sweep after setArg */
|
||||
pikaGC_enable(oNew);
|
||||
obj_enableGC(oNew);
|
||||
}
|
||||
return PIKA_RES_OK;
|
||||
}
|
||||
@ -598,6 +616,7 @@ PikaObj* newRootObj(char* name, NewFun newObjFun) {
|
||||
return NULL;
|
||||
}
|
||||
__pikaMain = newObj;
|
||||
obj_setName(newObj, name);
|
||||
g_PikaObjState.inRootObj = PIKA_FALSE;
|
||||
return newObj;
|
||||
}
|
||||
@ -624,16 +643,17 @@ static PikaObj* _obj_initMetaObj(PikaObj* obj, char* name) {
|
||||
NewFun constructor = (NewFun)getNewClassObjFunByName(obj, name);
|
||||
Args buffs = {0};
|
||||
PikaObj* thisClass;
|
||||
PikaObj* new_obj;
|
||||
PikaObj* oNew;
|
||||
if (NULL == constructor) {
|
||||
/* no such object */
|
||||
res = NULL;
|
||||
goto exit;
|
||||
}
|
||||
thisClass = obj_newObjFromConstructor(obj, name, constructor);
|
||||
new_obj = removeMethodInfo(thisClass);
|
||||
obj_runNativeMethod(new_obj, "__init__", NULL);
|
||||
args_setPtrWithType(obj->list, name, ARG_TYPE_OBJECT, new_obj);
|
||||
oNew = removeMethodInfo(thisClass);
|
||||
obj_setName(oNew, name);
|
||||
obj_runNativeMethod(oNew, "__init__", NULL);
|
||||
args_setPtrWithType(obj->list, name, ARG_TYPE_OBJECT, oNew);
|
||||
res = obj_getPtr(obj, name);
|
||||
// pikaGC_enable(res);
|
||||
goto exit;
|
||||
@ -735,7 +755,7 @@ static PikaObj* _obj_getObjWithKeepDeepth(PikaObj* self,
|
||||
goto exit;
|
||||
exit:
|
||||
if (NULL != obj) {
|
||||
pika_assert(pikaGC_checkAlive(obj));
|
||||
pika_assert(obj_checkAlive(obj));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
@ -1736,7 +1756,7 @@ PikaObj* pikaGC_getLast(PikaObj* self) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pikaGC_cleanMark(void) {
|
||||
void pikaGC_clean(PikaGC* gc) {
|
||||
PikaObj* obj = g_PikaObjState.gcChain;
|
||||
while (NULL != obj) {
|
||||
obj_clearFlag(obj, OBJ_FLAG_GC_MARKED);
|
||||
@ -1774,7 +1794,8 @@ uint32_t pikaGC_printFreeList(void) {
|
||||
while (NULL != obj) {
|
||||
if (!obj_getFlag(obj, OBJ_FLAG_GC_MARKED)) {
|
||||
count++;
|
||||
pika_platform_printf("gc free: %p\r\n", obj);
|
||||
pika_platform_printf("gc free: ");
|
||||
obj_dump(obj);
|
||||
}
|
||||
obj = obj->gcNext;
|
||||
}
|
||||
@ -1782,10 +1803,18 @@ uint32_t pikaGC_printFreeList(void) {
|
||||
return count;
|
||||
}
|
||||
|
||||
uint32_t pikaGC_FreeOnce(void) {
|
||||
pikaGC_markRoot();
|
||||
// pika_platform_printf("-----\r\n");
|
||||
// pikaGC_printCanFree();
|
||||
void obj_dump(PikaObj* self) {
|
||||
#if !PIKA_KERNAL_DEBUG_ENABLE
|
||||
return;
|
||||
#else
|
||||
pika_platform_printf("[%s]", self->name);
|
||||
pika_platform_printf("\t\t@%p", self);
|
||||
pika_platform_printf("\r\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t pikaGC_markSweepOnce(PikaGC* gc) {
|
||||
_pikaGC_mark(gc);
|
||||
uint32_t count = 0;
|
||||
PikaObj* freeList[16] = {0};
|
||||
PikaObj* obj = g_PikaObjState.gcChain;
|
||||
@ -1797,6 +1826,7 @@ uint32_t pikaGC_FreeOnce(void) {
|
||||
obj = obj->gcNext;
|
||||
}
|
||||
if (count > 0) {
|
||||
pikaGC_markDump();
|
||||
pikaGC_printFreeList();
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
obj_GC(freeList[i]);
|
||||
@ -1805,59 +1835,91 @@ uint32_t pikaGC_FreeOnce(void) {
|
||||
return count;
|
||||
}
|
||||
|
||||
int32_t pikaGC_markHandler(Arg* argEach, Args* context) {
|
||||
int32_t _pikaGC_markHandler(Arg* argEach, void* context) {
|
||||
PikaGC* gc = (PikaGC*)context;
|
||||
if (arg_isObject(argEach)) {
|
||||
PikaObj* obj = (PikaObj*)arg_getPtr(argEach);
|
||||
#if PIKA_KERNAL_DEBUG_ENABLE
|
||||
obj->gcRoot = (void*)context;
|
||||
obj->gcRoot = (void*)gc->oThis;
|
||||
#endif
|
||||
pikaGC_mark(obj);
|
||||
pikaGC_markObj(gc, obj);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pikaGC_mark(PikaObj* self) {
|
||||
void pikaGC_markObj(PikaGC* gc, PikaObj* self) {
|
||||
gc->oThis = self;
|
||||
gc->markDeepth++;
|
||||
if (NULL == self) {
|
||||
return;
|
||||
goto __exit;
|
||||
}
|
||||
if (obj_getFlag(self, OBJ_FLAG_GC_MARKED)) {
|
||||
return;
|
||||
goto __exit;
|
||||
}
|
||||
obj_setFlag(self, OBJ_FLAG_GC_MARKED);
|
||||
args_foreach(self->list, pikaGC_markHandler, (void*)self);
|
||||
if (NULL != gc->onMarkObj) {
|
||||
gc->onMarkObj(gc);
|
||||
}
|
||||
args_foreach(self->list, _pikaGC_markHandler, gc);
|
||||
if (self->constructor == New_PikaStdData_Dict) {
|
||||
PikaDict* dict = obj_getPtr(self, "dict");
|
||||
if (NULL == dict) {
|
||||
return;
|
||||
goto __exit;
|
||||
}
|
||||
args_foreach(&dict->super, pikaGC_markHandler, (void*)self);
|
||||
return;
|
||||
args_foreach(&dict->super, _pikaGC_markHandler, (void*)gc);
|
||||
goto __exit;
|
||||
}
|
||||
if (self->constructor == New_PikaStdData_List ||
|
||||
self->constructor == New_PikaStdData_Tuple) {
|
||||
PikaList* list = obj_getPtr(self, "list");
|
||||
if (NULL == list) {
|
||||
return;
|
||||
goto __exit;
|
||||
}
|
||||
args_foreach(&list->super, pikaGC_markHandler, (void*)self);
|
||||
return;
|
||||
args_foreach(&list->super, _pikaGC_markHandler, (void*)gc);
|
||||
goto __exit;
|
||||
}
|
||||
__exit:
|
||||
gc->markDeepth--;
|
||||
return;
|
||||
}
|
||||
|
||||
void pikaGC_markRoot() {
|
||||
pikaGC_cleanMark();
|
||||
void _pikaGC_mark(PikaGC* gc) {
|
||||
pikaGC_clean(gc);
|
||||
PikaObj* root = g_PikaObjState.gcChain;
|
||||
while (NULL != root) {
|
||||
if (obj_getFlag(root, OBJ_FLAG_GC_ROOT)) {
|
||||
pikaGC_mark(root);
|
||||
pikaGC_markObj(gc, root);
|
||||
}
|
||||
root = root->gcNext;
|
||||
}
|
||||
}
|
||||
|
||||
void pikaGC_mark(void) {
|
||||
PikaGC gc = {0};
|
||||
_pikaGC_mark(&gc);
|
||||
}
|
||||
|
||||
int _pikaGC_markDumpHandler(PikaGC* gc) {
|
||||
for (uint32_t i = 0; i < gc->markDeepth - 1; i++) {
|
||||
pika_platform_printf(" ");
|
||||
}
|
||||
if (gc->markDeepth != 1) {
|
||||
pika_platform_printf("- ");
|
||||
}
|
||||
obj_dump(gc->oThis);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pikaGC_markDump(void) {
|
||||
PikaGC gc = {0};
|
||||
pika_platform_printf("========= PIKA GC DUMP =========\r\n");
|
||||
gc.onMarkObj = _pikaGC_markDumpHandler;
|
||||
_pikaGC_mark(&gc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
PIKA_BOOL pikaGC_checkAlive(PikaObj* self) {
|
||||
PIKA_BOOL obj_checkAlive(PikaObj* self) {
|
||||
#if !PIKA_GC_MARK_SWEEP_ENABLE
|
||||
return PIKA_TRUE;
|
||||
#else
|
||||
@ -1888,12 +1950,13 @@ uint32_t pikaGC_markSweep(void) {
|
||||
#if !PIKA_GC_MARK_SWEEP_ENABLE
|
||||
return 0;
|
||||
#else
|
||||
PikaGC gc = {0};
|
||||
uint32_t count = 0;
|
||||
if (pikaGC_islock()) {
|
||||
return 0;
|
||||
}
|
||||
pikaGC_lock();
|
||||
while (pikaGC_FreeOnce() != 0) {
|
||||
while (pikaGC_markSweepOnce(&gc) != 0) {
|
||||
count++;
|
||||
};
|
||||
/* update gc state */
|
||||
@ -1933,7 +1996,7 @@ void pikaGC_append(PikaObj* self) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void pikaGC_remove(PikaObj* self) {
|
||||
void obj_removeGcChain(PikaObj* self) {
|
||||
#if !PIKA_GC_MARK_SWEEP_ENABLE
|
||||
return;
|
||||
#else
|
||||
@ -1948,7 +2011,7 @@ void pikaGC_remove(PikaObj* self) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void pikaGC_enable(PikaObj* self) {
|
||||
void obj_enableGC(PikaObj* self) {
|
||||
#if !PIKA_GC_MARK_SWEEP_ENABLE
|
||||
return;
|
||||
#else
|
||||
@ -1993,7 +2056,7 @@ PikaObj* New_PikaObj(void) {
|
||||
#endif
|
||||
#if PIKA_KERNAL_DEBUG_ENABLE
|
||||
self->aName = NULL;
|
||||
self->name = NULL;
|
||||
self->name = "PikaObj";
|
||||
self->parent = NULL;
|
||||
self->isAlive = PIKA_TRUE;
|
||||
#endif
|
||||
@ -2019,6 +2082,7 @@ Arg* arg_setRef(Arg* self, char* name, PikaObj* obj) {
|
||||
int32_t obj_newDirectObj(PikaObj* self, char* objName, NewFun newFunPtr) {
|
||||
Arg* aNewObj = arg_newDirectObj(newFunPtr);
|
||||
aNewObj = arg_setName(aNewObj, objName);
|
||||
obj_setName(arg_getPtr(aNewObj), objName);
|
||||
arg_setType(aNewObj, ARG_TYPE_OBJECT);
|
||||
// pikaGC_enable(arg_getPtr(aNewObj));
|
||||
args_setArg(self->list, aNewObj);
|
||||
@ -2027,9 +2091,9 @@ int32_t obj_newDirectObj(PikaObj* self, char* objName, NewFun newFunPtr) {
|
||||
|
||||
int32_t obj_newMetaObj(PikaObj* self, char* objName, NewFun newFunPtr) {
|
||||
/* add meta Obj, no inited */
|
||||
Arg* new_obj = arg_newMetaObj(newFunPtr);
|
||||
new_obj = arg_setName(new_obj, objName);
|
||||
args_setArg(self->list, new_obj);
|
||||
Arg* aMetaObj = arg_newMetaObj(newFunPtr);
|
||||
aMetaObj = arg_setName(aMetaObj, objName);
|
||||
args_setArg(self->list, aMetaObj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -75,29 +75,34 @@ struct NativeProperty {
|
||||
uint32_t methodGroupCount;
|
||||
};
|
||||
|
||||
/* clang-format off */
|
||||
typedef struct PikaObj PikaObj;
|
||||
struct PikaObj {
|
||||
Args* list;
|
||||
void* constructor;
|
||||
#if PIKA_GC_MARK_SWEEP_ENABLE
|
||||
PikaObj* gcNext;
|
||||
#if PIKA_KERNAL_DEBUG_ENABLE
|
||||
PikaObj* gcRoot;
|
||||
#endif
|
||||
#endif
|
||||
#if PIKA_KERNAL_DEBUG_ENABLE
|
||||
char* name;
|
||||
Arg* aName;
|
||||
PikaObj* parent;
|
||||
PIKA_BOOL isAlive;
|
||||
PIKA_BOOL isGCRoot;
|
||||
#endif
|
||||
#if PIKA_GC_MARK_SWEEP_ENABLE
|
||||
PikaObj* gcNext;
|
||||
#endif
|
||||
#if PIKA_KERNAL_DEBUG_ENABLE
|
||||
char* name;
|
||||
Arg* aName;
|
||||
PikaObj* parent;
|
||||
PIKA_BOOL isAlive;
|
||||
PIKA_BOOL isGCRoot;
|
||||
#endif
|
||||
#if PIKA_GC_MARK_SWEEP_ENABLE && PIKA_KERNAL_DEBUG_ENABLE
|
||||
PikaObj* gcRoot;
|
||||
#endif
|
||||
uint8_t refcnt;
|
||||
uint8_t flag;
|
||||
};
|
||||
|
||||
/* clang-format on */
|
||||
typedef struct PikaGC PikaGC;
|
||||
typedef int (*pikaGC_hook)(PikaGC* gc);
|
||||
struct PikaGC {
|
||||
uint32_t markDeepth;
|
||||
pikaGC_hook onMarkObj;
|
||||
PikaObj* oThis;
|
||||
};
|
||||
|
||||
typedef struct RangeData RangeData;
|
||||
struct RangeData {
|
||||
@ -625,34 +630,35 @@ void obj_printModules(PikaObj* self);
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define pika_assert_arg_alive(__arg) \
|
||||
do { \
|
||||
if (NULL != (__arg)) { \
|
||||
if (arg_isObject((__arg))) { \
|
||||
pika_assert(pikaGC_checkAlive(arg_getPtr((__arg)))); \
|
||||
} \
|
||||
} \
|
||||
#define pika_assert_arg_alive(__arg) \
|
||||
do { \
|
||||
if (NULL != (__arg)) { \
|
||||
if (arg_isObject((__arg))) { \
|
||||
pika_assert(obj_checkAlive(arg_getPtr((__arg)))); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define pika_assert_obj_alive(__obj) \
|
||||
do { \
|
||||
pika_assert(pikaGC_checkAlive((__obj))); \
|
||||
#define pika_assert_obj_alive(__obj) \
|
||||
do { \
|
||||
pika_assert(obj_checkAlive((__obj))); \
|
||||
} while (0)
|
||||
|
||||
void pikaGC_append(PikaObj* self);
|
||||
uint32_t pikaGC_count(void);
|
||||
void pikaGC_remove(PikaObj* self);
|
||||
void pikaGC_mark(PikaObj* self);
|
||||
void pikaGC_markRoot(void);
|
||||
uint32_t pikaGC_countMarked(void);
|
||||
uint32_t pikaGC_printFreeList(void);
|
||||
uint32_t pikaGC_markSweep(void);
|
||||
PIKA_BOOL pikaGC_checkAlive(PikaObj* self);
|
||||
void pikaGC_enable(PikaObj* self);
|
||||
void pikaGC_try(void);
|
||||
void obj_appendGcChain(PikaObj* self);
|
||||
void obj_removeGcChain(PikaObj* self);
|
||||
void obj_enableGC(PikaObj* self);
|
||||
PIKA_BOOL obj_checkAlive(PikaObj* self);
|
||||
void obj_setName(PikaObj* self, char* name);
|
||||
|
||||
void pikaGC_mark(void);
|
||||
void pikaGC_markDump(void);
|
||||
void pikaGC_lock(void);
|
||||
void pikaGC_unlock(void);
|
||||
PIKA_BOOL pikaGC_islock(void);
|
||||
uint32_t pikaGC_count(void);
|
||||
uint32_t pikaGC_countMarked(void);
|
||||
uint32_t pikaGC_markSweep(void);
|
||||
uint32_t pikaGC_printFreeList(void);
|
||||
|
||||
int pika_GIL_EXIT(void);
|
||||
int pika_GIL_ENTER(void);
|
||||
|
@ -1780,7 +1780,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pika_assert(pikaGC_checkAlive(oMethodHost));
|
||||
pika_assert(obj_checkAlive(oMethodHost));
|
||||
|
||||
#if !PIKA_NANO_ENABLE
|
||||
if (!bSkipInit && vm->in_super &&
|
||||
@ -1864,6 +1864,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
|
||||
arg_setType(aReturn, ARG_TYPE_OBJECT);
|
||||
/* init object */
|
||||
PikaObj* oNew = arg_getPtr(aReturn);
|
||||
obj_setName(oNew, sRunPath);
|
||||
Arg* aMethod = obj_getMethodArg_noalloc(oNew, "__init__", &arg_reg1);
|
||||
oSublocalsInit = New_Locals(NULL);
|
||||
Arg* aReturnInit = NULL;
|
||||
|
@ -34,11 +34,17 @@ const NativeProperty TinyObjNativeProp = {.super = NULL,
|
||||
PikaObj* New_TinyObj(Args* args) {
|
||||
PikaObj* self = New_PikaObj();
|
||||
self->constructor = New_TinyObj;
|
||||
#if PIKA_KERNAL_DEBUG_ENABLE
|
||||
self->name = "TinyObj";
|
||||
#endif
|
||||
return self;
|
||||
}
|
||||
|
||||
PikaObj* New_Locals(Args* args) {
|
||||
PikaObj* self = New_PikaObj();
|
||||
self->constructor = New_Locals;
|
||||
#if PIKA_KERNAL_DEBUG_ENABLE
|
||||
self->name = "Locals";
|
||||
#endif
|
||||
return self;
|
||||
}
|
||||
|
@ -441,8 +441,8 @@ Arg* args_getArgByIndex(Args* self, int index) {
|
||||
}
|
||||
|
||||
PIKA_RES args_foreach(Args* self,
|
||||
int32_t (*eachHandle)(Arg* argEach, Args* context),
|
||||
Args* context) {
|
||||
int32_t (*eachHandle)(Arg* argEach, void* context),
|
||||
void* context) {
|
||||
if (NULL == self->firstNode) {
|
||||
return PIKA_RES_OK;
|
||||
}
|
||||
|
@ -107,8 +107,8 @@ PIKA_RES args_setPtrWithType(Args* self,
|
||||
ArgType type,
|
||||
void* objPtr);
|
||||
PIKA_RES args_foreach(Args* self,
|
||||
int32_t (*eachHandle)(Arg* argEach, Args* context),
|
||||
Args* context);
|
||||
int32_t (*eachHandle)(Arg* argEach, void* context),
|
||||
void* context);
|
||||
|
||||
char* args_getBuff(Args* self, int32_t size);
|
||||
PIKA_RES args_pushArg(Args* self, Arg* arg);
|
||||
|
@ -168,7 +168,7 @@ static int32_t _stack_pushArg(Stack* stack, Arg* arg, PIKA_BOOL is_alloc) {
|
||||
int32_t stack_pushArg(Stack* stack, Arg* arg) {
|
||||
pika_assert(arg != NULL);
|
||||
if (arg_isObject(arg)) {
|
||||
pika_assert(pikaGC_checkAlive(arg_getPtr(arg)));
|
||||
pika_assert(obj_checkAlive(arg_getPtr(arg)));
|
||||
}
|
||||
if (arg_isSerialized(arg)) {
|
||||
return _stack_pushArg(stack, arg, PIKA_TRUE);
|
||||
|
@ -130,7 +130,7 @@ TEST(gc, heap_failed1) {
|
||||
#if PIKA_GC_MARK_SWEEP_ENABLE
|
||||
int cnt = pikaGC_count();
|
||||
EXPECT_EQ(cnt != 0, 1);
|
||||
pikaGC_markRoot();
|
||||
pikaGC_markDump();
|
||||
int cnt_marked = pikaGC_countMarked();
|
||||
EXPECT_EQ(cnt, cnt_marked);
|
||||
/* deinit */
|
||||
@ -165,6 +165,17 @@ TEST(gc, circle2) {
|
||||
obj_deinit(pikaMain);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
TEST(gc, tree1) {
|
||||
/* init */
|
||||
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
|
||||
/* run */
|
||||
pikaVM_runSingleFile(pikaMain, "test/python/gc/gc_tree1.py");
|
||||
/* assert */
|
||||
/* deinit */
|
||||
obj_deinit(pikaMain);
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_END
|
@ -1,6 +1,6 @@
|
||||
#include "test_common.h"
|
||||
TEST_START
|
||||
#if !PIKA_NANO_ENABLE && 0
|
||||
#if !PIKA_NANO_ENABLE && 1
|
||||
|
||||
TEST(pikaui, page) {
|
||||
/* init */
|
||||
@ -16,6 +16,5 @@ TEST(pikaui, page) {
|
||||
EXPECT_EQ(pikaMemNow(), 0);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
TEST_END
|
@ -59,6 +59,8 @@ class Page2(ui.Page):
|
||||
|
||||
|
||||
app = ui.App()
|
||||
page1 = Page1()
|
||||
page1.add(page1.build())
|
||||
app.pageManager.enter(Page2())
|
||||
app.timer.cb(0)
|
||||
# mem.now()
|
||||
|
11
test/python/gc/gc_tree1.py
Normal file
11
test/python/gc/gc_tree1.py
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
class Tree:
|
||||
parent = None
|
||||
child = []
|
||||
|
||||
t1 = Tree()
|
||||
t2 = Tree()
|
||||
t1.child.append(t2)
|
||||
del t2
|
||||
|
||||
gcdump()
|
Loading…
x
Reference in New Issue
Block a user