| Index: src/compiler.cc
|
| ===================================================================
|
| --- src/compiler.cc (revision 7180)
|
| +++ src/compiler.cc (working copy)
|
| @@ -172,6 +172,7 @@
|
| ASSERT(code->kind() == Code::FUNCTION);
|
| code->set_optimizable(false);
|
| info->SetCode(code);
|
| + CompilationCache::MarkForLazyOptimizing(info->closure());
|
| if (FLAG_trace_opt) {
|
| PrintF("[disabled optimization for: ");
|
| info->closure()->PrintName();
|
| @@ -221,11 +222,12 @@
|
| // or perform on-stack replacement for function with too many
|
| // stack-allocated local variables.
|
| //
|
| - // The encoding is as a signed value, with parameters using the negative
|
| - // indices and locals the non-negative ones.
|
| + // The encoding is as a signed value, with parameters and receiver using
|
| + // the negative indices and locals the non-negative ones.
|
| const int limit = LUnallocated::kMaxFixedIndices / 2;
|
| Scope* scope = info->scope();
|
| - if (scope->num_parameters() > limit || scope->num_stack_slots() > limit) {
|
| + if ((scope->num_parameters() + 1) > limit ||
|
| + scope->num_stack_slots() > limit) {
|
| AbortAndDisable(info);
|
| // True indicates the compilation pipeline is still going, not
|
| // necessarily that we optimized the code.
|
| @@ -247,7 +249,7 @@
|
| // performance of the hydrogen-based compiler.
|
| int64_t start = OS::Ticks();
|
| bool should_recompile = !info->shared_info()->has_deoptimization_support();
|
| - if (should_recompile || FLAG_time_hydrogen) {
|
| + if (should_recompile || FLAG_hydrogen_stats) {
|
| HPhase phase(HPhase::kFullCodeGen);
|
| CompilationInfo unoptimized(info->shared_info());
|
| // Note that we use the same AST that we will use for generating the
|
| @@ -261,10 +263,8 @@
|
| Handle<SharedFunctionInfo> shared = info->shared_info();
|
| shared->EnableDeoptimizationSupport(*unoptimized.code());
|
| // The existing unoptimized code was replaced with the new one.
|
| - Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
|
| - Handle<String>(shared->DebugName()),
|
| - shared->start_position(),
|
| - &unoptimized);
|
| + Compiler::RecordFunctionCompilation(
|
| + Logger::LAZY_COMPILE_TAG, &unoptimized, shared);
|
| }
|
| }
|
|
|
| @@ -273,7 +273,7 @@
|
| // optimizable marker in the code object and optimize anyway. This
|
| // is safe as long as the unoptimized code has deoptimization
|
| // support.
|
| - ASSERT(FLAG_always_opt || info->shared_info()->code()->optimizable());
|
| + ASSERT(FLAG_always_opt || code->optimizable());
|
| ASSERT(info->shared_info()->has_deoptimization_support());
|
|
|
| if (FLAG_trace_hydrogen) {
|
| @@ -282,21 +282,20 @@
|
| HTracer::Instance()->TraceCompilation(info->function());
|
| }
|
|
|
| - TypeFeedbackOracle oracle(
|
| - Handle<Code>(info->shared_info()->code()),
|
| - Handle<Context>(info->closure()->context()->global_context()));
|
| - HGraphBuilder builder(&oracle);
|
| + Handle<Context> global_context(info->closure()->context()->global_context());
|
| + TypeFeedbackOracle oracle(code, global_context);
|
| + HGraphBuilder builder(info, &oracle);
|
| HPhase phase(HPhase::kTotal);
|
| - HGraph* graph = builder.CreateGraph(info);
|
| + HGraph* graph = builder.CreateGraph();
|
| if (Top::has_pending_exception()) {
|
| info->SetCode(Handle<Code>::null());
|
| return false;
|
| }
|
|
|
| if (graph != NULL && FLAG_build_lithium) {
|
| - Handle<Code> code = graph->Compile();
|
| - if (!code.is_null()) {
|
| - info->SetCode(code);
|
| + Handle<Code> optimized_code = graph->Compile(info);
|
| + if (!optimized_code.is_null()) {
|
| + info->SetCode(optimized_code);
|
| FinishOptimization(info->closure(), start);
|
| return true;
|
| }
|
| @@ -415,13 +414,25 @@
|
| return Handle<SharedFunctionInfo>::null();
|
| }
|
|
|
| + // Allocate function.
|
| ASSERT(!info->code().is_null());
|
| + Handle<SharedFunctionInfo> result =
|
| + Factory::NewSharedFunctionInfo(
|
| + lit->name(),
|
| + lit->materialized_literal_count(),
|
| + info->code(),
|
| + SerializedScopeInfo::Create(info->scope()));
|
| +
|
| + ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
|
| + Compiler::SetFunctionInfo(result, lit, true, script);
|
| +
|
| if (script->name()->IsString()) {
|
| PROFILE(CodeCreateEvent(
|
| info->is_eval()
|
| ? Logger::EVAL_TAG
|
| : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
|
| *info->code(),
|
| + *result,
|
| String::cast(script->name())));
|
| GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
|
| script,
|
| @@ -432,21 +443,11 @@
|
| ? Logger::EVAL_TAG
|
| : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
|
| *info->code(),
|
| - ""));
|
| + *result,
|
| + Heap::empty_string()));
|
| GDBJIT(AddCode(Handle<String>(), script, info->code()));
|
| }
|
|
|
| - // Allocate function.
|
| - Handle<SharedFunctionInfo> result =
|
| - Factory::NewSharedFunctionInfo(
|
| - lit->name(),
|
| - lit->materialized_literal_count(),
|
| - info->code(),
|
| - SerializedScopeInfo::Create(info->scope()));
|
| -
|
| - ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
|
| - Compiler::SetFunctionInfo(result, lit, true, script);
|
| -
|
| // Hint to the runtime system used when allocating space for initial
|
| // property space by setting the expected number of properties for
|
| // the instances of the function.
|
| @@ -528,6 +529,7 @@
|
| info.MarkAsGlobal();
|
| info.SetExtension(extension);
|
| info.SetPreParseData(pre_data);
|
| + if (natives == NATIVES_CODE) info.MarkAsAllowingNativesSyntax();
|
| result = MakeFunctionInfo(&info);
|
| if (extension == NULL && !result.is_null()) {
|
| CompilationCache::PutScript(source, result);
|
| @@ -613,10 +615,7 @@
|
| ASSERT(!info->code().is_null());
|
| Handle<Code> code = info->code();
|
| Handle<JSFunction> function = info->closure();
|
| - RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
|
| - Handle<String>(shared->DebugName()),
|
| - shared->start_position(),
|
| - info);
|
| + RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
|
|
|
| if (info->IsOptimizing()) {
|
| function->ReplaceCode(*code);
|
| @@ -724,10 +723,6 @@
|
| ASSERT(!info.code().is_null());
|
|
|
| // Function compilation complete.
|
| - RecordFunctionCompilation(Logger::FUNCTION_TAG,
|
| - literal->debug_name(),
|
| - literal->start_position(),
|
| - &info);
|
| scope_info = SerializedScopeInfo::Create(info.scope());
|
| }
|
|
|
| @@ -738,6 +733,7 @@
|
| info.code(),
|
| scope_info);
|
| SetFunctionInfo(result, literal, false, script);
|
| + RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
|
| result->set_allows_lazy_compilation(allow_lazy);
|
|
|
| // Set the expected number of properties for instances and return
|
| @@ -776,28 +772,31 @@
|
|
|
|
|
| void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
|
| - Handle<String> name,
|
| - int start_position,
|
| - CompilationInfo* info) {
|
| + CompilationInfo* info,
|
| + Handle<SharedFunctionInfo> shared) {
|
| + // SharedFunctionInfo is passed separately, because if CompilationInfo
|
| + // was created using Script object, it will not have it.
|
| +
|
| // Log the code generation. If source information is available include
|
| // script name and line number. Check explicitly whether logging is
|
| // enabled as finding the line number is not free.
|
| - if (Logger::is_logging() ||
|
| - CpuProfiler::is_profiling()) {
|
| + if (Logger::is_logging() || CpuProfiler::is_profiling()) {
|
| Handle<Script> script = info->script();
|
| Handle<Code> code = info->code();
|
| + if (*code == Builtins::builtin(Builtins::LazyCompile)) return;
|
| if (script->name()->IsString()) {
|
| - int line_num = GetScriptLineNumber(script, start_position) + 1;
|
| + int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
|
| USE(line_num);
|
| PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
|
| *code,
|
| - *name,
|
| + *shared,
|
| String::cast(script->name()),
|
| line_num));
|
| } else {
|
| PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
|
| *code,
|
| - *name));
|
| + *shared,
|
| + shared->DebugName()));
|
| }
|
| }
|
|
|
|
|