OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |