| Index: src/compiler.cc
|
| diff --git a/src/compiler.cc b/src/compiler.cc
|
| index e4864e48015df3ef51186b5f814920b6d5364518..794df01f597b0e9df120cfddbf4d241c7c80511b 100755
|
| --- a/src/compiler.cc
|
| +++ b/src/compiler.cc
|
| @@ -551,6 +551,60 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
|
| }
|
|
|
|
|
| +class PrecompiledScope: public Scope {
|
| + public:
|
| + PrecompiledScope(Scope* inner_scope, SerializedScopeInfo* scope_info)
|
| + : Scope(inner_scope->outer_scope(), Scope::FUNCTION_SCOPE),
|
| + scope_info_(scope_info) {
|
| + InsertAfterScope(inner_scope);
|
| + if (scope_info->HasHeapAllocatedLocals()) {
|
| + num_heap_slots_ = scope_info->NumberOfContextSlots();
|
| + }
|
| + MarkAsResolved();
|
| + }
|
| +
|
| + virtual void Initialize(bool inside_with) {
|
| + UNREACHABLE();
|
| + }
|
| +
|
| + virtual Variable* LocalLookup(Handle<String> name) {
|
| + // Check arguments object lookup.
|
| + if (*name == *Factory::arguments_symbol()) {
|
| + return new Variable(this, name, Variable::VAR, true, Variable::ARGUMENTS);
|
| + }
|
| +
|
| + // Check context slot lookup.
|
| + Variable::Mode mode;
|
| + int index = scope_info_->ContextSlotIndex(*name, &mode);
|
| + if (index < 0) {
|
| + return NULL;
|
| + }
|
| +
|
| + Variable* var = new Variable(this, name, mode, true, Variable::NORMAL);
|
| + var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
|
| + return var;
|
| + }
|
| +
|
| + virtual Variable* DeclareLocal(Handle<String> name, Variable::Mode mode) {
|
| + UNREACHABLE();
|
| + return NULL;
|
| + }
|
| +
|
| + virtual VariableProxy* NewUnresolved(Handle<String> name, bool inside_with) {
|
| + UNREACHABLE();
|
| + return NULL;
|
| + }
|
| +
|
| + virtual Variable* NewTemporary(Handle<String> name) {
|
| + UNREACHABLE();
|
| + return NULL;
|
| + }
|
| +
|
| + private:
|
| + SerializedScopeInfo* scope_info_;
|
| +};
|
| +
|
| +
|
| bool Compiler::CompileLazy(CompilationInfo* info) {
|
| CompilationZoneScope zone_scope(DELETE_ON_EXIT);
|
|
|
| @@ -570,6 +624,25 @@ bool Compiler::CompileLazy(CompilationInfo* info) {
|
| // parsing statistics.
|
| HistogramTimerScope timer(&Counters::compile_lazy);
|
|
|
| + // If we have scope info, reuse it to build scope for function literal
|
| + // being compiled.
|
| + if (!info->closure().is_null()) {
|
| + SerializedScopeInfo* scope_info = info->closure()->shared()->scope_info();
|
| + if (scope_info != SerializedScopeInfo::Empty()) {
|
| + Scope* scope = info->function()->scope();
|
| + JSFunction* current = *info->closure();
|
| + do {
|
| + current = current->context()->closure();
|
| + SerializedScopeInfo* scope_info = current->shared()->scope_info();
|
| + if (scope_info != SerializedScopeInfo::Empty()) {
|
| + scope = new PrecompiledScope(scope, scope_info);
|
| + } else {
|
| + ASSERT(current->context()->IsGlobalContext());
|
| + }
|
| + } while (!current->context()->IsGlobalContext());
|
| + }
|
| + }
|
| +
|
| // Compile the code.
|
| if (!MakeCode(info)) {
|
| Top::StackOverflow();
|
| @@ -665,6 +738,12 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
|
| if (!MakeCrankshaftCode(&info)) {
|
| return Handle<SharedFunctionInfo>::null();
|
| }
|
| + if (!AlwaysFullCompiler()
|
| + && !info.scope()->outer_scope_calls_eval()
|
| + && !info.scope()->inside_with()) {
|
| + ASSERT(info.code()->kind() == Code::FUNCTION);
|
| + info.code()->set_optimizable(true);
|
| + }
|
| } else {
|
| // The bodies of function literals have not yet been visited by the
|
| // AST optimizer/analyzer.
|
|
|