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 |