diff --git a/src/nasal_dbg.cpp b/src/nasal_dbg.cpp index 35a85a4..94cbfd8 100644 --- a/src/nasal_dbg.cpp +++ b/src/nasal_dbg.cpp @@ -290,7 +290,7 @@ void dbg::run(const codegen& gen, counter.dump_all_code_line_counter(std::clog): counter.dump_this_file_line_counter(std::clog); } - ngc.info(); + ngc.status.dump_info(); ngc.clear(); imm.clear(); return; diff --git a/src/nasal_gc.cpp b/src/nasal_gc.cpp index fab1854..ba56bc4 100644 --- a/src/nasal_gc.cpp +++ b/src/nasal_gc.cpp @@ -1,5 +1,4 @@ #include "nasal_gc.h" -#include "util/util.h" namespace nasal { @@ -31,10 +30,9 @@ void gc::mark() { std::vector bfs; mark_context_root(bfs); - // concurrent mark, experimental - if (memory.size() > gc::concurrent_threshold() && bfs.size() > 16) { - status.flag_concurrent_mark_triggered = true; - usize size = bfs.size(); + // concurrent mark + if (memory.size() > UINT16_MAX * 16 && bfs.size() > 16) { + auto size = bfs.size(); std::thread t0(&gc::concurrent_mark, this, std::ref(bfs), 0, size/4); std::thread t1(&gc::concurrent_mark, this, std::ref(bfs), size/4, size/2); std::thread t2(&gc::concurrent_mark, this, std::ref(bfs), size/2, size/4*3); @@ -297,147 +295,6 @@ void gc::clear() { env_argv.clear(); } -void gc::info() const { - util::windows_code_page_manager wm; - wm.set_utf8_output(); - - using std::left; - using std::setw; - using std::setfill; - using std::setprecision; - - const char* used_table_name[] = { - "object type", - "gc cycle", - "alloc count", - "object count", - "detail", - "time spend", - "gc time", - "avg time", - "max gc", - "max mark", - "max sweep", - nullptr - }; - const char* name[] = { - "string", - "vector", - "hashmap", - "function", - "upvalue", - "ghost", - "coroutine", - "namespace", - nullptr - }; - - usize indent = 0, len = 0; - for(usize i = 0; used_table_name[i]; ++i) { - len = std::string(used_table_name[i]).length(); - indent = indent(status.gc_cycle_trigger_count[i]); - std::clog << "│ " << left << setw(indent) << setfill(' ') << name[i]; - std::clog << " │ " << left << setw(indent) << setfill(' ') << status.gc_cycle_trigger_count[i]; - std::clog << " │ " << left << setw(indent) << setfill(' ') << status.alloc_count[i]; - std::clog << " │ " << left << setw(indent) << setfill(' ') << status.object_size[i]; - std::clog << " │\n" << std::internal; - } - std::clog << mid_line << "\n"; - - const auto den = std::chrono::high_resolution_clock::duration::period::den; - std::clog << "│ " << left << setw(indent) << setfill(' ') << "detail"; - std::clog << " │ " << left << setw(indent) << setfill(' ') << "time spend"; - std::clog << " " << left << setw(indent) << setfill(' ') << " "; - std::clog << " " << left << setw(indent) << setfill(' ') << " "; - std::clog << " │\n" << another_mid_line << "\n"; - - std::clog << "│ " << left << setw(indent) << setfill(' ') << "gc time"; - std::clog << " │ " << setw(indent-3) << setprecision(4) << status.gc_time_ms() << " ms"; - std::clog << setw(indent*2+7) << " " << "│\n"; - - std::clog << "│ " << left << setw(indent) << setfill(' ') << "avg time"; - std::clog << " │ " << setw(indent-3) << setprecision(4) << status.avg_time_ms() << " ms"; - std::clog << setw(indent*2+7) << " " << "│\n"; - - std::clog << "│ " << left << setw(indent) << setfill(' ') << "avg mark"; - std::clog << " │ " << setw(indent-3) << setprecision(4) << status.avg_mark_time_ms() << " ms"; - std::clog << setw(indent*2+7) << " " << "│\n"; - - std::clog << "│ " << left << setw(indent) << setfill(' ') << "avg sweep"; - std::clog << " │ " << setw(indent-3) << setprecision(4) << status.avg_sweep_time_ms() << " ms"; - std::clog << setw(indent*2+7) << " " << "│\n"; - - std::clog << "│ " << left << setw(indent) << setfill(' ') << "max mark"; - std::clog << " │ " << setw(indent-3) << setprecision(4) << status.max_mark_time_ms() << " ms"; - std::clog << setw(indent*2+7) << " " << "│\n"; - - std::clog << "│ " << left << setw(indent) << setfill(' ') << "max sweep"; - std::clog << " │ " << setw(indent-3) << setprecision(4) << status.max_sweep_time_ms() << " ms"; - std::clog << setw(indent*2+7) << " " << "│\n"; - - std::clog << "│ " << left << setw(indent) << setfill(' ') << "concurrent"; - std::clog << " │ " << setw(indent) - << (status.flag_concurrent_mark_triggered? "true":"false"); - std::clog << setw(indent*2+7) << " " << "│\n"; - - std::clog << last_line << "\n" << std::internal; - - wm.restore_code_page(); -} - var gc::alloc(const vm_type type) { const u32 index = static_cast(type)-static_cast(vm_type::vm_str); ++status.alloc_count[index]; diff --git a/src/nasal_gc.h b/src/nasal_gc.h index 18c384f..c44e137 100644 --- a/src/nasal_gc.h +++ b/src/nasal_gc.h @@ -95,15 +95,10 @@ private: void mark_map(std::vector&, nas_map&); void sweep(); - static const auto concurrent_threshold() { - return UINT16_MAX * 16; - } - public: void extend(const vm_type); void init(const std::vector&, const std::vector&); void clear(); - void info() const; var alloc(const vm_type); void context_change(nas_co*); void context_reserve(); diff --git a/src/nasal_opcode.h b/src/nasal_opcode.h index 0b9fa1a..9201ff8 100644 --- a/src/nasal_opcode.h +++ b/src/nasal_opcode.h @@ -215,8 +215,7 @@ public: const nasal_builtin_table*, const std::string* file_list = nullptr); void dump(std::ostream&) const; + friend std::ostream& operator<<(std::ostream&, const codestream&); }; -std::ostream& operator<<(std::ostream&, const codestream&); - } \ No newline at end of file diff --git a/src/nasal_vm.cpp b/src/nasal_vm.cpp index 0dcfaaa..96b9388 100644 --- a/src/nasal_vm.cpp +++ b/src/nasal_vm.cpp @@ -717,7 +717,7 @@ void vm::run(const codegen& gen, // all nasal programs should end here vmexit: if (verbose) { - ngc.info(); + ngc.status.dump_info(); } imm.clear(); if (!is_repl_mode) { diff --git a/src/util/gc_stat.cpp b/src/util/gc_stat.cpp index 5bac2f6..d6631e5 100644 --- a/src/util/gc_stat.cpp +++ b/src/util/gc_stat.cpp @@ -1,6 +1,8 @@ +#include "util/util.h" #include "util/gc_stat.h" #include +#include namespace nasal { @@ -19,8 +21,6 @@ void gc_stat::init() { max_mark_time = 0; max_sweep_time = 0; - - flag_concurrent_mark_triggered = false; } f64 gc_stat::gc_time_ms() const { @@ -56,4 +56,138 @@ f64 gc_stat::max_sweep_time_ms() const { return (max_sweep_time * 1000.0) / den; } +void gc_stat::dump_info() const { + util::windows_code_page_manager wm; + wm.set_utf8_output(); + + using std::left; + using std::setw; + using std::setfill; + using std::setprecision; + + const char* used_table_name[] = { + "object type", + "gc cycle", + "alloc count", + "object count", + "detail", + "time spend", + "gc time", + "avg time", + "max gc", + "max mark", + "max sweep" + }; + const char* name[] = { + "string", + "vector", + "hashmap", + "function", + "upvalue", + "ghost", + "coroutine", + "namespace" + }; + + // calculate max indent length + usize indent = 0; + for (auto tname : used_table_name) { + auto len = strlen(tname); + indent = indent start_time; void stamp() { @@ -50,6 +48,8 @@ struct gc_stat { f64 avg_sweep_time_ms() const; f64 max_mark_time_ms() const; f64 max_sweep_time_ms() const; + + void dump_info() const; }; } \ No newline at end of file