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