Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Side by Side Diff: src/compiler.cc

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler.h ('k') | src/contexts.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 17 matching lines...) Expand all
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "compiler.h" 30 #include "compiler.h"
31 31
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "codegen-inl.h" 33 #include "codegen-inl.h"
34 #include "compilation-cache.h" 34 #include "compilation-cache.h"
35 #include "data-flow.h" 35 #include "data-flow.h"
36 #include "debug.h" 36 #include "debug.h"
37 #include "full-codegen.h" 37 #include "full-codegen.h"
38 #include "hydrogen.h"
39 #include "lithium-allocator.h"
38 #include "liveedit.h" 40 #include "liveedit.h"
39 #include "oprofile-agent.h" 41 #include "oprofile-agent.h"
40 #include "parser.h" 42 #include "parser.h"
41 #include "rewriter.h" 43 #include "rewriter.h"
44 #include "runtime-profiler.h"
42 #include "scopeinfo.h" 45 #include "scopeinfo.h"
43 #include "scopes.h" 46 #include "scopes.h"
47 #include "vm-state-inl.h"
44 48
45 namespace v8 { 49 namespace v8 {
46 namespace internal { 50 namespace internal {
47 51
48 52
49 CompilationInfo::CompilationInfo(Handle<Script> script) 53 CompilationInfo::CompilationInfo(Handle<Script> script)
50 : isolate_(script->GetIsolate()), 54 : isolate_(script->GetIsolate()),
51 flags_(0), 55 flags_(0),
52 function_(NULL), 56 function_(NULL),
53 scope_(NULL), 57 scope_(NULL),
54 script_(script), 58 script_(script),
55 extension_(NULL), 59 extension_(NULL),
56 pre_parse_data_(NULL) { 60 pre_parse_data_(NULL),
61 supports_deoptimization_(false),
62 osr_ast_id_(AstNode::kNoNumber) {
63 Initialize(NONOPT);
57 } 64 }
58 65
59 66
60 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info) 67 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info)
61 : isolate_(shared_info->GetIsolate()), 68 : isolate_(shared_info->GetIsolate()),
62 flags_(IsLazy::encode(true)), 69 flags_(IsLazy::encode(true)),
63 function_(NULL), 70 function_(NULL),
64 scope_(NULL), 71 scope_(NULL),
65 shared_info_(shared_info), 72 shared_info_(shared_info),
66 script_(Handle<Script>(Script::cast(shared_info->script()))), 73 script_(Handle<Script>(Script::cast(shared_info->script()))),
67 extension_(NULL), 74 extension_(NULL),
68 pre_parse_data_(NULL) { 75 pre_parse_data_(NULL),
76 supports_deoptimization_(false),
77 osr_ast_id_(AstNode::kNoNumber) {
78 Initialize(BASE);
69 } 79 }
70 80
71 81
72 CompilationInfo::CompilationInfo(Handle<JSFunction> closure) 82 CompilationInfo::CompilationInfo(Handle<JSFunction> closure)
73 : isolate_(closure->GetIsolate()), 83 : isolate_(closure->GetIsolate()),
74 flags_(IsLazy::encode(true)), 84 flags_(IsLazy::encode(true)),
75 function_(NULL), 85 function_(NULL),
76 scope_(NULL), 86 scope_(NULL),
77 closure_(closure), 87 closure_(closure),
78 shared_info_(Handle<SharedFunctionInfo>(closure->shared())), 88 shared_info_(Handle<SharedFunctionInfo>(closure->shared())),
79 script_(Handle<Script>(Script::cast(shared_info_->script()))), 89 script_(Handle<Script>(Script::cast(shared_info_->script()))),
80 extension_(NULL), 90 extension_(NULL),
81 pre_parse_data_(NULL) { 91 pre_parse_data_(NULL),
82 } 92 supports_deoptimization_(false),
83 93 osr_ast_id_(AstNode::kNoNumber) {
84 94 Initialize(BASE);
85 // For normal operation the syntax checker is used to determine whether to 95 }
86 // use the full compiler for top level code or not. However if the flag 96
87 // --always-full-compiler is specified or debugging is active the full 97
88 // compiler will be used for all code. 98 // Determine whether to use the full compiler for all code. If the flag
99 // --always-full-compiler is specified this is the case. For the virtual frame
100 // based compiler the full compiler is also used if a debugger is connected, as
101 // the code from the full compiler supports mode precise break points. For the
102 // crankshaft adaptive compiler debugging the optimized code is not possible at
103 // all. However crankshaft support recompilation of functions, so in this case
104 // the full compiler need not be be used if a debugger is attached, but only if
105 // break points has actually been set.
89 static bool AlwaysFullCompiler() { 106 static bool AlwaysFullCompiler() {
90 #ifdef ENABLE_DEBUGGER_SUPPORT 107 #ifdef ENABLE_DEBUGGER_SUPPORT
91 return FLAG_always_full_compiler || 108 Isolate* isolate = Isolate::Current();
92 Isolate::Current()->debugger()->IsDebuggerActive(); 109 if (V8::UseCrankshaft()) {
110 return FLAG_always_full_compiler || isolate->debug()->has_break_points();
111 } else {
112 return FLAG_always_full_compiler || isolate->debugger()->IsDebuggerActive();
113 }
93 #else 114 #else
94 return FLAG_always_full_compiler; 115 return FLAG_always_full_compiler;
95 #endif 116 #endif
96 } 117 }
97 118
98 119
120 static void FinishOptimization(Handle<JSFunction> function, int64_t start) {
121 int opt_count = function->shared()->opt_count();
122 function->shared()->set_opt_count(opt_count + 1);
123 if (!FLAG_trace_opt) return;
124
125 double ms = static_cast<double>(OS::Ticks() - start) / 1000;
126 PrintF("[optimizing: ");
127 function->PrintName();
128 PrintF(" / %" V8PRIxPTR, reinterpret_cast<intptr_t>(*function));
129 PrintF(" - took %0.3f ms]\n", ms);
130 }
131
132
133 static void AbortAndDisable(CompilationInfo* info) {
134 // Disable optimization for the shared function info and mark the
135 // code as non-optimizable. The marker on the shared function info
136 // is there because we flush non-optimized code thereby loosing the
137 // non-optimizable information for the code. When the code is
138 // regenerated and set on the shared function info it is marked as
139 // non-optimizable if optimization is disabled for the shared
140 // function info.
141 Handle<SharedFunctionInfo> shared = info->shared_info();
142 shared->set_optimization_disabled(true);
143 Handle<Code> code = Handle<Code>(shared->code());
144 ASSERT(code->kind() == Code::FUNCTION);
145 code->set_optimizable(false);
146 info->SetCode(code);
147 if (FLAG_trace_opt) {
148 PrintF("[disabled optimization for: ");
149 info->closure()->PrintName();
150 PrintF(" / %" V8PRIxPTR "]\n",
151 reinterpret_cast<intptr_t>(*info->closure()));
152 }
153 }
154
155
156 static bool MakeCrankshaftCode(CompilationInfo* info) {
157 // Test if we can optimize this function when asked to. We can only
158 // do this after the scopes are computed.
159 if (!info->AllowOptimize()) info->DisableOptimization();
160
161 // In case we are not optimizing simply return the code from
162 // the full code generator.
163 if (!info->IsOptimizing()) {
164 return FullCodeGenerator::MakeCode(info);
165 }
166
167 // We should never arrive here if there is not code object on the
168 // shared function object.
169 Handle<Code> code(info->shared_info()->code());
170 ASSERT(code->kind() == Code::FUNCTION);
171
172 // Fall back to using the full code generator if it's not possible
173 // to use the Hydrogen-based optimizing compiler. We already have
174 // generated code for this from the shared function object.
175 if (AlwaysFullCompiler() || !FLAG_use_hydrogen) {
176 info->SetCode(code);
177 return true;
178 }
179
180 // Limit the number of times we re-compile a functions with
181 // the optimizing compiler.
182 const int kMaxOptCount = FLAG_deopt_every_n_times == 0 ? 10 : 1000;
183 if (info->shared_info()->opt_count() > kMaxOptCount) {
184 AbortAndDisable(info);
185 // True indicates the compilation pipeline is still going, not
186 // necessarily that we optimized the code.
187 return true;
188 }
189
190 // Due to an encoding limit on LUnallocated operands in the Lithium
191 // language, we cannot optimize functions with too many formal parameters
192 // or perform on-stack replacement for function with too many
193 // stack-allocated local variables.
194 //
195 // The encoding is as a signed value, with parameters using the negative
196 // indices and locals the non-negative ones.
197 const int limit = LUnallocated::kMaxFixedIndices / 2;
198 Scope* scope = info->scope();
199 if (scope->num_parameters() > limit || scope->num_stack_slots() > limit) {
200 AbortAndDisable(info);
201 // True indicates the compilation pipeline is still going, not
202 // necessarily that we optimized the code.
203 return true;
204 }
205
206 // Take --hydrogen-filter into account.
207 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter);
208 Handle<String> name = info->function()->debug_name();
209 bool match = filter.is_empty() || name->IsEqualTo(filter);
210 if (!match) {
211 info->SetCode(code);
212 return true;
213 }
214
215 // Recompile the unoptimized version of the code if the current version
216 // doesn't have deoptimization support. Alternatively, we may decide to
217 // run the full code generator to get a baseline for the compile-time
218 // performance of the hydrogen-based compiler.
219 int64_t start = OS::Ticks();
220 bool should_recompile = !info->shared_info()->has_deoptimization_support();
221 if (should_recompile || FLAG_time_hydrogen) {
222 HPhase phase(HPhase::kFullCodeGen);
223 CompilationInfo unoptimized(info->shared_info());
224 // Note that we use the same AST that we will use for generating the
225 // optimized code.
226 unoptimized.SetFunction(info->function());
227 unoptimized.SetScope(info->scope());
228 if (should_recompile) unoptimized.EnableDeoptimizationSupport();
229 bool succeeded = FullCodeGenerator::MakeCode(&unoptimized);
230 if (should_recompile) {
231 if (!succeeded) return false;
232 Handle<SharedFunctionInfo> shared = info->shared_info();
233 shared->EnableDeoptimizationSupport(*unoptimized.code());
234 // The existing unoptimized code was replaced with the new one.
235 Compiler::RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
236 Handle<String>(shared->DebugName()),
237 shared->start_position(),
238 &unoptimized);
239 }
240 }
241
242 // Check that the unoptimized, shared code is ready for
243 // optimizations. When using the always_opt flag we disregard the
244 // optimizable marker in the code object and optimize anyway. This
245 // is safe as long as the unoptimized code has deoptimization
246 // support.
247 ASSERT(FLAG_always_opt || info->shared_info()->code()->optimizable());
248 ASSERT(info->shared_info()->has_deoptimization_support());
249
250 if (FLAG_trace_hydrogen) {
251 PrintF("-----------------------------------------------------------\n");
252 PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
253 HTracer::Instance()->TraceCompilation(info->function());
254 }
255
256 TypeFeedbackOracle oracle(Handle<Code>(info->shared_info()->code()));
257 HGraphBuilder builder(&oracle);
258 HPhase phase(HPhase::kTotal);
259 HGraph* graph = builder.CreateGraph(info);
260 if (graph != NULL && FLAG_build_lithium) {
261 Handle<Code> code = graph->Compile();
262 if (!code.is_null()) {
263 info->SetCode(code);
264 FinishOptimization(info->closure(), start);
265 return true;
266 }
267 }
268
269 // Compilation with the Hydrogen compiler failed. Keep using the
270 // shared code but mark it as unoptimizable.
271 AbortAndDisable(info);
272 // True indicates the compilation pipeline is still going, not necessarily
273 // that we optimized the code.
274 return true;
275 }
276
277
99 static bool MakeCode(CompilationInfo* info) { 278 static bool MakeCode(CompilationInfo* info) {
100 // Precondition: code has been parsed. Postcondition: the code field in 279 // Precondition: code has been parsed. Postcondition: the code field in
101 // the compilation info is set if compilation succeeded. 280 // the compilation info is set if compilation succeeded.
102 ASSERT(info->function() != NULL); 281 ASSERT(info->function() != NULL);
103 282
104 if (Rewriter::Rewrite(info) && 283 if (Rewriter::Rewrite(info) && Scope::Analyze(info)) {
105 Scope::Analyze(info) && 284 if (V8::UseCrankshaft()) return MakeCrankshaftCode(info);
106 Rewriter::Analyze(info)) { 285
107 // Generate code and return it. Code generator selection is governed by 286 // Generate code and return it. Code generator selection is governed by
108 // which backends are enabled and whether the function is considered 287 // which backends are enabled and whether the function is considered
109 // run-once code or not. 288 // run-once code or not.
110 // 289 //
111 // --full-compiler enables the dedicated backend for code we expect to 290 // --full-compiler enables the dedicated backend for code we expect to
112 // be run once 291 // be run once
113 // 292 //
114 // The normal choice of backend can be overridden with the flags 293 // The normal choice of backend can be overridden with the flags
115 // --always-full-compiler. 294 // --always-full-compiler.
116 Handle<SharedFunctionInfo> shared = info->shared_info(); 295 if (Rewriter::Analyze(info)) {
117 bool is_run_once = (shared.is_null()) 296 Handle<SharedFunctionInfo> shared = info->shared_info();
118 ? info->scope()->is_global_scope() 297 bool is_run_once = (shared.is_null())
119 : (shared->is_toplevel() || shared->try_full_codegen()); 298 ? info->scope()->is_global_scope()
120 bool can_use_full = 299 : (shared->is_toplevel() || shared->try_full_codegen());
121 FLAG_full_compiler && !info->function()->contains_loops(); 300 bool can_use_full =
122 if (AlwaysFullCompiler() || (is_run_once && can_use_full)) { 301 FLAG_full_compiler && !info->function()->contains_loops();
123 return FullCodeGenerator::MakeCode(info); 302 if (AlwaysFullCompiler() || (is_run_once && can_use_full)) {
124 } else { 303 return FullCodeGenerator::MakeCode(info);
125 AssignedVariablesAnalyzer ava; 304 } else {
126 return ava.Analyze(info) && CodeGenerator::MakeCode(info); 305 return AssignedVariablesAnalyzer::Analyze(info) &&
306 CodeGenerator::MakeCode(info);
307 }
127 } 308 }
128 } 309 }
129 310
130 return false; 311 return false;
131 } 312 }
132 313
133 314
134 #ifdef ENABLE_DEBUGGER_SUPPORT 315 #ifdef ENABLE_DEBUGGER_SUPPORT
135 bool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) { 316 bool Compiler::MakeCodeForLiveEdit(CompilationInfo* info) {
136 // Precondition: code has been parsed. Postcondition: the code field in 317 // Precondition: code has been parsed. Postcondition: the code field in
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 // Measure how long it takes to do the lazy compilation; only take the 562 // Measure how long it takes to do the lazy compilation; only take the
382 // rest of the function into account to avoid overlap with the lazy 563 // rest of the function into account to avoid overlap with the lazy
383 // parsing statistics. 564 // parsing statistics.
384 HistogramTimerScope timer(isolate->counters()->compile_lazy()); 565 HistogramTimerScope timer(isolate->counters()->compile_lazy());
385 566
386 // Compile the code. 567 // Compile the code.
387 if (!MakeCode(info)) { 568 if (!MakeCode(info)) {
388 isolate->StackOverflow(); 569 isolate->StackOverflow();
389 } else { 570 } else {
390 ASSERT(!info->code().is_null()); 571 ASSERT(!info->code().is_null());
572 Handle<Code> code = info->code();
573 Handle<JSFunction> function = info->closure();
391 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, 574 RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG,
392 Handle<String>(shared->DebugName()), 575 Handle<String>(shared->DebugName()),
393 shared->start_position(), 576 shared->start_position(),
394 info); 577 info);
395 578
396 // Update the shared function info with the compiled code and the 579 if (info->IsOptimizing()) {
397 // scope info. Please note, that the order of the sharedfunction 580 function->ReplaceCode(*code);
398 // initialization is important since SerializedScopeInfo::Create might 581 } else {
399 // trigger a GC, causing the ASSERT below to be invalid if the code 582 // Update the shared function info with the compiled code and the
400 // was flushed. By setting the code object last we avoid this. 583 // scope info. Please note, that the order of the shared function
401 Handle<SerializedScopeInfo> scope_info = 584 // info initialization is important since set_scope_info might
402 SerializedScopeInfo::Create(info->scope()); 585 // trigger a GC, causing the ASSERT below to be invalid if the code
403 shared->set_scope_info(*scope_info); 586 // was flushed. By settting the code object last we avoid this.
404 shared->set_code(*info->code()); 587 Handle<SerializedScopeInfo> scope_info =
405 if (!info->closure().is_null()) { 588 SerializedScopeInfo::Create(info->scope());
406 info->closure()->set_code(*info->code()); 589 shared->set_scope_info(*scope_info);
590 shared->set_code(*code);
591 if (!function.is_null()) {
592 function->ReplaceCode(*code);
593 ASSERT(!function->IsOptimized());
594 }
595
596 // Set the expected number of properties for instances.
597 FunctionLiteral* lit = info->function();
598 int expected = lit->expected_property_count();
599 SetExpectedNofPropertiesFromEstimate(shared, expected);
600
601 // Set the optimization hints after performing lazy compilation, as
602 // these are not set when the function is set up as a lazily
603 // compiled function.
604 shared->SetThisPropertyAssignmentsInfo(
605 lit->has_only_simple_this_property_assignments(),
606 *lit->this_property_assignments());
607
608 // Check the function has compiled code.
609 ASSERT(shared->is_compiled());
610 shared->set_code_age(0);
611
612 if (V8::UseCrankshaft() && info->AllowOptimize()) {
613 // If we're asked to always optimize, we compile the optimized
614 // version of the function right away - unless the debugger is
615 // active as it makes no sense to compile optimized code then.
616 if (FLAG_always_opt &&
617 !Isolate::Current()->debug()->has_break_points()) {
618 CompilationInfo optimized(function);
619 optimized.SetOptimizing(AstNode::kNoNumber);
620 return CompileLazy(&optimized);
621 } else if (isolate->compilation_cache()->ShouldOptimizeEagerly(
622 function)) {
623 isolate->runtime_profiler()->OptimizeSoon(*function);
624 }
625 }
407 } 626 }
408 627
409 // Set the expected number of properties for instances.
410 FunctionLiteral* lit = info->function();
411 SetExpectedNofPropertiesFromEstimate(shared,
412 lit->expected_property_count());
413
414 // Set the optimization hints after performing lazy compilation, as
415 // these are not set when the function is set up as a lazily compiled
416 // function.
417 shared->SetThisPropertyAssignmentsInfo(
418 lit->has_only_simple_this_property_assignments(),
419 *lit->this_property_assignments());
420
421 // Check the function has compiled code.
422 ASSERT(shared->is_compiled());
423 shared->set_code_age(0);
424 ASSERT(!info->code().is_null());
425 return true; 628 return true;
426 } 629 }
427 } 630 }
428 631
429 ASSERT(info->code().is_null()); 632 ASSERT(info->code().is_null());
430 return false; 633 return false;
431 } 634 }
432 635
433 636
434 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, 637 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
435 Handle<Script> script) { 638 Handle<Script> script) {
436 #ifdef DEBUG
437 // We should not try to compile the same function literal more than
438 // once.
439 literal->mark_as_compiled();
440 #endif
441
442 // Precondition: code has been parsed and scopes have been analyzed. 639 // Precondition: code has been parsed and scopes have been analyzed.
443 CompilationInfo info(script); 640 CompilationInfo info(script);
444 info.SetFunction(literal); 641 info.SetFunction(literal);
445 info.SetScope(literal->scope()); 642 info.SetScope(literal->scope());
446 643
447 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal); 644 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal);
448 // Determine if the function can be lazily compiled. This is necessary to 645 // Determine if the function can be lazily compiled. This is necessary to
449 // allow some of our builtin JS files to be lazily compiled. These 646 // allow some of our builtin JS files to be lazily compiled. These
450 // builtins cannot be handled lazily by the parser, since we have to know 647 // builtins cannot be handled lazily by the parser, since we have to know
451 // if a function uses the special natives syntax, which is something the 648 // if a function uses the special natives syntax, which is something the
452 // parser records. 649 // parser records.
453 bool allow_lazy = literal->AllowsLazyCompilation() && 650 bool allow_lazy = literal->AllowsLazyCompilation() &&
454 !LiveEditFunctionTracker::IsActive(info.isolate()); 651 !LiveEditFunctionTracker::IsActive(info.isolate());
455 652
456 Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty()); 653 Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty());
457 654
458 // Generate code 655 // Generate code
459 if (FLAG_lazy && allow_lazy) { 656 if (FLAG_lazy && allow_lazy) {
460 Handle<Code> code( 657 Handle<Code> code(
461 info.isolate()->builtins()->builtin(Builtins::LazyCompile)); 658 info.isolate()->builtins()->builtin(Builtins::LazyCompile));
462 info.SetCode(code); 659 info.SetCode(code);
463 } else { 660 } else {
464 // Generate code and return it. The way that the compilation mode 661 if (V8::UseCrankshaft()) {
465 // is controlled by the command-line flags is described in 662 if (!MakeCrankshaftCode(&info)) {
466 // the static helper function MakeCode.
467 //
468 // The bodies of function literals have not yet been visited by
469 // the AST analyzer.
470 if (!Rewriter::Analyze(&info)) return Handle<SharedFunctionInfo>::null();
471
472 bool is_run_once = literal->try_full_codegen();
473 bool use_full = FLAG_full_compiler && !literal->contains_loops();
474 if (AlwaysFullCompiler() || (use_full && is_run_once)) {
475 if (!FullCodeGenerator::MakeCode(&info)) {
476 return Handle<SharedFunctionInfo>::null(); 663 return Handle<SharedFunctionInfo>::null();
477 } 664 }
478 } else { 665 } else {
479 // We fall back to the classic V8 code generator. 666 // The bodies of function literals have not yet been visited by the
480 AssignedVariablesAnalyzer ava; 667 // AST optimizer/analyzer.
481 if (!ava.Analyze(&info)) return Handle<SharedFunctionInfo>::null(); 668 if (!Rewriter::Analyze(&info)) return Handle<SharedFunctionInfo>::null();
482 if (!CodeGenerator::MakeCode(&info)) { 669
483 return Handle<SharedFunctionInfo>::null(); 670 bool is_run_once = literal->try_full_codegen();
671 bool can_use_full = FLAG_full_compiler && !literal->contains_loops();
672
673 if (AlwaysFullCompiler() || (is_run_once && can_use_full)) {
674 if (!FullCodeGenerator::MakeCode(&info)) {
675 return Handle<SharedFunctionInfo>::null();
676 }
677 } else {
678 // We fall back to the classic V8 code generator.
679 if (!AssignedVariablesAnalyzer::Analyze(&info) ||
680 !CodeGenerator::MakeCode(&info)) {
681 return Handle<SharedFunctionInfo>::null();
682 }
484 } 683 }
485 } 684 }
685 ASSERT(!info.code().is_null());
486 686
487 // Function compilation complete. 687 // Function compilation complete.
488 RecordFunctionCompilation(Logger::FUNCTION_TAG, 688 RecordFunctionCompilation(Logger::FUNCTION_TAG,
489 literal->debug_name(), 689 literal->debug_name(),
490 literal->start_position(), 690 literal->start_position(),
491 &info); 691 &info);
492 scope_info = SerializedScopeInfo::Create(info.scope()); 692 scope_info = SerializedScopeInfo::Create(info.scope());
493 } 693 }
494 694
495 // Create a shared function info object. 695 // Create a shared function info object.
496 Handle<SharedFunctionInfo> result = 696 Handle<SharedFunctionInfo> result =
497 FACTORY->NewSharedFunctionInfo(literal->name(), 697 FACTORY->NewSharedFunctionInfo(literal->name(),
498 literal->materialized_literal_count(), 698 literal->materialized_literal_count(),
499 info.code(), 699 info.code(),
500 scope_info); 700 scope_info);
501 SetFunctionInfo(result, literal, false, script); 701 SetFunctionInfo(result, literal, false, script);
702 result->set_allows_lazy_compilation(allow_lazy);
502 703
503 // Set the expected number of properties for instances and return 704 // Set the expected number of properties for instances and return
504 // the resulting function. 705 // the resulting function.
505 SetExpectedNofPropertiesFromEstimate(result, 706 SetExpectedNofPropertiesFromEstimate(result,
506 literal->expected_property_count()); 707 literal->expected_property_count());
507 live_edit_tracker.RecordFunctionInfo(result, literal); 708 live_edit_tracker.RecordFunctionInfo(result, literal);
508 return result; 709 return result;
509 } 710 }
510 711
511 712
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 *code, 765 *code,
565 *name)); 766 *name));
566 OPROFILE(CreateNativeCodeRegion(*name, 767 OPROFILE(CreateNativeCodeRegion(*name,
567 code->instruction_start(), 768 code->instruction_start(),
568 code->instruction_size())); 769 code->instruction_size()));
569 } 770 }
570 } 771 }
571 } 772 }
572 773
573 } } // namespace v8::internal 774 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698