From d954a3fc5e824cefa8437928e87c576d819663c1 Mon Sep 17 00:00:00 2001 From: ValKmjolnir Date: Thu, 11 May 2023 19:26:34 +0800 Subject: [PATCH] :zap: optimize ghost table structure --- module/fib.cpp | 15 +++++++++++---- nasal_builtin.h | 34 +++++++++++++++++----------------- nasal_gc.h | 44 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 31 deletions(-) diff --git a/module/fib.cpp b/module/fib.cpp index 70c2219..c7327d0 100644 --- a/module/fib.cpp +++ b/module/fib.cpp @@ -40,13 +40,16 @@ var quick_fib(var* args, usize size, gc* ngc) { u32 ghost_for_test; void ghost_for_test_destructor(void* ptr) { - std::cout<<"delete "<alloc(vm_obj); - res.obj().set(ghost_for_test, new u32); + res.obj().set(ghost_for_test, new u32, &ngc->global_ghost_type_table); return res; } @@ -56,9 +59,9 @@ var set_new_ghost(var* args, usize size, gc* ngc) { std::cout<<"set_new_ghost: not ghost for test type.\n"; return nil; } - std::cout<<"set_new_ghost: successfully set ghost.\n"; f64 num=args[1].num(); *((u32*)res.obj().ptr)=static_cast(num); + std::cout<<"set_new_ghost: successfully set ghost = "<exists("fib_for_test")) { + nasal_fib_module::ghost_for_test=table->get_ghost_type_index("fib_for_test"); + return nasal_fib_module::func_tbl; + } nasal_fib_module::ghost_for_test=table->register_ghost_type( "fib_for_test", nasal_fib_module::ghost_for_test_destructor diff --git a/nasal_builtin.h b/nasal_builtin.h index 10b3071..f8653da 100644 --- a/nasal_builtin.h +++ b/nasal_builtin.h @@ -544,13 +544,13 @@ var builtin_open(var* local, gc& ngc) { return nas_err("open", "failed to open file <"+name.str()+">"); } var ret=ngc.alloc(vm_obj); - ret.obj().set(global_ghost_type_table.ghost_file, res); + ret.obj().set(ngc.global_ghost_type_table.ghost_file, res, &ngc.global_ghost_type_table); return ret; } var builtin_close(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("close", "not a valid filehandle"); } fd.obj().clear(); @@ -561,7 +561,7 @@ var builtin_read(var* local, gc& ngc) { var fd=local[1]; var buf=local[2]; var len=local[3]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("read", "not a valid filehandle"); } if (buf.type!=vm_str || buf.val.gcobj->unmut) { @@ -587,7 +587,7 @@ var builtin_read(var* local, gc& ngc) { var builtin_write(var* local, gc& ngc) { var fd=local[1]; var str=local[2]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("write", "not a valid filehandle"); } if (str.type!=vm_str) { @@ -600,7 +600,7 @@ var builtin_seek(var* local, gc& ngc) { var fd=local[1]; var pos=local[2]; var whence=local[3]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("seek", "not a valid filehandle"); } return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num())); @@ -608,7 +608,7 @@ var builtin_seek(var* local, gc& ngc) { var builtin_tell(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("tell", "not a valid filehandle"); } return var::num((f64)ftell((FILE*)fd.obj().ptr)); @@ -616,7 +616,7 @@ var builtin_tell(var* local, gc& ngc) { var builtin_readln(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("readln", "not a valid filehandle"); } var str=ngc.alloc(vm_str); @@ -664,7 +664,7 @@ var builtin_stat(var* local, gc& ngc) { var builtin_eof(var* local, gc& ngc) { var fd=local[1]; - if (!fd.objchk(global_ghost_type_table.ghost_file)) { + if (!fd.objchk(ngc.global_ghost_type_table.ghost_file)) { return nas_err("readln", "not a valid filehandle"); } return var::num((f64)feof((FILE*)fd.obj().ptr)); @@ -849,13 +849,13 @@ var builtin_opendir(var* local, gc& ngc) { } #endif var ret=ngc.alloc(vm_obj); - ret.obj().set(global_ghost_type_table.ghost_dir,p); + ret.obj().set(ngc.global_ghost_type_table.ghost_dir, p, &ngc.global_ghost_type_table); return ret; } var builtin_readdir(var* local, gc& ngc) { var handle=local[1]; - if (!handle.objchk(global_ghost_type_table.ghost_dir)) { + if (!handle.objchk(ngc.global_ghost_type_table.ghost_dir)) { return nas_err("readdir", "not a valid dir handle"); } #ifdef _MSC_VER @@ -872,7 +872,7 @@ var builtin_readdir(var* local, gc& ngc) { var builtin_closedir(var* local, gc& ngc) { var handle=local[1]; - if (!handle.objchk(global_ghost_type_table.ghost_dir)) { + if (!handle.objchk(ngc.global_ghost_type_table.ghost_dir)) { return nas_err("closedir", "not a valid dir handle"); } handle.obj().clear(); @@ -936,7 +936,7 @@ var builtin_dlopen(var* local, gc& ngc) { } var ret=ngc.temp=ngc.alloc(vm_hash); var lib=ngc.alloc(vm_obj); - lib.obj().set(global_ghost_type_table.ghost_dylib, ptr); + lib.obj().set(ngc.global_ghost_type_table.ghost_dylib, ptr, &ngc.global_ghost_type_table); ret.hash().elems["lib"]=lib; #ifdef _WIN32 @@ -948,14 +948,14 @@ var builtin_dlopen(var* local, gc& ngc) { return nas_err("dlopen", "cannot find function"); } // get function pointer by name - module_func_info* tbl=((get_func_ptr)func)(&global_ghost_type_table); + module_func_info* tbl=((get_func_ptr)func)(&ngc.global_ghost_type_table); if (!tbl) { return nas_err("dlopen", "failed to get module functions"); } for(u32 i=0;tbl[i].name;++i) { void* p=(void*)tbl[i].fd; var tmp=ngc.alloc(vm_obj); - tmp.obj().set(global_ghost_type_table.ghost_faddr, p); + tmp.obj().set(ngc.global_ghost_type_table.ghost_faddr, p, &ngc.global_ghost_type_table); ret.hash().elems[tbl[i].name]=tmp; } @@ -965,7 +965,7 @@ var builtin_dlopen(var* local, gc& ngc) { var builtin_dlclose(var* local, gc& ngc) { var libptr=local[1]; - if (!libptr.objchk(global_ghost_type_table.ghost_dylib)) { + if (!libptr.objchk(ngc.global_ghost_type_table.ghost_dylib)) { return nas_err("dlclose", "\"lib\" is not a valid dynamic lib"); } libptr.obj().clear(); @@ -975,7 +975,7 @@ var builtin_dlclose(var* local, gc& ngc) { var builtin_dlcallv(var* local, gc& ngc) { var fp=local[1]; var args=local[2]; - if (!fp.objchk(global_ghost_type_table.ghost_faddr)) { + if (!fp.objchk(ngc.global_ghost_type_table.ghost_faddr)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } auto& vec=args.vec().elems; @@ -988,7 +988,7 @@ var builtin_dlcallv(var* local, gc& ngc) { var builtin_dlcall(var* local, gc& ngc) { var fp=local[1]; - if (!fp.objchk(global_ghost_type_table.ghost_faddr)) { + if (!fp.objchk(ngc.global_ghost_type_table.ghost_faddr)) { return nas_err("dlcall", "\"ptr\" is not a valid function pointer"); } diff --git a/nasal_gc.h b/nasal_gc.h index 65c8414..fe51d8b 100644 --- a/nasal_gc.h +++ b/nasal_gc.h @@ -208,6 +208,7 @@ private: private: std::unordered_map mapper; + std::vector ghost_name; std::vector destructors; public: @@ -225,6 +226,18 @@ public: ghost_faddr=register_ghost_type("faddr", func_addr_destructor); } + bool exists(const string& name) const { + return mapper.count(name); + } + + usize get_ghost_type_index(const string& name) const { + return mapper.at(name); + } + + const string& get_ghost_name(usize index) const { + return ghost_name.at(index); + } + usize register_ghost_type(const std::string& name, dtor ptr) { if (mapper.count(name)) { std::cerr<<"nasal_gc.h: ghost_register_table::register_ghost_type: "; @@ -233,6 +246,7 @@ public: } auto res=destructors.size(); mapper[name]=res; + ghost_name.push_back(name); destructors.push_back(ptr); return res; } @@ -242,18 +256,26 @@ public: } }; -ghost_register_table global_ghost_type_table; - struct nas_obj { public: usize type; void* ptr; +private: + ghost_register_table* ghost_type_table; + public: - nas_obj(): type(0), ptr(nullptr) {} + nas_obj(): type(0), ptr(nullptr), ghost_type_table(nullptr) {} ~nas_obj() {clear();} - void set(usize, void*); + void set(usize, void*, ghost_register_table*); void clear(); + +public: + friend std::ostream& operator<<(std::ostream& out, nas_obj& ghost) { + out<<"get_ghost_name(ghost.type); + out<<" at 0x"<"; + return out; + } }; struct context { @@ -392,16 +414,17 @@ void nas_func::clear() { keys.clear(); } -void nas_obj::set(usize t, void* p) { +void nas_obj::set(usize t, void* p, ghost_register_table* table) { type=t; ptr=p; + ghost_type_table=table; } void nas_obj::clear() { - if (!ptr || !type) { + if (!ptr) { return; } - global_ghost_type_table.destructor(type)(ptr); + ghost_type_table->destructor(type)(ptr); ptr=nullptr; } @@ -486,7 +509,7 @@ std::ostream& operator<<(std::ostream& out, var& ref) { case vm_vec: out<"; break; + case vm_obj: out<"; break; } return out; @@ -541,6 +564,7 @@ const var one =var::num(1); const var nil =var::nil(); struct gc { + ghost_register_table global_ghost_type_table; /* main context temporary storage */ context mctx; @@ -714,7 +738,7 @@ void gc::sweep() { } void gc::extend(u8 type) { - u8 index=type-vm_str; + const u8 index=type-vm_str; size[index]+=incr[index]; for(u32 i=0;i& s, const std::vector& argv) { size[i]=gcnt[i]=acnt[i]=0; } - // coroutine pointer set to nullpre + // coroutine pointer set to nullptr cort=nullptr; // init constant strings