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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 return false; | 253 return false; |
254 #endif | 254 #endif |
255 } | 255 } |
256 | 256 |
257 | 257 |
258 static bool AlwaysFullCompiler(Isolate* isolate) { | 258 static bool AlwaysFullCompiler(Isolate* isolate) { |
259 return FLAG_always_full_compiler || IsDebuggerActive(isolate); | 259 return FLAG_always_full_compiler || IsDebuggerActive(isolate); |
260 } | 260 } |
261 | 261 |
262 | 262 |
263 void OptimizingCompiler::RecordOptimizationStats() { | 263 void RecompileJob::RecordOptimizationStats() { |
264 Handle<JSFunction> function = info()->closure(); | 264 Handle<JSFunction> function = info()->closure(); |
265 int opt_count = function->shared()->opt_count(); | 265 int opt_count = function->shared()->opt_count(); |
266 function->shared()->set_opt_count(opt_count + 1); | 266 function->shared()->set_opt_count(opt_count + 1); |
267 double ms_creategraph = time_taken_to_create_graph_.InMillisecondsF(); | 267 double ms_creategraph = time_taken_to_create_graph_.InMillisecondsF(); |
268 double ms_optimize = time_taken_to_optimize_.InMillisecondsF(); | 268 double ms_optimize = time_taken_to_optimize_.InMillisecondsF(); |
269 double ms_codegen = time_taken_to_codegen_.InMillisecondsF(); | 269 double ms_codegen = time_taken_to_codegen_.InMillisecondsF(); |
270 if (FLAG_trace_opt) { | 270 if (FLAG_trace_opt) { |
271 PrintF("[optimizing "); | 271 PrintF("[optimizing "); |
272 function->ShortPrint(); | 272 function->ShortPrint(); |
273 PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize, | 273 PrintF(" - took %0.3f, %0.3f, %0.3f ms]\n", ms_creategraph, ms_optimize, |
(...skipping 16 matching lines...) Expand all Loading... |
290 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_create_graph_, | 290 isolate()->GetHStatistics()->IncrementSubtotals(time_taken_to_create_graph_, |
291 time_taken_to_optimize_, | 291 time_taken_to_optimize_, |
292 time_taken_to_codegen_); | 292 time_taken_to_codegen_); |
293 } | 293 } |
294 } | 294 } |
295 | 295 |
296 | 296 |
297 // A return value of true indicates the compilation pipeline is still | 297 // A return value of true indicates the compilation pipeline is still |
298 // going, not necessarily that we optimized the code. | 298 // going, not necessarily that we optimized the code. |
299 static bool MakeCrankshaftCode(CompilationInfo* info) { | 299 static bool MakeCrankshaftCode(CompilationInfo* info) { |
300 OptimizingCompiler compiler(info); | 300 RecompileJob job(info); |
301 OptimizingCompiler::Status status = compiler.CreateGraph(); | 301 RecompileJob::Status status = job.CreateGraph(); |
302 | 302 |
303 if (status != OptimizingCompiler::SUCCEEDED) { | 303 if (status != RecompileJob::SUCCEEDED) { |
304 return status != OptimizingCompiler::FAILED; | 304 return status != RecompileJob::FAILED; |
305 } | 305 } |
306 status = compiler.OptimizeGraph(); | 306 status = job.OptimizeGraph(); |
307 if (status != OptimizingCompiler::SUCCEEDED) { | 307 if (status != RecompileJob::SUCCEEDED) { |
308 status = compiler.AbortOptimization(); | 308 status = job.AbortOptimization(); |
309 return status != OptimizingCompiler::FAILED; | 309 return status != RecompileJob::FAILED; |
310 } | 310 } |
311 status = compiler.GenerateAndInstallCode(); | 311 status = job.GenerateAndInstallCode(); |
312 return status != OptimizingCompiler::FAILED; | 312 return status != RecompileJob::FAILED; |
313 } | 313 } |
314 | 314 |
315 | 315 |
316 OptimizingCompiler::Status OptimizingCompiler::CreateGraph() { | 316 RecompileJob::Status RecompileJob::CreateGraph() { |
317 ASSERT(isolate()->use_crankshaft()); | 317 ASSERT(isolate()->use_crankshaft()); |
318 ASSERT(info()->IsOptimizing()); | 318 ASSERT(info()->IsOptimizing()); |
319 ASSERT(!info()->IsCompilingForDebugging()); | 319 ASSERT(!info()->IsCompilingForDebugging()); |
320 | 320 |
321 // We should never arrive here if there is no code object on the | 321 // We should never arrive here if there is no code object on the |
322 // shared function object. | 322 // shared function object. |
323 ASSERT(info()->shared_info()->code()->kind() == Code::FUNCTION); | 323 ASSERT(info()->shared_info()->code()->kind() == Code::FUNCTION); |
324 | 324 |
325 // We should never arrive here if optimization has been disabled on the | 325 // We should never arrive here if optimization has been disabled on the |
326 // shared function info. | 326 // shared function info. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 if (info()->HasAbortedDueToDependencyChange()) { | 445 if (info()->HasAbortedDueToDependencyChange()) { |
446 info_->set_bailout_reason(kBailedOutDueToDependencyChange); | 446 info_->set_bailout_reason(kBailedOutDueToDependencyChange); |
447 info_->AbortOptimization(); | 447 info_->AbortOptimization(); |
448 return SetLastStatus(BAILED_OUT); | 448 return SetLastStatus(BAILED_OUT); |
449 } | 449 } |
450 | 450 |
451 return SetLastStatus(SUCCEEDED); | 451 return SetLastStatus(SUCCEEDED); |
452 } | 452 } |
453 | 453 |
454 | 454 |
455 OptimizingCompiler::Status OptimizingCompiler::OptimizeGraph() { | 455 RecompileJob::Status RecompileJob::OptimizeGraph() { |
456 DisallowHeapAllocation no_allocation; | 456 DisallowHeapAllocation no_allocation; |
457 DisallowHandleAllocation no_handles; | 457 DisallowHandleAllocation no_handles; |
458 DisallowHandleDereference no_deref; | 458 DisallowHandleDereference no_deref; |
459 DisallowCodeDependencyChange no_dependency_change; | 459 DisallowCodeDependencyChange no_dependency_change; |
460 | 460 |
461 ASSERT(last_status() == SUCCEEDED); | 461 ASSERT(last_status() == SUCCEEDED); |
462 Timer t(this, &time_taken_to_optimize_); | 462 Timer t(this, &time_taken_to_optimize_); |
463 ASSERT(graph_ != NULL); | 463 ASSERT(graph_ != NULL); |
464 BailoutReason bailout_reason = kNoReason; | 464 BailoutReason bailout_reason = kNoReason; |
465 if (!graph_->Optimize(&bailout_reason)) { | 465 if (!graph_->Optimize(&bailout_reason)) { |
466 if (bailout_reason == kNoReason) graph_builder_->Bailout(bailout_reason); | 466 if (bailout_reason == kNoReason) graph_builder_->Bailout(bailout_reason); |
467 return SetLastStatus(BAILED_OUT); | 467 return SetLastStatus(BAILED_OUT); |
468 } else { | 468 } else { |
469 chunk_ = LChunk::NewChunk(graph_); | 469 chunk_ = LChunk::NewChunk(graph_); |
470 if (chunk_ == NULL) { | 470 if (chunk_ == NULL) { |
471 return SetLastStatus(BAILED_OUT); | 471 return SetLastStatus(BAILED_OUT); |
472 } | 472 } |
473 } | 473 } |
474 return SetLastStatus(SUCCEEDED); | 474 return SetLastStatus(SUCCEEDED); |
475 } | 475 } |
476 | 476 |
477 | 477 |
478 OptimizingCompiler::Status OptimizingCompiler::GenerateAndInstallCode() { | 478 RecompileJob::Status RecompileJob::GenerateAndInstallCode() { |
479 ASSERT(last_status() == SUCCEEDED); | 479 ASSERT(last_status() == SUCCEEDED); |
480 ASSERT(!info()->HasAbortedDueToDependencyChange()); | 480 ASSERT(!info()->HasAbortedDueToDependencyChange()); |
481 DisallowCodeDependencyChange no_dependency_change; | 481 DisallowCodeDependencyChange no_dependency_change; |
482 { // Scope for timer. | 482 { // Scope for timer. |
483 Timer timer(this, &time_taken_to_codegen_); | 483 Timer timer(this, &time_taken_to_codegen_); |
484 ASSERT(chunk_ != NULL); | 484 ASSERT(chunk_ != NULL); |
485 ASSERT(graph_ != NULL); | 485 ASSERT(graph_ != NULL); |
486 // Deferred handles reference objects that were accessible during | 486 // Deferred handles reference objects that were accessible during |
487 // graph creation. To make sure that we don't encounter inconsistencies | 487 // graph creation. To make sure that we don't encounter inconsistencies |
488 // between graph creation and code generation, we disallow accessing | 488 // between graph creation and code generation, we disallow accessing |
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 return true; | 1025 return true; |
1026 } | 1026 } |
1027 | 1027 |
1028 if (Parser::Parse(*info)) { | 1028 if (Parser::Parse(*info)) { |
1029 LanguageMode language_mode = info->function()->language_mode(); | 1029 LanguageMode language_mode = info->function()->language_mode(); |
1030 info->SetLanguageMode(language_mode); | 1030 info->SetLanguageMode(language_mode); |
1031 shared->set_language_mode(language_mode); | 1031 shared->set_language_mode(language_mode); |
1032 info->SaveHandles(); | 1032 info->SaveHandles(); |
1033 | 1033 |
1034 if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) { | 1034 if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) { |
1035 OptimizingCompiler* compiler = | 1035 RecompileJob* job = new(info->zone()) RecompileJob(*info); |
1036 new(info->zone()) OptimizingCompiler(*info); | 1036 RecompileJob::Status status = job->CreateGraph(); |
1037 OptimizingCompiler::Status status = compiler->CreateGraph(); | 1037 if (status == RecompileJob::SUCCEEDED) { |
1038 if (status == OptimizingCompiler::SUCCEEDED) { | |
1039 info.Detach(); | 1038 info.Detach(); |
1040 shared->code()->set_profiler_ticks(0); | 1039 shared->code()->set_profiler_ticks(0); |
1041 isolate->optimizing_compiler_thread()->QueueForOptimization(compiler); | 1040 isolate->optimizing_compiler_thread()->QueueForOptimization(job); |
1042 ASSERT(!isolate->has_pending_exception()); | 1041 ASSERT(!isolate->has_pending_exception()); |
1043 return true; | 1042 return true; |
1044 } else if (status == OptimizingCompiler::BAILED_OUT) { | 1043 } else if (status == RecompileJob::BAILED_OUT) { |
1045 isolate->clear_pending_exception(); | 1044 isolate->clear_pending_exception(); |
1046 InstallFullCode(*info); | 1045 InstallFullCode(*info); |
1047 } | 1046 } |
1048 } | 1047 } |
1049 } | 1048 } |
1050 } | 1049 } |
1051 | 1050 |
1052 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); | 1051 if (isolate->has_pending_exception()) isolate->clear_pending_exception(); |
1053 return false; | 1052 return false; |
1054 } | 1053 } |
1055 | 1054 |
1056 | 1055 |
1057 Handle<Code> Compiler::InstallOptimizedCode( | 1056 Handle<Code> Compiler::InstallOptimizedCode(RecompileJob* job) { |
1058 OptimizingCompiler* optimizing_compiler) { | 1057 SmartPointer<CompilationInfo> info(job->info()); |
1059 SmartPointer<CompilationInfo> info(optimizing_compiler->info()); | |
1060 // The function may have already been optimized by OSR. Simply continue. | 1058 // The function may have already been optimized by OSR. Simply continue. |
1061 // Except when OSR already disabled optimization for some reason. | 1059 // Except when OSR already disabled optimization for some reason. |
1062 if (info->shared_info()->optimization_disabled()) { | 1060 if (info->shared_info()->optimization_disabled()) { |
1063 info->AbortOptimization(); | 1061 info->AbortOptimization(); |
1064 InstallFullCode(*info); | 1062 InstallFullCode(*info); |
1065 if (FLAG_trace_concurrent_recompilation) { | 1063 if (FLAG_trace_concurrent_recompilation) { |
1066 PrintF(" ** aborting optimization for "); | 1064 PrintF(" ** aborting optimization for "); |
1067 info->closure()->PrintName(); | 1065 info->closure()->PrintName(); |
1068 PrintF(" as it has been disabled.\n"); | 1066 PrintF(" as it has been disabled.\n"); |
1069 } | 1067 } |
1070 ASSERT(!info->closure()->IsInRecompileQueue()); | 1068 ASSERT(!info->closure()->IsInRecompileQueue()); |
1071 return Handle<Code>::null(); | 1069 return Handle<Code>::null(); |
1072 } | 1070 } |
1073 | 1071 |
1074 Isolate* isolate = info->isolate(); | 1072 Isolate* isolate = info->isolate(); |
1075 VMState<COMPILER> state(isolate); | 1073 VMState<COMPILER> state(isolate); |
1076 Logger::TimerEventScope timer( | 1074 Logger::TimerEventScope timer( |
1077 isolate, Logger::TimerEventScope::v8_recompile_synchronous); | 1075 isolate, Logger::TimerEventScope::v8_recompile_synchronous); |
1078 // If crankshaft succeeded, install the optimized code else install | 1076 // If crankshaft succeeded, install the optimized code else install |
1079 // the unoptimized code. | 1077 // the unoptimized code. |
1080 OptimizingCompiler::Status status = optimizing_compiler->last_status(); | 1078 RecompileJob::Status status = job->last_status(); |
1081 if (info->HasAbortedDueToDependencyChange()) { | 1079 if (info->HasAbortedDueToDependencyChange()) { |
1082 info->set_bailout_reason(kBailedOutDueToDependencyChange); | 1080 info->set_bailout_reason(kBailedOutDueToDependencyChange); |
1083 status = optimizing_compiler->AbortOptimization(); | 1081 status = job->AbortOptimization(); |
1084 } else if (status != OptimizingCompiler::SUCCEEDED) { | 1082 } else if (status != RecompileJob::SUCCEEDED) { |
1085 info->set_bailout_reason(kFailedBailedOutLastTime); | 1083 info->set_bailout_reason(kFailedBailedOutLastTime); |
1086 status = optimizing_compiler->AbortOptimization(); | 1084 status = job->AbortOptimization(); |
1087 } else if (isolate->DebuggerHasBreakPoints()) { | 1085 } else if (isolate->DebuggerHasBreakPoints()) { |
1088 info->set_bailout_reason(kDebuggerIsActive); | 1086 info->set_bailout_reason(kDebuggerIsActive); |
1089 status = optimizing_compiler->AbortOptimization(); | 1087 status = job->AbortOptimization(); |
1090 } else { | 1088 } else { |
1091 status = optimizing_compiler->GenerateAndInstallCode(); | 1089 status = job->GenerateAndInstallCode(); |
1092 ASSERT(status == OptimizingCompiler::SUCCEEDED || | 1090 ASSERT(status == RecompileJob::SUCCEEDED || |
1093 status == OptimizingCompiler::BAILED_OUT); | 1091 status == RecompileJob::BAILED_OUT); |
1094 } | 1092 } |
1095 | 1093 |
1096 InstallCodeCommon(*info); | 1094 InstallCodeCommon(*info); |
1097 if (status == OptimizingCompiler::SUCCEEDED) { | 1095 if (status == RecompileJob::SUCCEEDED) { |
1098 Handle<Code> code = info->code(); | 1096 Handle<Code> code = info->code(); |
1099 ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty(isolate)); | 1097 ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty(isolate)); |
1100 info->closure()->ReplaceCode(*code); | 1098 info->closure()->ReplaceCode(*code); |
1101 if (info->shared_info()->SearchOptimizedCodeMap( | 1099 if (info->shared_info()->SearchOptimizedCodeMap( |
1102 info->closure()->context()->native_context()) == -1) { | 1100 info->closure()->context()->native_context()) == -1) { |
1103 InsertCodeIntoOptimizedCodeMap(*info); | 1101 InsertCodeIntoOptimizedCodeMap(*info); |
1104 } | 1102 } |
1105 if (FLAG_trace_concurrent_recompilation) { | 1103 if (FLAG_trace_concurrent_recompilation) { |
1106 PrintF(" ** Optimized code for "); | 1104 PrintF(" ** Optimized code for "); |
1107 info->closure()->PrintName(); | 1105 info->closure()->PrintName(); |
1108 PrintF(" installed.\n"); | 1106 PrintF(" installed.\n"); |
1109 } | 1107 } |
1110 } else { | 1108 } else { |
1111 info->AbortOptimization(); | 1109 info->AbortOptimization(); |
1112 InstallFullCode(*info); | 1110 InstallFullCode(*info); |
1113 } | 1111 } |
1114 // Optimized code is finally replacing unoptimized code. Reset the latter's | 1112 // Optimized code is finally replacing unoptimized code. Reset the latter's |
1115 // profiler ticks to prevent too soon re-opt after a deopt. | 1113 // profiler ticks to prevent too soon re-opt after a deopt. |
1116 info->shared_info()->code()->set_profiler_ticks(0); | 1114 info->shared_info()->code()->set_profiler_ticks(0); |
1117 ASSERT(!info->closure()->IsInRecompileQueue()); | 1115 ASSERT(!info->closure()->IsInRecompileQueue()); |
1118 return (status == OptimizingCompiler::SUCCEEDED) ? info->code() | 1116 return (status == RecompileJob::SUCCEEDED) ? info->code() |
1119 : Handle<Code>::null(); | 1117 : Handle<Code>::null(); |
1120 } | 1118 } |
1121 | 1119 |
1122 | 1120 |
1123 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, | 1121 Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal, |
1124 Handle<Script> script) { | 1122 Handle<Script> script) { |
1125 // Precondition: code has been parsed and scopes have been analyzed. | 1123 // Precondition: code has been parsed and scopes have been analyzed. |
1126 CompilationInfoWithZone info(script); | 1124 CompilationInfoWithZone info(script); |
1127 info.SetFunction(literal); | 1125 info.SetFunction(literal); |
1128 info.SetScope(literal->scope()); | 1126 info.SetScope(literal->scope()); |
1129 info.SetLanguageMode(literal->scope()->language_mode()); | 1127 info.SetLanguageMode(literal->scope()->language_mode()); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 AllowHandleDereference allow_deref; | 1280 AllowHandleDereference allow_deref; |
1283 bool tracing_on = info()->IsStub() | 1281 bool tracing_on = info()->IsStub() |
1284 ? FLAG_trace_hydrogen_stubs | 1282 ? FLAG_trace_hydrogen_stubs |
1285 : (FLAG_trace_hydrogen && | 1283 : (FLAG_trace_hydrogen && |
1286 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); | 1284 info()->closure()->PassesFilter(FLAG_trace_hydrogen_filter)); |
1287 return (tracing_on && | 1285 return (tracing_on && |
1288 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); | 1286 OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL); |
1289 } | 1287 } |
1290 | 1288 |
1291 } } // namespace v8::internal | 1289 } } // namespace v8::internal |
OLD | NEW |