Commit edf51c0f authored by kasperl@chromium.org's avatar kasperl@chromium.org

Optimize the scope creation code by lazily allocating the hash maps

for dynamic variables (only do it for the scopes that need them).
Review URL: http://codereview.chromium.org/113393

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1942 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 750a8391
...@@ -31,13 +31,6 @@ ...@@ -31,13 +31,6 @@
namespace v8 { namespace internal { namespace v8 { namespace internal {
static inline bool IsPowerOf2(uint32_t x) {
ASSERT(x != 0);
return (x & (x - 1)) == 0;
}
Allocator HashMap::DefaultAllocator; Allocator HashMap::DefaultAllocator;
......
...@@ -112,9 +112,7 @@ Scope::Scope() ...@@ -112,9 +112,7 @@ Scope::Scope()
locals_(false), locals_(false),
temps_(0), temps_(0),
params_(0), params_(0),
dynamics_(false), dynamics_(NULL),
dynamics_local_(false),
dynamics_global_(false),
unresolved_(0), unresolved_(0),
decls_(0) { decls_(0) {
} }
...@@ -125,9 +123,9 @@ Scope::Scope(Scope* outer_scope, Type type) ...@@ -125,9 +123,9 @@ Scope::Scope(Scope* outer_scope, Type type)
inner_scopes_(4), inner_scopes_(4),
type_(type), type_(type),
scope_name_(Factory::empty_symbol()), scope_name_(Factory::empty_symbol()),
locals_(),
temps_(4), temps_(4),
params_(4), params_(4),
dynamics_(NULL),
unresolved_(16), unresolved_(16),
decls_(4), decls_(4),
receiver_(NULL), receiver_(NULL),
...@@ -477,9 +475,11 @@ void Scope::Print(int n) { ...@@ -477,9 +475,11 @@ void Scope::Print(int n) {
PrintMap(&printer, n1, &locals_); PrintMap(&printer, n1, &locals_);
Indent(n1, "// dynamic vars\n"); Indent(n1, "// dynamic vars\n");
PrintMap(&printer, n1, &dynamics_); if (dynamics_ != NULL) {
PrintMap(&printer, n1, &dynamics_local_); PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC));
PrintMap(&printer, n1, &dynamics_global_); PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_LOCAL));
PrintMap(&printer, n1, dynamics_->GetMap(Variable::DYNAMIC_GLOBAL));
}
// Print inner scopes (disable by providing negative n). // Print inner scopes (disable by providing negative n).
if (n >= 0) { if (n >= 0) {
...@@ -495,23 +495,8 @@ void Scope::Print(int n) { ...@@ -495,23 +495,8 @@ void Scope::Print(int n) {
Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) { Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
// Space optimization: reuse existing non-local with the same name if (dynamics_ == NULL) dynamics_ = new DynamicScopePart();
// and mode. LocalsMap* map = dynamics_->GetMap(mode);
LocalsMap* map = NULL;
switch (mode) {
case Variable::DYNAMIC:
map = &dynamics_;
break;
case Variable::DYNAMIC_LOCAL:
map = &dynamics_local_;
break;
case Variable::DYNAMIC_GLOBAL:
map = &dynamics_global_;
break;
default:
UNREACHABLE();
break;
}
Variable* var = map->Lookup(name); Variable* var = map->Lookup(name);
if (var == NULL) { if (var == NULL) {
// Declare a new non-local. // Declare a new non-local.
......
...@@ -35,7 +35,6 @@ namespace v8 { namespace internal { ...@@ -35,7 +35,6 @@ namespace v8 { namespace internal {
// A hash map to support fast local variable declaration and lookup. // A hash map to support fast local variable declaration and lookup.
class LocalsMap: public HashMap { class LocalsMap: public HashMap {
public: public:
LocalsMap(); LocalsMap();
...@@ -53,6 +52,23 @@ class LocalsMap: public HashMap { ...@@ -53,6 +52,23 @@ class LocalsMap: public HashMap {
}; };
// The dynamic scope part holds hash maps for the variables that will
// be looked up dynamically from within eval and with scopes. The objects
// are allocated on-demand from Scope::NonLocal to avoid wasting memory
// and setup time for scopes that don't need them.
class DynamicScopePart : public ZoneObject {
public:
LocalsMap* GetMap(Variable::Mode mode) {
int index = mode - Variable::DYNAMIC;
ASSERT(index >= 0 && index < 3);
return &maps_[index];
}
private:
LocalsMap maps_[3];
};
// Global invariants after AST construction: Each reference (i.e. identifier) // Global invariants after AST construction: Each reference (i.e. identifier)
// to a JavaScript variable (including global properties) is represented by a // to a JavaScript variable (including global properties) is represented by a
// VariableProxy node. Immediately after AST construction and before variable // VariableProxy node. Immediately after AST construction and before variable
...@@ -278,9 +294,7 @@ class Scope: public ZoneObject { ...@@ -278,9 +294,7 @@ class Scope: public ZoneObject {
// parameter list in source order // parameter list in source order
ZoneList<Variable*> params_; ZoneList<Variable*> params_;
// variables that must be looked up dynamically // variables that must be looked up dynamically
LocalsMap dynamics_; DynamicScopePart* dynamics_;
LocalsMap dynamics_local_;
LocalsMap dynamics_global_;
// unresolved variables referred to from this scope // unresolved variables referred to from this scope
ZoneList<VariableProxy*> unresolved_; ZoneList<VariableProxy*> unresolved_;
// declarations // declarations
......
...@@ -42,8 +42,6 @@ static inline bool IsPowerOf2(T x) { ...@@ -42,8 +42,6 @@ static inline bool IsPowerOf2(T x) {
} }
// The C++ standard leaves the semantics of '>>' undefined for // The C++ standard leaves the semantics of '>>' undefined for
// negative signed operands. Most implementations do the right thing, // negative signed operands. Most implementations do the right thing,
// though. // though.
......
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