Commit b8787e34 authored by clemensh's avatar clemensh Committed by Commit bot

[gcmole] Avoid hardcoded maximum of 256 locals

This CL changes the datastructure to store live variables from a
std::bitset<256> to a std::vector<bool> to support an arbitrary number
of locals. Unfortunately, std::vector<bool> does not define |= and &=
operators, so I added them on the Environment class.

R=vegorov@chromium.org, mstarzinger@chromium.org, machenbach@chromium.org
BUG=v8:5970

Review-Url: https://codereview.chromium.org/2694103005
Cr-Commit-Position: refs/heads/master@{#43216}
parent 3fc10464
...@@ -318,22 +318,24 @@ const std::string DEAD_VAR_MSG("Possibly dead variable."); ...@@ -318,22 +318,24 @@ const std::string DEAD_VAR_MSG("Possibly dead variable.");
class Environment { class Environment {
public: public:
Environment() { } Environment() = default;
static Environment Unreachable() { static Environment Unreachable() {
Environment env; Environment env;
env.live_.set(); env.unreachable_ = true;
return env; return env;
} }
static Environment Merge(const Environment& l, static Environment Merge(const Environment& l,
const Environment& r) { const Environment& r) {
return Environment(l, r); Environment out(l);
out &= r;
return out;
} }
Environment ApplyEffect(ExprEffect effect) const { Environment ApplyEffect(ExprEffect effect) const {
Environment out = effect.hasGC() ? Environment() : Environment(*this); Environment out = effect.hasGC() ? Environment() : Environment(*this);
if (effect.env() != NULL) out.live_ |= effect.env()->live_; if (effect.env()) out |= *effect.env();
return out; return out;
} }
...@@ -342,20 +344,23 @@ class Environment { ...@@ -342,20 +344,23 @@ class Environment {
bool IsAlive(const std::string& name) const { bool IsAlive(const std::string& name) const {
SymbolTable::iterator code = symbol_table_.find(name); SymbolTable::iterator code = symbol_table_.find(name);
if (code == symbol_table_.end()) return false; if (code == symbol_table_.end()) return false;
return live_[code->second]; return is_live(code->second);
} }
bool Equal(const Environment& env) { bool Equal(const Environment& env) {
return live_ == env.live_; if (unreachable_) return env.unreachable_;
size_t size = std::max(live_.size(), env.live_.size());
for (size_t i = 0; i < size; ++i) {
if (is_live(i) != env.is_live(i)) return false;
}
return true;
} }
Environment Define(const std::string& name) const { Environment Define(const std::string& name) const {
return Environment(*this, SymbolToCode(name)); return Environment(*this, SymbolToCode(name));
} }
void MDefine(const std::string& name) { void MDefine(const std::string& name) { set_live(SymbolToCode(name)); }
live_.set(SymbolToCode(name));
}
static int SymbolToCode(const std::string& name) { static int SymbolToCode(const std::string& name) {
SymbolTable::iterator code = symbol_table_.find(name); SymbolTable::iterator code = symbol_table_.find(name);
...@@ -370,12 +375,7 @@ class Environment { ...@@ -370,12 +375,7 @@ class Environment {
} }
static void ClearSymbolTable() { static void ClearSymbolTable() {
std::vector<Environment*>::iterator end = envs_.end(); for (Environment* e : envs_) delete e;
for (std::vector<Environment*>::iterator i = envs_.begin();
i != end;
++i) {
delete *i;
}
envs_.clear(); envs_.clear();
symbol_table_.clear(); symbol_table_.clear();
} }
...@@ -383,16 +383,12 @@ class Environment { ...@@ -383,16 +383,12 @@ class Environment {
void Print() const { void Print() const {
bool comma = false; bool comma = false;
std::cout << "{"; std::cout << "{";
SymbolTable::iterator end = symbol_table_.end(); for (auto& e : symbol_table_) {
for (SymbolTable::iterator i = symbol_table_.begin(); if (!is_live(e.second)) continue;
i != end;
++i) {
if (live_[i->second]) {
if (comma) std::cout << ", "; if (comma) std::cout << ", ";
std::cout << i->first; std::cout << e.first;
comma = true; comma = true;
} }
}
std::cout << "}"; std::cout << "}";
} }
...@@ -403,20 +399,43 @@ class Environment { ...@@ -403,20 +399,43 @@ class Environment {
} }
private: private:
Environment(const Environment& l, const Environment& r)
: live_(l.live_ & r.live_) {
}
Environment(const Environment& l, int code) Environment(const Environment& l, int code)
: live_(l.live_) { : live_(l.live_) {
live_.set(code); set_live(code);
}
void set_live(size_t pos) {
if (live_.size() <= pos) live_.resize(std::max(pos + 1, 2 * live_.size()));
live_[pos] = true;
}
bool is_live(size_t pos) const {
return unreachable_ || (live_.size() > pos && live_[pos]);
}
Environment& operator|=(const Environment& o) {
unreachable_ |= o.unreachable_;
for (size_t i = 0, e = o.live_.size(); i < e; ++i) {
if (o.live_[i]) set_live(i);
}
return *this;
}
Environment& operator&=(const Environment& o) {
unreachable_ &= o.unreachable_;
size_t size = std::min(live_.size(), o.live_.size());
if (live_.size() > size) live_.resize(size);
for (size_t i = 0; i < size; ++i) {
if (live_[i] && (i > o.live_.size() || !o.live_[i])) live_[i] = false;
}
return *this;
} }
static SymbolTable symbol_table_; static SymbolTable symbol_table_;
static std::vector<Environment* > envs_; static std::vector<Environment*> envs_;
static const int kMaxNumberOfLocals = 256; std::vector<bool> live_;
std::bitset<kMaxNumberOfLocals> live_; bool unreachable_ = false;
friend class ExprEffect; friend class ExprEffect;
friend class CallProps; friend class CallProps;
...@@ -432,8 +451,11 @@ class CallProps { ...@@ -432,8 +451,11 @@ class CallProps {
if (in.hasRawDef()) raw_def_.set(arg); if (in.hasRawDef()) raw_def_.set(arg);
if (in.hasRawUse()) raw_use_.set(arg); if (in.hasRawUse()) raw_use_.set(arg);
if (in.env() != NULL) { if (in.env() != NULL) {
if (env_ == NULL) env_ = in.env(); if (env_ == NULL) {
env_->live_ |= in.env()->live_; env_ = in.env();
} else {
*env_ |= *in.env();
}
} }
} }
...@@ -462,8 +484,7 @@ class CallProps { ...@@ -462,8 +484,7 @@ class CallProps {
Environment::SymbolTable Environment::symbol_table_; Environment::SymbolTable Environment::symbol_table_;
std::vector<Environment* > Environment::envs_; std::vector<Environment*> Environment::envs_;
ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) { ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) {
Environment* a_env = a.env(); Environment* a_env = a.env();
...@@ -471,7 +492,7 @@ ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) { ...@@ -471,7 +492,7 @@ ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) {
Environment* out = NULL; Environment* out = NULL;
if (a_env != NULL && b_env != NULL) { if (a_env != NULL && b_env != NULL) {
out = Environment::Allocate(*a_env); out = Environment::Allocate(*a_env);
out->live_ &= b_env->live_; *out &= *b_env;
} }
return ExprEffect(a.effect_ | b.effect_, out); return ExprEffect(a.effect_ | b.effect_, out);
} }
...@@ -483,7 +504,7 @@ ExprEffect ExprEffect::MergeSeq(ExprEffect a, ExprEffect b) { ...@@ -483,7 +504,7 @@ ExprEffect ExprEffect::MergeSeq(ExprEffect a, ExprEffect b) {
Environment* out = (b_env == NULL) ? a_env : b_env; Environment* out = (b_env == NULL) ? a_env : b_env;
if (a_env != NULL && b_env != NULL) { if (a_env != NULL && b_env != NULL) {
out = Environment::Allocate(*b_env); out = Environment::Allocate(*b_env);
out->live_ |= a_env->live_; *out |= *a_env;
} }
return ExprEffect(a.effect_ | b.effect_, out); return ExprEffect(a.effect_ | b.effect_, out);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment