compiler.cc revision 6ded16be15dd865a9b21ea304d5273c8be299c87
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"
36eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke#include "fast-codegen.h"
376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "flow-graph.h"
38d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "full-codegen.h"
396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "liveedit.h"
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "oprofile-agent.h"
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "rewriter.h"
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scopes.h"
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic Handle<Code> MakeCode(Handle<Context> context, CompilationInfo* info) {
493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  FunctionLiteral* function = info->function();
503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ASSERT(function != NULL);
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Rewrite the AST by introducing .result assignments where needed.
526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!Rewriter::Process(function)) {
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Signal a stack overflow by returning a null handle.  The stack
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // overflow exception will be thrown by the caller.
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<Code>::null();
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Compute top scope and allocate variables. For lazy compilation
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the top scope only contains the single lazily compiled function,
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // so this doesn't re-allocate variables repeatedly.
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    HistogramTimerScope timer(&Counters::variable_allocation);
633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    Scope* top = info->scope();
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    while (top->outer_scope() != NULL) top = top->outer_scope();
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    top->AllocateVariables(context);
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (Bootstrapper::IsActive() ?
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      FLAG_print_builtin_scopes :
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      FLAG_print_scopes) {
723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    info->scope()->Print();
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optimize the AST.
773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (!Rewriter::Optimize(function)) {
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Signal a stack overflow by returning a null handle.  The stack
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // overflow exception will be thrown by the caller.
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<Code>::null();
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (function->scope()->num_parameters() > 0 ||
846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      function->scope()->num_stack_slots()) {
856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    AssignedVariablesAnalyzer ava(function);
866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ava.Analyze();
876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (ava.HasStackOverflow()) {
886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      return Handle<Code>::null();
896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (FLAG_use_flow_graph) {
936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    FlowGraphBuilder builder;
946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    FlowGraph* graph = builder.Build(function);
956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    USE(graph);
966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef DEBUG
986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (FLAG_print_graph_text && !builder.HasStackOverflow()) {
996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      graph->PrintAsText(function->name());
1006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif
1026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Generate code and return it.  Code generator selection is governed by
105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // which backends are enabled and whether the function is considered
106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // run-once code or not:
107d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //
108d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //  --full-compiler enables the dedicated backend for code we expect to be
109d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    run once
110d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //  --fast-compiler enables a speculative optimizing backend (for
111d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //    non-run-once code)
112d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  //
113d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // The normal choice of backend can be overridden with the flags
114d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // --always-full-compiler and --always-fast-compiler, which are mutually
115d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // incompatible.
116d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
117d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  Handle<SharedFunctionInfo> shared = info->shared_info();
119d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  bool is_run_once = (shared.is_null())
1203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      ? info->scope()->is_global_scope()
121d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      : (shared->is_toplevel() || shared->try_full_codegen());
122d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
123d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
124d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    FullCodeGenSyntaxChecker checker;
1253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    checker.Check(function);
126d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (checker.has_supported_syntax()) {
1273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      return FullCodeGenerator::MakeCode(info);
1283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    }
129d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  } else if (FLAG_always_fast_compiler ||
130d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke             (FLAG_fast_compiler && !is_run_once)) {
131d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    FastCodeGenSyntaxChecker checker;
1323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    checker.Check(info);
1334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    if (checker.has_supported_syntax()) {
1343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      return FastCodeGenerator::MakeCode(info);
1354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke    }
1363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
137d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return CodeGenerator::MakeCode(info);
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef ENABLE_DEBUGGER_SUPPORT
1436ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<Code> MakeCodeForLiveEdit(CompilationInfo* info) {
1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<Context> context = Handle<Context>::null();
1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return MakeCode(context, info);
1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif
1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1506ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic Handle<SharedFunctionInfo> MakeFunctionInfo(bool is_global,
1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    bool is_eval,
1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Compiler::ValidationState validate,
1536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Script> script,
1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    Handle<Context> context,
1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    v8::Extension* extension,
1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ScriptDataImpl* pre_data) {
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CompilationZoneScope zone_scope(DELETE_ON_EXIT);
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PostponeInterruptsScope postpone;
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!i::Top::global_context().is_null());
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  script->set_context_data((*i::Top::global_context())->data());
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_json = (validate == Compiler::VALIDATE_JSON);
1654515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (is_eval || is_json) {
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    script->set_compilation_type(
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // For eval scripts add information on the function from which eval was
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // called.
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (is_eval) {
1734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      StackTraceFrameIterator it;
1744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      if (!it.done()) {
1754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke        script->set_eval_from_shared(
1764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke            JSFunction::cast(it.frame()->function())->shared());
1774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke        int offset = static_cast<int>(
1784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke            it.frame()->pc() - it.frame()->code()->instruction_start());
1794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke        script->set_eval_from_instructions_offset(Smi::FromInt(offset));
1804515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      }
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Notify debugger
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Debugger::OnBeforeCompile(script);
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only allow non-global compiles for eval.
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(is_eval || is_global);
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Build AST.
1924515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  FunctionLiteral* lit =
1934515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      MakeAST(is_global, script, extension, pre_data, is_json);
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  LiveEditFunctionTracker live_edit_tracker(lit);
1966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for parse errors.
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (lit == NULL) {
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(Top::has_pending_exception());
2006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Measure how long it takes to do the compilation; only take the
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // rest of the function into account to avoid overlap with the
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // parsing statistics.
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HistogramTimer* rate = is_eval
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ? &Counters::compile_eval
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : &Counters::compile;
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HistogramTimerScope timer(rate);
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compile the code.
2123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  CompilationInfo info(lit, script, is_eval);
2133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Code> code = MakeCode(context, &info);
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for stack-overflow exceptions.
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (code.is_null()) {
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Top::StackOverflow();
2186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return Handle<SharedFunctionInfo>::null();
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (script->name()->IsString()) {
2226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    PROFILE(CodeCreateEvent(
2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        is_eval ? Logger::EVAL_TAG :
2246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
2256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        *code, String::cast(script->name())));
2266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    OPROFILE(CreateNativeCodeRegion(String::cast(script->name()),
2276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    code->instruction_start(),
2286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    code->instruction_size()));
2296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
2306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    PROFILE(CodeCreateEvent(
2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        is_eval ? Logger::EVAL_TAG :
2326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
2336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        *code, ""));
2346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    OPROFILE(CreateNativeCodeRegion(is_eval ? "Eval" : "Script",
2356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    code->instruction_start(),
2366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                    code->instruction_size()));
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocate function.
2406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result =
2416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Factory::NewSharedFunctionInfo(lit->name(),
2426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     lit->materialized_literal_count(),
2436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     code);
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
2466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Compiler::SetFunctionInfo(result, lit, true, script);
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Hint to the runtime system used when allocating space for initial
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // property space by setting the expected number of properties for
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the instances of the function.
2516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count());
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Notify debugger
2556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Debugger::OnAfterCompile(script, Debugger::NO_AFTER_COMPILE_FLAGS);
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  live_edit_tracker.RecordFunctionInfo(result, lit);
2596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return result;
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic StaticResource<SafeStringInputBuffer> safe_string_input_buffer;
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2676ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             Handle<Object> script_name,
2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             int line_offset,
2706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             int column_offset,
2716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             v8::Extension* extension,
2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             ScriptDataImpl* input_pre_data,
2736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             Handle<Object> script_data,
2746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                             NativesFlag natives) {
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int source_length = source->length();
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_load_size.Increment(source_length);
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_compile_size.Increment(source_length);
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The VM is in the COMPILER state until exiting this function.
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VMState state(COMPILER);
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do a lookup in the compilation cache but not for extensions.
2836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result;
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (extension == NULL) {
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = CompilationCache::LookupScript(source,
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            script_name,
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            line_offset,
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            column_offset);
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result.is_null()) {
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // No cache entry found. Do pre-parsing and compile the script.
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ScriptDataImpl* pre_data = input_pre_data;
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (pre_data == NULL && source_length >= FLAG_min_preparse_length) {
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Access<SafeStringInputBuffer> buf(&safe_string_input_buffer);
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      buf->Reset(source.location());
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      pre_data = PreParse(source, buf.value(), extension);
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Create a script object describing the script to be compiled.
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Script> script = Factory::NewScript(source);
3023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if (natives == NATIVES_CODE) {
3033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
3043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!script_name.is_null()) {
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      script->set_name(*script_name);
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      script->set_line_offset(Smi::FromInt(line_offset));
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      script->set_column_offset(Smi::FromInt(column_offset));
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    script->set_data(script_data.is_null() ? Heap::undefined_value()
312402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                           : *script_data);
313402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Compile the function and add it to the cache.
3156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result = MakeFunctionInfo(true,
3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              false,
3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              DONT_VALIDATE_JSON,
3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              script,
3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              Handle<Context>::null(),
3206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              extension,
3216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              pre_data);
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (extension == NULL && !result.is_null()) {
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      CompilationCache::PutScript(source, result);
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Get rid of the pre-parsing data (if necessary).
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (input_pre_data == NULL && pre_data != NULL) {
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      delete pre_data;
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result.is_null()) Top::ReportPendingMessages();
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3376ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                 Handle<Context> context,
3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                 bool is_global,
3406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                 ValidationState validate) {
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note that if validation is required then no path through this
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function is allowed to return a value without validating that
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the input is legal json.
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int source_length = source->length();
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_eval_size.Increment(source_length);
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_compile_size.Increment(source_length);
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The VM is in the COMPILER state until exiting this function.
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VMState state(COMPILER);
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Do a lookup in the compilation cache; if the entry is not there,
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // invoke the compiler and add the result to the cache.  If we're
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // evaluating json we bypass the cache since we can't be sure a
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // potential value in the cache has been validated.
3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result;
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (validate == DONT_VALIDATE_JSON)
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = CompilationCache::LookupEval(source, context, is_global);
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result.is_null()) {
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Create a script object describing the script to be compiled.
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Script> script = Factory::NewScript(source);
3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    result = MakeFunctionInfo(is_global,
3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              true,
3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              validate,
3666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              script,
3676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              context,
3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              NULL,
3696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              NULL);
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!result.is_null() && validate != VALIDATE_JSON) {
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // For json it's unlikely that we'll ever see exactly the same
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // string again so we don't use the compilation cache.
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      CompilationCache::PutEval(source, context, is_global, result);
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3814515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool Compiler::CompileLazy(CompilationInfo* info) {
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CompilationZoneScope zone_scope(DELETE_ON_EXIT);
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The VM is in the COMPILER state until exiting this function.
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VMState state(COMPILER);
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  PostponeInterruptsScope postpone;
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compute name, source code and script data.
3904515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  Handle<SharedFunctionInfo> shared = info->shared_info();
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> name(String::cast(shared->name()));
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int start_position = shared->start_position();
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int end_position = shared->end_position();
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool is_expression = shared->is_expression();
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::total_compile_size.Increment(end_position - start_position);
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate the AST for the lazily compiled function. The AST may be
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NULL in case of parser stack overflow.
4003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  FunctionLiteral* lit = MakeLazyAST(info->script(),
4013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                     name,
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     start_position,
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     end_position,
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                     is_expression);
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for parse errors.
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (lit == NULL) {
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(Top::has_pending_exception());
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  info->set_function(lit);
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Measure how long it takes to do the lazy compilation; only take
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the rest of the function into account to avoid overlap with the
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // lazy parsing statistics.
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HistogramTimerScope timer(&Counters::compile_lazy);
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compile the code.
4193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Code> code = MakeCode(Handle<Context>::null(), info);
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check for stack-overflow exception.
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (code.is_null()) {
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Top::StackOverflow();
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
4286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            name,
4296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            Handle<String>(shared->inferred_name()),
4306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            start_position,
4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            info->script(),
4326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                            code);
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update the shared function info with the compiled code.
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  shared->set_code(*code);
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the expected number of properties for instances.
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the optimication hints after performing lazy compilation, as these are
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // not set when the function is set up as a lazily compiled function.
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  shared->SetThisPropertyAssignmentsInfo(
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      lit->has_only_simple_this_property_assignments(),
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *lit->this_property_assignments());
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check the function has compiled code.
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(shared->is_compiled());
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4526ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
4536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                       Handle<Script> script,
4546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                       AstVisitor* caller) {
4556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  LiveEditFunctionTracker live_edit_tracker(literal);
456d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#ifdef DEBUG
457d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // We should not try to compile the same function literal more than
458d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // once.
459d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  literal->mark_as_compiled();
460d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#endif
461d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
462d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Determine if the function can be lazily compiled. This is
463d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // necessary to allow some of our builtin JS files to be lazily
464d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // compiled. These builtins cannot be handled lazily by the parser,
465d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // since we have to know if a function uses the special natives
466d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // syntax, which is something the parser records.
467402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  bool allow_lazy = literal->AllowsLazyCompilation() &&
468402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      !LiveEditFunctionTracker::IsActive();
469d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
470d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Generate code
471d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Handle<Code> code;
472d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (FLAG_lazy && allow_lazy) {
473d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    code = ComputeLazyCompile(literal->num_parameters());
474d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  } else {
475d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // The bodies of function literals have not yet been visited by
476d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // the AST optimizer/analyzer.
477d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (!Rewriter::Optimize(literal)) {
4786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      return Handle<SharedFunctionInfo>::null();
4796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (literal->scope()->num_parameters() > 0 ||
4826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        literal->scope()->num_stack_slots()) {
4836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      AssignedVariablesAnalyzer ava(literal);
4846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      ava.Analyze();
4856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (ava.HasStackOverflow()) {
4866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        return Handle<SharedFunctionInfo>::null();
4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
4886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
4896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (FLAG_use_flow_graph) {
4916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      FlowGraphBuilder builder;
4926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      FlowGraph* graph = builder.Build(literal);
4936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      USE(graph);
4946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef DEBUG
4966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (FLAG_print_graph_text && !builder.HasStackOverflow()) {
4976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        graph->PrintAsText(literal->name());
4986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
4996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif
500d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
501d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
502d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // Generate code and return it.  The way that the compilation mode
503d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // is controlled by the command-line flags is described in
504d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    // the static helper function MakeCode.
5053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    CompilationInfo info(literal, script, false);
5064515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
507d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    CHECK(!FLAG_always_full_compiler || !FLAG_always_fast_compiler);
508d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    bool is_run_once = literal->try_full_codegen();
509d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    bool is_compiled = false;
510d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    if (FLAG_always_full_compiler || (FLAG_full_compiler && is_run_once)) {
511d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      FullCodeGenSyntaxChecker checker;
512d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      checker.Check(literal);
513d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      if (checker.has_supported_syntax()) {
5143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        code = FullCodeGenerator::MakeCode(&info);
515d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        is_compiled = true;
516d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      }
517d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke    } else if (FLAG_always_fast_compiler ||
518d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke               (FLAG_fast_compiler && !is_run_once)) {
5194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      // Since we are not lazily compiling we do not have a receiver to
5204515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      // specialize for.
521d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      FastCodeGenSyntaxChecker checker;
5223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      checker.Check(&info);
5234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      if (checker.has_supported_syntax()) {
5243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        code = FastCodeGenerator::MakeCode(&info);
5254515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke        is_compiled = true;
5264515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      }
527d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
528d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
529d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (!is_compiled) {
530d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke      // We fall back to the classic V8 code generator.
5313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      code = CodeGenerator::MakeCode(&info);
532d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
533d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
534d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Check for stack-overflow exception.
535d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (code.is_null()) {
536d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      caller->SetStackOverflow();
5376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      return Handle<SharedFunctionInfo>::null();
538d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
539d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
540d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Function compilation complete.
5416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    RecordFunctionCompilation(Logger::FUNCTION_TAG,
5426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              literal->name(),
5436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              literal->inferred_name(),
5446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              literal->start_position(),
5456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              script,
5466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              code);
547d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
548d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Create a shared function info object.
5506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<SharedFunctionInfo> result =
5516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Factory::NewSharedFunctionInfo(literal->name(),
5526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     literal->materialized_literal_count(),
5536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                     code);
5546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetFunctionInfo(result, literal, false, script);
555d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
556d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Set the expected number of properties for instances and return
557d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // the resulting function.
5586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  SetExpectedNofPropertiesFromEstimate(result,
559d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                       literal->expected_property_count());
5606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  live_edit_tracker.RecordFunctionInfo(result, literal);
5616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return result;
562d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
563d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
564d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
565d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Sets the function info on a function.
566d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// The start_position points to the first '(' character after the function name
567d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// in the full script source. When counting characters in the script source the
568d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// the first character is number 0 (not 1).
5696ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
570d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               FunctionLiteral* lit,
571d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               bool is_toplevel,
572d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               Handle<Script> script) {
5736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_length(lit->num_parameters());
5746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_formal_parameter_count(lit->num_parameters());
5756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_script(*script);
5766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_function_token_position(lit->function_token_position());
5776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_start_position(lit->start_position());
5786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_end_position(lit->end_position());
5796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_is_expression(lit->is_expression());
5806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_is_toplevel(is_toplevel);
5816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_inferred_name(*lit->inferred_name());
5826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->SetThisPropertyAssignmentsInfo(
583d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      lit->has_only_simple_this_property_assignments(),
584d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      *lit->this_property_assignments());
5856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  function_info->set_try_full_codegen(lit->try_full_codegen());
586eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke}
587eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke
588eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke
5896ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
5906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<String> name,
5916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<String> inferred_name,
5926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         int start_position,
5936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<Script> script,
5946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                         Handle<Code> code) {
5953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Log the code generation. If source information is available
5963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // include script name and line number. Check explicitly whether
5973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // logging is enabled as finding the line number is not free.
5986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (Logger::is_logging()
5996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      || OProfileAgent::is_enabled()
6006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      || CpuProfiler::is_profiling()) {
6013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    Handle<String> func_name(name->length() > 0 ? *name : *inferred_name);
6023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if (script->name()->IsString()) {
6033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      int line_num = GetScriptLineNumber(script, start_position) + 1;
6046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      USE(line_num);
6056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
6066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              *code, *func_name,
6076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              String::cast(script->name()), line_num));
6086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      OPROFILE(CreateNativeCodeRegion(*func_name,
6096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      String::cast(script->name()),
6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      line_num,
6116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      code->instruction_start(),
6126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      code->instruction_size()));
6133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    } else {
6146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      PROFILE(CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
6156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                              *code, *func_name));
6166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      OPROFILE(CreateNativeCodeRegion(*func_name,
6176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      code->instruction_start(),
6186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                      code->instruction_size()));
6193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
6203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
6213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
6223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
624