Introduce subclasses of class CompilationInfo.

It was a wart that we had three handle fields, exactly one of which
was non-null; and that we had three overloaded constructors.  Instead,
introduce subclasses and virtual methods.

Remove some unused fields from class CompilationInfo.

Review URL: http://codereview.chromium.org/3566003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5560 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d46fb9d4
......@@ -146,9 +146,10 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
bool is_json = (validate == Compiler::VALIDATE_JSON);
#ifdef ENABLE_DEBUGGER_SUPPORT
if (is_eval || is_json) {
script->set_compilation_type(
is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
Script::CompilationType compilation_type = is_json
? Script::COMPILATION_TYPE_JSON
: Script::COMPILATION_TYPE_EVAL;
script->set_compilation_type(Smi::FromInt(compilation_type));
// For eval scripts add information on the function from which eval was
// called.
if (is_eval) {
......@@ -171,16 +172,16 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
ASSERT(is_eval || is_global);
// Build AST.
EagerCompilationInfo info(script, is_eval);
FunctionLiteral* lit =
MakeAST(is_global, script, extension, pre_data, is_json);
LiveEditFunctionTracker live_edit_tracker(lit);
// Check for parse errors.
if (lit == NULL) {
ASSERT(Top::has_pending_exception());
return Handle<SharedFunctionInfo>::null();
}
info.set_function(lit);
// Measure how long it takes to do the compilation; only take the
// rest of the function into account to avoid overlap with the
......@@ -191,7 +192,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
HistogramTimerScope timer(rate);
// Compile the code.
CompilationInfo info(lit, script, is_eval);
LiveEditFunctionTracker live_edit_tracker(lit);
Handle<Code> code = MakeCode(context, &info);
// Check for stack-overflow exceptions.
......@@ -482,7 +483,8 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
// Generate code and return it. The way that the compilation mode
// is controlled by the command-line flags is described in
// the static helper function MakeCode.
CompilationInfo info(literal, script, false);
EagerCompilationInfo info(script, false);
info.set_function(literal);
bool is_run_once = literal->try_full_codegen();
bool use_full = FLAG_full_compiler && !literal->contains_loops();
......
......@@ -41,94 +41,109 @@ namespace internal {
// is constructed based on the resources available at compile-time.
class CompilationInfo BASE_EMBEDDED {
public:
// Lazy compilation of a JSFunction.
CompilationInfo(Handle<JSFunction> closure, int loop_nesting)
: closure_(closure),
function_(NULL),
is_eval_(false),
loop_nesting_(loop_nesting) {
ASSERT(!closure_.is_null() &&
shared_info_.is_null() &&
script_.is_null());
}
virtual ~CompilationInfo() {}
// Dispatched behavior.
virtual Handle<SharedFunctionInfo> shared_info() const = 0;
// Lazy compilation based on SharedFunctionInfo.
explicit CompilationInfo(Handle<SharedFunctionInfo> shared_info)
: shared_info_(shared_info),
function_(NULL),
is_eval_(false),
loop_nesting_(0) {
ASSERT(closure_.is_null() &&
!shared_info_.is_null() &&
script_.is_null());
virtual Handle<Script> script() const {
return Handle<Script>(Script::cast(shared_info()->script()));
}
// Eager compilation.
CompilationInfo(FunctionLiteral* literal, Handle<Script> script, bool is_eval)
: script_(script),
function_(literal),
is_eval_(is_eval),
loop_nesting_(0) {
ASSERT(closure_.is_null() &&
shared_info_.is_null() &&
!script_.is_null());
virtual Handle<JSFunction> closure() const {
return Handle<JSFunction>::null();
}
// We can only get a JSFunction if we actually have one.
Handle<JSFunction> closure() { return closure_; }
virtual bool is_eval() const { return false; }
// We can get a SharedFunctionInfo from a JSFunction or if we actually
// have one.
Handle<SharedFunctionInfo> shared_info() {
if (!closure().is_null()) {
return Handle<SharedFunctionInfo>(closure()->shared());
} else {
return shared_info_;
}
}
virtual int loop_nesting() const { return 0; }
// We can always get a script. Either we have one or we can get a shared
// function info.
Handle<Script> script() {
if (!script_.is_null()) {
return script_;
} else {
ASSERT(shared_info()->script()->IsScript());
return Handle<Script>(Script::cast(shared_info()->script()));
}
}
virtual bool has_global_object() const { return false; }
virtual GlobalObject* global_object() const { return NULL; }
// There should always be a function literal, but it may be set after
// construction (for lazy compilation).
FunctionLiteral* function() { return function_; }
void set_function(FunctionLiteral* literal) { function_ = literal; }
// Simple accessors.
bool is_eval() { return is_eval_; }
int loop_nesting() { return loop_nesting_; }
// Derived accessors.
Scope* scope() { return function()->scope(); }
protected:
CompilationInfo() : function_(NULL) {}
private:
FunctionLiteral* function_;
bool has_global_object() {
return !closure().is_null() && (closure()->context()->global() != NULL);
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
};
class EagerCompilationInfo: public CompilationInfo {
public:
EagerCompilationInfo(Handle<Script> script, bool is_eval)
: script_(script), is_eval_(is_eval) {
ASSERT(!script.is_null());
}
GlobalObject* global_object() {
return has_global_object() ? closure()->context()->global() : NULL;
// Overridden functions from the base class.
virtual Handle<SharedFunctionInfo> shared_info() const {
return Handle<SharedFunctionInfo>::null();
}
// Derived accessors.
Scope* scope() { return function()->scope(); }
virtual Handle<Script> script() const { return script_; }
virtual bool is_eval() const { return is_eval_; }
private:
Handle<JSFunction> closure_;
Handle<SharedFunctionInfo> shared_info_;
Handle<Script> script_;
bool is_eval_;
};
FunctionLiteral* function_;
bool is_eval_;
int loop_nesting_;
class LazySharedCompilationInfo: public CompilationInfo {
public:
explicit LazySharedCompilationInfo(Handle<SharedFunctionInfo> shared_info)
: shared_info_(shared_info) {
ASSERT(!shared_info.is_null());
}
DISALLOW_COPY_AND_ASSIGN(CompilationInfo);
// Overridden functions from the base class.
virtual Handle<SharedFunctionInfo> shared_info() const {
return shared_info_;
}
private:
Handle<SharedFunctionInfo> shared_info_;
};
class LazyFunctionCompilationInfo: public CompilationInfo {
public:
LazyFunctionCompilationInfo(Handle<JSFunction> closure,
int loop_nesting)
: closure_(closure), loop_nesting_(loop_nesting) {
ASSERT(!closure.is_null());
}
// Overridden functions from the base class.
virtual Handle<SharedFunctionInfo> shared_info() const {
return Handle<SharedFunctionInfo>(closure_->shared());
}
virtual int loop_nesting() const { return loop_nesting_; }
virtual bool has_global_object() const {
return closure_->context()->global() != NULL;
}
virtual GlobalObject* global_object() const {
return closure_->context()->global();
}
private:
Handle<JSFunction> closure_;
int loop_nesting_;
};
......
......@@ -779,7 +779,7 @@ static bool CompileLazyHelper(CompilationInfo* info,
bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
ClearExceptionFlag flag) {
CompilationInfo info(shared);
LazySharedCompilationInfo info(shared);
return CompileLazyHelper(&info, flag);
}
......@@ -791,7 +791,7 @@ bool CompileLazy(Handle<JSFunction> function,
function->shared()->set_code_age(0);
return true;
} else {
CompilationInfo info(function, 0);
LazyFunctionCompilationInfo info(function, 0);
bool result = CompileLazyHelper(&info, flag);
PROFILE(FunctionCreateEvent(*function));
return result;
......@@ -806,7 +806,7 @@ bool CompileLazyInLoop(Handle<JSFunction> function,
function->shared()->set_code_age(0);
return true;
} else {
CompilationInfo info(function, 1);
LazyFunctionCompilationInfo info(function, 1);
bool result = CompileLazyHelper(&info, flag);
PROFILE(FunctionCreateEvent(*function));
return result;
......
......@@ -408,6 +408,7 @@ static void CompileScriptForTracker(Handle<Script> script) {
// Build AST.
ScriptDataImpl* pre_data = NULL;
EagerCompilationInfo info(script, is_eval);
FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data);
// Check for parse errors.
......@@ -415,10 +416,9 @@ static void CompileScriptForTracker(Handle<Script> script) {
ASSERT(Top::has_pending_exception());
return;
}
info.set_function(lit);
// Compile the code.
CompilationInfo info(lit, script, is_eval);
LiveEditFunctionTracker tracker(lit);
Handle<Code> code = MakeCodeForLiveEdit(&info);
......
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