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.");
class Environment {
public:
Environment() { }
Environment() = default;
static Environment Unreachable() {
Environment env;
env.live_.set();
env.unreachable_ = true;
return env;
}
static Environment Merge(const Environment& l,
const Environment& r) {
return Environment(l, r);
Environment out(l);
out &= r;
return out;
}
Environment ApplyEffect(ExprEffect effect) const {
Environment out = effect.hasGC() ? Environment() : Environment(*this);
if (effect.env() != NULL) out.live_ |= effect.env()->live_;
if (effect.env()) out |= *effect.env();
return out;
}
......@@ -342,20 +344,23 @@ class Environment {
bool IsAlive(const std::string& name) const {
SymbolTable::iterator code = symbol_table_.find(name);
if (code == symbol_table_.end()) return false;
return live_[code->second];
return is_live(code->second);
}
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 {
return Environment(*this, SymbolToCode(name));
}
void MDefine(const std::string& name) {
live_.set(SymbolToCode(name));
}
void MDefine(const std::string& name) { set_live(SymbolToCode(name)); }
static int SymbolToCode(const std::string& name) {
SymbolTable::iterator code = symbol_table_.find(name);
......@@ -370,12 +375,7 @@ class Environment {
}
static void ClearSymbolTable() {
std::vector<Environment*>::iterator end = envs_.end();
for (std::vector<Environment*>::iterator i = envs_.begin();
i != end;
++i) {
delete *i;
}
for (Environment* e : envs_) delete e;
envs_.clear();
symbol_table_.clear();
}
......@@ -383,15 +383,11 @@ class Environment {
void Print() const {
bool comma = false;
std::cout << "{";
SymbolTable::iterator end = symbol_table_.end();
for (SymbolTable::iterator i = symbol_table_.begin();
i != end;
++i) {
if (live_[i->second]) {
if (comma) std::cout << ", ";
std::cout << i->first;
comma = true;
}
for (auto& e : symbol_table_) {
if (!is_live(e.second)) continue;
if (comma) std::cout << ", ";
std::cout << e.first;
comma = true;
}
std::cout << "}";
}
......@@ -403,20 +399,43 @@ class Environment {
}
private:
Environment(const Environment& l, const Environment& r)
: live_(l.live_ & r.live_) {
}
Environment(const Environment& l, int code)
: 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 std::vector<Environment* > envs_;
static std::vector<Environment*> envs_;
static const int kMaxNumberOfLocals = 256;
std::bitset<kMaxNumberOfLocals> live_;
std::vector<bool> live_;
bool unreachable_ = false;
friend class ExprEffect;
friend class CallProps;
......@@ -432,8 +451,11 @@ class CallProps {
if (in.hasRawDef()) raw_def_.set(arg);
if (in.hasRawUse()) raw_use_.set(arg);
if (in.env() != NULL) {
if (env_ == NULL) env_ = in.env();
env_->live_ |= in.env()->live_;
if (env_ == NULL) {
env_ = in.env();
} else {
*env_ |= *in.env();
}
}
}
......@@ -462,8 +484,7 @@ class CallProps {
Environment::SymbolTable Environment::symbol_table_;
std::vector<Environment* > Environment::envs_;
std::vector<Environment*> Environment::envs_;
ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) {
Environment* a_env = a.env();
......@@ -471,7 +492,7 @@ ExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) {
Environment* out = NULL;
if (a_env != NULL && b_env != NULL) {
out = Environment::Allocate(*a_env);
out->live_ &= b_env->live_;
*out &= *b_env;
}
return ExprEffect(a.effect_ | b.effect_, out);
}
......@@ -483,7 +504,7 @@ ExprEffect ExprEffect::MergeSeq(ExprEffect a, ExprEffect b) {
Environment* out = (b_env == NULL) ? a_env : b_env;
if (a_env != NULL && b_env != NULL) {
out = Environment::Allocate(*b_env);
out->live_ |= a_env->live_;
*out |= *a_env;
}
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