diff options
-rw-r--r-- | eval.cc | 24 | ||||
-rw-r--r-- | eval.h | 14 | ||||
-rw-r--r-- | expr.cc | 8 | ||||
-rw-r--r-- | func.cc | 2 | ||||
-rw-r--r-- | main.cc | 3 | ||||
-rw-r--r-- | var.cc | 7 |
6 files changed, 54 insertions, 4 deletions
@@ -17,6 +17,7 @@ #include "eval.h" #include <errno.h> +#include <pthread.h> #include <string.h> #include "expr.h" @@ -37,7 +38,20 @@ Evaluator::Evaluator() eval_depth_(0), posix_sym_(Intern(".POSIX")), is_posix_(false), - kati_readonly_(Intern(".KATI_READONLY")) {} + kati_readonly_(Intern(".KATI_READONLY")) { +#if defined(__APPLE__) + stack_size_ = pthread_get_stacksize_np(pthread_self()); + stack_addr_ = (char*)pthread_get_stackaddr_np(pthread_self()) - stack_size_; +#else + pthread_attr_t attr; + CHECK(pthread_getattr_np(pthread_self(), &attr) == 0); + CHECK(pthread_attr_getstack(&attr, &stack_addr_, &stack_size_) == 0); + CHECK(pthread_attr_destroy(&attr) == 0); +#endif + + lowest_stack_ = (char*)stack_addr_ + stack_size_; + LOG_STAT("Stack size: %zd bytes", stack_size_); +} Evaluator::~Evaluator() { // delete vars_; @@ -289,6 +303,8 @@ void Evaluator::EvalIf(const IfStmt* stmt) { } void Evaluator::DoInclude(const string& fname) { + CheckStack(); + Makefile* mk = MakefileCacheManager::Get()->ReadMakefile(fname); if (!mk->Exists()) { Error(StringPrintf("%s does not exist", fname.c_str())); @@ -400,4 +416,10 @@ void Evaluator::Error(const string& msg) { ERROR_LOC(loc_, "%s", msg.c_str()); } +void Evaluator::DumpStackStats() const { + LOG_STAT("Max stack use: %zd bytes at %s:%d", + ((char*)stack_addr_ - (char*)lowest_stack_) + stack_size_, + LOCF(lowest_loc_)); +} + unordered_set<Symbol> Evaluator::used_undefined_vars_; @@ -86,6 +86,15 @@ class Evaluator { string GetShellFlag(); string GetShellAndFlag(); + void CheckStack() { + void* addr = __builtin_frame_address(0); + if (__builtin_expect(addr < lowest_stack_ && addr >= stack_addr_, 0)) { + lowest_stack_ = addr; + lowest_loc_ = loc_; + } + } + void DumpStackStats() const; + private: Var* EvalRHS(Symbol lhs, Value* rhs, @@ -119,6 +128,11 @@ class Evaluator { Symbol posix_sym_; bool is_posix_; + void* stack_addr_; + size_t stack_size_; + void* lowest_stack_; + Loc lowest_loc_; + static unordered_set<Symbol> used_undefined_vars_; Symbol kati_readonly_; @@ -52,7 +52,8 @@ class Literal : public Value { StringPiece val() const { return s_; } - virtual void Eval(Evaluator*, string* s) const override { + virtual void Eval(Evaluator* ev, string* s) const override { + ev->CheckStack(); s->append(s_.begin(), s_.end()); } @@ -79,6 +80,7 @@ class Expr : public Value { void AddValue(Value* v) { vals_.push_back(v); } virtual void Eval(Evaluator* ev, string* s) const override { + ev->CheckStack(); for (Value* v : vals_) { v->Eval(ev, s); } @@ -119,6 +121,7 @@ class SymRef : public Value { virtual ~SymRef() {} virtual void Eval(Evaluator* ev, string* s) const override { + ev->CheckStack(); Var* v = ev->LookupVar(name_); v->Used(ev, name_); v->Eval(ev, s); @@ -138,6 +141,7 @@ class VarRef : public Value { virtual ~VarRef() { delete name_; } virtual void Eval(Evaluator* ev, string* s) const override { + ev->CheckStack(); ev->IncrementEvalDepth(); const string&& name = name_->Eval(ev); ev->DecrementEvalDepth(); @@ -166,6 +170,7 @@ class VarSubst : public Value { } virtual void Eval(Evaluator* ev, string* s) const override { + ev->CheckStack(); ev->IncrementEvalDepth(); const string&& name = name_->Eval(ev); Symbol sym = Intern(name); @@ -205,6 +210,7 @@ class Func : public Value { } virtual void Eval(Evaluator* ev, string* s) const override { + ev->CheckStack(); LOG("Invoke func %s(%s)", name(), JoinValues(args_, ",").c_str()); ev->IncrementEvalDepth(); fi_->func(args_, ev, s); @@ -462,6 +462,7 @@ void ValueFunc(const vector<Value*>& args, Evaluator* ev, string* s) { void EvalFunc(const vector<Value*>& args, Evaluator* ev, string*) { // TODO: eval leaks everything... for now. // const string text = args[0]->Eval(ev); + ev->CheckStack(); string* text = new string; args[0]->Eval(ev, text); if (ev->avoid_io()) { @@ -595,6 +596,7 @@ void CallFunc(const vector<Value*>& args, Evaluator* ev, string* s) { Intern("0"), Intern("1"), Intern("2"), Intern("3"), Intern("4"), Intern("5"), Intern("6"), Intern("7"), Intern("8"), Intern("9")}; + ev->CheckStack(); const string&& func_name_buf = args[0]->Eval(ev); const StringPiece func_name = TrimSpace(func_name_buf); Var* func = ev->LookupVar(Intern(func_name)); @@ -195,6 +195,7 @@ static int Run(const vector<Symbol>& targets, if (g_flags.generate_ninja) { ScopedTimeReporter tr("generate ninja time"); GenerateNinja(nodes, ev, orig_args, start_time); + ev->DumpStackStats(); return 0; } @@ -216,6 +217,8 @@ static int Run(const vector<Symbol>& targets, Exec(nodes, ev); } + ev->DumpStackStats(); + for (Stmt* stmt : bootstrap_asts) delete stmt; delete ev; @@ -59,7 +59,8 @@ SimpleVar::SimpleVar(VarOrigin origin) : origin_(origin) {} SimpleVar::SimpleVar(const string& v, VarOrigin origin) : v_(v), origin_(origin) {} -void SimpleVar::Eval(Evaluator*, string* s) const { +void SimpleVar::Eval(Evaluator* ev, string* s) const { + ev->CheckStack(); *s += v_; } @@ -82,10 +83,12 @@ RecursiveVar::RecursiveVar(Value* v, VarOrigin origin, StringPiece orig) : v_(v), origin_(origin), orig_(orig) {} void RecursiveVar::Eval(Evaluator* ev, string* s) const { + ev->CheckStack(); v_->Eval(ev, s); } -void RecursiveVar::AppendVar(Evaluator*, Value* v) { +void RecursiveVar::AppendVar(Evaluator* ev, Value* v) { + ev->CheckStack(); v_ = NewExpr3(v_, NewLiteral(" "), v); } |