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