🎨 improve codes

This commit is contained in:
ValKmjolnir 2025-03-15 17:58:13 +08:00
parent ac8e5c6361
commit 10d2965197
7 changed files with 144 additions and 159 deletions

View File

@ -290,7 +290,7 @@ void dbg::run(const codegen& gen,
counter.dump_all_code_line_counter(std::clog): counter.dump_all_code_line_counter(std::clog):
counter.dump_this_file_line_counter(std::clog); counter.dump_this_file_line_counter(std::clog);
} }
ngc.info(); ngc.status.dump_info();
ngc.clear(); ngc.clear();
imm.clear(); imm.clear();
return; return;

View File

@ -1,5 +1,4 @@
#include "nasal_gc.h" #include "nasal_gc.h"
#include "util/util.h"
namespace nasal { namespace nasal {
@ -31,10 +30,9 @@ void gc::mark() {
std::vector<var> bfs; std::vector<var> bfs;
mark_context_root(bfs); mark_context_root(bfs);
// concurrent mark, experimental // concurrent mark
if (memory.size() > gc::concurrent_threshold() && bfs.size() > 16) { if (memory.size() > UINT16_MAX * 16 && bfs.size() > 16) {
status.flag_concurrent_mark_triggered = true; auto size = bfs.size();
usize size = bfs.size();
std::thread t0(&gc::concurrent_mark, this, std::ref(bfs), 0, size/4); 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 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); 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(); 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<len? len:indent;
}
for(usize i = 0; name[i]; ++i) {
len = std::string(name[i]).length();
indent = indent<len? len:indent;
}
for(u32 i = 0; i<GC_TYPE_SIZE; ++i) {
len = std::to_string(status.gc_cycle_trigger_count[i]).length();
indent = indent<len? len:indent;
len = std::to_string(status.alloc_count[i]).length();
indent = indent<len? len:indent;
len = std::to_string(status.object_size[i]).length();
indent = indent<len? len:indent;
}
auto indent_string = std::string("──");
for(usize i = 0; i<indent; ++i) {
indent_string += "";
}
const auto first_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto second_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto mid_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto another_mid_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto last_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
std::clog << "\n" << first_line << "\n";
std::clog << "" << left << setw(indent) << setfill(' ') << "object type";
std::clog << "" << left << setw(indent) << setfill(' ') << "gc cycle";
std::clog << "" << left << setw(indent) << setfill(' ') << "alloc count";
std::clog << "" << left << setw(indent) << setfill(' ') << "object count";
std::clog << "\n" << second_line << "\n" << std::internal;
double total = 0;
for(u8 i = 0; i<GC_TYPE_SIZE; ++i) {
if (!status.gc_cycle_trigger_count[i] &&
!status.alloc_count[i] &&
!status.object_size[i]) {
continue;
}
total += static_cast<f64>(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) { var gc::alloc(const vm_type type) {
const u32 index = static_cast<u32>(type)-static_cast<u32>(vm_type::vm_str); const u32 index = static_cast<u32>(type)-static_cast<u32>(vm_type::vm_str);
++status.alloc_count[index]; ++status.alloc_count[index];

View File

@ -95,15 +95,10 @@ private:
void mark_map(std::vector<var>&, nas_map&); void mark_map(std::vector<var>&, nas_map&);
void sweep(); void sweep();
static const auto concurrent_threshold() {
return UINT16_MAX * 16;
}
public: public:
void extend(const vm_type); void extend(const vm_type);
void init(const std::vector<std::string>&, const std::vector<std::string>&); void init(const std::vector<std::string>&, const std::vector<std::string>&);
void clear(); void clear();
void info() const;
var alloc(const vm_type); var alloc(const vm_type);
void context_change(nas_co*); void context_change(nas_co*);
void context_reserve(); void context_reserve();

View File

@ -215,8 +215,7 @@ public:
const nasal_builtin_table*, const nasal_builtin_table*,
const std::string* file_list = nullptr); const std::string* file_list = nullptr);
void dump(std::ostream&) const; void dump(std::ostream&) const;
friend std::ostream& operator<<(std::ostream&, const codestream&);
}; };
std::ostream& operator<<(std::ostream&, const codestream&);
} }

