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

Side by Side Diff: src/compiler.cc

Issue 10543141: Enable lazy compilation for non-trivial outer contexts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Ulan Degenbaev. Created 8 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/ast.cc ('k') | src/debug.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 111
112 112
113 // Primitive functions are unlikely to be picked up by the stack-walking 113 // Primitive functions are unlikely to be picked up by the stack-walking
114 // profiler, so they trigger their own optimization when they're called 114 // profiler, so they trigger their own optimization when they're called
115 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time. 115 // for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time.
116 bool CompilationInfo::ShouldSelfOptimize() { 116 bool CompilationInfo::ShouldSelfOptimize() {
117 return FLAG_self_optimization && 117 return FLAG_self_optimization &&
118 FLAG_crankshaft && 118 FLAG_crankshaft &&
119 !function()->flags()->Contains(kDontSelfOptimize) && 119 !function()->flags()->Contains(kDontSelfOptimize) &&
120 !function()->flags()->Contains(kDontOptimize) && 120 !function()->flags()->Contains(kDontOptimize) &&
121 function()->scope()->AllowsLazyRecompilation() && 121 function()->scope()->AllowsLazyCompilation() &&
122 (shared_info().is_null() || !shared_info()->optimization_disabled()); 122 (shared_info().is_null() || !shared_info()->optimization_disabled());
123 } 123 }
124 124
125 125
126 void CompilationInfo::AbortOptimization() { 126 void CompilationInfo::AbortOptimization() {
127 Handle<Code> code(shared_info()->code()); 127 Handle<Code> code(shared_info()->code());
128 SetCode(code); 128 SetCode(code);
129 } 129 }
130 130
131 131
132 // Determine whether to use the full compiler for all code. If the flag 132 // Determine whether to use the full compiler for all code. If the flag
133 // --always-full-compiler is specified this is the case. For the virtual frame 133 // --always-full-compiler is specified this is the case. For the virtual frame
134 // based compiler the full compiler is also used if a debugger is connected, as 134 // based compiler the full compiler is also used if a debugger is connected, as
135 // the code from the full compiler supports mode precise break points. For the 135 // the code from the full compiler supports mode precise break points. For the
136 // crankshaft adaptive compiler debugging the optimized code is not possible at 136 // crankshaft adaptive compiler debugging the optimized code is not possible at
137 // all. However crankshaft support recompilation of functions, so in this case 137 // all. However crankshaft support recompilation of functions, so in this case
138 // the full compiler need not be be used if a debugger is attached, but only if 138 // the full compiler need not be be used if a debugger is attached, but only if
139 // break points has actually been set. 139 // break points has actually been set.
140 static bool is_debugging_active() { 140 static bool IsDebuggerActive(Isolate* isolate) {
141 #ifdef ENABLE_DEBUGGER_SUPPORT 141 #ifdef ENABLE_DEBUGGER_SUPPORT
142 Isolate* isolate = Isolate::Current();
143 return V8::UseCrankshaft() ? 142 return V8::UseCrankshaft() ?
144 isolate->debug()->has_break_points() : 143 isolate->debug()->has_break_points() :
145 isolate->debugger()->IsDebuggerActive(); 144 isolate->debugger()->IsDebuggerActive();
146 #else 145 #else
147 return false; 146 return false;
148 #endif 147 #endif
149 } 148 }
150 149
151 150
152 static bool AlwaysFullCompiler() { 151 static bool AlwaysFullCompiler(Isolate* isolate) {
153 return FLAG_always_full_compiler || is_debugging_active(); 152 return FLAG_always_full_compiler || IsDebuggerActive(isolate);
154 } 153 }
155 154
156 155
157 static void FinishOptimization(Handle<JSFunction> function, int64_t start) { 156 static void FinishOptimization(Handle<JSFunction> function, int64_t start) {
158 int opt_count = function->shared()->opt_count(); 157 int opt_count = function->shared()->opt_count();
159 function->shared()->set_opt_count(opt_count + 1); 158 function->shared()->set_opt_count(opt_count + 1);
160 double ms = static_cast<double>(OS::Ticks() - start) / 1000; 159 double ms = static_cast<double>(OS::Ticks() - start) / 1000;
161 if (FLAG_trace_opt) { 160 if (FLAG_trace_opt) {
162 PrintF("[optimizing: "); 161 PrintF("[optimizing: ");
163 function->PrintName(); 162 function->PrintName();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 Handle<Code> code(info->shared_info()->code()); 197 Handle<Code> code(info->shared_info()->code());
199 ASSERT(code->kind() == Code::FUNCTION); 198 ASSERT(code->kind() == Code::FUNCTION);
200 199
201 // We should never arrive here if optimization has been disabled on the 200 // We should never arrive here if optimization has been disabled on the
202 // shared function info. 201 // shared function info.
203 ASSERT(!info->shared_info()->optimization_disabled()); 202 ASSERT(!info->shared_info()->optimization_disabled());
204 203
205 // Fall back to using the full code generator if it's not possible 204 // Fall back to using the full code generator if it's not possible
206 // to use the Hydrogen-based optimizing compiler. We already have 205 // to use the Hydrogen-based optimizing compiler. We already have
207 // generated code for this from the shared function object. 206 // generated code for this from the shared function object.
208 if (AlwaysFullCompiler()) { 207 if (AlwaysFullCompiler(info->isolate())) {
209 info->SetCode(code); 208 info->SetCode(code);
210 return true; 209 return true;
211 } 210 }
212 211
213 // Limit the number of times we re-compile a functions with 212 // Limit the number of times we re-compile a functions with
214 // the optimizing compiler. 213 // the optimizing compiler.
215 const int kMaxOptCount = 214 const int kMaxOptCount =
216 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; 215 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000;
217 if (info->shared_info()->opt_count() > kMaxOptCount) { 216 if (info->shared_info()->opt_count() > kMaxOptCount) {
218 info->AbortOptimization(); 217 info->AbortOptimization();
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 info.SetFunction(literal); 711 info.SetFunction(literal);
713 info.SetScope(literal->scope()); 712 info.SetScope(literal->scope());
714 info.SetLanguageMode(literal->scope()->language_mode()); 713 info.SetLanguageMode(literal->scope()->language_mode());
715 714
716 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal); 715 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal);
717 // Determine if the function can be lazily compiled. This is necessary to 716 // Determine if the function can be lazily compiled. This is necessary to
718 // allow some of our builtin JS files to be lazily compiled. These 717 // allow some of our builtin JS files to be lazily compiled. These
719 // builtins cannot be handled lazily by the parser, since we have to know 718 // builtins cannot be handled lazily by the parser, since we have to know
720 // if a function uses the special natives syntax, which is something the 719 // if a function uses the special natives syntax, which is something the
721 // parser records. 720 // parser records.
721 // If the debugger requests compilation for break points, we cannot be
722 // aggressive about lazy compilation, because it might trigger compilation
723 // of functions without an outer context when setting a breakpoint through
724 // Runtime::FindSharedFunctionInfoInScript.
725 bool allow_lazy_without_ctx = literal->AllowsLazyCompilationWithoutContext();
722 bool allow_lazy = literal->AllowsLazyCompilation() && 726 bool allow_lazy = literal->AllowsLazyCompilation() &&
723 !LiveEditFunctionTracker::IsActive(info.isolate()); 727 !LiveEditFunctionTracker::IsActive(info.isolate()) &&
728 (!info.isolate()->DebuggerHasBreakPoints() || allow_lazy_without_ctx);
724 729
725 Handle<ScopeInfo> scope_info(ScopeInfo::Empty()); 730 Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
726 731
727 // Generate code 732 // Generate code
728 if (FLAG_lazy && allow_lazy) { 733 if (FLAG_lazy && allow_lazy) {
729 Handle<Code> code = info.isolate()->builtins()->LazyCompile(); 734 Handle<Code> code = info.isolate()->builtins()->LazyCompile();
730 info.SetCode(code); 735 info.SetCode(code);
731 } else if ((V8::UseCrankshaft() && MakeCrankshaftCode(&info)) || 736 } else if ((V8::UseCrankshaft() && MakeCrankshaftCode(&info)) ||
732 (!V8::UseCrankshaft() && FullCodeGenerator::MakeCode(&info))) { 737 (!V8::UseCrankshaft() && FullCodeGenerator::MakeCode(&info))) {
733 ASSERT(!info.code().is_null()); 738 ASSERT(!info.code().is_null());
734 scope_info = ScopeInfo::Create(info.scope(), info.isolate()->zone()); 739 scope_info = ScopeInfo::Create(info.scope(), info.isolate()->zone());
735 } else { 740 } else {
736 return Handle<SharedFunctionInfo>::null(); 741 return Handle<SharedFunctionInfo>::null();
737 } 742 }
738 743
739 // Create a shared function info object. 744 // Create a shared function info object.
740 Handle<SharedFunctionInfo> result = 745 Handle<SharedFunctionInfo> result =
741 FACTORY->NewSharedFunctionInfo(literal->name(), 746 FACTORY->NewSharedFunctionInfo(literal->name(),
742 literal->materialized_literal_count(), 747 literal->materialized_literal_count(),
743 info.code(), 748 info.code(),
744 scope_info); 749 scope_info);
745 SetFunctionInfo(result, literal, false, script); 750 SetFunctionInfo(result, literal, false, script);
746 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); 751 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result);
747 result->set_allows_lazy_compilation(allow_lazy); 752 result->set_allows_lazy_compilation(allow_lazy);
753 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx);
748 754
749 // Set the expected number of properties for instances and return 755 // Set the expected number of properties for instances and return
750 // the resulting function. 756 // the resulting function.
751 SetExpectedNofPropertiesFromEstimate(result, 757 SetExpectedNofPropertiesFromEstimate(result,
752 literal->expected_property_count()); 758 literal->expected_property_count());
753 live_edit_tracker.RecordFunctionInfo(result, literal, info.isolate()->zone()); 759 live_edit_tracker.RecordFunctionInfo(result, literal, info.isolate()->zone());
754 return result; 760 return result;
755 } 761 }
756 762
757 763
(...skipping 12 matching lines...) Expand all
770 function_info->set_start_position(lit->start_position()); 776 function_info->set_start_position(lit->start_position());
771 function_info->set_end_position(lit->end_position()); 777 function_info->set_end_position(lit->end_position());
772 function_info->set_is_expression(lit->is_expression()); 778 function_info->set_is_expression(lit->is_expression());
773 function_info->set_is_anonymous(lit->is_anonymous()); 779 function_info->set_is_anonymous(lit->is_anonymous());
774 function_info->set_is_toplevel(is_toplevel); 780 function_info->set_is_toplevel(is_toplevel);
775 function_info->set_inferred_name(*lit->inferred_name()); 781 function_info->set_inferred_name(*lit->inferred_name());
776 function_info->SetThisPropertyAssignmentsInfo( 782 function_info->SetThisPropertyAssignmentsInfo(
777 lit->has_only_simple_this_property_assignments(), 783 lit->has_only_simple_this_property_assignments(),
778 *lit->this_property_assignments()); 784 *lit->this_property_assignments());
779 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); 785 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation());
786 function_info->set_allows_lazy_compilation_without_context(
787 lit->AllowsLazyCompilationWithoutContext());
780 function_info->set_language_mode(lit->language_mode()); 788 function_info->set_language_mode(lit->language_mode());
781 function_info->set_uses_arguments(lit->scope()->arguments() != NULL); 789 function_info->set_uses_arguments(lit->scope()->arguments() != NULL);
782 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters()); 790 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
783 function_info->set_ast_node_count(lit->ast_node_count()); 791 function_info->set_ast_node_count(lit->ast_node_count());
784 function_info->set_is_function(lit->is_function()); 792 function_info->set_is_function(lit->is_function());
785 function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); 793 function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize));
786 function_info->set_dont_inline(lit->flags()->Contains(kDontInline)); 794 function_info->set_dont_inline(lit->flags()->Contains(kDontInline));
787 } 795 }
788 796
789 797
(...skipping 30 matching lines...) Expand all
820 } 828 }
821 } 829 }
822 830
823 GDBJIT(AddCode(Handle<String>(shared->DebugName()), 831 GDBJIT(AddCode(Handle<String>(shared->DebugName()),
824 Handle<Script>(info->script()), 832 Handle<Script>(info->script()),
825 Handle<Code>(info->code()), 833 Handle<Code>(info->code()),
826 info)); 834 info));
827 } 835 }
828 836
829 } } // namespace v8::internal 837 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast.cc ('k') | src/debug.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698