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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 const pp::CompletionCallback& translate_notify_callback) { | 94 const pp::CompletionCallback& translate_notify_callback) { |
95 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", | 95 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", |
96 static_cast<void*>(plugin), pexe_url.c_str())); | 96 static_cast<void*>(plugin), pexe_url.c_str())); |
97 PnaclCoordinator* coordinator = | 97 PnaclCoordinator* coordinator = |
98 new PnaclCoordinator(plugin, pexe_url, | 98 new PnaclCoordinator(plugin, pexe_url, |
99 pnacl_options, | 99 pnacl_options, |
100 translate_notify_callback); | 100 translate_notify_callback); |
101 | 101 |
102 GetNaClInterface()->SetPNaClStartTime(plugin->pp_instance()); | 102 GetNaClInterface()->SetPNaClStartTime(plugin->pp_instance()); |
103 int cpus = plugin->nacl_interface()->GetNumberOfProcessors(); | 103 int cpus = plugin->nacl_interface()->GetNumberOfProcessors(); |
104 coordinator->split_module_count_ = std::min(4, std::max(1, cpus)); | 104 coordinator->num_threads_ = std::min(4, std::max(1, cpus)); |
105 | 105 if (pnacl_options.use_subzero) { |
| 106 coordinator->split_module_count_ = 1; |
| 107 } else { |
| 108 coordinator->split_module_count_ = coordinator->num_threads_; |
| 109 } |
106 // First start a network request for the pexe, to tickle the component | 110 // First start a network request for the pexe, to tickle the component |
107 // updater's On-Demand resource throttler, and to get Last-Modified/ETag | 111 // updater's On-Demand resource throttler, and to get Last-Modified/ETag |
108 // cache information. We can cancel the request later if there's | 112 // cache information. We can cancel the request later if there's |
109 // a bitcode->nexe cache hit. | 113 // a bitcode->nexe cache hit. |
110 coordinator->OpenBitcodeStream(); | 114 coordinator->OpenBitcodeStream(); |
111 return coordinator; | 115 return coordinator; |
112 } | 116 } |
113 | 117 |
114 PnaclCoordinator::PnaclCoordinator( | 118 PnaclCoordinator::PnaclCoordinator( |
115 Plugin* plugin, | 119 Plugin* plugin, |
116 const std::string& pexe_url, | 120 const std::string& pexe_url, |
117 const PP_PNaClOptions& pnacl_options, | 121 const PP_PNaClOptions& pnacl_options, |
118 const pp::CompletionCallback& translate_notify_callback) | 122 const pp::CompletionCallback& translate_notify_callback) |
119 : translate_finish_error_(PP_OK), | 123 : translate_finish_error_(PP_OK), |
120 plugin_(plugin), | 124 plugin_(plugin), |
121 translate_notify_callback_(translate_notify_callback), | 125 translate_notify_callback_(translate_notify_callback), |
122 translation_finished_reported_(false), | 126 translation_finished_reported_(false), |
123 pexe_url_(pexe_url), | 127 pexe_url_(pexe_url), |
124 pnacl_options_(pnacl_options), | 128 pnacl_options_(pnacl_options), |
125 architecture_attributes_(GetArchitectureAttributes(plugin)), | 129 architecture_attributes_(GetArchitectureAttributes(plugin)), |
126 split_module_count_(1), | 130 split_module_count_(0), |
127 error_already_reported_(false), | 131 num_threads_(0), |
128 pexe_size_(0), | 132 error_already_reported_(false), |
129 pexe_bytes_compiled_(0), | 133 pexe_size_(0), |
130 expected_pexe_size_(-1) { | 134 pexe_bytes_compiled_(0), |
| 135 expected_pexe_size_(-1) { |
131 callback_factory_.Initialize(this); | 136 callback_factory_.Initialize(this); |
132 } | 137 } |
133 | 138 |
134 PnaclCoordinator::~PnaclCoordinator() { | 139 PnaclCoordinator::~PnaclCoordinator() { |
135 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p, " | 140 PLUGIN_PRINTF(("PnaclCoordinator::~PnaclCoordinator (this=%p, " |
136 "translate_thread=%p\n", | 141 "translate_thread=%p\n", |
137 static_cast<void*>(this), translate_thread_.get())); | 142 static_cast<void*>(this), translate_thread_.get())); |
138 // Stopping the translate thread will cause the translate thread to try to | 143 // Stopping the translate thread will cause the translate thread to try to |
139 // run translation_complete_callback_ on the main thread. This destructor is | 144 // run translation_complete_callback_ on the main thread. This destructor is |
140 // running from the main thread, and by the time it exits, callback_factory_ | 145 // running from the main thread, and by the time it exits, callback_factory_ |
141 // will have been destroyed. This will result in the cancellation of | 146 // will have been destroyed. This will result in the cancellation of |
142 // translation_complete_callback_, so no notification will be delivered. | 147 // translation_complete_callback_, so no notification will be delivered. |
143 if (translate_thread_.get() != NULL) | 148 if (translate_thread_.get() != NULL) |
144 translate_thread_->AbortSubprocesses(); | 149 translate_thread_->AbortSubprocesses(); |
145 if (!translation_finished_reported_) { | 150 if (!translation_finished_reported_) { |
146 plugin_->nacl_interface()->ReportTranslationFinished( | 151 plugin_->nacl_interface()->ReportTranslationFinished( |
147 plugin_->pp_instance(), | 152 plugin_->pp_instance(), PP_FALSE, pnacl_options_.opt_level, |
148 PP_FALSE, 0, 0, 0); | 153 pnacl_options_.use_subzero, 0, 0); |
149 } | 154 } |
150 // Force deleting the translate_thread now. It must be deleted | 155 // Force deleting the translate_thread now. It must be deleted |
151 // before any scoped_* fields hanging off of PnaclCoordinator | 156 // before any scoped_* fields hanging off of PnaclCoordinator |
152 // since the thread may be accessing those fields. | 157 // since the thread may be accessing those fields. |
153 // It will also be accessing obj_files_. | 158 // It will also be accessing obj_files_. |
154 translate_thread_.reset(NULL); | 159 translate_thread_.reset(NULL); |
155 for (size_t i = 0; i < obj_files_.size(); i++) | 160 for (size_t i = 0; i < obj_files_.size(); i++) |
156 delete obj_files_[i]; | 161 delete obj_files_[i]; |
157 } | 162 } |
158 | 163 |
(...skipping 27 matching lines...) Expand all Loading... |
186 // Note: this doesn't *cancel* the callbacks from the factories attached | 191 // Note: this doesn't *cancel* the callbacks from the factories attached |
187 // to the various helper classes (e.g., pnacl_resources). Thus, those | 192 // to the various helper classes (e.g., pnacl_resources). Thus, those |
188 // callbacks may still run asynchronously. We let those run but ignore | 193 // callbacks may still run asynchronously. We let those run but ignore |
189 // any other errors they may generate so that they do not end up running | 194 // any other errors they may generate so that they do not end up running |
190 // translate_notify_callback_, which has already been freed. | 195 // translate_notify_callback_, which has already been freed. |
191 callback_factory_.CancelAll(); | 196 callback_factory_.CancelAll(); |
192 if (!error_already_reported_) { | 197 if (!error_already_reported_) { |
193 error_already_reported_ = true; | 198 error_already_reported_ = true; |
194 translation_finished_reported_ = true; | 199 translation_finished_reported_ = true; |
195 plugin_->nacl_interface()->ReportTranslationFinished( | 200 plugin_->nacl_interface()->ReportTranslationFinished( |
196 plugin_->pp_instance(), | 201 plugin_->pp_instance(), PP_FALSE, pnacl_options_.opt_level, |
197 PP_FALSE, 0, 0, 0); | 202 pnacl_options_.use_subzero, 0, 0); |
198 translate_notify_callback_.Run(PP_ERROR_FAILED); | 203 translate_notify_callback_.Run(PP_ERROR_FAILED); |
199 } | 204 } |
200 } | 205 } |
201 | 206 |
202 // Signal that Pnacl translation completed normally. | 207 // Signal that Pnacl translation completed normally. |
203 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { | 208 void PnaclCoordinator::TranslateFinished(int32_t pp_error) { |
204 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" | 209 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished (pp_error=%" |
205 NACL_PRId32 ")\n", pp_error)); | 210 NACL_PRId32 ")\n", pp_error)); |
206 // Bail out if there was an earlier error (e.g., pexe load failure), | 211 // Bail out if there was an earlier error (e.g., pexe load failure), |
207 // or if there is an error from the translation thread. | 212 // or if there is an error from the translation thread. |
(...skipping 27 matching lines...) Expand all Loading... |
235 } | 240 } |
236 // The nexe is written to the temp_nexe_file_. We must Reset() the file | 241 // The nexe is written to the temp_nexe_file_. We must Reset() the file |
237 // pointer to be able to read it again from the beginning. | 242 // pointer to be able to read it again from the beginning. |
238 temp_nexe_file_->Reset(); | 243 temp_nexe_file_->Reset(); |
239 | 244 |
240 // Report to the browser that translation finished. The browser will take | 245 // Report to the browser that translation finished. The browser will take |
241 // care of storing the nexe in the cache. | 246 // care of storing the nexe in the cache. |
242 translation_finished_reported_ = true; | 247 translation_finished_reported_ = true; |
243 plugin_->nacl_interface()->ReportTranslationFinished( | 248 plugin_->nacl_interface()->ReportTranslationFinished( |
244 plugin_->pp_instance(), PP_TRUE, pnacl_options_.opt_level, | 249 plugin_->pp_instance(), PP_TRUE, pnacl_options_.opt_level, |
245 pexe_size_, translate_thread_->GetCompileTime()); | 250 pnacl_options_.use_subzero, pexe_size_, |
| 251 translate_thread_->GetCompileTime()); |
246 | 252 |
247 NexeReadDidOpen(PP_OK); | 253 NexeReadDidOpen(PP_OK); |
248 } | 254 } |
249 | 255 |
250 void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { | 256 void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { |
251 PLUGIN_PRINTF(("PnaclCoordinator::NexeReadDidOpen (pp_error=%" | 257 PLUGIN_PRINTF(("PnaclCoordinator::NexeReadDidOpen (pp_error=%" |
252 NACL_PRId32 ")\n", pp_error)); | 258 NACL_PRId32 ")\n", pp_error)); |
253 if (pp_error != PP_OK) { | 259 if (pp_error != PP_OK) { |
254 if (pp_error == PP_ERROR_FILENOTFOUND) { | 260 if (pp_error == PP_ERROR_FILENOTFOUND) { |
255 ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_NOTFOUND, | 261 ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_NOTFOUND, |
(...skipping 22 matching lines...) Expand all Loading... |
278 // that get downloaded before the compilation thread is accepting | 284 // that get downloaded before the compilation thread is accepting |
279 // SRPCs won't get dropped. | 285 // SRPCs won't get dropped. |
280 translate_thread_.reset(new PnaclTranslateThread()); | 286 translate_thread_.reset(new PnaclTranslateThread()); |
281 if (translate_thread_ == NULL) { | 287 if (translate_thread_ == NULL) { |
282 ReportNonPpapiError( | 288 ReportNonPpapiError( |
283 PP_NACL_ERROR_PNACL_THREAD_CREATE, | 289 PP_NACL_ERROR_PNACL_THREAD_CREATE, |
284 "PnaclCoordinator: could not allocate translation thread."); | 290 "PnaclCoordinator: could not allocate translation thread."); |
285 return; | 291 return; |
286 } | 292 } |
287 | 293 |
288 GetNaClInterface()->StreamPexe(plugin_->pp_instance(), | 294 GetNaClInterface()->StreamPexe( |
289 pexe_url_.c_str(), | 295 plugin_->pp_instance(), pexe_url_.c_str(), pnacl_options_.opt_level, |
290 pnacl_options_.opt_level, | 296 pnacl_options_.use_subzero, &kPexeStreamHandler, this); |
291 &kPexeStreamHandler, | |
292 this); | |
293 } | 297 } |
294 | 298 |
295 void PnaclCoordinator::BitcodeStreamCacheHit(PP_FileHandle handle) { | 299 void PnaclCoordinator::BitcodeStreamCacheHit(PP_FileHandle handle) { |
296 if (handle == PP_kInvalidFileHandle) { | 300 if (handle == PP_kInvalidFileHandle) { |
297 ReportNonPpapiError( | 301 ReportNonPpapiError( |
298 PP_NACL_ERROR_PNACL_CREATE_TEMP, | 302 PP_NACL_ERROR_PNACL_CREATE_TEMP, |
299 std::string( | 303 std::string( |
300 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); | 304 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); |
301 BitcodeStreamDidFinish(PP_ERROR_FAILED); | 305 BitcodeStreamDidFinish(PP_ERROR_FAILED); |
302 return; | 306 return; |
303 } | 307 } |
304 temp_nexe_file_.reset(new TempFile(plugin_, handle)); | 308 temp_nexe_file_.reset(new TempFile(plugin_, handle)); |
305 // Open it for reading as the cached nexe file. | 309 // Open it for reading as the cached nexe file. |
306 NexeReadDidOpen(temp_nexe_file_->Open(false)); | 310 NexeReadDidOpen(temp_nexe_file_->Open(false)); |
307 } | 311 } |
308 | 312 |
309 void PnaclCoordinator::BitcodeStreamCacheMiss(int64_t expected_pexe_size, | 313 void PnaclCoordinator::BitcodeStreamCacheMiss(int64_t expected_pexe_size, |
310 PP_FileHandle nexe_handle) { | 314 PP_FileHandle nexe_handle) { |
311 // IMPORTANT: Make sure that PnaclResources::StartLoad() is only | 315 // IMPORTANT: Make sure that PnaclResources::StartLoad() is only |
312 // called after you receive a response to a request for a .pexe file. | 316 // called after you receive a response to a request for a .pexe file. |
313 // | 317 // |
314 // The component updater's resource throttles + OnDemand update/install | 318 // The component updater's resource throttles + OnDemand update/install |
315 // should block the URL request until the compiler is present. Now we | 319 // should block the URL request until the compiler is present. Now we |
316 // can load the resources (e.g. llc and ld nexes). | 320 // can load the resources (e.g. llc and ld nexes). |
317 resources_.reset(new PnaclResources(plugin_)); | 321 resources_.reset(new PnaclResources(plugin_, pnacl_options_.use_subzero)); |
318 CHECK(resources_ != NULL); | 322 CHECK(resources_ != NULL); |
319 | 323 |
320 // The first step of loading resources: read the resource info file. | 324 // The first step of loading resources: read the resource info file. |
321 if (!resources_->ReadResourceInfo()) { | 325 if (!resources_->ReadResourceInfo()) { |
322 ExitWithError(); | 326 ExitWithError(); |
323 return; | 327 return; |
324 } | 328 } |
325 | 329 |
326 // Second step of loading resources: call StartLoad to load pnacl-llc | 330 // Second step of loading resources: call StartLoad to load pnacl-llc |
327 // and pnacl-ld, based on the filenames found in the resource info file. | 331 // and pnacl-ld, based on the filenames found in the resource info file. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 | 438 |
435 void PnaclCoordinator::RunTranslate(int32_t pp_error) { | 439 void PnaclCoordinator::RunTranslate(int32_t pp_error) { |
436 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" | 440 PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" |
437 NACL_PRId32 ")\n", pp_error)); | 441 NACL_PRId32 ")\n", pp_error)); |
438 // Invoke llc followed by ld off the main thread. This allows use of | 442 // Invoke llc followed by ld off the main thread. This allows use of |
439 // blocking RPCs that would otherwise block the JavaScript main thread. | 443 // blocking RPCs that would otherwise block the JavaScript main thread. |
440 pp::CompletionCallback report_translate_finished = | 444 pp::CompletionCallback report_translate_finished = |
441 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); | 445 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); |
442 | 446 |
443 CHECK(translate_thread_ != NULL); | 447 CHECK(translate_thread_ != NULL); |
444 translate_thread_->RunTranslate(report_translate_finished, | 448 translate_thread_->RunTranslate(report_translate_finished, &obj_files_, |
445 &obj_files_, | 449 num_threads_, temp_nexe_file_.get(), |
446 temp_nexe_file_.get(), | 450 invalid_desc_wrapper_.get(), &error_info_, |
447 invalid_desc_wrapper_.get(), | 451 resources_.get(), &pnacl_options_, |
448 &error_info_, | 452 architecture_attributes_, this, plugin_); |
449 resources_.get(), | |
450 &pnacl_options_, | |
451 architecture_attributes_, | |
452 this, | |
453 plugin_); | |
454 } | 453 } |
455 | 454 |
456 } // namespace plugin | 455 } // namespace plugin |
OLD | NEW |