fix args_foreach handler

add PikaGC class

add gc.onMarkObj

add GC DUMP

support gcdump()

improve gcdump
This commit is contained in:
pikastech 2023-03-09 13:56:17 +08:00
parent e58095c2eb
commit ca65efd1fa
17 changed files with 247 additions and 131 deletions

View File

@ -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:

View File

@ -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();
}

View File

@ -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,

View File

@ -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:

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -0,0 +1,11 @@
class Tree:
parent = None
child = []
t1 = Tree()
t2 = Tree()
t1.child.append(t2)
del t2
gcdump()