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