compiler.cc revision 257744e915dfc84d6d07a6b2accf8402d9ffc708
18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 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" 391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block#include "lithium.h" 406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "liveedit.h" 41f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "parser.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "rewriter.h" 43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "runtime-profiler.h" 443bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch#include "scopeinfo.h" 45f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "scopes.h" 46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h" 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 52f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCompilationInfo::CompilationInfo(Handle<Script> script) 5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(script->GetIsolate()), 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block flags_(0), 55f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch function_(NULL), 56f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch scope_(NULL), 57f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch script_(script), 58f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch extension_(NULL), 59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pre_parse_data_(NULL), 60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch supports_deoptimization_(false), 61b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch osr_ast_id_(AstNode::kNoNumber) { 62b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Initialize(NONOPT); 63f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 64f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 65f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 66f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info) 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(shared_info->GetIsolate()), 6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block flags_(IsLazy::encode(true)), 69f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch function_(NULL), 70f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch scope_(NULL), 71f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch shared_info_(shared_info), 72f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch script_(Handle<Script>(Script::cast(shared_info->script()))), 73f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch extension_(NULL), 74b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pre_parse_data_(NULL), 75b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch supports_deoptimization_(false), 76b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch osr_ast_id_(AstNode::kNoNumber) { 77b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Initialize(BASE); 78f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 79f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 80f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 81f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCompilationInfo::CompilationInfo(Handle<JSFunction> closure) 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(closure->GetIsolate()), 8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block flags_(IsLazy::encode(true)), 84f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch function_(NULL), 85f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch scope_(NULL), 86f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch closure_(closure), 87f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch shared_info_(Handle<SharedFunctionInfo>(closure->shared())), 88f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch script_(Handle<Script>(Script::cast(shared_info_->script()))), 89f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch extension_(NULL), 90b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pre_parse_data_(NULL), 91b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch supports_deoptimization_(false), 92b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch osr_ast_id_(AstNode::kNoNumber) { 93b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Initialize(BASE); 94f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 95f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 96f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Disable optimization for the rest of the compilation pipeline. 98b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdochvoid CompilationInfo::DisableOptimization() { 99257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool is_optimizable_closure = 100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FLAG_optimize_closures && 101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch closure_.is_null() && 102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch !scope_->HasTrivialOuterContext() && 103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch !scope_->outer_scope_calls_non_strict_eval() && 104257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch !scope_->inside_with(); 105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SetMode(is_optimizable_closure ? BASE : NONOPT); 106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 108b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid CompilationInfo::AbortOptimization() { 110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code(shared_info()->code()); 111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SetCode(code); 112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Isolate* isolate = code->GetIsolate(); 113257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->compilation_cache()->MarkForLazyOptimizing(closure()); 114b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 115b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 116b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Determine whether to use the full compiler for all code. If the flag 118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// --always-full-compiler is specified this is the case. For the virtual frame 119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// based compiler the full compiler is also used if a debugger is connected, as 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// the code from the full compiler supports mode precise break points. For the 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// crankshaft adaptive compiler debugging the optimized code is not possible at 122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// all. However crankshaft support recompilation of functions, so in this case 123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// the full compiler need not be be used if a debugger is attached, but only if 124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// break points has actually been set. 125257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic bool is_debugging_active() { 126f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return V8::UseCrankshaft() ? 129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->debug()->has_break_points() : 130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->debugger()->IsDebuggerActive(); 131f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#else 132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return false; 133f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif 134f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 135f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic bool AlwaysFullCompiler() { 138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return FLAG_always_full_compiler || is_debugging_active(); 139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void FinishOptimization(Handle<JSFunction> function, int64_t start) { 143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int opt_count = function->shared()->opt_count(); 144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->shared()->set_opt_count(opt_count + 1); 145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch double ms = static_cast<double>(OS::Ticks() - start) / 1000; 146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_opt) { 147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[optimizing: "); 148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->PrintName(); 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" / %" V8PRIxPTR, reinterpret_cast<intptr_t>(*function)); 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" - took %0.3f ms]\n", ms); 151b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 152b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_opt_stats) { 153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static double compilation_time = 0.0; 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int compiled_functions = 0; 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static int code_size = 0; 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 157b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch compilation_time += ms; 158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch compiled_functions++; 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_size += function->shared()->SourceSize(); 160b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("Compiled: %d functions with %d byte source size in %fms.\n", 161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch compiled_functions, 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch code_size, 163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch compilation_time); 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic bool MakeCrankshaftCode(CompilationInfo* info) { 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Test if we can optimize this function when asked to. We can only 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // do this after the scopes are computed. 171b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info->AllowOptimize()) info->DisableOptimization(); 172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 173b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // In case we are not optimizing simply return the code from 174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the full code generator. 175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!info->IsOptimizing()) { 176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return FullCodeGenerator::MakeCode(info); 177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We should never arrive here if there is not code object on the 180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // shared function object. 181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code(info->shared_info()->code()); 182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(code->kind() == Code::FUNCTION); 183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 18444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // We should never arrive here if optimization has been disabled on the 18544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // shared function info. 18644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!info->shared_info()->optimization_disabled()); 18744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Fall back to using the full code generator if it's not possible 189b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // to use the Hydrogen-based optimizing compiler. We already have 190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // generated code for this from the shared function object. 191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (AlwaysFullCompiler() || !FLAG_use_hydrogen) { 192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch info->SetCode(code); 193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Limit the number of times we re-compile a functions with 197b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the optimizing compiler. 198b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch const int kMaxOptCount = 199b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; 200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (info->shared_info()->opt_count() > kMaxOptCount) { 201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->AbortOptimization(); 202257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<JSFunction> closure = info->closure(); 203257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->shared_info()->DisableOptimization(*closure); 204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // True indicates the compilation pipeline is still going, not 205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // necessarily that we optimized the code. 206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Due to an encoding limit on LUnallocated operands in the Lithium 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // language, we cannot optimize functions with too many formal parameters 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // or perform on-stack replacement for function with too many 212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // stack-allocated local variables. 213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // 214e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // The encoding is as a signed value, with parameters and receiver using 215e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // the negative indices and locals the non-negative ones. 2167d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch const int parameter_limit = -LUnallocated::kMinFixedIndex; 2177d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch const int locals_limit = LUnallocated::kMaxFixedIndex; 218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Scope* scope = info->scope(); 2197d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch if ((scope->num_parameters() + 1) > parameter_limit || 2207d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch (info->osr_ast_id() != AstNode::kNoNumber && 2217d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit)) { 222257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->AbortOptimization(); 223257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<JSFunction> closure = info->closure(); 224257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->shared_info()->DisableOptimization(*closure); 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // True indicates the compilation pipeline is still going, not 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // necessarily that we optimized the code. 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 230b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Take --hydrogen-filter into account. 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<String> name = info->function()->debug_name(); 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool match = filter.is_empty() || name->IsEqualTo(filter); 234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!match) { 235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch info->SetCode(code); 236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Recompile the unoptimized version of the code if the current version 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // doesn't have deoptimization support. Alternatively, we may decide to 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // run the full code generator to get a baseline for the compile-time 242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // performance of the hydrogen-based compiler. 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int64_t start = OS::Ticks(); 244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool should_recompile = !info->shared_info()->has_deoptimization_support(); 24544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (should_recompile || FLAG_hydrogen_stats) { 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhase phase(HPhase::kFullCodeGen); 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompilationInfo unoptimized(info->shared_info()); 248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Note that we use the same AST that we will use for generating the 249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimized code. 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unoptimized.SetFunction(info->function()); 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unoptimized.SetScope(info->scope()); 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (should_recompile) unoptimized.EnableDeoptimizationSupport(); 253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bool succeeded = FullCodeGenerator::MakeCode(&unoptimized); 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (should_recompile) { 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!succeeded) return false; 256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<SharedFunctionInfo> shared = info->shared_info(); 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->EnableDeoptimizationSupport(*unoptimized.code()); 258b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The existing unoptimized code was replaced with the new one. 259e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Compiler::RecordFunctionCompilation( 260e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Logger::LAZY_COMPILE_TAG, &unoptimized, shared); 261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check that the unoptimized, shared code is ready for 265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimizations. When using the always_opt flag we disregard the 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // optimizable marker in the code object and optimize anyway. This 267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // is safe as long as the unoptimized code has deoptimization 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // support. 269e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(FLAG_always_opt || code->optimizable()); 270b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(info->shared_info()->has_deoptimization_support()); 271b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_hydrogen) { 273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("-----------------------------------------------------------\n"); 274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("Compiling method %s using hydrogen\n", *name->ToCString()); 275b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HTracer::Instance()->TraceCompilation(info->function()); 276b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 278e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Context> global_context(info->closure()->context()->global_context()); 279e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch TypeFeedbackOracle oracle(code, global_context); 280e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HGraphBuilder builder(info, &oracle); 281b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch HPhase phase(HPhase::kTotal); 282e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch HGraph* graph = builder.CreateGraph(); 28344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (info->isolate()->has_pending_exception()) { 2841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block info->SetCode(Handle<Code>::null()); 2851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return false; 2861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 2871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (graph != NULL && FLAG_build_lithium) { 289e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<Code> optimized_code = graph->Compile(info); 290e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (!optimized_code.is_null()) { 291e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch info->SetCode(optimized_code); 292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FinishOptimization(info->closure(), start); 293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Keep using the shared code. 298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->AbortOptimization(); 299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!builder.inline_bailout()) { 300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Mark the shared code as unoptimizable unless it was an inlined 301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // function that bailed out. 302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<JSFunction> closure = info->closure(); 303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch info->shared_info()->DisableOptimization(*closure); 304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // True indicates the compilation pipeline is still going, not necessarily 306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // that we optimized the code. 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return true; 308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochstatic bool GenerateCode(CompilationInfo* info) { 312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return V8::UseCrankshaft() ? 313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch MakeCrankshaftCode(info) : 314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch FullCodeGenerator::MakeCode(info); 315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 318f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstatic bool MakeCode(CompilationInfo* info) { 319f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Precondition: code has been parsed. Postcondition: the code field in 320f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // the compilation info is set if compilation succeeded. 321f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(info->function() != NULL); 322257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return Rewriter::Rewrite(info) && Scope::Analyze(info) && GenerateCode(info); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef ENABLE_DEBUGGER_SUPPORT 327f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) { 328f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Precondition: code has been parsed. Postcondition: the code field in 329f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // the compilation info is set if compilation succeeded. 330f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool succeeded = MakeCode(info); 3313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (!info->shared_info().is_null()) { 3320d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Handle<SerializedScopeInfo> scope_info = 3330d5e116f6aee03185f237311a943491bb079a768Kristian Monsen SerializedScopeInfo::Create(info->scope()); 3340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen info->shared_info()->set_scope_info(*scope_info); 3353bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 336f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return succeeded; 3376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif 3396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 341f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstatic Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) { 34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = info->isolate(); 343257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CompilationZoneScope zone_scope(isolate, DELETE_ON_EXIT); 34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block PostponeInterruptsScope postpone(isolate); 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!isolate->global_context().is_null()); 347f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Script> script = info->script(); 34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block script->set_context_data((*isolate->global_context())->data()); 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef ENABLE_DEBUGGER_SUPPORT 3513e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (info->is_eval()) { 3523e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu Script::CompilationType compilation_type = Script::COMPILATION_TYPE_EVAL; 353f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch script->set_compilation_type(Smi::FromInt(compilation_type)); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For eval scripts add information on the function from which eval was 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // called. 356f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (info->is_eval()) { 3578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch StackTraceFrameIterator it(isolate); 3584515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (!it.done()) { 3594515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke script->set_eval_from_shared( 3604515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke JSFunction::cast(it.frame()->function())->shared()); 3618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Code* code = it.frame()->LookupCode(); 3624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int offset = static_cast<int>( 36344f0eee88ff00398ff7f715fab053374d808c90dSteve Block it.frame()->pc() - code->instruction_start()); 3644515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke script->set_eval_from_instructions_offset(Smi::FromInt(offset)); 3654515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify debugger 37044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->debugger()->OnBeforeCompile(script); 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Only allow non-global compiles for eval. 374f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(info->is_eval() || info->is_global()); 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3763e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (!ParserApi::Parse(info)) return Handle<SharedFunctionInfo>::null(); 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Measure how long it takes to do the compilation; only take the 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // rest of the function into account to avoid overlap with the 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // parsing statistics. 381f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch HistogramTimer* rate = info->is_eval() 38244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ? info->isolate()->counters()->compile_eval() 38344f0eee88ff00398ff7f715fab053374d808c90dSteve Block : info->isolate()->counters()->compile(); 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HistogramTimerScope timer(rate); 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the code. 387f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch FunctionLiteral* lit = info->function(); 38844f0eee88ff00398ff7f715fab053374d808c90dSteve Block LiveEditFunctionTracker live_edit_tracker(isolate, lit); 389f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!MakeCode(info)) { 39044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->StackOverflow(); 3916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Handle<SharedFunctionInfo>::null(); 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 394e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Allocate function. 395f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(!info->code().is_null()); 396e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<SharedFunctionInfo> result = 39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->factory()->NewSharedFunctionInfo( 398e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lit->name(), 399e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch lit->materialized_literal_count(), 400e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch info->code(), 401e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch SerializedScopeInfo::Create(info->scope())); 402e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 403e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position()); 404e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Compiler::SetFunctionInfo(result, lit, true, script); 405e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (script->name()->IsString()) { 40744f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate, CodeCreateEvent( 408f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info->is_eval() 409f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ? Logger::EVAL_TAG 410f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 411f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *info->code(), 412e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *result, 413f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch String::cast(script->name()))); 414b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJIT(AddCode(Handle<String>(String::cast(script->name())), 415b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch script, 416b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch info->code())); 4176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 41844f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate, CodeCreateEvent( 419f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info->is_eval() 420f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ? Logger::EVAL_TAG 421f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), 422f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *info->code(), 423e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *result, 42444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->heap()->empty_string())); 425b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch GDBJIT(AddCode(Handle<String>(), script, info->code())); 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Hint to the runtime system used when allocating space for initial 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // property space by setting the expected number of properties for 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the instances of the function. 4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count()); 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify debugger 43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->debugger()->OnAfterCompile( 43644f0eee88ff00398ff7f715fab053374d808c90dSteve Block script, Debugger::NO_AFTER_COMPILE_FLAGS); 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block live_edit_tracker.RecordFunctionInfo(result, lit); 4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4456ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::Compile(Handle<String> source, 4466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> script_name, 4476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int line_offset, 4486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int column_offset, 4496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::Extension* extension, 4506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ScriptDataImpl* input_pre_data, 4516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Object> script_data, 4526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block NativesFlag natives) { 45344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = source->GetIsolate(); 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int source_length = source->length(); 45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_load_size()->Increment(source_length); 45644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_compile_size()->Increment(source_length); 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The VM is in the COMPILER state until exiting this function. 45944f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, COMPILER); 46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 46144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CompilationCache* compilation_cache = isolate->compilation_cache(); 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do a lookup in the compilation cache but not for extensions. 4646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> result; 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (extension == NULL) { 46644f0eee88ff00398ff7f715fab053374d808c90dSteve Block result = compilation_cache->LookupScript(source, 46744f0eee88ff00398ff7f715fab053374d808c90dSteve Block script_name, 46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block line_offset, 46944f0eee88ff00398ff7f715fab053374d808c90dSteve Block column_offset); 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result.is_null()) { 47359151504615d929945dc59db37bf1166937748c6Steve Block // No cache entry found. Do pre-parsing, if it makes sense, and compile 47459151504615d929945dc59db37bf1166937748c6Steve Block // the script. 47559151504615d929945dc59db37bf1166937748c6Steve Block // Building preparse data that is only used immediately after is only a 47659151504615d929945dc59db37bf1166937748c6Steve Block // saving if we might skip building the AST for lazily compiled functions. 47759151504615d929945dc59db37bf1166937748c6Steve Block // I.e., preparse data isn't relevant when the lazy flag is off, and 47859151504615d929945dc59db37bf1166937748c6Steve Block // for small sources, odds are that there aren't many functions 47959151504615d929945dc59db37bf1166937748c6Steve Block // that would be compiled lazily anyway, so we skip the preparse step 48059151504615d929945dc59db37bf1166937748c6Steve Block // in that case too. 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScriptDataImpl* pre_data = input_pre_data; 48259151504615d929945dc59db37bf1166937748c6Steve Block if (pre_data == NULL 48359151504615d929945dc59db37bf1166937748c6Steve Block && source_length >= FLAG_min_preparse_length) { 484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (source->IsExternalTwoByteString()) { 485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ExternalTwoByteStringUC16CharacterStream stream( 486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 487b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pre_data = ParserApi::PartialPreParse(&stream, extension); 488b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 489b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch GenericStringUC16CharacterStream stream(source, 0, source->length()); 490b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch pre_data = ParserApi::PartialPreParse(&stream, extension); 491b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a script object describing the script to be compiled. 49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Script> script = FACTORY->NewScript(source); 4963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (natives == NATIVES_CODE) { 4973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 4983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!script_name.is_null()) { 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->set_name(*script_name); 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->set_line_offset(Smi::FromInt(line_offset)); 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block script->set_column_offset(Smi::FromInt(column_offset)); 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50544f0eee88ff00398ff7f715fab053374d808c90dSteve Block script->set_data(script_data.is_null() ? HEAP->undefined_value() 506402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu : *script_data); 507402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compile the function and add it to the cache. 509f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompilationInfo info(script); 510f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.MarkAsGlobal(); 511f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetExtension(extension); 512f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetPreParseData(pre_data); 513f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch result = MakeFunctionInfo(&info); 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (extension == NULL && !result.is_null()) { 51544f0eee88ff00398ff7f715fab053374d808c90dSteve Block compilation_cache->PutScript(source, result); 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get rid of the pre-parsing data (if necessary). 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (input_pre_data == NULL && pre_data != NULL) { 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block delete pre_data; 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (result.is_null()) isolate->ReportPendingMessages(); 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5296ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, 5306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<Context> context, 5311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool is_global, 5321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block StrictModeFlag strict_mode) { 53344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = source->GetIsolate(); 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int source_length = source->length(); 53544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_eval_size()->Increment(source_length); 53644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_compile_size()->Increment(source_length); 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The VM is in the COMPILER state until exiting this function. 53944f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, COMPILER); 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 541f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Do a lookup in the compilation cache; if the entry is not there, invoke 5423e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu // the compiler and add the result to the cache. 5436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> result; 54444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CompilationCache* compilation_cache = isolate->compilation_cache(); 54544f0eee88ff00398ff7f715fab053374d808c90dSteve Block result = compilation_cache->LookupEval(source, 54644f0eee88ff00398ff7f715fab053374d808c90dSteve Block context, 54744f0eee88ff00398ff7f715fab053374d808c90dSteve Block is_global, 54844f0eee88ff00398ff7f715fab053374d808c90dSteve Block strict_mode); 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (result.is_null()) { 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a script object describing the script to be compiled. 55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Script> script = isolate->factory()->NewScript(source); 553f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompilationInfo info(script); 554f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.MarkAsEval(); 555f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (is_global) info.MarkAsGlobal(); 5568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (strict_mode == kStrictMode) info.MarkAsStrictMode(); 557f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetCallingContext(context); 558f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch result = MakeFunctionInfo(&info); 5593e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (!result.is_null()) { 56044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CompilationCache* compilation_cache = isolate->compilation_cache(); 5611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // If caller is strict mode, the result must be strict as well, 5621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // but not the other way around. Consider: 5631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // eval("'use strict'; ..."); 5641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ASSERT(strict_mode == kNonStrictMode || result->strict_mode()); 56544f0eee88ff00398ff7f715fab053374d808c90dSteve Block compilation_cache->PutEval(source, context, is_global, result); 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool Compiler::CompileLazy(CompilationInfo* info) { 574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Isolate* isolate = info->isolate(); 575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CompilationZoneScope zone_scope(isolate, DELETE_ON_EXIT); 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The VM is in the COMPILER state until exiting this function. 579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch VMState state(isolate, COMPILER); 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58144f0eee88ff00398ff7f715fab053374d808c90dSteve Block PostponeInterruptsScope postpone(isolate); 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5834515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Handle<SharedFunctionInfo> shared = info->shared_info(); 584f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch int compiled_size = shared->end_position() - shared->start_position(); 58544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->total_compile_size()->Increment(compiled_size); 586f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 587f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Generate the AST for the lazily compiled function. 5883e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu if (ParserApi::Parse(info)) { 589f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Measure how long it takes to do the lazy compilation; only take the 590f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // rest of the function into account to avoid overlap with the lazy 591f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // parsing statistics. 59244f0eee88ff00398ff7f715fab053374d808c90dSteve Block HistogramTimerScope timer(isolate->counters()->compile_lazy()); 593f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 5948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch // After parsing we know function's strict mode. Remember it. 5958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (info->function()->strict_mode()) { 5968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch shared->set_strict_mode(true); 5978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch info->MarkAsStrictMode(); 5988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 5998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 600f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Compile the code. 601f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!MakeCode(info)) { 60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!isolate->has_pending_exception()) { 60344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->StackOverflow(); 6041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 605f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 606f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(!info->code().is_null()); 607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code = info->code(); 60844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Set optimizable to false if this is disallowed by the shared 60944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // function info, e.g., we might have flushed the code and must 61044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // reset this bit when lazy compiling the code again. 61144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (shared->optimization_disabled()) code->set_optimizable(false); 61244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 613b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<JSFunction> function = info->closure(); 614e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared); 615f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (info->IsOptimizing()) { 617b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->ReplaceCode(*code); 618b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else { 619b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Update the shared function info with the compiled code and the 620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // scope info. Please note, that the order of the shared function 621b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // info initialization is important since set_scope_info might 622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // trigger a GC, causing the ASSERT below to be invalid if the code 623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // was flushed. By settting the code object last we avoid this. 624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<SerializedScopeInfo> scope_info = 625b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SerializedScopeInfo::Create(info->scope()); 626b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->set_scope_info(*scope_info); 627b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->set_code(*code); 628b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!function.is_null()) { 629b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->ReplaceCode(*code); 630b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!function->IsOptimized()); 631b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 632b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 633b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set the expected number of properties for instances. 634b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch FunctionLiteral* lit = info->function(); 635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int expected = lit->expected_property_count(); 636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SetExpectedNofPropertiesFromEstimate(shared, expected); 637b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 638b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Set the optimization hints after performing lazy compilation, as 639b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // these are not set when the function is set up as a lazily 640b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // compiled function. 641b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->SetThisPropertyAssignmentsInfo( 642b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch lit->has_only_simple_this_property_assignments(), 643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch *lit->this_property_assignments()); 644b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 645b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Check the function has compiled code. 646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(shared->is_compiled()); 647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch shared->set_code_age(0); 648b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 64944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (info->AllowOptimize() && !shared->optimization_disabled()) { 650b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // If we're asked to always optimize, we compile the optimized 651b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // version of the function right away - unless the debugger is 652b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // active as it makes no sense to compile optimized code then. 65344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (FLAG_always_opt && 654257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch !Isolate::Current()->DebuggerHasBreakPoints()) { 655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompilationInfo optimized(function); 656b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch optimized.SetOptimizing(AstNode::kNoNumber); 657b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return CompileLazy(&optimized); 65844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else if (isolate->compilation_cache()->ShouldOptimizeEagerly( 65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block function)) { 66044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->runtime_profiler()->OptimizeSoon(*function); 661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 663f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 665f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return true; 666f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 66780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 669f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ASSERT(info->code().is_null()); 670f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return false; 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6746ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 675f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Script> script) { 676f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Precondition: code has been parsed and scopes have been analyzed. 677f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CompilationInfo info(script); 678f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetFunction(literal); 679f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetScope(literal->scope()); 680257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (literal->scope()->is_strict_mode()) info.MarkAsStrictMode(); 681f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal); 683f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Determine if the function can be lazily compiled. This is necessary to 684f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // allow some of our builtin JS files to be lazily compiled. These 685f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // builtins cannot be handled lazily by the parser, since we have to know 686f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // if a function uses the special natives syntax, which is something the 687f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // parser records. 688402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu bool allow_lazy = literal->AllowsLazyCompilation() && 68944f0eee88ff00398ff7f715fab053374d808c90dSteve Block !LiveEditFunctionTracker::IsActive(info.isolate()); 690d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 6913bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty()); 6923bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 693d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Generate code 694d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (FLAG_lazy && allow_lazy) { 69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Code> code = info.isolate()->builtins()->LazyCompile(); 696f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.SetCode(code); 6978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if ((V8::UseCrankshaft() && MakeCrankshaftCode(&info)) || 6988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch (!V8::UseCrankshaft() && FullCodeGenerator::MakeCode(&info))) { 699b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(!info.code().is_null()); 7003bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch scope_info = SerializedScopeInfo::Create(info.scope()); 7018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else { 7028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Handle<SharedFunctionInfo>::null(); 703d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 704d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 7056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Create a shared function info object. 7066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<SharedFunctionInfo> result = 70744f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewSharedFunctionInfo(literal->name(), 7086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block literal->materialized_literal_count(), 709f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch info.code(), 7103bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch scope_info); 7116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetFunctionInfo(result, literal, false, script); 712e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); 713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch result->set_allows_lazy_compilation(allow_lazy); 714d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 715d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Set the expected number of properties for instances and return 716d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // the resulting function. 7176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SetExpectedNofPropertiesFromEstimate(result, 718d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block literal->expected_property_count()); 7196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block live_edit_tracker.RecordFunctionInfo(result, literal); 7206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return result; 721d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 722d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 723d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 724d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Sets the function info on a function. 725d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// The start_position points to the first '(' character after the function name 726d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// in the full script source. When counting characters in the script source the 727d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// the first character is number 0 (not 1). 7286ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info, 729d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block FunctionLiteral* lit, 730d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block bool is_toplevel, 731d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Handle<Script> script) { 7326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_length(lit->num_parameters()); 7336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_formal_parameter_count(lit->num_parameters()); 7346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_script(*script); 7356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_function_token_position(lit->function_token_position()); 7366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_start_position(lit->start_position()); 7376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_end_position(lit->end_position()); 7386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_is_expression(lit->is_expression()); 7396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_is_toplevel(is_toplevel); 7406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->set_inferred_name(*lit->inferred_name()); 7416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block function_info->SetThisPropertyAssignmentsInfo( 742d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block lit->has_only_simple_this_property_assignments(), 743d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block *lit->this_property_assignments()); 7447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); 7451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block function_info->set_strict_mode(lit->strict_mode()); 746eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke} 747eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke 748eab96aab0834f21954b5d6aa6366bcfb348ed811Leon Clarke 7496ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, 750e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch CompilationInfo* info, 751e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Handle<SharedFunctionInfo> shared) { 752e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // SharedFunctionInfo is passed separately, because if CompilationInfo 753e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // was created using Script object, it will not have it. 754e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 755f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Log the code generation. If source information is available include 756f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // script name and line number. Check explicitly whether logging is 757f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // enabled as finding the line number is not free. 758257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (info->isolate()->logger()->is_logging() || 759257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CpuProfiler::is_profiling(info->isolate())) { 760f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Script> script = info->script(); 761f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Code> code = info->code(); 76244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (*code == info->isolate()->builtins()->builtin(Builtins::kLazyCompile)) 76344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 7643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu if (script->name()->IsString()) { 765e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int line_num = GetScriptLineNumber(script, shared->start_position()) + 1; 7666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block USE(line_num); 76744f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(info->isolate(), 76844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 769f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *code, 770e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *shared, 771f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch String::cast(script->name()), 772f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch line_num)); 7733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } else { 77444f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(info->isolate(), 77544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(Logger::ToNativeByScript(tag, *script), 776f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *code, 777e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch *shared, 778e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch shared->DebugName())); 7793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 7803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 781b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 7828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GDBJIT(AddCode(Handle<String>(shared->DebugName()), 783b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<Script>(info->script()), 784b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Handle<Code>(info->code()))); 7853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 7863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 788