detailed stracktrace only when option -d, second implemented in c++

This commit is contained in:
VaclavT 2021-10-11 12:04:49 +02:00
parent b68987fdd7
commit ecbc3af789
6 changed files with 38 additions and 47 deletions

View File

@ -69,18 +69,15 @@ utils/local_install.sh
- multiline editing (see kilocpp editor) - multiline editing (see kilocpp editor)
- execute system command should capture stderr - execute system command should capture stderr
- add some mem stats to benchmark - add some mem stats to benchmark
- add tests for usql
#### Code #### Code
- add documentation - add documentation
- add more unit test, mainly for usql - add more unit test, mainly for usql
- rename constants in ml_profiler.h - rename constants in ml_profiler.h
- replace to_string macro in ml.cpp
- add instrumentation (time, nr of evals, num of atoms, debug info, debug environment etc) - add instrumentation (time, nr of evals, num of atoms, debug info, debug environment etc)
#### Language #### Language
- support for "#t" or "t" symbol as a true and "#f" for false - support for "#t" or "t" symbol as a true and "#f" for false
- support for exceptions
- string functions - string functions
- compare - needed for sorting, cmp ignore case - compare - needed for sorting, cmp ignore case
- regexp match, regexp tokens - regexp match, regexp tokens
@ -91,8 +88,6 @@ utils/local_install.sh
- get-env, set-env; set-env cannot be implemented in stdlib.lsp, because popen is in fact subshell - get-env, set-env; set-env cannot be implemented in stdlib.lsp, because popen is in fact subshell
#### Performance #### Performance
- define is one of most frequent callee, when in scope with very few vars, lookup sequentially
- first, second are often called -> implement in c++
- push_back - repeatedly without reserving size - push_back - repeatedly without reserving size
- range - with for(int i...) and reserving result size can be 3times faster on (range 1 10000) - range - with for(int i...) and reserving result size can be 3times faster on (range 1 10000)
- mini_sprintf - unnecesary copying between vector and list - mini_sprintf - unnecesary copying between vector and list

5
ml.cpp
View File

