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