View File

@ -717,7 +717,7 @@ void vm::run(const codegen& gen,
// all nasal programs should end here // all nasal programs should end here
vmexit: vmexit:
if (verbose) { if (verbose) {
ngc.info(); ngc.status.dump_info();
} }
imm.clear(); imm.clear();
if (!is_repl_mode) { if (!is_repl_mode) {

View File

@ -1,6 +1,8 @@
#include "util/util.h"
#include "util/gc_stat.h" #include "util/gc_stat.h"
#include <chrono> #include <chrono>
#include <iomanip>
namespace nasal { namespace nasal {
@ -19,8 +21,6 @@ void gc_stat::init() {
max_mark_time = 0; max_mark_time = 0;
max_sweep_time = 0; max_sweep_time = 0;
flag_concurrent_mark_triggered = false;
} }
f64 gc_stat::gc_time_ms() const { 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; 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<len? len:indent;
}
for (auto n : name) {
auto len = strlen(n);
indent = indent<len? len:indent;
}
for(u32 i = 0; i < GC_TYPE_SIZE; ++i) {
auto len = std::to_string(gc_cycle_trigger_count[i]).length();
indent = indent<len? len:indent;
len = std::to_string(alloc_count[i]).length();
indent = indent<len? len:indent;
len = std::to_string(object_size[i]).length();
indent = indent<len? len:indent;
}
auto indent_string = std::string("──");
for(usize i = 0; i < indent; ++i) {
indent_string += "";
}
const auto first_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto second_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto mid_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto another_mid_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
const auto last_line = "" + indent_string + "" +
indent_string + "" +
indent_string + "" +
indent_string + "";
std::clog << "\n" << first_line << "\n";
std::clog << "" << left << setw(indent) << setfill(' ') << "object type";
std::clog << "" << left << setw(indent) << setfill(' ') << "gc cycle";
std::clog << "" << left << setw(indent) << setfill(' ') << "alloc count";
std::clog << "" << left << setw(indent) << setfill(' ') << "object count";
std::clog << "\n" << second_line << "\n" << std::internal;
for (u32 i = 0; i < GC_TYPE_SIZE; ++i) {
if (!gc_cycle_trigger_count[i] &&
!alloc_count[i] &&
!object_size[i]) {
continue;
}
std::clog << "" << left << setw(indent) << setfill(' ') << name[i];
std::clog << "" << left << setw(indent) << setfill(' ') << gc_cycle_trigger_count[i];
std::clog << "" << left << setw(indent) << setfill(' ') << alloc_count[i];
std::clog << "" << left << setw(indent) << setfill(' ') << object_size[i];
std::clog << "\n" << std::internal;
}
std::clog << mid_line << "\n";
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) << 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) << 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) << 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) << 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) << 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) << max_sweep_time_ms() << " ms";
std::clog << setw(indent*2+7) << " " << "\n";
std::clog << last_line << "\n" << std::internal;
wm.restore_code_page();
}
} }

View File

@ -19,8 +19,6 @@ struct gc_stat {
i64 max_mark_time = 0; i64 max_mark_time = 0;
i64 max_sweep_time = 0; i64 max_sweep_time = 0;
bool flag_concurrent_mark_triggered = false;
std::chrono::time_point<std::chrono::high_resolution_clock> start_time; std::chrono::time_point<std::chrono::high_resolution_clock> start_time;
void stamp() { void stamp() {
@ -50,6 +48,8 @@ struct gc_stat {
f64 avg_sweep_time_ms() const; f64 avg_sweep_time_ms() const;
f64 max_mark_time_ms() const; f64 max_mark_time_ms() const;
f64 max_sweep_time_ms() const; f64 max_sweep_time_ms() const;
void dump_info() const;
}; };
} }