✨ use incremental gc const initialization
This commit is contained in:
parent
85bc699905
commit
6c8b4c6a87
|
@ -1181,13 +1181,15 @@ const error& codegen::compile(parse& parse, linker& import) {
|
|||
// check global variables size
|
||||
if (global.size()>=STACK_DEPTH/2) {
|
||||
err.err("code",
|
||||
"too many global variables: " + std::to_string(global.size()));
|
||||
"too many global variables: " + std::to_string(global.size())
|
||||
);
|
||||
}
|
||||
|
||||
// check generated code size
|
||||
if (code.size()>0xffffff) {
|
||||
err.err("code",
|
||||
"bytecode size overflow: " + std::to_string(code.size()));
|
||||
"bytecode size overflow: " + std::to_string(code.size())
|
||||
);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -536,7 +536,9 @@ void gc::extend(u8 type) {
|
|||
}
|
||||
|
||||
void gc::init(
|
||||
const std::vector<std::string>& s, const std::vector<std::string>& argv) {
|
||||
const std::vector<std::string>& constant_strings,
|
||||
const std::vector<std::string>& argv
|
||||
) {
|
||||
// initialize counters
|
||||
worktime = 0;
|
||||
for(u8 i = 0; i<gc_type_size; ++i) {
|
||||
|
@ -547,16 +549,24 @@ void gc::init(
|
|||
cort = nullptr;
|
||||
|
||||
// init constant strings
|
||||
strs.resize(s.size());
|
||||
strs.resize(constant_strings.size());
|
||||
for(u32 i = 0; i<strs.size(); ++i) {
|
||||
strs[i]=var::gcobj(new nas_val(vm_str));
|
||||
// incremental initialization, avoid memory leak in repl mode
|
||||
if (strs[i].type==vm_str && strs[i].str()==constant_strings[i]) {
|
||||
continue;
|
||||
}
|
||||
strs[i] = var::gcobj(new nas_val(vm_str));
|
||||
strs[i].val.gcobj->unmut = 1;
|
||||
strs[i].str() = s[i];
|
||||
strs[i].str() = constant_strings[i];
|
||||
}
|
||||
|
||||
// record arguments
|
||||
env_argv.resize(argv.size());
|
||||
for(usize i = 0; i<argv.size(); ++i) {
|
||||
// incremental initialization, avoid memory leak in repl mode
|
||||
if (env_argv[i].type==vm_str && env_argv[i].str()==argv[i]) {
|
||||
continue;
|
||||
}
|
||||
env_argv[i] = var::gcobj(new nas_val(vm_str));
|
||||
env_argv[i].val.gcobj->unmut = 1;
|
||||
env_argv[i].str() = argv[i];
|
||||
|
|
|
@ -66,7 +66,7 @@ struct nas_val; // nas_val includes gc-managed types
|
|||
|
||||
struct var {
|
||||
public:
|
||||
u8 type;
|
||||
u8 type = vm_none;
|
||||
union {
|
||||
u32 ret;
|
||||
i64 cnt;
|
||||
|
|
10
src/repl.cpp
10
src/repl.cpp
|
@ -10,6 +10,9 @@ namespace nasal {
|
|||
namespace repl {
|
||||
|
||||
void repl::add_command_history(const std::string& history) {
|
||||
if (command_history.size() && command_history.back()==history) {
|
||||
return;
|
||||
}
|
||||
command_history.push_back(history);
|
||||
if (command_history.size()>1000) {
|
||||
command_history.pop_front();
|
||||
|
@ -74,16 +77,12 @@ void repl::help() {
|
|||
}
|
||||
|
||||
bool repl::run() {
|
||||
using clk = std::chrono::high_resolution_clock;
|
||||
const auto den = clk::duration::period::den;
|
||||
|
||||
auto nasal_lexer = std::unique_ptr<lexer>(new lexer);
|
||||
auto nasal_parser = std::unique_ptr<parse>(new parse);
|
||||
auto nasal_linker = std::unique_ptr<linker>(new linker);
|
||||
auto nasal_opt = std::unique_ptr<optimizer>(new optimizer);
|
||||
auto nasal_codegen = std::unique_ptr<codegen>(new codegen);
|
||||
|
||||
auto start = clk::now();
|
||||
update_temp_file();
|
||||
if (nasal_lexer->scan("<nasal-repl>").geterr()) {
|
||||
return false;
|
||||
|
@ -102,9 +101,6 @@ bool repl::run() {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto end = clk::now();
|
||||
std::clog << "[compile time: " << (end-start).count()*1000.0/den << " ms]\n";
|
||||
|
||||
// TODO: gc init stage in this run may cause memory leak,
|
||||
// because constant strings will be generated again.
|
||||
// but we could not delete old strings, they maybe still on stack.
|
||||
|
|
Loading…
Reference in New Issue