@ -2162,6 +2162,9 @@ int main(int argc, char *argv[]) {
// performance monitor on // performance monitor on
if (cmdOptionExists(argv, argv + argc, "-p")) if (cmdOptionExists(argv, argv + argc, "-p"))
MlPerfMon::instance().turnOn(); MlPerfMon::instance().turnOn();
// better stacktrace
if (cmdOptionExists(argv, argv + argc, "-d"))
MlPerfMon::instance().debugOn();
// skip loading std lib // skip loading std lib
if (!cmdOptionExists(argv, argv + argc, "-b")) { if (!cmdOptionExists(argv, argv + argc, "-b")) {
load_std_lib(env); load_std_lib(env);
@ -2169,7 +2172,7 @@ int main(int argc, char *argv[]) {
// help // help
if (cmdOptionExists(argv, argv + argc, "-h")) { if (cmdOptionExists(argv, argv + argc, "-h")) {
std::cout std::cout
<< "Usage:\n\t-h print this help\n\t-b skip stdlib loading\n\t-c code - runs code passed on command line\n\t-f source_file - executes code in file\n\t-i runs repl\n\t-run used for shebang\n\t-p prints profile info at the end\n\t-v prints version string\n\n"; << "Usage:\n\t-h print this help\n\t-b skip stdlib loading\n\t-c code - runs code passed on command line\n\t-f source_file - executes code in file\n\t-i runs repl\n\t-run used for shebang\n\t-p prints profile info at the end\n\t-d better stacktrace when exception\n\t-v prints version string\n\n";
return 0; return 0;
} }
// version // version

32
ml.h
View File

@ -58,7 +58,6 @@ public:
friend std::ostream &operator<<(std::ostream &os, MlEnvironment const &v); friend std::ostream &operator<<(std::ostream &os, MlEnvironment const &v);
private: private:
// The definitions in the scope. // The definitions in the scope.
std::map<std::string, MlValue> defs; std::map<std::string, MlValue> defs;
MlEnvironment *parent_scope; MlEnvironment *parent_scope;
@ -97,40 +96,21 @@ typedef MlValue (*Builtin)(std::vector<MlValue>, MlEnvironment &);
class MlPerfMon; class MlPerfMon;
class MlValue { class MlValue {
public: public:
MlValue(); // Constructs a nil value
// Constructs a nil value
MlValue();
// Constructs an integer
MlValue(long i); MlValue(long i);
// Constructs a floating point value
MlValue(double f); MlValue(double f);
// Constructs a bool value
MlValue(bool b); MlValue(bool b);
MlValue(const std::vector<MlValue> &list); // Constructs a list
// Constructs a list static MlValue quote(const MlValue &quoted); // Construct a quoted value
MlValue(const std::vector<MlValue> &list);
// Construct a quoted value
static MlValue quote(const MlValue &quoted);
// Construct an atom
static MlValue atom(const std::string &s); static MlValue atom(const std::string &s);
// Construct a string
static MlValue string(const std::string &s); static MlValue string(const std::string &s);
// Construct a nil
static MlValue nil(); static MlValue nil();
// Construct a lambda function MlValue(const std::vector<MlValue> &params, MlValue ret, MlEnvironment const &env); // Construct a lambda function
MlValue(const std::vector<MlValue> &params, MlValue ret, MlEnvironment const &env); MlValue(const std::string &name, Builtin b); // Construct a builtin function
// Construct a builtin function
MlValue(const std::string &name, Builtin b);
std::vector<std::string> get_used_atoms(); std::vector<std::string> get_used_atoms();

View File

@ -16,21 +16,32 @@ void MlPerfMon::turnOn() {
start_time = std::chrono::high_resolution_clock::now(); start_time = std::chrono::high_resolution_clock::now();
} }
void MlPerfMon::debugOn() {
debugStacktraceOn = true;
}
void MlPerfMon::add_method_call(const MlValue &function, const std::vector<MlValue> &args) { void MlPerfMon::add_method_call(const MlValue &function, const std::vector<MlValue> &args) {
// only main thread is logged, to prevent mixing from others threads so lock not needed // only main thread is logged, to prevent mixing from others threads so lock not needed
if (main_thread_id != std::this_thread::get_id()) return; if (main_thread_id != std::this_thread::get_id()) return;
std::string method = function.type == MlValue::LAMBDA ? "lambda" : function.str; std::string method = function.type == MlValue::LAMBDA ? "lambda" : function.str;
if (debugStacktraceOn) {
// call stack with more info
std::string args_string; std::string args_string;
for (size_t i = 0; i < args.size() && args_string.size() < 64; i++) { for (size_t i = 0; i < args.size() && args_string.size() < call_stack_args_str_len; i++) {
args_string.append(" "); args_string.append(" ");
args_string.append(args[i].display()); args_string.append(args[i].display());
} }
if (args_string.size() > 64) if (args_string.size() > call_stack_args_str_len)
args_string = args_string.substr(0, 62) + ".."; // TODO introduce constant here args_string = args_string.substr(0, call_stack_args_str_len) + "..";
else
args_string.append(")");
call_stack.push_back("(" + method + args_string + ")"); call_stack.push_back("(" + method + args_string);
} else {
call_stack.push_back(method);
}
if (perfOn) if (perfOn)
calls_counter[method]++; calls_counter[method]++;
@ -57,7 +68,7 @@ std::string MlPerfMon::callstack() const {
return cs.append("\n"); return cs.append("\n");
} }
size_t MlPerfMon::get_callstack_position() { size_t MlPerfMon::get_callstack_position() const {
return call_stack.size(); return call_stack.size();
} }
@ -71,7 +82,7 @@ void MlPerfMon::clear_callstack() {
call_stack.empty(); call_stack.empty();
} }
void MlPerfMon::print_results() { void MlPerfMon::print_results() const {
if (perfOn) { if (perfOn) {
time_point<high_resolution_clock> end_time = high_resolution_clock::now(); time_point<high_resolution_clock> end_time = high_resolution_clock::now();

View File

@ -12,11 +12,12 @@
static const int method_name_print_len = 15; static const int method_name_print_len = 15;
static const int print_top_methods = 15; static const int print_top_methods = 15;
static const int call_stack_max_methods = 10; static const int call_stack_max_methods = 10;
static const int call_stack_args_str_len = 64;
class MlPerfMon { class MlPerfMon {
private: private:
MlPerfMon() : perfOn(false) { MlPerfMon() : perfOn(false), debugStacktraceOn(false) {
main_thread_id = std::this_thread::get_id(); main_thread_id = std::this_thread::get_id();
}; };
@ -29,20 +30,22 @@ public:
} }
void turnOn(); void turnOn();
void debugOn();
void add_method_call(const MlValue &function, const std::vector<MlValue> &args); void add_method_call(const MlValue &function, const std::vector<MlValue> &args);
void end_method_call(); void end_method_call();
std::string callstack() const; std::string callstack() const;
size_t get_callstack_position(); size_t get_callstack_position() const;
void restore_callstack_position(size_t to_position); void restore_callstack_position(size_t to_position);
void clear_callstack(); void clear_callstack();
void print_results(); void print_results() const;
private: private:
bool perfOn; bool perfOn;
bool debugStacktraceOn;
std::unordered_map<std::string, long> calls_counter; std::unordered_map<std::string, long> calls_counter;
std::chrono::time_point<std::chrono::high_resolution_clock> start_time; std::chrono::time_point<std::chrono::high_resolution_clock> start_time;
std::deque<std::string> call_stack; std::deque<std::string> call_stack;

View File

@ -50,7 +50,6 @@
(second (system-cmd (+ "echo ${" var "} | tr -d \"\n\"")))) (second (system-cmd (+ "echo ${" var "} | tr -d \"\n\""))))
(defun second (l) (index l 1))
(defun third (l) (index l 2)) (defun third (l) (index l 2))
(defun fourth (l) (index l 3)) (defun fourth (l) (index l 3))
(defun fifth (l) (index l 4)) (defun fifth (l) (index l 4))