compiler.cc revision 80d68eab642096c1a48b6474d6ec33064b0ad1f5
16ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// Copyright 2010 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bootstrapper.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "codegen-inl.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compilation-cache.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compiler.h"
346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "data-flow.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h"
36d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "full-codegen.h"
376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "liveedit.h"
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "oprofile-agent.h"
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "rewriter.h"
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopes.h"
413bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch#include "scopeinfo.h"
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// For normal operation the syntax checker is used to determine whether to
47f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// use the full compiler for top level code or not. However if the flag
48f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// --always-full-compiler is specified or debugging is active the full
49f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke// compiler will be used for all code.
50f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkestatic bool AlwaysFullCompiler() {
51f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT
52f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  return FLAG_always_full_compiler || Debugger::IsDebuggerActive();
53f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#else
54f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  return FLAG_always_full_compiler;
55f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif
56f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
57f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  FunctionLiteral* function = info->function();
613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(function != NULL);
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Rewrite the AST by introducing .result assignments where needed.
636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!Rewriter::Process(function)) {
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Signal a stack overflow by returning a null handle.  The stack
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // overflow exception will be thrown by the caller.
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<Code>::null();
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Compute top scope and allocate variables. For lazy compilation
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the top scope only contains the single lazily compiled function,
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // so this doesn't re-allocate variables repeatedly.
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    HistogramTimerScope timer(&Counters::variable_allocation);
743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    Scope* top = info->scope();
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    while (top->outer_scope() != NULL) top = top->outer_scope();
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    top->AllocateVariables(context);
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (Bootstrapper::IsActive() ?
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      FLAG_print_builtin_scopes :
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      FLAG_print_scopes) {
833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    info->scope()->Print();
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optimize the AST.
883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (!Rewriter::Optimize(function)) {
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Signal a stack overflow by returning a null handle.  The stack
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // overflow exception will be thrown by the caller.
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<Code>::null();
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
94d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Generate code and return it.  Code generator selection is governed by
95d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // which backends are enabled and whether the function is considered
96d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // run-once code or not:
97d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //
98d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //  --full-compiler enables the dedicated backend for code we expect to be
99d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    run once
100d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //
101d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The normal choice of backend can be overridden with the flags
102756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // --always-full-compiler.
1034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  Handle<SharedFunctionInfo> shared = info->shared_info();
104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  bool is_run_once = (shared.is_null())
1053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      ? info->scope()->is_global_scope()
106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      : (shared->is_toplevel() || shared->try_full_codegen());
10780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  bool use_full = FLAG_full_compiler && !function->contains_loops();
10880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (AlwaysFullCompiler() || (use_full && is_run_once)) {
109f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    return FullCodeGenerator::MakeCode(info);
1103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
11280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  AssignedVariablesAnalyzer ava(function);
11380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (!ava.Analyze()) return Handle<Code>::null();
1143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return CodeGenerator::MakeCode(info);
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef ENABLE_DEBUGGER_SUPPORT
1196ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<Code> MakeCodeForLiveEdit(CompilationInfo* info) {
1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<Context> context = Handle<Context>::null();
1213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  Handle<Code> code = MakeCode(context, info);
1223bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!info->shared_info().is_null()) {
1233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    info->shared_info()->set_scope_info(
1243bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch        *SerializedScopeInfo::Create(info->scope()));
1253bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
1263bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  return code;
1276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif
1296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    bool is_eval,
1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Compiler::ValidationState validate,
1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Script> script,
1356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Context> context,
1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    v8::Extension* extension,
1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ScriptDataImpl* pre_data) {
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CompilationZoneScope zone_scope(DELETE_ON_EXIT);
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PostponeInterruptsScope postpone;
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!i::Top::global_context().is_null());
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  script->set_context_data((*i::Top::global_context())->data());
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_json = (validate == Compiler::VALIDATE_JSON);
1464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_eval || is_json) {
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    script->set_compilation_type(
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // For eval scripts add information on the function from which eval was
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // called.
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (is_eval) {
1544515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      StackTraceFrameIterator it;
1554515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      if (!it.done()) {
1564515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke        script->set_eval_from_shared(
1574515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke            JSFunction::cast(it.frame()->function())->shared());
1584515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke        int offset = static_cast<int>(
1594515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke            it.frame()->pc() - it.frame()->code()->instruction_start());
1604515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke        script->set_eval_from_instructions_offset(Smi::FromInt(offset));
1614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      }
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Notify debugger
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debugger::OnBeforeCompile(script);
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only allow non-global compiles for eval.
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(is_eval || is_global);
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Build AST.
1734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  FunctionLiteral* lit =
1744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      MakeAST(is_global, script, extension, pre_data, is_json);
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  LiveEditFunctionTracker live_edit_tracker(lit);
1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for parse errors.
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (lit == NULL) {
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(Top::has_pending_exception());
1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Measure how long it takes to do the compilation; only take the
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // rest of the function into account to avoid overlap with the
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // parsing statistics.
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HistogramTimer* rate = is_eval
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ? &Counters::compile_eval
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : &Counters::compile;
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HistogramTimerScope timer(rate);
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compile the code.
1933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  CompilationInfo info(lit, script, is_eval);
1943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Code> code = MakeCode(context, &info);
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for stack-overflow exceptions.
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (code.is_null()) {
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Top::StackOverflow();
1996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (script->name()->IsString()) {
2036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    PROFILE(CodeCreateEvent(
2046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        is_eval ? Logger::EVAL_TAG :
2056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
2066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        *code, String::cast(script->name())));
2076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    OPROFILE(CreateNativeCodeRegion(String::cast(script->name()),
2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    code->instruction_start(),
2096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    code->instruction_size()));
2106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    PROFILE(CodeCreateEvent(
2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        is_eval ? Logger::EVAL_TAG :
2136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
2146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        *code, ""));
2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    OPROFILE(CreateNativeCodeRegion(is_eval ? "Eval" : "Script",
2166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    code->instruction_start(),
2176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    code->instruction_size()));
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocate function.
2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result =
2223bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch      Factory::NewSharedFunctionInfo(
2233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch          lit->name(),
2243bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch          lit->materialized_literal_count(),
2253bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch          code,
2263bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch          SerializedScopeInfo::Create(info.scope()));
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
2296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Compiler::SetFunctionInfo(result, lit, true, script);
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Hint to the runtime system used when allocating space for initial
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // property space by setting the expected number of properties for
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the instances of the function.
2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count());
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Notify debugger
2386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Debugger::OnAfterCompile(script, Debugger::NO_AFTER_COMPILE_FLAGS);
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  live_edit_tracker.RecordFunctionInfo(result, lit);
2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return result;
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2476ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
2486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             Handle<Object> script_name,
2496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             int line_offset,
2506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             int column_offset,
2516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             v8::Extension* extension,
2526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             ScriptDataImpl* input_pre_data,
2536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             Handle<Object> script_data,
2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             NativesFlag natives) {
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int source_length = source->length();
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_load_size.Increment(source_length);
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_compile_size.Increment(source_length);
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The VM is in the COMPILER state until exiting this function.
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VMState state(COMPILER);
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do a lookup in the compilation cache but not for extensions.
2636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result;
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (extension == NULL) {
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = CompilationCache::LookupScript(source,
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            script_name,
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            line_offset,
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            column_offset);
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result.is_null()) {
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // No cache entry found. Do pre-parsing and compile the script.
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ScriptDataImpl* pre_data = input_pre_data;
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (pre_data == NULL && source_length >= FLAG_min_preparse_length) {
2753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch      pre_data = PreParse(source, NULL, extension);
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Create a script object describing the script to be compiled.
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Script> script = Factory::NewScript(source);
2803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if (natives == NATIVES_CODE) {
2813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
2823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!script_name.is_null()) {
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      script->set_name(*script_name);
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      script->set_line_offset(Smi::FromInt(line_offset));
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      script->set_column_offset(Smi::FromInt(column_offset));
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
289402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    script->set_data(script_data.is_null() ? Heap::undefined_value()
290402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                           : *script_data);
291402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Compile the function and add it to the cache.
2936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result = MakeFunctionInfo(true,
2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              false,
2956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              DONT_VALIDATE_JSON,
2966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              script,
2976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              Handle<Context>::null(),
2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              extension,
2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              pre_data);
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (extension == NULL && !result.is_null()) {
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      CompilationCache::PutScript(source, result);
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Get rid of the pre-parsing data (if necessary).
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (input_pre_data == NULL && pre_data != NULL) {
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      delete pre_data;
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result.is_null()) Top::ReportPendingMessages();
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3156ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                 Handle<Context> context,
3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                 bool is_global,
3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                 ValidationState validate) {
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note that if validation is required then no path through this
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function is allowed to return a value without validating that
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the input is legal json.
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int source_length = source->length();
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_eval_size.Increment(source_length);
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_compile_size.Increment(source_length);
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The VM is in the COMPILER state until exiting this function.
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VMState state(COMPILER);
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do a lookup in the compilation cache; if the entry is not there,
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // invoke the compiler and add the result to the cache.  If we're
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // evaluating json we bypass the cache since we can't be sure a
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // potential value in the cache has been validated.
3346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result;
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (validate == DONT_VALIDATE_JSON)
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = CompilationCache::LookupEval(source, context, is_global);
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result.is_null()) {
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Create a script object describing the script to be compiled.
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Script> script = Factory::NewScript(source);
3416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result = MakeFunctionInfo(is_global,
3426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              true,
3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              validate,
3446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              script,
3456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              context,
3466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              NULL,
3476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              NULL);
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!result.is_null() && validate != VALIDATE_JSON) {
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // For json it's unlikely that we'll ever see exactly the same
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // string again so we don't use the compilation cache.
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      CompilationCache::PutEval(source, context, is_global, result);
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3594515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool Compiler::CompileLazy(CompilationInfo* info) {
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CompilationZoneScope zone_scope(DELETE_ON_EXIT);
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The VM is in the COMPILER state until exiting this function.
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VMState state(COMPILER);
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PostponeInterruptsScope postpone;
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute name, source code and script data.
3684515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  Handle<SharedFunctionInfo> shared = info->shared_info();
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> name(String::cast(shared->name()));
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int start_position = shared->start_position();
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int end_position = shared->end_position();
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_expression = shared->is_expression();
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_compile_size.Increment(end_position - start_position);
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate the AST for the lazily compiled function. The AST may be
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NULL in case of parser stack overflow.
3783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  FunctionLiteral* lit = MakeLazyAST(info->script(),
3793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                     name,
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     start_position,
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     end_position,
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     is_expression);
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for parse errors.
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (lit == NULL) {
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(Top::has_pending_exception());
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  info->set_function(lit);
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Measure how long it takes to do the lazy compilation; only take
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the rest of the function into account to avoid overlap with the
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // lazy parsing statistics.
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HistogramTimerScope timer(&Counters::compile_lazy);
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compile the code.
3973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Code> code = MakeCode(Handle<Context>::null(), info);
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for stack-overflow exception.
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (code.is_null()) {
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Top::StackOverflow();
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
4066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            name,
4076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            Handle<String>(shared->inferred_name()),
4086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            start_position,
4096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            info->script(),
4106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            code);
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // Update the shared function info with the compiled code and the scope info.
4133bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // Please note, that the order of the sharedfunction initialization is
4143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // important since set_scope_info might trigger a GC, causing the ASSERT
4153bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // below to be invalid if the code was flushed. By settting the code
4163bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  // object last we avoid this.
4173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  shared->set_scope_info(*SerializedScopeInfo::Create(info->scope()));
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  shared->set_code(*code);
41980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (!info->closure().is_null()) {
42080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    info->closure()->set_code(*code);
42180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the expected number of properties for instances.
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the optimication hints after performing lazy compilation, as these are
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // not set when the function is set up as a lazily compiled function.
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  shared->SetThisPropertyAssignmentsInfo(
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      lit->has_only_simple_this_property_assignments(),
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *lit->this_property_assignments());
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check the function has compiled code.
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(shared->is_compiled());
434756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  shared->set_code_age(0);
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4396ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                       Handle<Script> script,
4416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                       AstVisitor* caller) {
4426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  LiveEditFunctionTracker live_edit_tracker(literal);
443d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef DEBUG
444d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // We should not try to compile the same function literal more than
445d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // once.
446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  literal->mark_as_compiled();
447d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif
448d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
449d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Determine if the function can be lazily compiled. This is
450d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // necessary to allow some of our builtin JS files to be lazily
451d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // compiled. These builtins cannot be handled lazily by the parser,
452d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // since we have to know if a function uses the special natives
453d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // syntax, which is something the parser records.
454402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  bool allow_lazy = literal->AllowsLazyCompilation() &&
455402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      !LiveEditFunctionTracker::IsActive();
456d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
4573bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty());
4583bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
459d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Generate code
460d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Handle<Code> code;
461d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (FLAG_lazy && allow_lazy) {
462756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    code = Handle<Code>(Builtins::builtin(Builtins::LazyCompile));
463d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  } else {
464d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // The bodies of function literals have not yet been visited by
465d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // the AST optimizer/analyzer.
466d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (!Rewriter::Optimize(literal)) {
4676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      return Handle<SharedFunctionInfo>::null();
4686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
4696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
470d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Generate code and return it.  The way that the compilation mode
471d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // is controlled by the command-line flags is described in
472d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // the static helper function MakeCode.
4733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    CompilationInfo info(literal, script, false);
4744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
475d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    bool is_run_once = literal->try_full_codegen();
47680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    bool use_full = FLAG_full_compiler && !literal->contains_loops();
47780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    if (AlwaysFullCompiler() || (use_full && is_run_once)) {
478f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      code = FullCodeGenerator::MakeCode(&info);
47980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    } else {
480d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // We fall back to the classic V8 code generator.
48180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      AssignedVariablesAnalyzer ava(literal);
48280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      if (!ava.Analyze()) return Handle<SharedFunctionInfo>::null();
4833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      code = CodeGenerator::MakeCode(&info);
484d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
485d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
486d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Check for stack-overflow exception.
487d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (code.is_null()) {
488d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      caller->SetStackOverflow();
4896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      return Handle<SharedFunctionInfo>::null();
490d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
491d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
492d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Function compilation complete.
4936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    RecordFunctionCompilation(Logger::FUNCTION_TAG,
4946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              literal->name(),
4956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              literal->inferred_name(),
4966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              literal->start_position(),
4976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              script,
4986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              code);
4993bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    scope_info = SerializedScopeInfo::Create(info.scope());
500d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
501d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Create a shared function info object.
5036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result =
5046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Factory::NewSharedFunctionInfo(literal->name(),
5056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     literal->materialized_literal_count(),
5063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                                     code,
5073bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch                                     scope_info);
5086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFunctionInfo(result, literal, false, script);
509d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
510d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Set the expected number of properties for instances and return
511d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // the resulting function.
5126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetExpectedNofPropertiesFromEstimate(result,
513d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                       literal->expected_property_count());
5146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  live_edit_tracker.RecordFunctionInfo(result, literal);
5156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return result;
516d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
517d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
518d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
519d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Sets the function info on a function.
520d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// The start_position points to the first '(' character after the function name
521d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// in the full script source. When counting characters in the script source the
522d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// the first character is number 0 (not 1).
5236ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
524d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               FunctionLiteral* lit,
525d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               bool is_toplevel,
526d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               Handle<Script> script) {
5276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_length(lit->num_parameters());
5286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_formal_parameter_count(lit->num_parameters());
5296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_script(*script);
5306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_function_token_position(lit->function_token_position());
5316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_start_position(lit->start_position());
5326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_end_position(lit->end_position());
5336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_is_expression(lit->is_expression());
5346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_is_toplevel(is_toplevel);
5356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_inferred_name(*lit->inferred_name());
5366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->SetThisPropertyAssignmentsInfo(
537d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      lit->has_only_simple_this_property_assignments(),
538d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      *lit->this_property_assignments());
5396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_try_full_codegen(lit->try_full_codegen());
5407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
541eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke}
542eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke
543eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke
5446ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
5456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<String> name,
5466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<String> inferred_name,
5476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         int start_position,
5486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<Script> script,
5496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<Code> code) {
5503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Log the code generation. If source information is available
5513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // include script name and line number. Check explicitly whether
5523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // logging is enabled as finding the line number is not free.
5536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (Logger::is_logging()
5546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      || OProfileAgent::is_enabled()
5556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      || CpuProfiler::is_profiling()) {
5563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    Handle<String> func_name(name->length() > 0 ? *name : *inferred_name);
5573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if (script->name()->IsString()) {
5583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      int line_num = GetScriptLineNumber(script, start_position) + 1;
5596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      USE(line_num);
5606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
5616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              *code, *func_name,
5626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              String::cast(script->name()), line_num));
5636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      OPROFILE(CreateNativeCodeRegion(*func_name,
5646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      String::cast(script->name()),
5656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      line_num,
5666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      code->instruction_start(),
5676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      code->instruction_size()));
5683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    } else {
5696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
5706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              *code, *func_name));
5716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      OPROFILE(CreateNativeCodeRegion(*func_name,
5726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      code->instruction_start(),
5736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      code->instruction_size()));
5743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
5753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
5763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
5773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
579