13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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 30f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "compiler.h" 31f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bootstrapper.h" 338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#include "codegen.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compilation-cache.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h" 36d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke#include "full-codegen.h" 37b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "gdb-jit.h" 38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "hydrogen.h" 393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "isolate-inl.h" 401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "lithium.h" 416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "liveedit.h" 42f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "parser.h" 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "rewriter.h" 44b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "runtime-profiler.h" 45589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "scanner-character-streams.h" 463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch#include "scopeinfo.h" 47f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "scopes.h" 48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h" 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 54f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCompilationInfo::CompilationInfo(Handle<Script> script) 5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(script->GetIsolate()), 563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags_(LanguageModeField::encode(CLASSIC_MODE)), 57f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch function_(NULL), 58f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch scope_(NULL), 593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch global_scope_(NULL), 60f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch script_(script), 61f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch extension_(NULL), 62b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pre_parse_data_(NULL), 63b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch osr_ast_id_(AstNode::kNoNumber) { 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Initialize(BASE); 65f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 66f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 67f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 68f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info) 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(shared_info->GetIsolate()), 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags_(LanguageModeField::encode(CLASSIC_MODE) | 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IsLazy::encode(true)), 72f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch function_(NULL), 73f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch scope_(NULL), 743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch global_scope_(NULL), 75f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch shared_info_(shared_info), 76f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch script_(Handle<Script>(Script::cast(shared_info->script()))), 77f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch extension_(NULL), 78b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pre_parse_data_(NULL), 79b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch osr_ast_id_(AstNode::kNoNumber) { 80b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Initialize(BASE); 81f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 82f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 83f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 84f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCompilationInfo::CompilationInfo(Handle<JSFunction> closure) 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(closure->GetIsolate()), 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags_(LanguageModeField::encode(CLASSIC_MODE) | 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IsLazy::encode(true)), 88f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch function_(NULL), 89f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch scope_(NULL), 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch global_scope_(NULL), 91f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch closure_(closure), 92f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch shared_info_(Handle<SharedFunctionInfo>(closure->shared())), 93f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch script_(Handle<Script>(Script::cast(shared_info_->script()))), 94f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch extension_(NULL), 95b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pre_parse_data_(NULL), 96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch osr_ast_id_(AstNode::kNoNumber) { 97b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Initialize(BASE); 98f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 99f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 100f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Disable optimization for the rest of the compilation pipeline. 102b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid CompilationInfo::DisableOptimization() { 103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool is_optimizable_closure = 104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FLAG_optimize_closures && 105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch closure_.is_null() && 106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch !scope_->HasTrivialOuterContext() && 107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch !scope_->outer_scope_calls_non_strict_eval() && 108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch !scope_->inside_with(); 109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SetMode(is_optimizable_closure ? BASE : NONOPT); 110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 112b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Primitive functions are unlikely to be picked up by the stack-walking 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// profiler, so they trigger their own optimization when they're called 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool CompilationInfo::ShouldSelfOptimize() { 1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return FLAG_self_optimization && 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FLAG_crankshaft && 1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !function()->flags()->Contains(kDontSelfOptimize) && 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !function()->flags()->Contains(kDontOptimize) && 1214768e9d22b13edbae2ae177109420028748bf872Ben Murdoch function()->scope()->AllowsLazyRecompilation() && 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (shared_info().is_null() || !shared_info()->optimization_disabled()); 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid CompilationInfo::AbortOptimization() { 127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code(shared_info()->code()); 128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SetCode(code); 129b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 130b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 131b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Determine whether to use the full compiler for all code. If the flag 133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// --always-full-compiler is specified this is the case. For the virtual frame 134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// based compiler the full compiler is also used if a debugger is connected, as 135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// the code from the full compiler supports mode precise break points. For the 136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// crankshaft adaptive compiler debugging the optimized code is not possible at 137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// all. However crankshaft support recompilation of functions, so in this case 138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// the full compiler need not be be used if a debugger is attached, but only if 139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// break points has actually been set. 140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic bool is_debugging_active() { 141f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return V8::UseCrankshaft() ? 144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->debug()->has_break_points() : 145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->debugger()->IsDebuggerActive(); 146f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#else 147257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return false; 148f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif 149f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 150f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 152257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic bool AlwaysFullCompiler() { 153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return FLAG_always_full_compiler || is_debugging_active(); 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void FinishOptimization(Handle<JSFunction> function, int64_t start) { 158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int opt_count = function->shared()->opt_count(); 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->shared()->set_opt_count(opt_count + 1); 160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double ms = static_cast<double>(OS::Ticks() - start) / 1000; 161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_opt) { 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[optimizing: "); 163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->PrintName(); 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" / %" V8PRIxPTR, reinterpret_cast<intptr_t>(*function)); 165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" - took %0.3f ms]\n", ms); 166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_opt_stats) { 168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static double compilation_time = 0.0; 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int compiled_functions = 0; 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int code_size = 0; 171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch compilation_time += ms; 173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch compiled_functions++; 174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_size += function->shared()->SourceSize(); 175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("Compiled: %d functions with %d byte source size in %fms.\n", 176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch compiled_functions, 177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_size, 178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch compilation_time); 179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic bool MakeCrankshaftCode(CompilationInfo* info) { 184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Test if we can optimize this function when asked to. We can only 185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // do this after the scopes are computed. 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!V8::UseCrankshaft()) { 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->DisableOptimization(); 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // In case we are not optimizing simply return the code from 191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the full code generator. 192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info->IsOptimizing()) { 193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return FullCodeGenerator::MakeCode(info); 194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We should never arrive here if there is not code object on the 197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // shared function object. 198b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code(info->shared_info()->code()); 199b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(code->kind() == Code::FUNCTION); 200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // We should never arrive here if optimization has been disabled on the 20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // shared function info. 20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!info->shared_info()->optimization_disabled()); 20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Fall back to using the full code generator if it's not possible 206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // to use the Hydrogen-based optimizing compiler. We already have 207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // generated code for this from the shared function object. 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (AlwaysFullCompiler()) { 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch info->SetCode(code); 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Limit the number of times we re-compile a functions with 214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the optimizing compiler. 215b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const int kMaxOptCount = 216b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (info->shared_info()->opt_count() > kMaxOptCount) { 218257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->AbortOptimization(); 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->shared_info()->DisableOptimization(); 220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // True indicates the compilation pipeline is still going, not 221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // necessarily that we optimized the code. 222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 224b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Due to an encoding limit on LUnallocated operands in the Lithium 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // language, we cannot optimize functions with too many formal parameters 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // or perform on-stack replacement for function with too many 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // stack-allocated local variables. 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 230e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The encoding is as a signed value, with parameters and receiver using 231e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the negative indices and locals the non-negative ones. 2327d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch const int parameter_limit = -LUnallocated::kMinFixedIndex; 2337d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch const int locals_limit = LUnallocated::kMaxFixedIndex; 234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scope* scope = info->scope(); 2357d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch if ((scope->num_parameters() + 1) > parameter_limit || 2367d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch (info->osr_ast_id() != AstNode::kNoNumber && 2377d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit)) { 238257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->AbortOptimization(); 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->shared_info()->DisableOptimization(); 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // True indicates the compilation pipeline is still going, not 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // necessarily that we optimized the code. 242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Take --hydrogen-filter into account. 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<String> name = info->function()->debug_name(); 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (*FLAG_hydrogen_filter != '\0') { 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((filter[0] == '-' 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch && name->IsEqualTo(filter.SubVector(1, filter.length()))) 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch || (filter[0] != '-' && !name->IsEqualTo(filter))) { 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->SetCode(code); 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return true; 2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Recompile the unoptimized version of the code if the current version 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // doesn't have deoptimization support. Alternatively, we may decide to 259b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // run the full code generator to get a baseline for the compile-time 260b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // performance of the hydrogen-based compiler. 261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int64_t start = OS::Ticks(); 262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool should_recompile = !info->shared_info()->has_deoptimization_support(); 26344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (should_recompile || FLAG_hydrogen_stats) { 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhase phase(HPhase::kFullCodeGen); 265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompilationInfo unoptimized(info->shared_info()); 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Note that we use the same AST that we will use for generating the 267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized code. 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unoptimized.SetFunction(info->function()); 269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unoptimized.SetScope(info->scope()); 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (should_recompile) unoptimized.EnableDeoptimizationSupport(); 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool succeeded = FullCodeGenerator::MakeCode(&unoptimized); 272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (should_recompile) { 273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!succeeded) return false; 274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<SharedFunctionInfo> shared = info->shared_info(); 275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->EnableDeoptimizationSupport(*unoptimized.code()); 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The existing unoptimized code was replaced with the new one. 277e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Compiler::RecordFunctionCompilation( 278e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Logger::LAZY_COMPILE_TAG, &unoptimized, shared); 279b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 282b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that the unoptimized, shared code is ready for 283b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimizations. When using the always_opt flag we disregard the 284b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimizable marker in the code object and optimize anyway. This 285b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // is safe as long as the unoptimized code has deoptimization 286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // support. 287e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(FLAG_always_opt || code->optimizable()); 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(info->shared_info()->has_deoptimization_support()); 289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_hydrogen) { 291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("-----------------------------------------------------------\n"); 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("Compiling method %s using hydrogen\n", *name->ToCString()); 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HTracer::Instance()->TraceCompilation(info->function()); 294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 296e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Context> global_context(info->closure()->context()->global_context()); 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TypeFeedbackOracle oracle(code, global_context, info->isolate()); 298e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HGraphBuilder builder(info, &oracle); 299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhase phase(HPhase::kTotal); 300e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HGraph* graph = builder.CreateGraph(); 30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (info->isolate()->has_pending_exception()) { 3021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block info->SetCode(Handle<Code>::null()); 3031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return false; 3041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 3051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (graph != NULL) { 307e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Code> optimized_code = graph->Compile(info); 308e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!optimized_code.is_null()) { 309e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch info->SetCode(optimized_code); 310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FinishOptimization(info->closure(), start); 311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Keep using the shared code. 316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->AbortOptimization(); 317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!builder.inline_bailout()) { 318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Mark the shared code as unoptimizable unless it was an inlined 319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // function that bailed out. 3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->shared_info()->DisableOptimization(); 321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 322b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // True indicates the compilation pipeline is still going, not necessarily 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // that we optimized the code. 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic bool GenerateCode(CompilationInfo* info) { 3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return info->IsCompilingForDebugging() || !V8::UseCrankshaft() ? 3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FullCodeGenerator::MakeCode(info) : 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MakeCrankshaftCode(info); 332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 335f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstatic bool MakeCode(CompilationInfo* info) { 336f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Precondition: code has been parsed. Postcondition: the code field in 337f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // the compilation info is set if compilation succeeded. 338f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(info->function() != NULL); 339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return Rewriter::Rewrite(info) && Scope::Analyze(info) && GenerateCode(info); 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef ENABLE_DEBUGGER_SUPPORT 344f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) { 345f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Precondition: code has been parsed. Postcondition: the code field in 346f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // the compilation info is set if compilation succeeded. 347f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool succeeded = MakeCode(info); 3483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (!info->shared_info().is_null()) { 3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope()); 3500d5e116f6aee03185f237311a943491bb079a768Kristian Monsen info->shared_info()->set_scope_info(*scope_info); 3513bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 352f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return succeeded; 3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 357f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstatic Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) { 35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = info->isolate(); 3593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneScope zone_scope(isolate, DELETE_ON_EXIT); 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block PostponeInterruptsScope postpone(isolate); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!isolate->global_context().is_null()); 363f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Script> script = info->script(); 36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block script->set_context_data((*isolate->global_context())->data()); 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3664515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 3673e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (info->is_eval()) { 3683e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Script::CompilationType compilation_type = Script::COMPILATION_TYPE_EVAL; 369f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch script->set_compilation_type(Smi::FromInt(compilation_type)); 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For eval scripts add information on the function from which eval was 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // called. 372f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (info->is_eval()) { 3738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StackTraceFrameIterator it(isolate); 3744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (!it.done()) { 3754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke script->set_eval_from_shared( 3764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke JSFunction::cast(it.frame()->function())->shared()); 3778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Code* code = it.frame()->LookupCode(); 3784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int offset = static_cast<int>( 37944f0eee88ff00398ff7f715fab053374d808c90dSteve Block it.frame()->pc() - code->instruction_start()); 3804515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke script->set_eval_from_instructions_offset(Smi::FromInt(offset)); 3814515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify debugger 38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->debugger()->OnBeforeCompile(script); 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Only allow non-global compiles for eval. 390f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(info->is_eval() || info->is_global()); 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ParsingFlags flags = kNoParsingFlags; 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (info->pre_parse_data() != NULL || 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch String::cast(script->source())->length() > FLAG_min_preparse_length) { 3943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags = kAllowLazy; 3953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!ParserApi::Parse(info, flags)) { 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Handle<SharedFunctionInfo>::null(); 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Measure how long it takes to do the compilation; only take the 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // rest of the function into account to avoid overlap with the 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parsing statistics. 403f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch HistogramTimer* rate = info->is_eval() 40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ? info->isolate()->counters()->compile_eval() 40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block : info->isolate()->counters()->compile(); 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HistogramTimerScope timer(rate); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the code. 409f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch FunctionLiteral* lit = info->function(); 41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block LiveEditFunctionTracker live_edit_tracker(isolate, lit); 411f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!MakeCode(info)) { 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!isolate->has_pending_exception()) isolate->StackOverflow(); 4136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 416e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Allocate function. 417f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(!info->code().is_null()); 418e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<SharedFunctionInfo> result = 41944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->factory()->NewSharedFunctionInfo( 420e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lit->name(), 421e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lit->materialized_literal_count(), 422e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch info->code(), 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ScopeInfo::Create(info->scope())); 424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 425e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position()); 426e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Compiler::SetFunctionInfo(result, lit, true, script); 427e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (script->name()->IsString()) { 42944f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate, CodeCreateEvent( 430f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info->is_eval() 431f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ? Logger::EVAL_TAG 432f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 433f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *info->code(), 434e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *result, 435f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch String::cast(script->name()))); 436b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJIT(AddCode(Handle<String>(String::cast(script->name())), 437b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch script, 4383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch info->code(), 4393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch info)); 4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 44144f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate, CodeCreateEvent( 442f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info->is_eval() 443f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ? Logger::EVAL_TAG 444f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 445f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *info->code(), 446e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *result, 44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->heap()->empty_string())); 4483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch GDBJIT(AddCode(Handle<String>(), script, info->code(), info)); 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Hint to the runtime system used when allocating space for initial 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // property space by setting the expected number of properties for 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the instances of the function. 4546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count()); 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch script->set_compilation_state( 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Smi::FromInt(Script::COMPILATION_STATE_COMPILED)); 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify debugger 46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->debugger()->OnAfterCompile( 46244f0eee88ff00398ff7f715fab053374d808c90dSteve Block script, Debugger::NO_AFTER_COMPILE_FLAGS); 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block live_edit_tracker.RecordFunctionInfo(result, lit); 4666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4716ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::Compile(Handle<String> source, 4726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> script_name, 4736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 4746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset, 4756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::Extension* extension, 4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ScriptDataImpl* pre_data, 4776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> script_data, 4786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block NativesFlag natives) { 47944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = source->GetIsolate(); 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int source_length = source->length(); 48144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_load_size()->Increment(source_length); 48244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_compile_size()->Increment(source_length); 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The VM is in the COMPILER state until exiting this function. 48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, COMPILER); 48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 48744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CompilationCache* compilation_cache = isolate->compilation_cache(); 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do a lookup in the compilation cache but not for extensions. 4906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> result; 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (extension == NULL) { 49244f0eee88ff00398ff7f715fab053374d808c90dSteve Block result = compilation_cache->LookupScript(source, 49344f0eee88ff00398ff7f715fab053374d808c90dSteve Block script_name, 49444f0eee88ff00398ff7f715fab053374d808c90dSteve Block line_offset, 49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block column_offset); 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result.is_null()) { 49959151504615d929945dc59db37bf1166937748c6Steve Block // No cache entry found. Do pre-parsing, if it makes sense, and compile 50059151504615d929945dc59db37bf1166937748c6Steve Block // the script. 50159151504615d929945dc59db37bf1166937748c6Steve Block // Building preparse data that is only used immediately after is only a 50259151504615d929945dc59db37bf1166937748c6Steve Block // saving if we might skip building the AST for lazily compiled functions. 50359151504615d929945dc59db37bf1166937748c6Steve Block // I.e., preparse data isn't relevant when the lazy flag is off, and 50459151504615d929945dc59db37bf1166937748c6Steve Block // for small sources, odds are that there aren't many functions 50559151504615d929945dc59db37bf1166937748c6Steve Block // that would be compiled lazily anyway, so we skip the preparse step 50659151504615d929945dc59db37bf1166937748c6Steve Block // in that case too. 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a script object describing the script to be compiled. 50944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Script> script = FACTORY->NewScript(source); 5103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (natives == NATIVES_CODE) { 5113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 5123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!script_name.is_null()) { 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->set_name(*script_name); 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->set_line_offset(Smi::FromInt(line_offset)); 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->set_column_offset(Smi::FromInt(column_offset)); 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51944f0eee88ff00398ff7f715fab053374d808c90dSteve Block script->set_data(script_data.is_null() ? HEAP->undefined_value() 520402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu : *script_data); 521402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the function and add it to the cache. 523f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompilationInfo info(script); 524f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.MarkAsGlobal(); 525f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetExtension(extension); 526f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetPreParseData(pre_data); 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_use_strict) { 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info.SetLanguageMode(FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE); 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 530f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch result = MakeFunctionInfo(&info); 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (extension == NULL && !result.is_null()) { 53244f0eee88ff00398ff7f715fab053374d808c90dSteve Block compilation_cache->PutScript(source, result); 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5348f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch } else { 5358f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch if (result->ic_age() != HEAP->global_ic_age()) { 5368f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch result->ResetForNewContext(HEAP->global_ic_age()); 5378f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch } 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (result.is_null()) isolate->ReportPendingMessages(); 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5456ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, 5466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context, 5471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool is_global, 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LanguageMode language_mode, 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int scope_position) { 55044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = source->GetIsolate(); 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int source_length = source->length(); 55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_eval_size()->Increment(source_length); 55344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_compile_size()->Increment(source_length); 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The VM is in the COMPILER state until exiting this function. 55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, COMPILER); 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 558f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Do a lookup in the compilation cache; if the entry is not there, invoke 5593e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // the compiler and add the result to the cache. 5606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> result; 56144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CompilationCache* compilation_cache = isolate->compilation_cache(); 56244f0eee88ff00398ff7f715fab053374d808c90dSteve Block result = compilation_cache->LookupEval(source, 56344f0eee88ff00398ff7f715fab053374d808c90dSteve Block context, 56444f0eee88ff00398ff7f715fab053374d808c90dSteve Block is_global, 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch language_mode, 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope_position); 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result.is_null()) { 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a script object describing the script to be compiled. 57044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Script> script = isolate->factory()->NewScript(source); 571f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompilationInfo info(script); 572f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.MarkAsEval(); 573f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (is_global) info.MarkAsGlobal(); 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info.SetLanguageMode(language_mode); 575f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetCallingContext(context); 576f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch result = MakeFunctionInfo(&info); 5773e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (!result.is_null()) { 5783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Explicitly disable optimization for eval code. We're not yet prepared 5793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // to handle eval-code in the optimizing compiler. 5803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->DisableOptimization(); 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If caller is strict mode, the result must be in strict mode or 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // extended mode as well, but not the other way around. Consider: 5841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // eval("'use strict'; ..."); 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(language_mode != STRICT_MODE || !result->is_classic_mode()); 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If caller is in extended mode, the result must also be in 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // extended mode. 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(language_mode != EXTENDED_MODE || 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch result->is_extended_mode()); 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compilation_cache->PutEval( 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch source, context, is_global, result, scope_position); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5938f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch } else { 5948f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch if (result->ic_age() != HEAP->global_ic_age()) { 5958f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch result->ResetForNewContext(HEAP->global_ic_age()); 5968f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch } 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool Compiler::CompileLazy(CompilationInfo* info) { 604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Isolate* isolate = info->isolate(); 605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 6063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneScope zone_scope(isolate, DELETE_ON_EXIT); 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The VM is in the COMPILER state until exiting this function. 609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch VMState state(isolate, COMPILER); 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61144f0eee88ff00398ff7f715fab053374d808c90dSteve Block PostponeInterruptsScope postpone(isolate); 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Handle<SharedFunctionInfo> shared = info->shared_info(); 614f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch int compiled_size = shared->end_position() - shared->start_position(); 61544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_compile_size()->Increment(compiled_size); 616f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 617f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Generate the AST for the lazily compiled function. 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (ParserApi::Parse(info, kNoParsingFlags)) { 619f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Measure how long it takes to do the lazy compilation; only take the 620f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // rest of the function into account to avoid overlap with the lazy 621f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // parsing statistics. 62244f0eee88ff00398ff7f715fab053374d808c90dSteve Block HistogramTimerScope timer(isolate->counters()->compile_lazy()); 623f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // After parsing we know the function's language mode. Remember it. 6253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LanguageMode language_mode = info->function()->language_mode(); 6263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info->SetLanguageMode(language_mode); 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shared->set_language_mode(language_mode); 6288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 629f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Compile the code. 630f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!MakeCode(info)) { 63144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!isolate->has_pending_exception()) { 63244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->StackOverflow(); 6331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 634f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 635f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(!info->code().is_null()); 636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code = info->code(); 63744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Set optimizable to false if this is disallowed by the shared 63844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // function info, e.g., we might have flushed the code and must 63944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // reset this bit when lazy compiling the code again. 64044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (shared->optimization_disabled()) code->set_optimizable(false); 64144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<JSFunction> function = info->closure(); 643e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); 644f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (info->IsOptimizing()) { 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(shared->scope_info() != ScopeInfo::Empty()); 647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->ReplaceCode(*code); 648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 649b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Update the shared function info with the compiled code and the 650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // scope info. Please note, that the order of the shared function 651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // info initialization is important since set_scope_info might 652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // trigger a GC, causing the ASSERT below to be invalid if the code 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // was flushed. By setting the code object last we avoid this. 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope()); 655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->set_scope_info(*scope_info); 656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->set_code(*code); 657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!function.is_null()) { 658b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->ReplaceCode(*code); 659b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!function->IsOptimized()); 660b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set the expected number of properties for instances. 663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FunctionLiteral* lit = info->function(); 664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int expected = lit->expected_property_count(); 665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetExpectedNofPropertiesFromEstimate(shared, expected); 666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set the optimization hints after performing lazy compilation, as 668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // these are not set when the function is set up as a lazily 669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // compiled function. 670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->SetThisPropertyAssignmentsInfo( 671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch lit->has_only_simple_this_property_assignments(), 672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *lit->this_property_assignments()); 673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check the function has compiled code. 675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(shared->is_compiled()); 676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->set_code_age(0); 6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); 6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shared->set_dont_inline(lit->flags()->Contains(kDontInline)); 6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shared->set_ast_node_count(lit->ast_node_count()); 680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (V8::UseCrankshaft()&& 6823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !function.is_null() && 6833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !shared->optimization_disabled()) { 684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // If we're asked to always optimize, we compile the optimized 685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // version of the function right away - unless the debugger is 686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // active as it makes no sense to compile optimized code then. 68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (FLAG_always_opt && 688257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch !Isolate::Current()->DebuggerHasBreakPoints()) { 689b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompilationInfo optimized(function); 690b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch optimized.SetOptimizing(AstNode::kNoNumber); 691b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return CompileLazy(&optimized); 692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 693b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 694f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 696f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return true; 697f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 69880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 700f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(info->code().is_null()); 701f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return false; 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7056ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 706f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Script> script) { 707f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Precondition: code has been parsed and scopes have been analyzed. 708f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompilationInfo info(script); 709f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetFunction(literal); 710f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetScope(literal->scope()); 7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch info.SetLanguageMode(literal->scope()->language_mode()); 712f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal); 714f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Determine if the function can be lazily compiled. This is necessary to 715f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // allow some of our builtin JS files to be lazily compiled. These 716f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // builtins cannot be handled lazily by the parser, since we have to know 717f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // if a function uses the special natives syntax, which is something the 718f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // parser records. 719402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu bool allow_lazy = literal->AllowsLazyCompilation() && 72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block !LiveEditFunctionTracker::IsActive(info.isolate()); 721d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ScopeInfo> scope_info(ScopeInfo::Empty()); 7233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 724d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Generate code 725d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (FLAG_lazy && allow_lazy) { 72644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Code> code = info.isolate()->builtins()->LazyCompile(); 727f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetCode(code); 7288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if ((V8::UseCrankshaft() && MakeCrankshaftCode(&info)) || 7298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch (!V8::UseCrankshaft() && FullCodeGenerator::MakeCode(&info))) { 730b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!info.code().is_null()); 7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch scope_info = ScopeInfo::Create(info.scope()); 7328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 7338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Handle<SharedFunctionInfo>::null(); 734d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 735d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 7366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Create a shared function info object. 7376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> result = 73844f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewSharedFunctionInfo(literal->name(), 7396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block literal->materialized_literal_count(), 740f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.code(), 7413bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch scope_info); 7426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetFunctionInfo(result, literal, false, script); 743e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); 744b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result->set_allows_lazy_compilation(allow_lazy); 745d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 746d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Set the expected number of properties for instances and return 747d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // the resulting function. 7486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetExpectedNofPropertiesFromEstimate(result, 749d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block literal->expected_property_count()); 7506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block live_edit_tracker.RecordFunctionInfo(result, literal); 7516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 752d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 753d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 754d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 755d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Sets the function info on a function. 756d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// The start_position points to the first '(' character after the function name 757d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// in the full script source. When counting characters in the script source the 758d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// the first character is number 0 (not 1). 7596ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info, 760d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block FunctionLiteral* lit, 761d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block bool is_toplevel, 762d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Handle<Script> script) { 7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_info->set_length(lit->parameter_count()); 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_info->set_formal_parameter_count(lit->parameter_count()); 7656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_script(*script); 7666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_function_token_position(lit->function_token_position()); 7676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_start_position(lit->start_position()); 7686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_end_position(lit->end_position()); 7696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_is_expression(lit->is_expression()); 7703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch function_info->set_is_anonymous(lit->is_anonymous()); 7716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_is_toplevel(is_toplevel); 7726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_inferred_name(*lit->inferred_name()); 7736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->SetThisPropertyAssignmentsInfo( 774d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block lit->has_only_simple_this_property_assignments(), 775d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *lit->this_property_assignments()); 7767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_info->set_language_mode(lit->language_mode()); 7783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch function_info->set_uses_arguments(lit->scope()->arguments() != NULL); 7793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters()); 7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_info->set_ast_node_count(lit->ast_node_count()); 7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_info->set_is_function(lit->is_function()); 7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); 7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_info->set_dont_inline(lit->flags()->Contains(kDontInline)); 784eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke} 785eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke 786eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke 7876ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, 788e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch CompilationInfo* info, 789e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<SharedFunctionInfo> shared) { 790e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // SharedFunctionInfo is passed separately, because if CompilationInfo 791e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // was created using Script object, it will not have it. 792e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 793f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Log the code generation. If source information is available include 794f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // script name and line number. Check explicitly whether logging is 795f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // enabled as finding the line number is not free. 796257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (info->isolate()->logger()->is_logging() || 797257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CpuProfiler::is_profiling(info->isolate())) { 798f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Script> script = info->script(); 799f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Code> code = info->code(); 80044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (*code == info->isolate()->builtins()->builtin(Builtins::kLazyCompile)) 80144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 8023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (script->name()->IsString()) { 803e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int line_num = GetScriptLineNumber(script, shared->start_position()) + 1; 8046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block USE(line_num); 80544f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(info->isolate(), 80644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 807f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *code, 808e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *shared, 809f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch String::cast(script->name()), 810f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch line_num)); 8113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else { 81244f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(info->isolate(), 81344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 814f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *code, 815e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *shared, 816e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch shared->DebugName())); 8173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 8183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 819b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 8208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GDBJIT(AddCode(Handle<String>(shared->DebugName()), 821b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<Script>(info->script()), 8223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Code>(info->code()), 8233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch info)); 8243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 8253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 827