| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/nacl/renderer/plugin/pnacl_coordinator.h" | 5 #include "components/nacl/renderer/plugin/pnacl_coordinator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 &DidFinishStream | 55 &DidFinishStream |
| 56 }; | 56 }; |
| 57 | 57 |
| 58 } // namespace | 58 } // namespace |
| 59 | 59 |
| 60 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( | 60 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( |
| 61 Plugin* plugin, | 61 Plugin* plugin, |
| 62 const std::string& pexe_url, | 62 const std::string& pexe_url, |
| 63 const PP_PNaClOptions& pnacl_options, | 63 const PP_PNaClOptions& pnacl_options, |
| 64 const pp::CompletionCallback& translate_notify_callback) { | 64 const pp::CompletionCallback& translate_notify_callback) { |
| 65 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", | |
| 66 static_cast<void*>(plugin), pexe_url.c_str())); | |
| 67 PnaclCoordinator* coordinator = | 65 PnaclCoordinator* coordinator = |
| 68 new PnaclCoordinator(plugin, pexe_url, | 66 new PnaclCoordinator(plugin, pexe_url, |
| 69 pnacl_options, | 67 pnacl_options, |
| 70 translate_notify_callback); | 68 translate_notify_callback); |
| 71 | 69 |
| 72 GetNaClInterface()->SetPNaClStartTime(plugin->pp_instance()); | 70 GetNaClInterface()->SetPNaClStartTime(plugin->pp_instance()); |
| 73 int cpus = plugin->nacl_interface()->GetNumberOfProcessors(); | 71 int cpus = plugin->nacl_interface()->GetNumberOfProcessors(); |
| 74 coordinator->num_threads_ = std::min(4, std::max(1, cpus)); | 72 coordinator->num_threads_ = std::min(4, std::max(1, cpus)); |
| 75 if (pnacl_options.use_subzero) { | 73 if (pnacl_options.use_subzero) { |
| 76 coordinator->split_module_count_ = 1; | 74 coordinator->split_module_count_ = 1; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 100 split_module_count_(0), | 98 split_module_count_(0), |
| 101 num_threads_(0), | 99 num_threads_(0), |
| 102 error_already_reported_(false), | 100 error_already_reported_(false), |
| 103 pexe_size_(0), | 101 pexe_size_(0), |
| 104 pexe_bytes_compiled_(0), | 102 pexe_bytes_compiled_(0), |
| 105 expected_pexe_size_(-1) { | 103 expected_pexe_size_(-1) { |
| 106 callback_factory_.Initialize(this); | 104 callback_factory_.Initialize(this); |
| 107 } | 105 } |
| 108 | 106 |
| 109 PnaclCoordinator::~PnaclCoordinator() { | 107 PnaclCoordinator::~PnaclCoordinator() { |
| 110 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p, " | |
| 111 "translate_thread=%p\n", | |
| 112 static_cast<void*>(this), translate_thread_.get())); | |
| 113 // Stopping the translate thread will cause the translate thread to try to | 108 // Stopping the translate thread will cause the translate thread to try to |
| 114 // run translation_complete_callback_ on the main thread. This destructor is | 109 // run translation_complete_callback_ on the main thread. This destructor is |
| 115 // running from the main thread, and by the time it exits, callback_factory_ | 110 // running from the main thread, and by the time it exits, callback_factory_ |
| 116 // will have been destroyed. This will result in the cancellation of | 111 // will have been destroyed. This will result in the cancellation of |
| 117 // translation_complete_callback_, so no notification will be delivered. | 112 // translation_complete_callback_, so no notification will be delivered. |
| 118 if (translate_thread_.get() != NULL) | 113 if (translate_thread_.get() != NULL) |
| 119 translate_thread_->AbortSubprocesses(); | 114 translate_thread_->AbortSubprocesses(); |
| 120 if (!translation_finished_reported_) { | 115 if (!translation_finished_reported_) { |
| 121 plugin_->nacl_interface()->ReportTranslationFinished( | 116 plugin_->nacl_interface()->ReportTranslationFinished( |
| 122 plugin_->pp_instance(), PP_FALSE, pnacl_options_.opt_level, | 117 plugin_->pp_instance(), PP_FALSE, pnacl_options_.opt_level, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 136 | 131 |
| 137 void PnaclCoordinator::ReportNonPpapiError(PP_NaClError err_code, | 132 void PnaclCoordinator::ReportNonPpapiError(PP_NaClError err_code, |
| 138 const std::string& message) { | 133 const std::string& message) { |
| 139 ErrorInfo error_info; | 134 ErrorInfo error_info; |
| 140 error_info.SetReport(err_code, message); | 135 error_info.SetReport(err_code, message); |
| 141 plugin_->ReportLoadError(error_info); | 136 plugin_->ReportLoadError(error_info); |
| 142 ExitWithError(); | 137 ExitWithError(); |
| 143 } | 138 } |
| 144 | 139 |
| 145 void PnaclCoordinator::ExitWithError() { | 140 void PnaclCoordinator::ExitWithError() { |
| 146 PLUGIN_PRINTF(("PnaclCoordinator::ExitWithError\n")); | |
| 147 // Free all the intermediate callbacks we ever created. | 141 // Free all the intermediate callbacks we ever created. |
| 148 // Note: this doesn't *cancel* the callbacks from the factories attached | 142 // Note: this doesn't *cancel* the callbacks from the factories attached |
| 149 // to the various helper classes (e.g., pnacl_resources). Thus, those | 143 // to the various helper classes (e.g., pnacl_resources). Thus, those |
| 150 // callbacks may still run asynchronously. We let those run but ignore | 144 // callbacks may still run asynchronously. We let those run but ignore |
| 151 // any other errors they may generate so that they do not end up running | 145 // any other errors they may generate so that they do not end up running |
| 152 // translate_notify_callback_, which has already been freed. | 146 // translate_notify_callback_, which has already been freed. |
| 153 callback_factory_.CancelAll(); | 147 callback_factory_.CancelAll(); |
| 154 if (!error_already_reported_) { | 148 if (!error_already_reported_) { |
| 155 error_already_reported_ = true; | 149 error_already_reported_ = true; |
| 156 translation_finished_reported_ = true; | 150 translation_finished_reported_ = true; |
| 157 plugin_->nacl_interface()->ReportTranslationFinished( | 151 plugin_->nacl_interface()->ReportTranslationFinished( |
| 158 plugin_->pp_instance(), PP_FALSE, pnacl_options_.opt_level, | 152 plugin_->pp_instance(), PP_FALSE, pnacl_options_.opt_level, |
| 159 pnacl_options_.use_subzero, 0, 0, 0); | 153 pnacl_options_.use_subzero, 0, 0, 0); |
| 160 translate_notify_callback_.Run(PP_ERROR_FAILED); | 154 translate_notify_callback_.Run(PP_ERROR_FAILED); |
| 161 } | 155 } |
| 162 } | 156 } |
| 163 | 157 |
| 164 // Signal that Pnacl translation completed normally. | 158 // Signal that Pnacl translation completed normally. |
| 165 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { | 159 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { |
| 166 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" | |
| 167 NACL_PRId32 ")\n", pp_error)); | |
| 168 // Bail out if there was an earlier error (e.g., pexe load failure), | 160 // Bail out if there was an earlier error (e.g., pexe load failure), |
| 169 // or if there is an error from the translation thread. | 161 // or if there is an error from the translation thread. |
| 170 if (translate_finish_error_ != PP_OK || pp_error != PP_OK) { | 162 if (translate_finish_error_ != PP_OK || pp_error != PP_OK) { |
| 171 plugin_->ReportLoadError(error_info_); | 163 plugin_->ReportLoadError(error_info_); |
| 172 ExitWithError(); | 164 ExitWithError(); |
| 173 return; | 165 return; |
| 174 } | 166 } |
| 175 | 167 |
| 176 // Send out one last progress event, to finish up the progress events | 168 // Send out one last progress event, to finish up the progress events |
| 177 // that were delayed (see the delay inserted in BitcodeGotCompiled). | 169 // that were delayed (see the delay inserted in BitcodeGotCompiled). |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 | 290 |
| 299 void PnaclCoordinator::BitcodeStreamGotData(const void* data, int32_t length) { | 291 void PnaclCoordinator::BitcodeStreamGotData(const void* data, int32_t length) { |
| 300 DCHECK(translate_thread_.get()); | 292 DCHECK(translate_thread_.get()); |
| 301 | 293 |
| 302 translate_thread_->PutBytes(data, length); | 294 translate_thread_->PutBytes(data, length); |
| 303 if (data && length > 0) | 295 if (data && length > 0) |
| 304 pexe_size_ += length; | 296 pexe_size_ += length; |
| 305 } | 297 } |
| 306 | 298 |
| 307 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { | 299 void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { |
| 308 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamDidFinish (pp_error=%" | |
| 309 NACL_PRId32 ")\n", pp_error)); | |
| 310 if (pp_error != PP_OK) { | 300 if (pp_error != PP_OK) { |
| 311 // Defer reporting the error and cleanup until after the translation | 301 // Defer reporting the error and cleanup until after the translation |
| 312 // thread returns, because it may be accessing the coordinator's | 302 // thread returns, because it may be accessing the coordinator's |
| 313 // objects or writing to the files. | 303 // objects or writing to the files. |
| 314 translate_finish_error_ = pp_error; | 304 translate_finish_error_ = pp_error; |
| 315 if (pp_error == PP_ERROR_ABORTED) { | 305 if (pp_error == PP_ERROR_ABORTED) { |
| 316 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_ABORTED, | 306 error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_ABORTED, |
| 317 "PnaclCoordinator: pexe load failed (aborted)."); | 307 "PnaclCoordinator: pexe load failed (aborted)."); |
| 318 } | 308 } |
| 319 if (pp_error == PP_ERROR_NOACCESS) { | 309 if (pp_error == PP_ERROR_NOACCESS) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 } | 353 } |
| 364 } | 354 } |
| 365 | 355 |
| 366 pp::CompletionCallback PnaclCoordinator::GetCompileProgressCallback( | 356 pp::CompletionCallback PnaclCoordinator::GetCompileProgressCallback( |
| 367 int64_t bytes_compiled) { | 357 int64_t bytes_compiled) { |
| 368 return callback_factory_.NewCallback(&PnaclCoordinator::BitcodeGotCompiled, | 358 return callback_factory_.NewCallback(&PnaclCoordinator::BitcodeGotCompiled, |
| 369 bytes_compiled); | 359 bytes_compiled); |
| 370 } | 360 } |
| 371 | 361 |
| 372 void PnaclCoordinator::LoadCompiler() { | 362 void PnaclCoordinator::LoadCompiler() { |
| 373 PLUGIN_PRINTF(("PnaclCoordinator::LoadCompiler")); | |
| 374 base::TimeTicks compiler_load_start_time = base::TimeTicks::Now(); | 363 base::TimeTicks compiler_load_start_time = base::TimeTicks::Now(); |
| 375 pp::CompletionCallback load_finished = callback_factory_.NewCallback( | 364 pp::CompletionCallback load_finished = callback_factory_.NewCallback( |
| 376 &PnaclCoordinator::RunCompile, compiler_load_start_time); | 365 &PnaclCoordinator::RunCompile, compiler_load_start_time); |
| 377 PnaclResources::ResourceType compiler_type = pnacl_options_.use_subzero | 366 PnaclResources::ResourceType compiler_type = pnacl_options_.use_subzero |
| 378 ? PnaclResources::SUBZERO | 367 ? PnaclResources::SUBZERO |
| 379 : PnaclResources::LLC; | 368 : PnaclResources::LLC; |
| 380 // Transfer file_info ownership to the sel_ldr launcher. | 369 // Transfer file_info ownership to the sel_ldr launcher. |
| 381 PP_NaClFileInfo file_info = resources_->TakeFileInfo(compiler_type); | 370 PP_NaClFileInfo file_info = resources_->TakeFileInfo(compiler_type); |
| 382 const std::string& url = resources_->GetUrl(compiler_type); | 371 const std::string& url = resources_->GetUrl(compiler_type); |
| 383 plugin_->LoadHelperNaClModule(url, file_info, &compiler_subprocess_, | 372 plugin_->LoadHelperNaClModule(url, file_info, &compiler_subprocess_, |
| 384 load_finished); | 373 load_finished); |
| 385 } | 374 } |
| 386 | 375 |
| 387 void PnaclCoordinator::RunCompile(int32_t pp_error, | 376 void PnaclCoordinator::RunCompile(int32_t pp_error, |
| 388 base::TimeTicks compiler_load_start_time) { | 377 base::TimeTicks compiler_load_start_time) { |
| 389 PLUGIN_PRINTF( | |
| 390 ("PnaclCoordinator::RunCompile (pp_error=%" NACL_PRId32 ")\n", pp_error)); | |
| 391 if (pp_error != PP_OK) { | 378 if (pp_error != PP_OK) { |
| 392 ReportNonPpapiError( | 379 ReportNonPpapiError( |
| 393 PP_NACL_ERROR_PNACL_LLC_SETUP, | 380 PP_NACL_ERROR_PNACL_LLC_SETUP, |
| 394 "PnaclCoordinator: Compiler process could not be created."); | 381 "PnaclCoordinator: Compiler process could not be created."); |
| 395 return; | 382 return; |
| 396 } | 383 } |
| 397 int64_t compiler_load_time_total = | 384 int64_t compiler_load_time_total = |
| 398 (base::TimeTicks::Now() - compiler_load_start_time).InMicroseconds(); | 385 (base::TimeTicks::Now() - compiler_load_start_time).InMicroseconds(); |
| 399 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.LoadCompiler", | 386 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.LoadCompiler", |
| 400 compiler_load_time_total); | 387 compiler_load_time_total); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 412 callback_factory_.NewCallback(&PnaclCoordinator::LoadLinker); | 399 callback_factory_.NewCallback(&PnaclCoordinator::LoadLinker); |
| 413 CHECK(translate_thread_ != NULL); | 400 CHECK(translate_thread_ != NULL); |
| 414 translate_thread_->SetupState( | 401 translate_thread_->SetupState( |
| 415 report_translate_finished, &compiler_subprocess_, &ld_subprocess_, | 402 report_translate_finished, &compiler_subprocess_, &ld_subprocess_, |
| 416 &obj_files_, num_threads_, &temp_nexe_file_, | 403 &obj_files_, num_threads_, &temp_nexe_file_, |
| 417 &error_info_, &pnacl_options_, architecture_attributes_, this); | 404 &error_info_, &pnacl_options_, architecture_attributes_, this); |
| 418 translate_thread_->RunCompile(compile_finished); | 405 translate_thread_->RunCompile(compile_finished); |
| 419 } | 406 } |
| 420 | 407 |
| 421 void PnaclCoordinator::LoadLinker(int32_t pp_error) { | 408 void PnaclCoordinator::LoadLinker(int32_t pp_error) { |
| 422 PLUGIN_PRINTF( | |
| 423 ("PnaclCoordinator::LoadLinker (pp_error=%" NACL_PRId32 ")\n", pp_error)); | |
| 424 // Errors in the previous step would have skipped to TranslateFinished | 409 // Errors in the previous step would have skipped to TranslateFinished |
| 425 // so we only expect PP_OK here. | 410 // so we only expect PP_OK here. |
| 426 DCHECK(pp_error == PP_OK); | 411 DCHECK(pp_error == PP_OK); |
| 427 if (pp_error != PP_OK) { | 412 if (pp_error != PP_OK) { |
| 428 return; | 413 return; |
| 429 } | 414 } |
| 430 ErrorInfo error_info; | 415 ErrorInfo error_info; |
| 431 base::TimeTicks ld_load_start_time = base::TimeTicks::Now(); | 416 base::TimeTicks ld_load_start_time = base::TimeTicks::Now(); |
| 432 pp::CompletionCallback load_finished = callback_factory_.NewCallback( | 417 pp::CompletionCallback load_finished = callback_factory_.NewCallback( |
| 433 &PnaclCoordinator::RunLink, ld_load_start_time); | 418 &PnaclCoordinator::RunLink, ld_load_start_time); |
| 434 // Transfer file_info ownership to the sel_ldr launcher. | 419 // Transfer file_info ownership to the sel_ldr launcher. |
| 435 PP_NaClFileInfo ld_file_info = resources_->TakeFileInfo(PnaclResources::LD); | 420 PP_NaClFileInfo ld_file_info = resources_->TakeFileInfo(PnaclResources::LD); |
| 436 plugin_->LoadHelperNaClModule(resources_->GetUrl(PnaclResources::LD), | 421 plugin_->LoadHelperNaClModule(resources_->GetUrl(PnaclResources::LD), |
| 437 ld_file_info, &ld_subprocess_, load_finished); | 422 ld_file_info, &ld_subprocess_, load_finished); |
| 438 } | 423 } |
| 439 | 424 |
| 440 void PnaclCoordinator::RunLink(int32_t pp_error, | 425 void PnaclCoordinator::RunLink(int32_t pp_error, |
| 441 base::TimeTicks ld_load_start_time) { | 426 base::TimeTicks ld_load_start_time) { |
| 442 PLUGIN_PRINTF( | |
| 443 ("PnaclCoordinator::RunLink (pp_error=%" NACL_PRId32 ")\n", pp_error)); | |
| 444 if (pp_error != PP_OK) { | 427 if (pp_error != PP_OK) { |
| 445 ReportNonPpapiError( | 428 ReportNonPpapiError( |
| 446 PP_NACL_ERROR_PNACL_LD_SETUP, | 429 PP_NACL_ERROR_PNACL_LD_SETUP, |
| 447 "PnaclCoordinator: Linker process could not be created."); | 430 "PnaclCoordinator: Linker process could not be created."); |
| 448 return; | 431 return; |
| 449 } | 432 } |
| 450 GetNaClInterface()->LogTranslateTime( | 433 GetNaClInterface()->LogTranslateTime( |
| 451 "NaCl.Perf.PNaClLoadTime.LoadLinker", | 434 "NaCl.Perf.PNaClLoadTime.LoadLinker", |
| 452 (base::TimeTicks::Now() - ld_load_start_time).InMicroseconds()); | 435 (base::TimeTicks::Now() - ld_load_start_time).InMicroseconds()); |
| 453 translate_thread_->RunLink(); | 436 translate_thread_->RunLink(); |
| 454 } | 437 } |
| 455 | 438 |
| 456 } // namespace plugin | 439 } // namespace plugin |
| OLD | NEW |