blob: 01e261a95b6470f4857bc8ef841d59727df87741 [file] [log] [blame]
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000030#include "compiler.h"
31
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000032#include "bootstrapper.h"
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000033#include "codegen.h"
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000034#include "compilation-cache.h"
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +000035#include "cpu-profiler.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036#include "debug.h"
ulan@chromium.org6e196bf2013-03-13 09:38:22 +000037#include "deoptimizer.h"
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +000038#include "full-codegen.h"
erik.corry@gmail.com0511e242011-01-19 11:11:08 +000039#include "gdb-jit.h"
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +000040#include "typing.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000041#include "hydrogen.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000042#include "isolate-inl.h"
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000043#include "lithium.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000044#include "liveedit.h"
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000045#include "parser.h"
ager@chromium.org71daaf62009-04-01 07:22:49 +000046#include "rewriter.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000047#include "runtime-profiler.h"
ricow@chromium.org55ee8072011-09-08 16:33:10 +000048#include "scanner-character-streams.h"
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +000049#include "scopeinfo.h"
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000050#include "scopes.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000051#include "vm-state-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000052
kasperl@chromium.org71affb52009-05-26 05:44:31 +000053namespace v8 {
54namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000055
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000056
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +000057CompilationInfo::CompilationInfo(Handle<Script> script,
58 Zone* zone)
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +000059 : flags_(LanguageModeField::encode(CLASSIC_MODE)),
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000060 script_(script),
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000061 osr_ast_id_(BailoutId::None()),
62 osr_pc_offset_(0) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000063 Initialize(script->GetIsolate(), BASE, zone);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000064}
65
66
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000067CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info,
68 Zone* zone)
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +000069 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000070 shared_info_(shared_info),
71 script_(Handle<Script>(Script::cast(shared_info->script()))),
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000072 osr_ast_id_(BailoutId::None()),
73 osr_pc_offset_(0) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000074 Initialize(script_->GetIsolate(), BASE, zone);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000075}
76
77
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +000078CompilationInfo::CompilationInfo(Handle<JSFunction> closure,
79 Zone* zone)
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +000080 : flags_(LanguageModeField::encode(CLASSIC_MODE) | IsLazy::encode(true)),
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000081 closure_(closure),
82 shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
83 script_(Handle<Script>(Script::cast(shared_info_->script()))),
yangguo@chromium.org355cfd12012-08-29 15:32:24 +000084 context_(closure->context()),
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000085 osr_ast_id_(BailoutId::None()),
86 osr_pc_offset_(0) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000087 Initialize(script_->GetIsolate(), BASE, zone);
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +000088}
89
90
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000091CompilationInfo::CompilationInfo(HydrogenCodeStub* stub,
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +000092 Isolate* isolate,
93 Zone* zone)
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000094 : flags_(LanguageModeField::encode(CLASSIC_MODE) |
95 IsLazy::encode(true)),
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000096 osr_ast_id_(BailoutId::None()),
97 osr_pc_offset_(0) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000098 Initialize(isolate, STUB, zone);
99 code_stub_ = stub;
100}
101
102
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000103void CompilationInfo::Initialize(Isolate* isolate,
104 Mode mode,
105 Zone* zone) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000106 isolate_ = isolate;
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000107 function_ = NULL;
108 scope_ = NULL;
109 global_scope_ = NULL;
110 extension_ = NULL;
111 pre_parse_data_ = NULL;
112 zone_ = zone;
113 deferred_handles_ = NULL;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000114 code_stub_ = NULL;
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000115 prologue_offset_ = kPrologueOffsetNotSet;
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000116 opt_count_ = shared_info().is_null() ? 0 : shared_info()->opt_count();
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000117 no_frame_ranges_ = isolate->cpu_profiler()->is_profiling()
118 ? new List<OffsetRange>(2) : NULL;
danno@chromium.org41728482013-06-12 22:31:22 +0000119 for (int i = 0; i < DependentCode::kGroupCount; i++) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000120 dependencies_[i] = NULL;
danno@chromium.org41728482013-06-12 22:31:22 +0000121 }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000122 if (mode == STUB) {
123 mode_ = STUB;
124 return;
125 }
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000126 mode_ = isolate->use_crankshaft() ? mode : NONOPT;
danno@chromium.org59400602013-08-13 17:09:37 +0000127 abort_due_to_dependency_ = false;
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000128 if (script_->type()->value() == Script::TYPE_NATIVE) {
129 MarkAsNative();
130 }
131 if (!shared_info_.is_null()) {
132 ASSERT(language_mode() == CLASSIC_MODE);
133 SetLanguageMode(shared_info_->language_mode());
134 }
danno@chromium.org59400602013-08-13 17:09:37 +0000135 set_bailout_reason(kUnknown);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000136}
137
138
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000139CompilationInfo::~CompilationInfo() {
140 delete deferred_handles_;
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000141 delete no_frame_ranges_;
danno@chromium.org41728482013-06-12 22:31:22 +0000142#ifdef DEBUG
143 // Check that no dependent maps have been added or added dependent maps have
144 // been rolled back or committed.
145 for (int i = 0; i < DependentCode::kGroupCount; i++) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000146 ASSERT_EQ(NULL, dependencies_[i]);
danno@chromium.org41728482013-06-12 22:31:22 +0000147 }
148#endif // DEBUG
149}
150
151
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000152void CompilationInfo::CommitDependencies(Handle<Code> code) {
danno@chromium.org41728482013-06-12 22:31:22 +0000153 for (int i = 0; i < DependentCode::kGroupCount; i++) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000154 ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i];
155 if (group_objects == NULL) continue;
danno@chromium.org41728482013-06-12 22:31:22 +0000156 ASSERT(!object_wrapper_.is_null());
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000157 for (int j = 0; j < group_objects->length(); j++) {
158 DependentCode::DependencyGroup group =
159 static_cast<DependentCode::DependencyGroup>(i);
160 DependentCode* dependent_code =
161 DependentCode::ForObject(group_objects->at(j), group);
162 dependent_code->UpdateToFinishedCode(group, this, *code);
danno@chromium.org41728482013-06-12 22:31:22 +0000163 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000164 dependencies_[i] = NULL; // Zone-allocated, no need to delete.
danno@chromium.org41728482013-06-12 22:31:22 +0000165 }
166}
167
168
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000169void CompilationInfo::RollbackDependencies() {
danno@chromium.org41728482013-06-12 22:31:22 +0000170 // Unregister from all dependent maps if not yet committed.
171 for (int i = 0; i < DependentCode::kGroupCount; i++) {
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000172 ZoneList<Handle<HeapObject> >* group_objects = dependencies_[i];
173 if (group_objects == NULL) continue;
174 for (int j = 0; j < group_objects->length(); j++) {
175 DependentCode::DependencyGroup group =
176 static_cast<DependentCode::DependencyGroup>(i);
177 DependentCode* dependent_code =
178 DependentCode::ForObject(group_objects->at(j), group);
179 dependent_code->RemoveCompilationInfo(group, this);
danno@chromium.org41728482013-06-12 22:31:22 +0000180 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000181 dependencies_[i] = NULL; // Zone-allocated, no need to delete.
danno@chromium.org41728482013-06-12 22:31:22 +0000182 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000183}
184
185
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000186int CompilationInfo::num_parameters() const {
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000187 ASSERT(!IsStub());
188 return scope()->num_parameters();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000189}
190
191
192int CompilationInfo::num_heap_slots() const {
193 if (IsStub()) {
194 return 0;
195 } else {
196 return scope()->num_heap_slots();
197 }
198}
199
200
201Code::Flags CompilationInfo::flags() const {
202 if (IsStub()) {
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000203 return Code::ComputeFlags(code_stub()->GetCodeKind(),
204 code_stub()->GetICState(),
205 code_stub()->GetExtraICState(),
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000206 code_stub()->GetStubType(),
207 code_stub()->GetStubFlags());
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000208 } else {
209 return Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
210 }
211}
212
213
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000214// Disable optimization for the rest of the compilation pipeline.
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000215void CompilationInfo::DisableOptimization() {
lrn@chromium.org1c092762011-05-09 09:42:16 +0000216 bool is_optimizable_closure =
217 FLAG_optimize_closures &&
218 closure_.is_null() &&
219 !scope_->HasTrivialOuterContext() &&
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000220 !scope_->outer_scope_calls_non_strict_eval() &&
lrn@chromium.org1c092762011-05-09 09:42:16 +0000221 !scope_->inside_with();
222 SetMode(is_optimizable_closure ? BASE : NONOPT);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000223}
224
225
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000226// Primitive functions are unlikely to be picked up by the stack-walking
227// profiler, so they trigger their own optimization when they're called
228// for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time.
229bool CompilationInfo::ShouldSelfOptimize() {
230 return FLAG_self_optimization &&
231 FLAG_crankshaft &&
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000232 !function()->flags()->Contains(kDontSelfOptimize) &&
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000233 !function()->dont_optimize() &&
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000234 function()->scope()->AllowsLazyCompilation() &&
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000235 (shared_info().is_null() || !shared_info()->optimization_disabled());
236}
237
238
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000239// Determine whether to use the full compiler for all code. If the flag
240// --always-full-compiler is specified this is the case. For the virtual frame
241// based compiler the full compiler is also used if a debugger is connected, as
242// the code from the full compiler supports mode precise break points. For the
243// crankshaft adaptive compiler debugging the optimized code is not possible at
244// all. However crankshaft support recompilation of functions, so in this case
245// the full compiler need not be be used if a debugger is attached, but only if
246// break points has actually been set.
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000247static bool IsDebuggerActive(Isolate* isolate) {
kmillikin@chromium.org9155e252010-05-26 13:27:57 +0000248#ifdef ENABLE_DEBUGGER_SUPPORT
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000249 return isolate->use_crankshaft() ?
lrn@chromium.org1c092762011-05-09 09:42:16 +0000250 isolate->debug()->has_break_points() :
251 isolate->debugger()->IsDebuggerActive();
kmillikin@chromium.org9155e252010-05-26 13:27:57 +0000252#else
lrn@chromium.org1c092762011-05-09 09:42:16 +0000253 return false;
kmillikin@chromium.org9155e252010-05-26 13:27:57 +0000254#endif
255}
256
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000257
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000258static bool AlwaysFullCompiler(Isolate* isolate) {
259 return FLAG_always_full_compiler || IsDebuggerActive(isolate);
lrn@chromium.org1c092762011-05-09 09:42:16 +0000260}
261
262
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +0000263void RecompileJob::RecordOptimizationStats() {
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000264 Handle<JSFunction> function = info()->closure();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000265 int opt_count = function->shared()->opt_count();
266 function->shared()->set_opt_count(opt_count + 1);
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000267 double ms_creategraph = time_taken_to_create_graph_.InMillisecondsF();
268 double ms_optimize = time_taken_to_optimize_.InMillisecondsF();
269 double ms_codegen = time_taken_to_codegen_.InMillisecondsF();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000270 if (FLAG_trace_opt) {
ulan@chromium.org906e2fb2013-05-14 08:14:38 +0000271 PrintF("[optimizing ");
272 function->ShortPrint();
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000273 PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize,
274 ms_codegen);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000275 }
276 if (FLAG_trace_opt_stats) {
277 static double compilation_time = 0.0;
278 static int compiled_functions = 0;
279 static int code_size = 0;
280
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000281 compilation_time += (ms_creategraph + ms_optimize + ms_codegen);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000282 compiled_functions++;
283 code_size += function->shared()->SourceSize();
284 PrintF("Compiled: %d functions with %d byte source size in %fms.\n",
285 compiled_functions,
286 code_size,
287 compilation_time);
288 }
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000289 if (FLAG_hydrogen_stats) {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000290 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_create_graph_,
291 time_taken_to_optimize_,
292 time_taken_to_codegen_);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000293 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000294}
295
296
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000297// A return value of true indicates the compilation pipeline is still
298// going, not necessarily that we optimized the code.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000299static bool MakeCrankshaftCode(CompilationInfo* info) {
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +0000300 RecompileJob job(info);
301 RecompileJob::Status status = job.CreateGraph();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000302
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +0000303 if (status != RecompileJob::SUCCEEDED) {
304 return status != RecompileJob::FAILED;
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000305 }
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +0000306 status = job.OptimizeGraph();
307 if (status != RecompileJob::SUCCEEDED) {
308 status = job.AbortOptimization();
309 return status != RecompileJob::FAILED;
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000310 }
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +0000311 status = job.GenerateAndInstallCode();
312 return status != RecompileJob::FAILED;
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000313}
314
315
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +0000316RecompileJob::Status RecompileJob::CreateGraph() {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000317 ASSERT(isolate()->use_crankshaft());
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000318 ASSERT(info()->IsOptimizing());
319 ASSERT(!info()->IsCompilingForDebugging());
320
321 // We should never arrive here if there is no code object on the
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000322 // shared function object.
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000323 ASSERT(info()->shared_info()->code()->kind() == Code::FUNCTION);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000324
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000325 // We should never arrive here if optimization has been disabled on the
326 // shared function info.
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000327 ASSERT(!info()->shared_info()->optimization_disabled());
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000328
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000329 // Fall back to using the full code generator if it's not possible
330 // to use the Hydrogen-based optimizing compiler. We already have
331 // generated code for this from the shared function object.
ulan@chromium.org750145a2013-03-07 15:14:13 +0000332 if (AlwaysFullCompiler(isolate())) {
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000333 info()->AbortOptimization();
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000334 return SetLastStatus(BAILED_OUT);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000335 }
336
337 // Limit the number of times we re-compile a functions with
338 // the optimizing compiler.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000339 const int kMaxOptCount =
verwaest@chromium.orgde64f722012-08-16 15:44:54 +0000340 FLAG_deopt_every_n_times == 0 ? FLAG_max_opt_count : 1000;
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000341 if (info()->opt_count() > kMaxOptCount) {
danno@chromium.org59400602013-08-13 17:09:37 +0000342 info()->set_bailout_reason(kOptimizedTooManyTimes);
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000343 return AbortOptimization();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000344 }
345
346 // Due to an encoding limit on LUnallocated operands in the Lithium
347 // language, we cannot optimize functions with too many formal parameters
348 // or perform on-stack replacement for function with too many
349 // stack-allocated local variables.
350 //
ager@chromium.org9ee27ae2011-03-02 13:43:26 +0000351 // The encoding is as a signed value, with parameters and receiver using
352 // the negative indices and locals the non-negative ones.
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000353 const int parameter_limit = -LUnallocated::kMinFixedSlotIndex;
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000354 Scope* scope = info()->scope();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000355 if ((scope->num_parameters() + 1) > parameter_limit) {
danno@chromium.org59400602013-08-13 17:09:37 +0000356 info()->set_bailout_reason(kTooManyParameters);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000357 return AbortOptimization();
358 }
359
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000360 const int locals_limit = LUnallocated::kMaxFixedSlotIndex;
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000361 if (info()->is_osr() &&
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000362 scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit) {
danno@chromium.org59400602013-08-13 17:09:37 +0000363 info()->set_bailout_reason(kTooManyParametersLocals);
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000364 return AbortOptimization();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000365 }
366
367 // Take --hydrogen-filter into account.
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +0000368 if (!info()->closure()->PassesFilter(FLAG_hydrogen_filter)) {
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000369 info()->AbortOptimization();
370 return SetLastStatus(BAILED_OUT);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000371 }
372
373 // Recompile the unoptimized version of the code if the current version
374 // doesn't have deoptimization support. Alternatively, we may decide to
375 // run the full code generator to get a baseline for the compile-time
376 // performance of the hydrogen-based compiler.
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000377 bool should_recompile = !info()->shared_info()->has_deoptimization_support();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000378 if (should_recompile || FLAG_hydrogen_stats) {
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000379 ElapsedTimer timer;
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000380 if (FLAG_hydrogen_stats) {
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000381 timer.Start();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000382 }
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000383 CompilationInfoWithZone unoptimized(info()->shared_info());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000384 // Note that we use the same AST that we will use for generating the
385 // optimized code.
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000386 unoptimized.SetFunction(info()->function());
387 unoptimized.SetScope(info()->scope());
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000388 unoptimized.SetContext(info()->context());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000389 if (should_recompile) unoptimized.EnableDeoptimizationSupport();
390 bool succeeded = FullCodeGenerator::MakeCode(&unoptimized);
391 if (should_recompile) {
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000392 if (!succeeded) return SetLastStatus(FAILED);
393 Handle<SharedFunctionInfo> shared = info()->shared_info();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000394 shared->EnableDeoptimizationSupport(*unoptimized.code());
395 // The existing unoptimized code was replaced with the new one.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000396 Compiler::RecordFunctionCompilation(
397 Logger::LAZY_COMPILE_TAG, &unoptimized, shared);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000398 }
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000399 if (FLAG_hydrogen_stats) {
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000400 isolate()->GetHStatistics()->IncrementFullCodeGen(timer.Elapsed());
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000401 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000402 }
403
404 // Check that the unoptimized, shared code is ready for
405 // optimizations. When using the always_opt flag we disregard the
406 // optimizable marker in the code object and optimize anyway. This
407 // is safe as long as the unoptimized code has deoptimization
408 // support.
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000409 ASSERT(FLAG_always_opt || info()->shared_info()->code()->optimizable());
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000410 ASSERT(info()->shared_info()->has_deoptimization_support());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000411
412 if (FLAG_trace_hydrogen) {
ulan@chromium.org906e2fb2013-05-14 08:14:38 +0000413 Handle<String> name = info()->function()->debug_name();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000414 PrintF("-----------------------------------------------------------\n");
415 PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
ulan@chromium.org750145a2013-03-07 15:14:13 +0000416 isolate()->GetHTracer()->TraceCompilation(info());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000417 }
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000418
419 // Type-check the function.
danno@chromium.org41728482013-06-12 22:31:22 +0000420 AstTyper::Run(info());
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000421
422 graph_builder_ = new(info()->zone()) HOptimizedGraphBuilder(info());
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000423
424 Timer t(this, &time_taken_to_create_graph_);
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000425 graph_ = graph_builder_->CreateGraph();
426
ulan@chromium.org750145a2013-03-07 15:14:13 +0000427 if (isolate()->has_pending_exception()) {
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000428 info()->SetCode(Handle<Code>::null());
429 return SetLastStatus(FAILED);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000430 }
431
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000432 // The function being compiled may have bailed out due to an inline
433 // candidate bailing out. In such a case, we don't disable
434 // optimization on the shared_info.
435 ASSERT(!graph_builder_->inline_bailout() || graph_ == NULL);
436 if (graph_ == NULL) {
437 if (graph_builder_->inline_bailout()) {
438 info_->AbortOptimization();
439 return SetLastStatus(BAILED_OUT);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000440 } else {
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000441 return AbortOptimization();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000442 }
443 }
444
danno@chromium.org59400602013-08-13 17:09:37 +0000445 if (info()->HasAbortedDueToDependencyChange()) {
446 info_->set_bailout_reason(kBailedOutDueToDependencyChange);
447 info_->AbortOptimization();
448 return SetLastStatus(BAILED_OUT);
449 }
450
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000451 return SetLastStatus(SUCCEEDED);
452}
453
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +0000454
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +0000455RecompileJob::Status RecompileJob::OptimizeGraph() {
rossberg@chromium.org79e79022013-06-03 15:43:46 +0000456 DisallowHeapAllocation no_allocation;
457 DisallowHandleAllocation no_handles;
458 DisallowHandleDereference no_deref;
danno@chromium.org59400602013-08-13 17:09:37 +0000459 DisallowCodeDependencyChange no_dependency_change;
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000460
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000461 ASSERT(last_status() == SUCCEEDED);
462 Timer t(this, &time_taken_to_optimize_);
463 ASSERT(graph_ != NULL);
danno@chromium.org59400602013-08-13 17:09:37 +0000464 BailoutReason bailout_reason = kNoReason;
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000465 if (!graph_->Optimize(&bailout_reason)) {
danno@chromium.org59400602013-08-13 17:09:37 +0000466 if (bailout_reason == kNoReason) graph_builder_->Bailout(bailout_reason);
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000467 return SetLastStatus(BAILED_OUT);
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000468 } else {
469 chunk_ = LChunk::NewChunk(graph_);
470 if (chunk_ == NULL) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000471 return SetLastStatus(BAILED_OUT);
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000472 }
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000473 }
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000474 return SetLastStatus(SUCCEEDED);
475}
476
477
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +0000478RecompileJob::Status RecompileJob::GenerateAndInstallCode() {
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000479 ASSERT(last_status() == SUCCEEDED);
danno@chromium.org59400602013-08-13 17:09:37 +0000480 ASSERT(!info()->HasAbortedDueToDependencyChange());
481 DisallowCodeDependencyChange no_dependency_change;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000482 { // Scope for timer.
483 Timer timer(this, &time_taken_to_codegen_);
484 ASSERT(chunk_ != NULL);
485 ASSERT(graph_ != NULL);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000486 // Deferred handles reference objects that were accessible during
487 // graph creation. To make sure that we don't encounter inconsistencies
488 // between graph creation and code generation, we disallow accessing
489 // objects through deferred handles during the latter, with exceptions.
yangguo@chromium.org20301242013-06-03 16:06:25 +0000490 DisallowDeferredHandleDereference no_deferred_handle_deref;
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000491 Handle<Code> optimized_code = chunk_->Codegen();
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000492 if (optimized_code.is_null()) {
danno@chromium.org59400602013-08-13 17:09:37 +0000493 if (info()->bailout_reason() == kNoReason) {
494 info()->set_bailout_reason(kCodeGenerationFailed);
495 }
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000496 return AbortOptimization();
497 }
498 info()->SetCode(optimized_code);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000499 }
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000500 RecordOptimizationStats();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000501 // Add to the weak list of optimized code objects.
502 info()->context()->native_context()->AddOptimizedCode(*info()->code());
verwaest@chromium.org178fb152012-07-18 11:21:48 +0000503 return SetLastStatus(SUCCEEDED);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000504}
505
506
lrn@chromium.org1c092762011-05-09 09:42:16 +0000507static bool GenerateCode(CompilationInfo* info) {
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000508 bool is_optimizing = info->isolate()->use_crankshaft() &&
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000509 !info->IsCompilingForDebugging() &&
510 info->IsOptimizing();
511 if (is_optimizing) {
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000512 Logger::TimerEventScope timer(
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000513 info->isolate(), Logger::TimerEventScope::v8_recompile_synchronous);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000514 return MakeCrankshaftCode(info);
515 } else {
516 if (info->IsOptimizing()) {
517 // Have the CompilationInfo decide if the compilation should be
518 // BASE or NONOPT.
519 info->DisableOptimization();
520 }
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000521 Logger::TimerEventScope timer(
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000522 info->isolate(), Logger::TimerEventScope::v8_compile_full_code);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000523 return FullCodeGenerator::MakeCode(info);
524 }
lrn@chromium.org1c092762011-05-09 09:42:16 +0000525}
526
527
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000528static bool MakeCode(CompilationInfo* info) {
529 // Precondition: code has been parsed. Postcondition: the code field in
530 // the compilation info is set if compilation succeeded.
531 ASSERT(info->function() != NULL);
lrn@chromium.org1c092762011-05-09 09:42:16 +0000532 return Rewriter::Rewrite(info) && Scope::Analyze(info) && GenerateCode(info);
ager@chromium.org3a37e9b2009-04-27 09:26:21 +0000533}
534
535
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000536#ifdef ENABLE_DEBUGGER_SUPPORT
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000537bool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) {
538 // Precondition: code has been parsed. Postcondition: the code field in
539 // the compilation info is set if compilation succeeded.
540 bool succeeded = MakeCode(info);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000541 if (!info->shared_info().is_null()) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000542 Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope(),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000543 info->zone());
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +0000544 info->shared_info()->set_scope_info(*scope_info);
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +0000545 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000546 return succeeded;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000547}
548#endif
549
550
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000551static bool DebuggerWantsEagerCompilation(CompilationInfo* info,
552 bool allow_lazy_without_ctx = false) {
553 return LiveEditFunctionTracker::IsActive(info->isolate()) ||
554 (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx);
555}
556
557
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000558static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000559 Isolate* isolate = info->isolate();
560 PostponeInterruptsScope postpone(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000561
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000562 ASSERT(!isolate->native_context().is_null());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000563 Handle<Script> script = info->script();
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000564 // TODO(svenpanne) Obscure place for this, perhaps move to OnBeforeCompile?
565 FixedArray* array = isolate->native_context()->embedder_data();
566 script->set_context_data(array->get(0));
ager@chromium.orge2902be2009-06-08 12:21:35 +0000567
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000568#ifdef ENABLE_DEBUGGER_SUPPORT
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000569 if (info->is_eval()) {
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000570 script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
ager@chromium.orge2902be2009-06-08 12:21:35 +0000571 // For eval scripts add information on the function from which eval was
572 // called.
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000573 if (info->is_eval()) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000574 StackTraceFrameIterator it(isolate);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000575 if (!it.done()) {
danno@chromium.org169691d2013-07-15 08:01:13 +0000576 script->set_eval_from_shared(it.frame()->function()->shared());
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000577 Code* code = it.frame()->LookupCode();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000578 int offset = static_cast<int>(
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000579 it.frame()->pc() - code->instruction_start());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000580 script->set_eval_from_instructions_offset(Smi::FromInt(offset));
581 }
ager@chromium.orge2902be2009-06-08 12:21:35 +0000582 }
583 }
584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000585 // Notify debugger
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000586 isolate->debugger()->OnBeforeCompile(script);
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000587#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000588
589 // Only allow non-global compiles for eval.
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000590 ASSERT(info->is_eval() || info->is_global());
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000591 {
592 Parser parser(info);
593 if ((info->pre_parse_data() != NULL ||
594 String::cast(script->source())->length() > FLAG_min_preparse_length) &&
595 !DebuggerWantsEagerCompilation(info))
596 parser.set_allow_lazy(true);
597 if (!parser.Parse()) {
598 return Handle<SharedFunctionInfo>::null();
599 }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000600 }
kasper.lund212ac232008-07-16 07:07:30 +0000601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000602 // Measure how long it takes to do the compilation; only take the
603 // rest of the function into account to avoid overlap with the
604 // parsing statistics.
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000605 HistogramTimer* rate = info->is_eval()
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000606 ? info->isolate()->counters()->compile_eval()
607 : info->isolate()->counters()->compile();
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000608 HistogramTimerScope timer(rate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000609
610 // Compile the code.
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000611 FunctionLiteral* lit = info->function();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000612 LiveEditFunctionTracker live_edit_tracker(isolate, lit);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000613 if (!MakeCode(info)) {
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000614 if (!isolate->has_pending_exception()) isolate->StackOverflow();
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000615 return Handle<SharedFunctionInfo>::null();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616 }
617
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000618 // Allocate function.
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000619 ASSERT(!info->code().is_null());
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000620 Handle<SharedFunctionInfo> result =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000621 isolate->factory()->NewSharedFunctionInfo(
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000622 lit->name(),
623 lit->materialized_literal_count(),
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000624 lit->is_generator(),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000625 info->code(),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000626 ScopeInfo::Create(info->scope(), info->zone()));
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000627
628 ASSERT_EQ(RelocInfo::kNoPosition, lit->function_token_position());
629 Compiler::SetFunctionInfo(result, lit, true, script);
630
ager@chromium.orgb26c50a2010-03-26 09:27:16 +0000631 if (script->name()->IsString()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000632 PROFILE(isolate, CodeCreateEvent(
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000633 info->is_eval()
634 ? Logger::EVAL_TAG
635 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
636 *info->code(),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000637 *result,
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000638 info,
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000639 String::cast(script->name())));
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000640 GDBJIT(AddCode(Handle<String>(String::cast(script->name())),
641 script,
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000642 info->code(),
643 info));
ager@chromium.orgb26c50a2010-03-26 09:27:16 +0000644 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000645 PROFILE(isolate, CodeCreateEvent(
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000646 info->is_eval()
647 ? Logger::EVAL_TAG
648 : Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
649 *info->code(),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000650 *result,
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000651 info,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000652 isolate->heap()->empty_string()));
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000653 GDBJIT(AddCode(Handle<String>(), script, info->code(), info));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000654 }
655
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000656 // Hint to the runtime system used when allocating space for initial
657 // property space by setting the expected number of properties for
658 // the instances of the function.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000659 SetExpectedNofPropertiesFromEstimate(result, lit->expected_property_count());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000660
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000661 script->set_compilation_state(Script::COMPILATION_STATE_COMPILED);
rossberg@chromium.org2c067b12012-03-19 11:01:52 +0000662
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000663#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000664 // Notify debugger
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000665 isolate->debugger()->OnAfterCompile(
666 script, Debugger::NO_AFTER_COMPILE_FLAGS);
ager@chromium.org65dad4b2009-04-23 08:48:43 +0000667#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000668
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000669 live_edit_tracker.RecordFunctionInfo(result, lit, info->zone());
kmillikin@chromium.org4111b802010-05-03 10:34:42 +0000670
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000671 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000672}
673
674
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000675Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
676 Handle<Object> script_name,
677 int line_offset,
678 int column_offset,
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000679 bool is_shared_cross_origin,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000680 Handle<Context> context,
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000681 v8::Extension* extension,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000682 ScriptDataImpl* pre_data,
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000683 Handle<Object> script_data,
684 NativesFlag natives) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000685 Isolate* isolate = source->GetIsolate();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000686 int source_length = source->length();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000687 isolate->counters()->total_load_size()->Increment(source_length);
688 isolate->counters()->total_compile_size()->Increment(source_length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000689
690 // The VM is in the COMPILER state until exiting this function.
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000691 VMState<COMPILER> state(isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000692
693 CompilationCache* compilation_cache = isolate->compilation_cache();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000694
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000695 // Do a lookup in the compilation cache but not for extensions.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000696 Handle<SharedFunctionInfo> result;
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000697 if (extension == NULL) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000698 result = compilation_cache->LookupScript(source,
699 script_name,
700 line_offset,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000701 column_offset,
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000702 is_shared_cross_origin,
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000703 context);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000704 }
705
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000706 if (result.is_null()) {
sgjesse@chromium.org2ec107f2010-09-13 09:19:46 +0000707 // No cache entry found. Do pre-parsing, if it makes sense, and compile
708 // the script.
709 // Building preparse data that is only used immediately after is only a
710 // saving if we might skip building the AST for lazily compiled functions.
711 // I.e., preparse data isn't relevant when the lazy flag is off, and
712 // for small sources, odds are that there aren't many functions
713 // that would be compiled lazily anyway, so we skip the preparse step
714 // in that case too.
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000715
716 // Create a script object describing the script to be compiled.
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +0000717 Handle<Script> script = isolate->factory()->NewScript(source);
fschneider@chromium.org086aac62010-03-17 13:18:24 +0000718 if (natives == NATIVES_CODE) {
719 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
720 }
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000721 if (!script_name.is_null()) {
722 script->set_name(*script_name);
723 script->set_line_offset(Smi::FromInt(line_offset));
724 script->set_column_offset(Smi::FromInt(column_offset));
725 }
danno@chromium.orgd3c42102013-08-01 16:58:23 +0000726 script->set_is_shared_cross_origin(is_shared_cross_origin);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000727
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000728 script->set_data(script_data.is_null() ? isolate->heap()->undefined_value()
ager@chromium.org5c838252010-02-19 08:53:10 +0000729 : *script_data);
730
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000731 // Compile the function and add it to the cache.
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000732 CompilationInfoWithZone info(script);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000733 info.MarkAsGlobal();
734 info.SetExtension(extension);
735 info.SetPreParseData(pre_data);
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000736 info.SetContext(context);
rossberg@chromium.org2c067b12012-03-19 11:01:52 +0000737 if (FLAG_use_strict) {
738 info.SetLanguageMode(FLAG_harmony_scoping ? EXTENDED_MODE : STRICT_MODE);
739 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000740 result = MakeFunctionInfo(&info);
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000741 if (extension == NULL && !result.is_null() && !result->dont_cache()) {
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000742 compilation_cache->PutScript(source, context, result);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000743 }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000744 } else {
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000745 if (result->ic_age() != isolate->heap()->global_ic_age()) {
746 result->ResetForNewContext(isolate->heap()->global_ic_age());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000747 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000748 }
749
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000750 if (result.is_null()) isolate->ReportPendingMessages();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000751 return result;
752}
753
754
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000755Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
756 Handle<Context> context,
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000757 bool is_global,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000758 LanguageMode language_mode,
svenpanne@chromium.org9faefa42013-03-08 13:13:16 +0000759 ParseRestriction restriction,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000760 int scope_position) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000761 Isolate* isolate = source->GetIsolate();
ager@chromium.orgc3e50d82008-11-05 11:53:10 +0000762 int source_length = source->length();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000763 isolate->counters()->total_eval_size()->Increment(source_length);
764 isolate->counters()->total_compile_size()->Increment(source_length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765
766 // The VM is in the COMPILER state until exiting this function.
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000767 VMState<COMPILER> state(isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000768
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000769 // Do a lookup in the compilation cache; if the entry is not there, invoke
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000770 // the compiler and add the result to the cache.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000771 Handle<SharedFunctionInfo> result;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000772 CompilationCache* compilation_cache = isolate->compilation_cache();
773 result = compilation_cache->LookupEval(source,
774 context,
775 is_global,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000776 language_mode,
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000777 scope_position);
ager@chromium.orgadd848f2009-08-13 12:44:13 +0000778
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000779 if (result.is_null()) {
780 // Create a script object describing the script to be compiled.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 Handle<Script> script = isolate->factory()->NewScript(source);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000782 CompilationInfoWithZone info(script);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000783 info.MarkAsEval();
784 if (is_global) info.MarkAsGlobal();
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000785 info.SetLanguageMode(language_mode);
svenpanne@chromium.org9faefa42013-03-08 13:13:16 +0000786 info.SetParseRestriction(restriction);
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000787 info.SetContext(context);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000788 result = MakeFunctionInfo(&info);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000789 if (!result.is_null()) {
yangguo@chromium.org56454712012-02-16 15:33:53 +0000790 // Explicitly disable optimization for eval code. We're not yet prepared
791 // to handle eval-code in the optimizing compiler.
danno@chromium.org59400602013-08-13 17:09:37 +0000792 result->DisableOptimization(kEval);
yangguo@chromium.org56454712012-02-16 15:33:53 +0000793
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000794 // If caller is strict mode, the result must be in strict mode or
795 // extended mode as well, but not the other way around. Consider:
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000796 // eval("'use strict'; ...");
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000797 ASSERT(language_mode != STRICT_MODE || !result->is_classic_mode());
798 // If caller is in extended mode, the result must also be in
799 // extended mode.
800 ASSERT(language_mode != EXTENDED_MODE ||
801 result->is_extended_mode());
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000802 if (!result->dont_cache()) {
803 compilation_cache->PutEval(
804 source, context, is_global, result, scope_position);
805 }
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000806 }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000807 } else {
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000808 if (result->ic_age() != isolate->heap()->global_ic_age()) {
809 result->ResetForNewContext(isolate->heap()->global_ic_age());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000810 }
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000811 }
ager@chromium.org8bb60582008-12-11 12:02:20 +0000812
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000813 return result;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814}
815
816
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000817static bool InstallFullCode(CompilationInfo* info) {
818 // Update the shared function info with the compiled code and the
819 // scope info. Please note, that the order of the shared function
820 // info initialization is important since set_scope_info might
821 // trigger a GC, causing the ASSERT below to be invalid if the code
822 // was flushed. By setting the code object last we avoid this.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000823 Handle<SharedFunctionInfo> shared = info->shared_info();
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000824 Handle<Code> code = info->code();
danno@chromium.org59400602013-08-13 17:09:37 +0000825 CHECK(code->kind() == Code::FUNCTION);
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000826 Handle<JSFunction> function = info->closure();
827 Handle<ScopeInfo> scope_info =
828 ScopeInfo::Create(info->scope(), info->zone());
829 shared->set_scope_info(*scope_info);
yangguo@chromium.org9768bf12013-01-11 14:51:07 +0000830 shared->ReplaceCode(*code);
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000831 if (!function.is_null()) {
832 function->ReplaceCode(*code);
833 ASSERT(!function->IsOptimized());
834 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000835
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000836 // Set the expected number of properties for instances.
837 FunctionLiteral* lit = info->function();
838 int expected = lit->expected_property_count();
839 SetExpectedNofPropertiesFromEstimate(shared, expected);
840
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000841 // Check the function has compiled code.
842 ASSERT(shared->is_compiled());
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +0000843 shared->set_dont_optimize_reason(lit->dont_optimize_reason());
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000844 shared->set_dont_inline(lit->flags()->Contains(kDontInline));
845 shared->set_ast_node_count(lit->ast_node_count());
846
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000847 if (info->isolate()->use_crankshaft() &&
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000848 !function.is_null() &&
849 !shared->optimization_disabled()) {
850 // If we're asked to always optimize, we compile the optimized
851 // version of the function right away - unless the debugger is
852 // active as it makes no sense to compile optimized code then.
853 if (FLAG_always_opt &&
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000854 !info->isolate()->DebuggerHasBreakPoints()) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000855 CompilationInfoWithZone optimized(function);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000856 optimized.SetOptimizing(BailoutId::None());
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000857 return Compiler::CompileLazy(&optimized);
858 }
859 }
860 return true;
861}
862
863
864static void InstallCodeCommon(CompilationInfo* info) {
865 Handle<SharedFunctionInfo> shared = info->shared_info();
866 Handle<Code> code = info->code();
867 ASSERT(!code.is_null());
868
869 // Set optimizable to false if this is disallowed by the shared
870 // function info, e.g., we might have flushed the code and must
871 // reset this bit when lazy compiling the code again.
872 if (shared->optimization_disabled()) code->set_optimizable(false);
873
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +0000874 if (shared->code() == *code) {
875 // Do not send compilation event for the same code twice.
876 return;
877 }
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000878 Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info, shared);
879}
880
881
882static void InsertCodeIntoOptimizedCodeMap(CompilationInfo* info) {
883 Handle<Code> code = info->code();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000884 if (code->kind() != Code::OPTIMIZED_FUNCTION) return; // Nothing to do.
885
886 // Cache non-OSR optimized code.
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000887 if (FLAG_cache_optimized_code && !info->is_osr()) {
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000888 Handle<JSFunction> function = info->closure();
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000889 Handle<SharedFunctionInfo> shared(function->shared());
890 Handle<FixedArray> literals(function->literals());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000891 Handle<Context> native_context(function->context()->native_context());
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000892 SharedFunctionInfo::AddToOptimizedCodeMap(
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000893 shared, native_context, code, literals);
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000894 }
895}
896
897
898static bool InstallCodeFromOptimizedCodeMap(CompilationInfo* info) {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000899 if (!info->IsOptimizing()) return false; // Nothing to look up.
900
901 // Lookup non-OSR optimized code.
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000902 if (FLAG_cache_optimized_code && !info->is_osr()) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000903 Handle<SharedFunctionInfo> shared = info->shared_info();
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000904 Handle<JSFunction> function = info->closure();
905 ASSERT(!function.is_null());
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000906 Handle<Context> native_context(function->context()->native_context());
907 int index = shared->SearchOptimizedCodeMap(*native_context);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000908 if (index > 0) {
909 if (FLAG_trace_opt) {
ulan@chromium.org906e2fb2013-05-14 08:14:38 +0000910 PrintF("[found optimized code for ");
911 function->ShortPrint();
912 PrintF("]\n");
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000913 }
ulan@chromium.orgd9e468a2012-06-25 09:47:40 +0000914 // Caching of optimized code enabled and optimized code found.
915 shared->InstallFromOptimizedCodeMap(*function, index);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000916 return true;
917 }
918 }
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000919 return false;
920}
921
922
923bool Compiler::CompileLazy(CompilationInfo* info) {
924 Isolate* isolate = info->isolate();
925
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000926 // The VM is in the COMPILER state until exiting this function.
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000927 VMState<COMPILER> state(isolate);
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000928
929 PostponeInterruptsScope postpone(isolate);
930
931 Handle<SharedFunctionInfo> shared = info->shared_info();
932 int compiled_size = shared->end_position() - shared->start_position();
933 isolate->counters()->total_compile_size()->Increment(compiled_size);
934
935 if (InstallCodeFromOptimizedCodeMap(info)) return true;
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000936
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000937 // Generate the AST for the lazily compiled function.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000938 if (Parser::Parse(info)) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000939 // Measure how long it takes to do the lazy compilation; only take the
940 // rest of the function into account to avoid overlap with the lazy
941 // parsing statistics.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000942 HistogramTimerScope timer(isolate->counters()->compile_lazy());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000943
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000944 // After parsing we know the function's language mode. Remember it.
945 LanguageMode language_mode = info->function()->language_mode();
946 info->SetLanguageMode(language_mode);
947 shared->set_language_mode(language_mode);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000948
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000949 // Compile the code.
950 if (!MakeCode(info)) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000951 if (!isolate->has_pending_exception()) {
952 isolate->StackOverflow();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000953 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000954 } else {
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000955 InstallCodeCommon(info);
kasper.lund212ac232008-07-16 07:07:30 +0000956
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000957 if (info->IsOptimizing()) {
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000958 // Optimized code successfully created.
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000959 Handle<Code> code = info->code();
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000960 ASSERT(shared->scope_info() != ScopeInfo::Empty(isolate));
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000961 // TODO(titzer): Only replace the code if it was not an OSR compile.
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000962 info->closure()->ReplaceCode(*code);
963 InsertCodeIntoOptimizedCodeMap(info);
964 return true;
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000965 } else if (!info->is_osr()) {
966 // Compilation failed. Replace with full code if not OSR compile.
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000967 return InstallFullCode(info);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000968 }
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000969 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970 }
971
ager@chromium.orgb61a0d12010-10-13 08:35:23 +0000972 ASSERT(info->code().is_null());
973 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000974}
975
976
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000977bool Compiler::RecompileConcurrent(Handle<JSFunction> closure,
978 uint32_t osr_pc_offset) {
979 bool compiling_for_osr = (osr_pc_offset != 0);
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000980
981 Isolate* isolate = closure->GetIsolate();
rossberg@chromium.org92597162013-08-23 13:28:00 +0000982 // Here we prepare compile data for the concurrent recompilation thread, but
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000983 // this still happens synchronously and interrupts execution.
984 Logger::TimerEventScope timer(
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000985 isolate, Logger::TimerEventScope::v8_recompile_synchronous);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000986
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000987 if (!isolate->optimizing_compiler_thread()->IsQueueAvailable()) {
rossberg@chromium.org92597162013-08-23 13:28:00 +0000988 if (FLAG_trace_concurrent_recompilation) {
danno@chromium.org59400602013-08-13 17:09:37 +0000989 PrintF(" ** Compilation queue full, will retry optimizing ");
990 closure->PrintName();
991 PrintF(" on next run.\n");
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000992 }
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000993 return false;
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000994 }
995
996 SmartPointer<CompilationInfo> info(new CompilationInfoWithZone(closure));
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000997 Handle<SharedFunctionInfo> shared = info->shared_info();
998
999 if (compiling_for_osr) {
1000 BailoutId osr_ast_id =
1001 shared->code()->TranslatePcOffsetToAstId(osr_pc_offset);
1002 ASSERT(!osr_ast_id.IsNone());
1003 info->SetOptimizing(osr_ast_id);
1004 info->set_osr_pc_offset(osr_pc_offset);
1005
1006 if (FLAG_trace_osr) {
1007 PrintF("[COSR - attempt to queue ");
1008 closure->PrintName();
1009 PrintF(" at AST id %d]\n", osr_ast_id.ToInt());
1010 }
1011 } else {
1012 info->SetOptimizing(BailoutId::None());
1013 }
1014
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001015 VMState<COMPILER> state(isolate);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001016 PostponeInterruptsScope postpone(isolate);
1017
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001018 int compiled_size = shared->end_position() - shared->start_position();
1019 isolate->counters()->total_compile_size()->Increment(compiled_size);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001020
1021 {
1022 CompilationHandleScope handle_scope(*info);
1023
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001024 if (!compiling_for_osr && InstallCodeFromOptimizedCodeMap(*info)) {
1025 return true;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001026 }
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001027
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001028 if (Parser::Parse(*info)) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001029 LanguageMode language_mode = info->function()->language_mode();
1030 info->SetLanguageMode(language_mode);
1031 shared->set_language_mode(language_mode);
1032 info->SaveHandles();
1033
1034 if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) {
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001035 RecompileJob* job = new(info->zone()) RecompileJob(*info);
1036 RecompileJob::Status status = job->CreateGraph();
1037 if (status == RecompileJob::SUCCEEDED) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00001038 info.Detach();
1039 shared->code()->set_profiler_ticks(0);
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001040 isolate->optimizing_compiler_thread()->QueueForOptimization(job);
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001041 ASSERT(!isolate->has_pending_exception());
1042 return true;
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001043 } else if (status == RecompileJob::BAILED_OUT) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001044 isolate->clear_pending_exception();
1045 InstallFullCode(*info);
1046 }
1047 }
1048 }
1049 }
1050
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001051 if (isolate->has_pending_exception()) isolate->clear_pending_exception();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001052 return false;
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001053}
1054
1055
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001056Handle<Code> Compiler::InstallOptimizedCode(RecompileJob* job) {
1057 SmartPointer<CompilationInfo> info(job->info());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00001058 // The function may have already been optimized by OSR. Simply continue.
1059 // Except when OSR already disabled optimization for some reason.
1060 if (info->shared_info()->optimization_disabled()) {
danno@chromium.org41728482013-06-12 22:31:22 +00001061 info->AbortOptimization();
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00001062 InstallFullCode(*info);
rossberg@chromium.org92597162013-08-23 13:28:00 +00001063 if (FLAG_trace_concurrent_recompilation) {
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00001064 PrintF(" ** aborting optimization for ");
1065 info->closure()->PrintName();
1066 PrintF(" as it has been disabled.\n");
1067 }
dslomov@chromium.org4a35c5a2013-09-13 07:28:52 +00001068 ASSERT(!info->closure()->IsInRecompileQueue());
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +00001069 return Handle<Code>::null();
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00001070 }
ulan@chromium.org750145a2013-03-07 15:14:13 +00001071
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00001072 Isolate* isolate = info->isolate();
danno@chromium.orgca29dd82013-04-26 11:59:48 +00001073 VMState<COMPILER> state(isolate);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +00001074 Logger::TimerEventScope timer(
danno@chromium.org1f34ad32012-11-26 14:53:56 +00001075 isolate, Logger::TimerEventScope::v8_recompile_synchronous);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001076 // If crankshaft succeeded, install the optimized code else install
1077 // the unoptimized code.
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001078 RecompileJob::Status status = job->last_status();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001079 if (info->HasAbortedDueToDependencyChange()) {
danno@chromium.org59400602013-08-13 17:09:37 +00001080 info->set_bailout_reason(kBailedOutDueToDependencyChange);
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001081 status = job->AbortOptimization();
1082 } else if (status != RecompileJob::SUCCEEDED) {
danno@chromium.org59400602013-08-13 17:09:37 +00001083 info->set_bailout_reason(kFailedBailedOutLastTime);
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001084 status = job->AbortOptimization();
machenbach@chromium.orgc1789ee2013-07-05 07:09:57 +00001085 } else if (isolate->DebuggerHasBreakPoints()) {
danno@chromium.org59400602013-08-13 17:09:37 +00001086 info->set_bailout_reason(kDebuggerIsActive);
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001087 status = job->AbortOptimization();
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001088 } else {
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001089 status = job->GenerateAndInstallCode();
1090 ASSERT(status == RecompileJob::SUCCEEDED ||
1091 status == RecompileJob::BAILED_OUT);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001092 }
1093
1094 InstallCodeCommon(*info);
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001095 if (status == RecompileJob::SUCCEEDED) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001096 Handle<Code> code = info->code();
hpayer@chromium.org8432c912013-02-28 15:55:26 +00001097 ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty(isolate));
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001098 info->closure()->ReplaceCode(*code);
1099 if (info->shared_info()->SearchOptimizedCodeMap(
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001100 info->closure()->context()->native_context()) == -1) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001101 InsertCodeIntoOptimizedCodeMap(*info);
1102 }
rossberg@chromium.org92597162013-08-23 13:28:00 +00001103 if (FLAG_trace_concurrent_recompilation) {
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001104 PrintF(" ** Optimized code for ");
1105 info->closure()->PrintName();
1106 PrintF(" installed.\n");
1107 }
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001108 } else {
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +00001109 info->AbortOptimization();
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001110 InstallFullCode(*info);
1111 }
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001112 // Optimized code is finally replacing unoptimized code. Reset the latter's
1113 // profiler ticks to prevent too soon re-opt after a deopt.
1114 info->shared_info()->code()->set_profiler_ticks(0);
dslomov@chromium.org4a35c5a2013-09-13 07:28:52 +00001115 ASSERT(!info->closure()->IsInRecompileQueue());
machenbach@chromium.org8e36b5b2013-09-26 07:36:30 +00001116 return (status == RecompileJob::SUCCEEDED) ? info->code()
1117 : Handle<Code>::null();
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +00001118}
1119
1120
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001121Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001122 Handle<Script> script) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001123 // Precondition: code has been parsed and scopes have been analyzed.
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001124 CompilationInfoWithZone info(script);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001125 info.SetFunction(literal);
1126 info.SetScope(literal->scope());
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001127 info.SetLanguageMode(literal->scope()->language_mode());
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001128
hpayer@chromium.org8432c912013-02-28 15:55:26 +00001129 Isolate* isolate = info.isolate();
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00001130 Factory* factory = isolate->factory();
hpayer@chromium.org8432c912013-02-28 15:55:26 +00001131 LiveEditFunctionTracker live_edit_tracker(isolate, literal);
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001132 // Determine if the function can be lazily compiled. This is necessary to
1133 // allow some of our builtin JS files to be lazily compiled. These
1134 // builtins cannot be handled lazily by the parser, since we have to know
1135 // if a function uses the special natives syntax, which is something the
1136 // parser records.
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001137 // If the debugger requests compilation for break points, we cannot be
1138 // aggressive about lazy compilation, because it might trigger compilation
1139 // of functions without an outer context when setting a breakpoint through
jkummerow@chromium.org78502a92012-09-06 13:50:42 +00001140 // Debug::FindSharedFunctionInfoInScript.
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001141 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext();
ager@chromium.org5c838252010-02-19 08:53:10 +00001142 bool allow_lazy = literal->AllowsLazyCompilation() &&
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00001143 !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001144
hpayer@chromium.org8432c912013-02-28 15:55:26 +00001145 Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate));
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00001146
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001147 // Generate code
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001148 if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) {
hpayer@chromium.org8432c912013-02-28 15:55:26 +00001149 Handle<Code> code = isolate->builtins()->LazyCompile();
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001150 info.SetCode(code);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001151 } else if (GenerateCode(&info)) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001152 ASSERT(!info.code().is_null());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001153 scope_info = ScopeInfo::Create(info.scope(), info.zone());
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001154 } else {
1155 return Handle<SharedFunctionInfo>::null();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001156 }
1157
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00001158 // Create a shared function info object.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001159 Handle<SharedFunctionInfo> result =
verwaest@chromium.orgd4be0f02013-06-05 13:39:03 +00001160 factory->NewSharedFunctionInfo(literal->name(),
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001161 literal->materialized_literal_count(),
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00001162 literal->is_generator(),
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001163 info.code(),
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00001164 scope_info);
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001165 SetFunctionInfo(result, literal, false, script);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001166 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001167 result->set_allows_lazy_compilation(allow_lazy);
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001168 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001169
1170 // Set the expected number of properties for instances and return
1171 // the resulting function.
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001172 SetExpectedNofPropertiesFromEstimate(result,
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001173 literal->expected_property_count());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001174 live_edit_tracker.RecordFunctionInfo(result, literal, info.zone());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001175 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001176}
1177
1178
1179// Sets the function info on a function.
1180// The start_position points to the first '(' character after the function name
1181// in the full script source. When counting characters in the script source the
1182// the first character is number 0 (not 1).
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001183void Compiler::SetFunctionInfo(Handle<SharedFunctionInfo> function_info,
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001184 FunctionLiteral* lit,
1185 bool is_toplevel,
1186 Handle<Script> script) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001187 function_info->set_length(lit->parameter_count());
1188 function_info->set_formal_parameter_count(lit->parameter_count());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001189 function_info->set_script(*script);
1190 function_info->set_function_token_position(lit->function_token_position());
1191 function_info->set_start_position(lit->start_position());
1192 function_info->set_end_position(lit->end_position());
1193 function_info->set_is_expression(lit->is_expression());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001194 function_info->set_is_anonymous(lit->is_anonymous());
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001195 function_info->set_is_toplevel(is_toplevel);
1196 function_info->set_inferred_name(*lit->inferred_name());
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00001197 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001198 function_info->set_allows_lazy_compilation_without_context(
1199 lit->AllowsLazyCompilationWithoutContext());
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00001200 function_info->set_language_mode(lit->language_mode());
whesse@chromium.org7b260152011-06-20 15:33:18 +00001201 function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
1202 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001203 function_info->set_ast_node_count(lit->ast_node_count());
yangguo@chromium.org56454712012-02-16 15:33:53 +00001204 function_info->set_is_function(lit->is_function());
jkummerow@chromium.org2c9426b2013-09-05 16:31:13 +00001205 function_info->set_dont_optimize_reason(lit->dont_optimize_reason());
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001206 function_info->set_dont_inline(lit->flags()->Contains(kDontInline));
danno@chromium.org81cac2b2012-07-10 11:28:27 +00001207 function_info->set_dont_cache(lit->flags()->Contains(kDontCache));
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001208 function_info->set_is_generator(lit->is_generator());
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001209}
1210
1211
ager@chromium.orgb26c50a2010-03-26 09:27:16 +00001212void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001213 CompilationInfo* info,
1214 Handle<SharedFunctionInfo> shared) {
1215 // SharedFunctionInfo is passed separately, because if CompilationInfo
1216 // was created using Script object, it will not have it.
1217
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001218 // Log the code generation. If source information is available include
1219 // script name and line number. Check explicitly whether logging is
1220 // enabled as finding the line number is not free.
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00001221 if (info->isolate()->logger()->is_logging_code_events() ||
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00001222 info->isolate()->cpu_profiler()->is_profiling()) {
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001223 Handle<Script> script = info->script();
1224 Handle<Code> code = info->code();
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001225 if (*code == info->isolate()->builtins()->builtin(Builtins::kLazyCompile))
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001226 return;
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001227 int line_num = GetScriptLineNumber(script, shared->start_position()) + 1;
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001228 int column_num =
1229 GetScriptColumnNumber(script, shared->start_position()) + 1;
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001230 USE(line_num);
ager@chromium.org5c838252010-02-19 08:53:10 +00001231 if (script->name()->IsString()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001232 PROFILE(info->isolate(),
1233 CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001234 *code,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001235 *shared,
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001236 info,
danno@chromium.orgf95d4b92013-06-13 14:40:17 +00001237 String::cast(script->name()),
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001238 line_num,
1239 column_num));
ager@chromium.org5c838252010-02-19 08:53:10 +00001240 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001241 PROFILE(info->isolate(),
1242 CodeCreateEvent(Logger::ToNativeByScript(tag, *script),
ager@chromium.orgb61a0d12010-10-13 08:35:23 +00001243 *code,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001244 *shared,
jkummerow@chromium.org4e308cf2013-05-17 13:39:16 +00001245 info,
mstarzinger@chromium.orge0e1b0d2013-07-08 08:38:06 +00001246 info->isolate()->heap()->empty_string(),
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001247 line_num,
1248 column_num));
ager@chromium.org5c838252010-02-19 08:53:10 +00001249 }
1250 }
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001251
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001252 GDBJIT(AddCode(Handle<String>(shared->DebugName()),
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001253 Handle<Script>(info->script()),
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001254 Handle<Code>(info->code()),
1255 info));
ager@chromium.org5c838252010-02-19 08:53:10 +00001256}
ager@chromium.org5c838252010-02-19 08:53:10 +00001257
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001258
1259CompilationPhase::CompilationPhase(const char* name, CompilationInfo* info)
1260 : name_(name), info_(info), zone_(info->isolate()) {
1261 if (FLAG_hydrogen_stats) {
1262 info_zone_start_allocation_size_ = info->zone()->allocation_size();
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001263 timer_.Start();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001264 }
1265}
1266
1267
1268CompilationPhase::~CompilationPhase() {
1269 if (FLAG_hydrogen_stats) {
1270 unsigned size = zone()->allocation_size();
1271 size += info_->zone()->allocation_size() - info_zone_start_allocation_size_;
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +00001272 isolate()->GetHStatistics()->SaveTiming(name_, timer_.Elapsed(), size);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001273 }
1274}
1275
1276
1277bool CompilationPhase::ShouldProduceTraceOutput() const {
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +00001278 // Trace if the appropriate trace flag is set and the phase name's first
1279 // character is in the FLAG_trace_phase command line parameter.
verwaest@chromium.org662436e2013-08-28 08:41:27 +00001280 AllowHandleDereference allow_deref;
jkummerow@chromium.org1e8da742013-08-26 17:13:35 +00001281 bool tracing_on = info()->IsStub()
1282 ? FLAG_trace_hydrogen_stubs
1283 : (FLAG_trace_hydrogen &&
1284 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter));
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +00001285 return (tracing_on &&
1286 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +00001287}
1288
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001289} } // namespace v8::internal