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()->AllowsLazyCompilation() && | 121 function()->scope()->AllowsLazyRecompilation() && |
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 IsDebuggerActive(Isolate* isolate) { | 140 static bool is_debugging_active() { |
141 #ifdef ENABLE_DEBUGGER_SUPPORT | 141 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 142 Isolate* isolate = Isolate::Current(); |
142 return V8::UseCrankshaft() ? | 143 return V8::UseCrankshaft() ? |
143 isolate->debug()->has_break_points() : | 144 isolate->debug()->has_break_points() : |
144 isolate->debugger()->IsDebuggerActive(); | 145 isolate->debugger()->IsDebuggerActive(); |
145 #else | 146 #else |
146 return false; | 147 return false; |
147 #endif | 148 #endif |
148 } | 149 } |
149 | 150 |
150 | 151 |
151 static bool AlwaysFullCompiler(Isolate* isolate) { | 152 static bool AlwaysFullCompiler() { |
152 return FLAG_always_full_compiler || IsDebuggerActive(isolate); | 153 return FLAG_always_full_compiler || is_debugging_active(); |
153 } | 154 } |
154 | 155 |
155 | 156 |
156 static void FinishOptimization(Handle<JSFunction> function, int64_t start) { | 157 static void FinishOptimization(Handle<JSFunction> function, int64_t start) { |
157 int opt_count = function->shared()->opt_count(); | 158 int opt_count = function->shared()->opt_count(); |
158 function->shared()->set_opt_count(opt_count + 1); | 159 function->shared()->set_opt_count(opt_count + 1); |
159 double ms = static_cast<double>(OS::Ticks() - start) / 1000; | 160 double ms = static_cast<double>(OS::Ticks() - start) / 1000; |
160 if (FLAG_trace_opt) { | 161 if (FLAG_trace_opt) { |
161 PrintF("[optimizing: "); | 162 PrintF("[optimizing: "); |
162 function->PrintName(); | 163 function->PrintName(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 Handle<Code> code(info->shared_info()->code()); | 198 Handle<Code> code(info->shared_info()->code()); |
198 ASSERT(code->kind() == Code::FUNCTION); | 199 ASSERT(code->kind() == Code::FUNCTION); |
199 | 200 |
200 // We should never arrive here if optimization has been disabled on the | 201 // We should never arrive here if optimization has been disabled on the |
201 // shared function info. | 202 // shared function info. |
202 ASSERT(!info->shared_info()->optimization_disabled()); | 203 ASSERT(!info->shared_info()->optimization_disabled()); |
203 | 204 |
204 // Fall back to using the full code generator if it's not possible | 205 // Fall back to using the full code generator if it's not possible |
205 // to use the Hydrogen-based optimizing compiler. We already have | 206 // to use the Hydrogen-based optimizing compiler. We already have |
206 // generated code for this from the shared function object. | 207 // generated code for this from the shared function object. |
207 if (AlwaysFullCompiler(info->isolate())) { | 208 if (AlwaysFullCompiler()) { |
208 info->SetCode(code); | 209 info->SetCode(code); |
209 return true; | 210 return true; |
210 } | 211 } |
211 | 212 |
212 // Limit the number of times we re-compile a functions with | 213 // Limit the number of times we re-compile a functions with |
213 // the optimizing compiler. | 214 // the optimizing compiler. |
214 const int kMaxOptCount = | 215 const int kMaxOptCount = |
215 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; | 216 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; |
216 if (info->shared_info()->opt_count() > kMaxOptCount) { | 217 if (info->shared_info()->opt_count() > kMaxOptCount) { |
217 info->AbortOptimization(); | 218 info->AbortOptimization(); |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
711 info.SetFunction(literal); | 712 info.SetFunction(literal); |
712 info.SetScope(literal->scope()); | 713 info.SetScope(literal->scope()); |
713 info.SetLanguageMode(literal->scope()->language_mode()); | 714 info.SetLanguageMode(literal->scope()->language_mode()); |
714 | 715 |
715 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal); | 716 LiveEditFunctionTracker live_edit_tracker(info.isolate(), literal); |
716 // Determine if the function can be lazily compiled. This is necessary to | 717 // Determine if the function can be lazily compiled. This is necessary to |
717 // allow some of our builtin JS files to be lazily compiled. These | 718 // allow some of our builtin JS files to be lazily compiled. These |
718 // builtins cannot be handled lazily by the parser, since we have to know | 719 // builtins cannot be handled lazily by the parser, since we have to know |
719 // if a function uses the special natives syntax, which is something the | 720 // if a function uses the special natives syntax, which is something the |
720 // parser records. | 721 // 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(); | |
726 bool allow_lazy = literal->AllowsLazyCompilation() && | 722 bool allow_lazy = literal->AllowsLazyCompilation() && |
727 !LiveEditFunctionTracker::IsActive(info.isolate()) && | 723 !LiveEditFunctionTracker::IsActive(info.isolate()); |
728 (!info.isolate()->DebuggerHasBreakPoints() || allow_lazy_without_ctx); | |
729 | 724 |
730 Handle<ScopeInfo> scope_info(ScopeInfo::Empty()); | 725 Handle<ScopeInfo> scope_info(ScopeInfo::Empty()); |
731 | 726 |
732 // Generate code | 727 // Generate code |
733 if (FLAG_lazy && allow_lazy) { | 728 if (FLAG_lazy && allow_lazy) { |
734 Handle<Code> code = info.isolate()->builtins()->LazyCompile(); | 729 Handle<Code> code = info.isolate()->builtins()->LazyCompile(); |
735 info.SetCode(code); | 730 info.SetCode(code); |
736 } else if ((V8::UseCrankshaft() && MakeCrankshaftCode(&info)) || | 731 } else if ((V8::UseCrankshaft() && MakeCrankshaftCode(&info)) || |
737 (!V8::UseCrankshaft() && FullCodeGenerator::MakeCode(&info))) { | 732 (!V8::UseCrankshaft() && FullCodeGenerator::MakeCode(&info))) { |
738 ASSERT(!info.code().is_null()); | 733 ASSERT(!info.code().is_null()); |
739 scope_info = ScopeInfo::Create(info.scope(), info.isolate()->zone()); | 734 scope_info = ScopeInfo::Create(info.scope(), info.isolate()->zone()); |
740 } else { | 735 } else { |
741 return Handle<SharedFunctionInfo>::null(); | 736 return Handle<SharedFunctionInfo>::null(); |
742 } | 737 } |
743 | 738 |
744 // Create a shared function info object. | 739 // Create a shared function info object. |
745 Handle<SharedFunctionInfo> result = | 740 Handle<SharedFunctionInfo> result = |
746 FACTORY->NewSharedFunctionInfo(literal->name(), | 741 FACTORY->NewSharedFunctionInfo(literal->name(), |
747 literal->materialized_literal_count(), | 742 literal->materialized_literal_count(), |
748 info.code(), | 743 info.code(), |
749 scope_info); | 744 scope_info); |
750 SetFunctionInfo(result, literal, false, script); | 745 SetFunctionInfo(result, literal, false, script); |
751 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); | 746 RecordFunctionCompilation(Logger::FUNCTION_TAG, &info, result); |
752 result->set_allows_lazy_compilation(allow_lazy); | 747 result->set_allows_lazy_compilation(allow_lazy); |
753 result->set_allows_lazy_compilation_without_context(allow_lazy_without_ctx); | |
754 | 748 |
755 // Set the expected number of properties for instances and return | 749 // Set the expected number of properties for instances and return |
756 // the resulting function. | 750 // the resulting function. |
757 SetExpectedNofPropertiesFromEstimate(result, | 751 SetExpectedNofPropertiesFromEstimate(result, |
758 literal->expected_property_count()); | 752 literal->expected_property_count()); |
759 live_edit_tracker.RecordFunctionInfo(result, literal, info.isolate()->zone()); | 753 live_edit_tracker.RecordFunctionInfo(result, literal, info.isolate()->zone()); |
760 return result; | 754 return result; |
761 } | 755 } |
762 | 756 |
763 | 757 |
(...skipping 12 matching lines...) Expand all Loading... |
776 function_info->set_start_position(lit->start_position()); | 770 function_info->set_start_position(lit->start_position()); |
777 function_info->set_end_position(lit->end_position()); | 771 function_info->set_end_position(lit->end_position()); |
778 function_info->set_is_expression(lit->is_expression()); | 772 function_info->set_is_expression(lit->is_expression()); |
779 function_info->set_is_anonymous(lit->is_anonymous()); | 773 function_info->set_is_anonymous(lit->is_anonymous()); |
780 function_info->set_is_toplevel(is_toplevel); | 774 function_info->set_is_toplevel(is_toplevel); |
781 function_info->set_inferred_name(*lit->inferred_name()); | 775 function_info->set_inferred_name(*lit->inferred_name()); |
782 function_info->SetThisPropertyAssignmentsInfo( | 776 function_info->SetThisPropertyAssignmentsInfo( |
783 lit->has_only_simple_this_property_assignments(), | 777 lit->has_only_simple_this_property_assignments(), |
784 *lit->this_property_assignments()); | 778 *lit->this_property_assignments()); |
785 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); | 779 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); |
786 function_info->set_allows_lazy_compilation_without_context( | |
787 lit->AllowsLazyCompilationWithoutContext()); | |
788 function_info->set_language_mode(lit->language_mode()); | 780 function_info->set_language_mode(lit->language_mode()); |
789 function_info->set_uses_arguments(lit->scope()->arguments() != NULL); | 781 function_info->set_uses_arguments(lit->scope()->arguments() != NULL); |
790 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters()); | 782 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters()); |
791 function_info->set_ast_node_count(lit->ast_node_count()); | 783 function_info->set_ast_node_count(lit->ast_node_count()); |
792 function_info->set_is_function(lit->is_function()); | 784 function_info->set_is_function(lit->is_function()); |
793 function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); | 785 function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); |
794 function_info->set_dont_inline(lit->flags()->Contains(kDontInline)); | 786 function_info->set_dont_inline(lit->flags()->Contains(kDontInline)); |
795 } | 787 } |
796 | 788 |
797 | 789 |
(...skipping 30 matching lines...) Expand all Loading... |
828 } | 820 } |
829 } | 821 } |
830 | 822 |
831 GDBJIT(AddCode(Handle<String>(shared->DebugName()), | 823 GDBJIT(AddCode(Handle<String>(shared->DebugName()), |
832 Handle<Script>(info->script()), | 824 Handle<Script>(info->script()), |
833 Handle<Code>(info->code()), | 825 Handle<Code>(info->code()), |
834 info)); | 826 info)); |
835 } | 827 } |
836 | 828 |
837 } } // namespace v8::internal | 829 } } // namespace v8::internal |
OLD | NEW |