diff options
author | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2016-02-17 17:19:21 +0900 |
---|---|---|
committer | Shinichiro Hamaji <shinichiro.hamaji@gmail.com> | 2016-02-17 17:19:21 +0900 |
commit | 92a4738218523292a0cec0310023eed194025f24 (patch) | |
tree | 384f420b0b9c8254be840caeb22d4b8576522db2 | |
parent | 121165ed878d844662a25d5ee3b95ab1ceaddca2 (diff) | |
download | kati-92a4738218523292a0cec0310023eed194025f24.tar.gz |
[C++] Add a fast path for interning lhs of assignments
-rw-r--r-- | eval.cc | 2 | ||||
-rw-r--r-- | expr.cc | 1 | ||||
-rw-r--r-- | expr.h | 2 | ||||
-rw-r--r-- | stmt.cc | 13 | ||||
-rw-r--r-- | stmt.h | 9 |
5 files changed, 26 insertions, 1 deletions
@@ -96,7 +96,7 @@ Var* Evaluator::EvalRHS(Symbol lhs, Value* rhs_v, StringPiece orig_rhs, void Evaluator::EvalAssign(const AssignStmt* stmt) { loc_ = stmt->loc(); last_rule_ = NULL; - Symbol lhs = Intern(stmt->lhs->Eval(this)); + Symbol lhs = stmt->GetLhsSymbol(this); if (lhs.empty()) Error("*** empty variable name."); Var* rhs = EvalRHS(lhs, stmt->rhs, stmt->orig_rhs, stmt->op, @@ -63,6 +63,7 @@ class Literal : public Value { } virtual bool IsLiteral() const override { return true; } + virtual StringPiece GetLiteralValueUnsafe() const { return s_; } virtual string DebugString_() const override { return s_.as_string(); @@ -42,6 +42,8 @@ class Value : public Evaluable { virtual Value* Compact() { return this; } virtual bool IsLiteral() const { return false; } + // Only safe after IsLiteral() returns true. + virtual StringPiece GetLiteralValueUnsafe() const { return ""; } string DebugString() const; @@ -55,6 +55,19 @@ string AssignStmt::DebugString() const { opstr, dirstr, LOCF(loc())); } +Symbol AssignStmt::GetLhsSymbol(Evaluator* ev) const { + if (!lhs->IsLiteral()) { + string buf; + lhs->Eval(ev, &buf); + return Intern(buf); + } + + if (!lhs_sym_cache_.IsValid()) { + lhs_sym_cache_ = Intern(lhs->GetLiteralValueUnsafe()); + } + return lhs_sym_cache_; +} + string CommandStmt::DebugString() const { return StringPrintf("CommandStmt(%s, loc=%s:%d)", expr->DebugString().c_str(), LOCF(loc())); @@ -20,6 +20,7 @@ #include "loc.h" #include "string_piece.h" +#include "symtab.h" using namespace std; @@ -85,11 +86,19 @@ struct AssignStmt : public Stmt { AssignOp op; AssignDirective directive; + AssignStmt() + : lhs_sym_cache_(Symbol::IsUninitialized{}) { + } virtual ~AssignStmt(); virtual void Eval(Evaluator* ev) const; virtual string DebugString() const; + + Symbol GetLhsSymbol(Evaluator* ev) const; + + private: + mutable Symbol lhs_sym_cache_; }; struct CommandStmt : public Stmt { |