Chromium Code Reviews| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 54 CompilationInfo::CompilationInfo(Handle<Script> script) | 54 CompilationInfo::CompilationInfo(Handle<Script> script) |
| 55 : isolate_(script->GetIsolate()), | 55 : isolate_(script->GetIsolate()), |
| 56 flags_(LanguageModeField::encode(CLASSIC_MODE)), | 56 flags_(LanguageModeField::encode(CLASSIC_MODE)), |
| 57 function_(NULL), | 57 function_(NULL), |
| 58 scope_(NULL), | 58 scope_(NULL), |
| 59 global_scope_(NULL), | 59 global_scope_(NULL), |
| 60 script_(script), | 60 script_(script), |
| 61 extension_(NULL), | 61 extension_(NULL), |
| 62 pre_parse_data_(NULL), | 62 pre_parse_data_(NULL), |
| 63 osr_ast_id_(AstNode::kNoNumber) { | 63 osr_ast_id_(AstNode::kNoNumber) { |
| 64 Initialize(NONOPT); | 64 Initialize(BASE); |
| 65 } | 65 } |
| 66 | 66 |
| 67 | 67 |
| 68 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info) | 68 CompilationInfo::CompilationInfo(Handle<SharedFunctionInfo> shared_info) |
| 69 : isolate_(shared_info->GetIsolate()), | 69 : isolate_(shared_info->GetIsolate()), |
| 70 flags_(LanguageModeField::encode(CLASSIC_MODE) | | 70 flags_(LanguageModeField::encode(CLASSIC_MODE) | |
| 71 IsLazy::encode(true)), | 71 IsLazy::encode(true)), |
| 72 function_(NULL), | 72 function_(NULL), |
| 73 scope_(NULL), | 73 scope_(NULL), |
| 74 global_scope_(NULL), | 74 global_scope_(NULL), |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 compiled_functions, | 175 compiled_functions, |
| 176 code_size, | 176 code_size, |
| 177 compilation_time); | 177 compilation_time); |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 | 180 |
| 181 | 181 |
| 182 static bool MakeCrankshaftCode(CompilationInfo* info) { | 182 static bool MakeCrankshaftCode(CompilationInfo* info) { |
| 183 // Test if we can optimize this function when asked to. We can only | 183 // Test if we can optimize this function when asked to. We can only |
| 184 // do this after the scopes are computed. | 184 // do this after the scopes are computed. |
| 185 if (!info->AllowOptimize()) { | 185 if (!V8::UseCrankshaft()) { |
| 186 info->DisableOptimization(); | 186 info->DisableOptimization(); |
| 187 } else if (info->IsOptimizable()) { | |
| 188 info->EnableDeoptimizationSupport(); | |
| 189 } | 187 } |
| 190 | 188 |
| 191 // In case we are not optimizing simply return the code from | 189 // In case we are not optimizing simply return the code from |
| 192 // the full code generator. | 190 // the full code generator. |
| 193 if (!info->IsOptimizing()) { | 191 if (!info->IsOptimizing()) { |
| 194 return FullCodeGenerator::MakeCode(info); | 192 return FullCodeGenerator::MakeCode(info); |
| 195 } | 193 } |
| 196 | 194 |
| 197 // We should never arrive here if there is not code object on the | 195 // We should never arrive here if there is not code object on the |
| 198 // shared function object. | 196 // shared function object. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 210 info->SetCode(code); | 208 info->SetCode(code); |
| 211 return true; | 209 return true; |
| 212 } | 210 } |
| 213 | 211 |
| 214 // Limit the number of times we re-compile a functions with | 212 // Limit the number of times we re-compile a functions with |
| 215 // the optimizing compiler. | 213 // the optimizing compiler. |
| 216 const int kMaxOptCount = | 214 const int kMaxOptCount = |
| 217 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; | 215 FLAG_deopt_every_n_times == 0 ? Compiler::kDefaultMaxOptCount : 1000; |
| 218 if (info->shared_info()->opt_count() > kMaxOptCount) { | 216 if (info->shared_info()->opt_count() > kMaxOptCount) { |
| 219 info->AbortOptimization(); | 217 info->AbortOptimization(); |
| 220 Handle<JSFunction> closure = info->closure(); | 218 Handle<JSFunction> closure = info->closure(); |
|
Tobias Burnus
2012/02/14 21:22:55
GCC 4.7 warns that closure no longer used but only
| |
| 221 info->shared_info()->DisableOptimization(*closure); | 219 info->shared_info()->DisableOptimization(); |
| 222 // True indicates the compilation pipeline is still going, not | 220 // True indicates the compilation pipeline is still going, not |
| 223 // necessarily that we optimized the code. | 221 // necessarily that we optimized the code. |
| 224 return true; | 222 return true; |
| 225 } | 223 } |
| 226 | 224 |
| 227 // Due to an encoding limit on LUnallocated operands in the Lithium | 225 // Due to an encoding limit on LUnallocated operands in the Lithium |
| 228 // language, we cannot optimize functions with too many formal parameters | 226 // language, we cannot optimize functions with too many formal parameters |
| 229 // or perform on-stack replacement for function with too many | 227 // or perform on-stack replacement for function with too many |
| 230 // stack-allocated local variables. | 228 // stack-allocated local variables. |
| 231 // | 229 // |
| 232 // The encoding is as a signed value, with parameters and receiver using | 230 // The encoding is as a signed value, with parameters and receiver using |
| 233 // the negative indices and locals the non-negative ones. | 231 // the negative indices and locals the non-negative ones. |
| 234 const int parameter_limit = -LUnallocated::kMinFixedIndex; | 232 const int parameter_limit = -LUnallocated::kMinFixedIndex; |
| 235 const int locals_limit = LUnallocated::kMaxFixedIndex; | 233 const int locals_limit = LUnallocated::kMaxFixedIndex; |
| 236 Scope* scope = info->scope(); | 234 Scope* scope = info->scope(); |
| 237 if ((scope->num_parameters() + 1) > parameter_limit || | 235 if ((scope->num_parameters() + 1) > parameter_limit || |
| 238 (info->osr_ast_id() != AstNode::kNoNumber && | 236 (info->osr_ast_id() != AstNode::kNoNumber && |
| 239 scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit)) { | 237 scope->num_parameters() + 1 + scope->num_stack_slots() > locals_limit)) { |
| 240 info->AbortOptimization(); | 238 info->AbortOptimization(); |
| 241 Handle<JSFunction> closure = info->closure(); | 239 Handle<JSFunction> closure = info->closure(); |
|
Tobias Burnus
2012/02/14 21:22:55
Ditto.
| |
| 242 info->shared_info()->DisableOptimization(*closure); | 240 info->shared_info()->DisableOptimization(); |
| 243 // True indicates the compilation pipeline is still going, not | 241 // True indicates the compilation pipeline is still going, not |
| 244 // necessarily that we optimized the code. | 242 // necessarily that we optimized the code. |
| 245 return true; | 243 return true; |
| 246 } | 244 } |
| 247 | 245 |
| 248 // Take --hydrogen-filter into account. | 246 // Take --hydrogen-filter into account. |
| 249 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); | 247 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); |
| 250 Handle<String> name = info->function()->debug_name(); | 248 Handle<String> name = info->function()->debug_name(); |
| 251 bool match = filter.is_empty() || name->IsEqualTo(filter); | 249 bool match = filter.is_empty() || name->IsEqualTo(filter); |
| 252 if (!match) { | 250 if (!match) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 310 FinishOptimization(info->closure(), start); | 308 FinishOptimization(info->closure(), start); |
| 311 return true; | 309 return true; |
| 312 } | 310 } |
| 313 } | 311 } |
| 314 | 312 |
| 315 // Keep using the shared code. | 313 // Keep using the shared code. |
| 316 info->AbortOptimization(); | 314 info->AbortOptimization(); |
| 317 if (!builder.inline_bailout()) { | 315 if (!builder.inline_bailout()) { |
| 318 // Mark the shared code as unoptimizable unless it was an inlined | 316 // Mark the shared code as unoptimizable unless it was an inlined |
| 319 // function that bailed out. | 317 // function that bailed out. |
| 320 Handle<JSFunction> closure = info->closure(); | 318 Handle<JSFunction> closure = info->closure(); |
|
Tobias Burnus
2012/02/14 21:22:55
Ditto.
| |
| 321 info->shared_info()->DisableOptimization(*closure); | 319 info->shared_info()->DisableOptimization(); |
| 322 } | 320 } |
| 323 // True indicates the compilation pipeline is still going, not necessarily | 321 // True indicates the compilation pipeline is still going, not necessarily |
| 324 // that we optimized the code. | 322 // that we optimized the code. |
| 325 return true; | 323 return true; |
| 326 } | 324 } |
| 327 | 325 |
| 328 | 326 |
| 329 static bool GenerateCode(CompilationInfo* info) { | 327 static bool GenerateCode(CompilationInfo* info) { |
| 330 return info->IsCompilingForDebugging() || !V8::UseCrankshaft() ? | 328 return info->IsCompilingForDebugging() || !V8::UseCrankshaft() ? |
| 331 FullCodeGenerator::MakeCode(info) : | 329 FullCodeGenerator::MakeCode(info) : |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 566 if (result.is_null()) { | 564 if (result.is_null()) { |
| 567 // Create a script object describing the script to be compiled. | 565 // Create a script object describing the script to be compiled. |
| 568 Handle<Script> script = isolate->factory()->NewScript(source); | 566 Handle<Script> script = isolate->factory()->NewScript(source); |
| 569 CompilationInfo info(script); | 567 CompilationInfo info(script); |
| 570 info.MarkAsEval(); | 568 info.MarkAsEval(); |
| 571 if (is_global) info.MarkAsGlobal(); | 569 if (is_global) info.MarkAsGlobal(); |
| 572 info.SetLanguageMode(language_mode); | 570 info.SetLanguageMode(language_mode); |
| 573 info.SetCallingContext(context); | 571 info.SetCallingContext(context); |
| 574 result = MakeFunctionInfo(&info); | 572 result = MakeFunctionInfo(&info); |
| 575 if (!result.is_null()) { | 573 if (!result.is_null()) { |
| 574 // Explicitly disable optimization for eval code. We're not yet prepared | |
| 575 // to handle eval-code in the optimizing compiler. | |
| 576 result->DisableOptimization(); | |
| 577 | |
| 576 // If caller is strict mode, the result must be in strict mode or | 578 // If caller is strict mode, the result must be in strict mode or |
| 577 // extended mode as well, but not the other way around. Consider: | 579 // extended mode as well, but not the other way around. Consider: |
| 578 // eval("'use strict'; ..."); | 580 // eval("'use strict'; ..."); |
| 579 ASSERT(language_mode != STRICT_MODE || !result->is_classic_mode()); | 581 ASSERT(language_mode != STRICT_MODE || !result->is_classic_mode()); |
| 580 // If caller is in extended mode, the result must also be in | 582 // If caller is in extended mode, the result must also be in |
| 581 // extended mode. | 583 // extended mode. |
| 582 ASSERT(language_mode != EXTENDED_MODE || | 584 ASSERT(language_mode != EXTENDED_MODE || |
| 583 result->is_extended_mode()); | 585 result->is_extended_mode()); |
| 584 compilation_cache->PutEval( | 586 compilation_cache->PutEval( |
| 585 source, context, is_global, result, scope_position); | 587 source, context, is_global, result, scope_position); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 // Set the optimization hints after performing lazy compilation, as | 659 // Set the optimization hints after performing lazy compilation, as |
| 658 // these are not set when the function is set up as a lazily | 660 // these are not set when the function is set up as a lazily |
| 659 // compiled function. | 661 // compiled function. |
| 660 shared->SetThisPropertyAssignmentsInfo( | 662 shared->SetThisPropertyAssignmentsInfo( |
| 661 lit->has_only_simple_this_property_assignments(), | 663 lit->has_only_simple_this_property_assignments(), |
| 662 *lit->this_property_assignments()); | 664 *lit->this_property_assignments()); |
| 663 | 665 |
| 664 // Check the function has compiled code. | 666 // Check the function has compiled code. |
| 665 ASSERT(shared->is_compiled()); | 667 ASSERT(shared->is_compiled()); |
| 666 shared->set_code_age(0); | 668 shared->set_code_age(0); |
| 667 shared->set_dont_crankshaft(lit->flags()->Contains(kDontOptimize)); | 669 shared->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); |
| 668 shared->set_dont_inline(lit->flags()->Contains(kDontInline)); | 670 shared->set_dont_inline(lit->flags()->Contains(kDontInline)); |
| 669 shared->set_ast_node_count(lit->ast_node_count()); | 671 shared->set_ast_node_count(lit->ast_node_count()); |
| 670 | 672 |
| 671 if (info->AllowOptimize() && !shared->optimization_disabled()) { | 673 if (V8::UseCrankshaft()&& |
| 674 !function.is_null() && | |
| 675 !shared->optimization_disabled()) { | |
| 672 // If we're asked to always optimize, we compile the optimized | 676 // If we're asked to always optimize, we compile the optimized |
| 673 // version of the function right away - unless the debugger is | 677 // version of the function right away - unless the debugger is |
| 674 // active as it makes no sense to compile optimized code then. | 678 // active as it makes no sense to compile optimized code then. |
| 675 if (FLAG_always_opt && | 679 if (FLAG_always_opt && |
| 676 !Isolate::Current()->DebuggerHasBreakPoints()) { | 680 !Isolate::Current()->DebuggerHasBreakPoints()) { |
| 677 CompilationInfo optimized(function); | 681 CompilationInfo optimized(function); |
| 678 optimized.SetOptimizing(AstNode::kNoNumber); | 682 optimized.SetOptimizing(AstNode::kNoNumber); |
| 679 return CompileLazy(&optimized); | 683 return CompileLazy(&optimized); |
| 680 } | 684 } |
| 681 } | 685 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 759 function_info->set_is_toplevel(is_toplevel); | 763 function_info->set_is_toplevel(is_toplevel); |
| 760 function_info->set_inferred_name(*lit->inferred_name()); | 764 function_info->set_inferred_name(*lit->inferred_name()); |
| 761 function_info->SetThisPropertyAssignmentsInfo( | 765 function_info->SetThisPropertyAssignmentsInfo( |
| 762 lit->has_only_simple_this_property_assignments(), | 766 lit->has_only_simple_this_property_assignments(), |
| 763 *lit->this_property_assignments()); | 767 *lit->this_property_assignments()); |
| 764 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); | 768 function_info->set_allows_lazy_compilation(lit->AllowsLazyCompilation()); |
| 765 function_info->set_language_mode(lit->language_mode()); | 769 function_info->set_language_mode(lit->language_mode()); |
| 766 function_info->set_uses_arguments(lit->scope()->arguments() != NULL); | 770 function_info->set_uses_arguments(lit->scope()->arguments() != NULL); |
| 767 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters()); | 771 function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters()); |
| 768 function_info->set_ast_node_count(lit->ast_node_count()); | 772 function_info->set_ast_node_count(lit->ast_node_count()); |
| 769 function_info->set_dont_crankshaft(lit->flags()->Contains(kDontOptimize)); | 773 function_info->set_is_function(lit->is_function()); |
| 774 function_info->set_dont_optimize(lit->flags()->Contains(kDontOptimize)); | |
| 770 function_info->set_dont_inline(lit->flags()->Contains(kDontInline)); | 775 function_info->set_dont_inline(lit->flags()->Contains(kDontInline)); |
| 771 } | 776 } |
| 772 | 777 |
| 773 | 778 |
| 774 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, | 779 void Compiler::RecordFunctionCompilation(Logger::LogEventsAndTags tag, |
| 775 CompilationInfo* info, | 780 CompilationInfo* info, |
| 776 Handle<SharedFunctionInfo> shared) { | 781 Handle<SharedFunctionInfo> shared) { |
| 777 // SharedFunctionInfo is passed separately, because if CompilationInfo | 782 // SharedFunctionInfo is passed separately, because if CompilationInfo |
| 778 // was created using Script object, it will not have it. | 783 // was created using Script object, it will not have it. |
| 779 | 784 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 804 } | 809 } |
| 805 } | 810 } |
| 806 | 811 |
| 807 GDBJIT(AddCode(Handle<String>(shared->DebugName()), | 812 GDBJIT(AddCode(Handle<String>(shared->DebugName()), |
| 808 Handle<Script>(info->script()), | 813 Handle<Script>(info->script()), |
| 809 Handle<Code>(info->code()), | 814 Handle<Code>(info->code()), |
| 810 info)); | 815 info)); |
| 811 } | 816 } |
| 812 | 817 |
| 813 } } // namespace v8::internal | 818 } } // namespace v8::internal |
| OLD | NEW |