| 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 |