⚡ optimize ghost table structure
This commit is contained in:
parent
7cc9ef436e
commit
d954a3fc5e
|
@ -40,13 +40,16 @@ var quick_fib(var* args, usize size, gc* ngc) {
|
||||||
u32 ghost_for_test;
|
u32 ghost_for_test;
|
||||||
|
|
||||||
void ghost_for_test_destructor(void* ptr) {
|
void ghost_for_test_destructor(void* ptr) {
|
||||||
std::cout<<"delete "<<ptr<<"\n";
|
std::cout<<"ghost_for_test::destructor (0x";
|
||||||
|
std::cout<<std::hex<<(u64)ptr<<std::dec<<") {\n";
|
||||||
delete (u32*)ptr;
|
delete (u32*)ptr;
|
||||||
|
std::cout<<" delete 0x"<<std::hex<<(u64)ptr<<std::dec<<";\n";
|
||||||
|
std::cout<<"}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
var create_new_ghost(var* args, usize size, gc* ngc) {
|
var create_new_ghost(var* args, usize size, gc* ngc) {
|
||||||
var res=ngc->alloc(vm_obj);
|
var res=ngc->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;
|
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";
|
std::cout<<"set_new_ghost: not ghost for test type.\n";
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
std::cout<<"set_new_ghost: successfully set ghost.\n";
|
|
||||||
f64 num=args[1].num();
|
f64 num=args[1].num();
|
||||||
*((u32*)res.obj().ptr)=static_cast<u32>(num);
|
*((u32*)res.obj().ptr)=static_cast<u32>(num);
|
||||||
|
std::cout<<"set_new_ghost: successfully set ghost = "<<num<<"\n";
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +71,7 @@ var print_new_ghost(var* args, usize size, gc* ngc) {
|
||||||
std::cout<<"print_new_ghost: not ghost for test type.\n";
|
std::cout<<"print_new_ghost: not ghost for test type.\n";
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
std::cout<<"print_new_ghost: result = "<<*((u32*)res.obj().ptr)<<"\n";
|
std::cout<<"print_new_ghost: "<<res.obj()<<" result = "<<*((u32*)res.obj().ptr)<<"\n";
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +87,10 @@ module_func_info func_tbl[]={
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" module_func_info* get(ghost_register_table* table) {
|
extern "C" module_func_info* get(ghost_register_table* table) {
|
||||||
|
if (table->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(
|
nasal_fib_module::ghost_for_test=table->register_ghost_type(
|
||||||
"fib_for_test",
|
"fib_for_test",
|
||||||
nasal_fib_module::ghost_for_test_destructor
|
nasal_fib_module::ghost_for_test_destructor
|
||||||
|
|
|
@ -544,13 +544,13 @@ var builtin_open(var* local, gc& ngc) {
|
||||||
return nas_err("open", "failed to open file <"+name.str()+">");
|
return nas_err("open", "failed to open file <"+name.str()+">");
|
||||||
}
|
}
|
||||||
var ret=ngc.alloc(vm_obj);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
var builtin_close(var* local, gc& ngc) {
|
var builtin_close(var* local, gc& ngc) {
|
||||||
var fd=local[1];
|
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");
|
return nas_err("close", "not a valid filehandle");
|
||||||
}
|
}
|
||||||
fd.obj().clear();
|
fd.obj().clear();
|
||||||
|
@ -561,7 +561,7 @@ var builtin_read(var* local, gc& ngc) {
|
||||||
var fd=local[1];
|
var fd=local[1];
|
||||||
var buf=local[2];
|
var buf=local[2];
|
||||||
var len=local[3];
|
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");
|
return nas_err("read", "not a valid filehandle");
|
||||||
}
|
}
|
||||||
if (buf.type!=vm_str || buf.val.gcobj->unmut) {
|
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 builtin_write(var* local, gc& ngc) {
|
||||||
var fd=local[1];
|
var fd=local[1];
|
||||||
var str=local[2];
|
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");
|
return nas_err("write", "not a valid filehandle");
|
||||||
}
|
}
|
||||||
if (str.type!=vm_str) {
|
if (str.type!=vm_str) {
|
||||||
|
@ -600,7 +600,7 @@ var builtin_seek(var* local, gc& ngc) {
|
||||||
var fd=local[1];
|
var fd=local[1];
|
||||||
var pos=local[2];
|
var pos=local[2];
|
||||||
var whence=local[3];
|
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 nas_err("seek", "not a valid filehandle");
|
||||||
}
|
}
|
||||||
return var::num((f64)fseek((FILE*)fd.obj().ptr, pos.num(), whence.num()));
|
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 builtin_tell(var* local, gc& ngc) {
|
||||||
var fd=local[1];
|
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 nas_err("tell", "not a valid filehandle");
|
||||||
}
|
}
|
||||||
return var::num((f64)ftell((FILE*)fd.obj().ptr));
|
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 builtin_readln(var* local, gc& ngc) {
|
||||||
var fd=local[1];
|
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 nas_err("readln", "not a valid filehandle");
|
||||||
}
|
}
|
||||||
var str=ngc.alloc(vm_str);
|
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 builtin_eof(var* local, gc& ngc) {
|
||||||
var fd=local[1];
|
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 nas_err("readln", "not a valid filehandle");
|
||||||
}
|
}
|
||||||
return var::num((f64)feof((FILE*)fd.obj().ptr));
|
return var::num((f64)feof((FILE*)fd.obj().ptr));
|
||||||
|
@ -849,13 +849,13 @@ var builtin_opendir(var* local, gc& ngc) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
var ret=ngc.alloc(vm_obj);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
var builtin_readdir(var* local, gc& ngc) {
|
var builtin_readdir(var* local, gc& ngc) {
|
||||||
var handle=local[1];
|
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");
|
return nas_err("readdir", "not a valid dir handle");
|
||||||
}
|
}
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -872,7 +872,7 @@ var builtin_readdir(var* local, gc& ngc) {
|
||||||
|
|
||||||
var builtin_closedir(var* local, gc& ngc) {
|
var builtin_closedir(var* local, gc& ngc) {
|
||||||
var handle=local[1];
|
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");
|
return nas_err("closedir", "not a valid dir handle");
|
||||||
}
|
}
|
||||||
handle.obj().clear();
|
handle.obj().clear();
|
||||||
|
@ -936,7 +936,7 @@ var builtin_dlopen(var* local, gc& ngc) {
|
||||||
}
|
}
|
||||||
var ret=ngc.temp=ngc.alloc(vm_hash);
|
var ret=ngc.temp=ngc.alloc(vm_hash);
|
||||||
var lib=ngc.alloc(vm_obj);
|
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;
|
ret.hash().elems["lib"]=lib;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -948,14 +948,14 @@ var builtin_dlopen(var* local, gc& ngc) {
|
||||||
return nas_err("dlopen", "cannot find <get> function");
|
return nas_err("dlopen", "cannot find <get> function");
|
||||||
}
|
}
|
||||||
// get function pointer by name
|
// 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) {
|
if (!tbl) {
|
||||||
return nas_err("dlopen", "failed to get module functions");
|
return nas_err("dlopen", "failed to get module functions");
|
||||||
}
|
}
|
||||||
for(u32 i=0;tbl[i].name;++i) {
|
for(u32 i=0;tbl[i].name;++i) {
|
||||||
void* p=(void*)tbl[i].fd;
|
void* p=(void*)tbl[i].fd;
|
||||||
var tmp=ngc.alloc(vm_obj);
|
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;
|
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 builtin_dlclose(var* local, gc& ngc) {
|
||||||
var libptr=local[1];
|
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");
|
return nas_err("dlclose", "\"lib\" is not a valid dynamic lib");
|
||||||
}
|
}
|
||||||
libptr.obj().clear();
|
libptr.obj().clear();
|
||||||
|
@ -975,7 +975,7 @@ var builtin_dlclose(var* local, gc& ngc) {
|
||||||
var builtin_dlcallv(var* local, gc& ngc) {
|
var builtin_dlcallv(var* local, gc& ngc) {
|
||||||
var fp=local[1];
|
var fp=local[1];
|
||||||
var args=local[2];
|
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");
|
return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
|
||||||
}
|
}
|
||||||
auto& vec=args.vec().elems;
|
auto& vec=args.vec().elems;
|
||||||
|
@ -988,7 +988,7 @@ var builtin_dlcallv(var* local, gc& ngc) {
|
||||||
|
|
||||||
var builtin_dlcall(var* local, gc& ngc) {
|
var builtin_dlcall(var* local, gc& ngc) {
|
||||||
var fp=local[1];
|
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");
|
return nas_err("dlcall", "\"ptr\" is not a valid function pointer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
44
nasal_gc.h
44
nasal_gc.h
|
@ -208,6 +208,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<string,usize> mapper;
|
std::unordered_map<string,usize> mapper;
|
||||||
|
std::vector<string> ghost_name;
|
||||||
std::vector<dtor> destructors;
|
std::vector<dtor> destructors;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -225,6 +226,18 @@ public:
|
||||||
ghost_faddr=register_ghost_type("faddr", func_addr_destructor);
|
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) {
|
usize register_ghost_type(const std::string& name, dtor ptr) {
|
||||||
if (mapper.count(name)) {
|
if (mapper.count(name)) {
|
||||||
std::cerr<<"nasal_gc.h: ghost_register_table::register_ghost_type: ";
|
std::cerr<<"nasal_gc.h: ghost_register_table::register_ghost_type: ";
|
||||||
|
@ -233,6 +246,7 @@ public:
|
||||||
}
|
}
|
||||||
auto res=destructors.size();
|
auto res=destructors.size();
|
||||||
mapper[name]=res;
|
mapper[name]=res;
|
||||||
|
ghost_name.push_back(name);
|
||||||
destructors.push_back(ptr);
|
destructors.push_back(ptr);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -242,18 +256,26 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ghost_register_table global_ghost_type_table;
|
|
||||||
|
|
||||||
struct nas_obj {
|
struct nas_obj {
|
||||||
public:
|
public:
|
||||||
usize type;
|
usize type;
|
||||||
void* ptr;
|
void* ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ghost_register_table* ghost_type_table;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nas_obj(): type(0), ptr(nullptr) {}
|
nas_obj(): type(0), ptr(nullptr), ghost_type_table(nullptr) {}
|
||||||
~nas_obj() {clear();}
|
~nas_obj() {clear();}
|
||||||
void set(usize, void*);
|
void set(usize, void*, ghost_register_table*);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend std::ostream& operator<<(std::ostream& out, nas_obj& ghost) {
|
||||||
|
out<<"<object "<<ghost.ghost_type_table->get_ghost_name(ghost.type);
|
||||||
|
out<<" at 0x"<<std::hex<<(u64)ghost.ptr<<std::dec<<">";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct context {
|
struct context {
|
||||||
|
@ -392,16 +414,17 @@ void nas_func::clear() {
|
||||||
keys.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;
|
type=t;
|
||||||
ptr=p;
|
ptr=p;
|
||||||
|
ghost_type_table=table;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nas_obj::clear() {
|
void nas_obj::clear() {
|
||||||
if (!ptr || !type) {
|
if (!ptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
global_ghost_type_table.destructor(type)(ptr);
|
ghost_type_table->destructor(type)(ptr);
|
||||||
ptr=nullptr;
|
ptr=nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,7 +509,7 @@ std::ostream& operator<<(std::ostream& out, var& ref) {
|
||||||
case vm_vec: out<<ref.vec(); break;
|
case vm_vec: out<<ref.vec(); break;
|
||||||
case vm_hash: out<<ref.hash(); break;
|
case vm_hash: out<<ref.hash(); break;
|
||||||
case vm_func: out<<"func(..) {..}";break;
|
case vm_func: out<<"func(..) {..}";break;
|
||||||
case vm_obj: out<<"<object>"; break;
|
case vm_obj: out<<ref.obj(); break;
|
||||||
case vm_co: out<<"<coroutine>"; break;
|
case vm_co: out<<"<coroutine>"; break;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
@ -541,6 +564,7 @@ const var one =var::num(1);
|
||||||
const var nil =var::nil();
|
const var nil =var::nil();
|
||||||
|
|
||||||
struct gc {
|
struct gc {
|
||||||
|
ghost_register_table global_ghost_type_table;
|
||||||
/* main context temporary storage */
|
/* main context temporary storage */
|
||||||
context mctx;
|
context mctx;
|
||||||
|
|
||||||
|
@ -714,7 +738,7 @@ void gc::sweep() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc::extend(u8 type) {
|
void gc::extend(u8 type) {
|
||||||
u8 index=type-vm_str;
|
const u8 index=type-vm_str;
|
||||||
size[index]+=incr[index];
|
size[index]+=incr[index];
|
||||||
|
|
||||||
for(u32 i=0;i<incr[index];++i) {
|
for(u32 i=0;i<incr[index];++i) {
|
||||||
|
@ -744,7 +768,7 @@ void gc::init(const std::vector<string>& s, const std::vector<string>& argv) {
|
||||||
size[i]=gcnt[i]=acnt[i]=0;
|
size[i]=gcnt[i]=acnt[i]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// coroutine pointer set to nullpre
|
// coroutine pointer set to nullptr
|
||||||
cort=nullptr;
|
cort=nullptr;
|
||||||
|
|
||||||
// init constant strings
|
// init constant strings
|
||||||
|
|
Loading…
Reference in New Issue