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 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "components/nacl/renderer/plugin/plugin.h" | 12 #include "components/nacl/renderer/plugin/plugin.h" |
13 #include "components/nacl/renderer/plugin/plugin_error.h" | 13 #include "components/nacl/renderer/plugin/plugin_error.h" |
14 #include "components/nacl/renderer/plugin/pnacl_translate_thread.h" | 14 #include "components/nacl/renderer/plugin/pnacl_translate_thread.h" |
15 #include "components/nacl/renderer/plugin/service_runtime.h" | 15 #include "components/nacl/renderer/plugin/service_runtime.h" |
16 #include "components/nacl/renderer/plugin/temporary_file.h" | |
17 #include "ppapi/c/pp_bool.h" | 16 #include "ppapi/c/pp_bool.h" |
18 #include "ppapi/c/pp_errors.h" | 17 #include "ppapi/c/pp_errors.h" |
19 | 18 |
20 namespace plugin { | 19 namespace plugin { |
21 | 20 |
22 namespace { | 21 namespace { |
23 | 22 |
24 std::string GetArchitectureAttributes(Plugin* plugin) { | 23 std::string GetArchitectureAttributes(Plugin* plugin) { |
25 pp::Var attrs_var(pp::PASS_REF, | 24 pp::Var attrs_var(pp::PASS_REF, |
26 plugin->nacl_interface()->GetCpuFeatureAttrs()); | 25 plugin->nacl_interface()->GetCpuFeatureAttrs()); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 if (!translation_finished_reported_) { | 120 if (!translation_finished_reported_) { |
122 plugin_->nacl_interface()->ReportTranslationFinished( | 121 plugin_->nacl_interface()->ReportTranslationFinished( |
123 plugin_->pp_instance(), PP_FALSE, pnacl_options_.opt_level, | 122 plugin_->pp_instance(), PP_FALSE, pnacl_options_.opt_level, |
124 pnacl_options_.use_subzero, 0, 0, 0); | 123 pnacl_options_.use_subzero, 0, 0, 0); |
125 } | 124 } |
126 // Force deleting the translate_thread now. It must be deleted | 125 // Force deleting the translate_thread now. It must be deleted |
127 // before any scoped_* fields hanging off of PnaclCoordinator | 126 // before any scoped_* fields hanging off of PnaclCoordinator |
128 // since the thread may be accessing those fields. | 127 // since the thread may be accessing those fields. |
129 // It will also be accessing obj_files_. | 128 // It will also be accessing obj_files_. |
130 translate_thread_.reset(NULL); | 129 translate_thread_.reset(NULL); |
131 for (size_t i = 0; i < obj_files_.size(); i++) | |
132 delete obj_files_[i]; | |
133 } | 130 } |
134 | 131 |
135 PP_FileHandle PnaclCoordinator::TakeTranslatedFileHandle() { | 132 PP_FileHandle PnaclCoordinator::TakeTranslatedFileHandle() { |
136 DCHECK(temp_nexe_file_ != NULL); | 133 DCHECK(temp_nexe_file_.IsValid()); |
137 return temp_nexe_file_->TakeFileHandle(); | 134 return temp_nexe_file_.TakePlatformFile(); |
138 } | 135 } |
139 | 136 |
140 void PnaclCoordinator::ReportNonPpapiError(PP_NaClError err_code, | 137 void PnaclCoordinator::ReportNonPpapiError(PP_NaClError err_code, |
141 const std::string& message) { | 138 const std::string& message) { |
142 ErrorInfo error_info; | 139 ErrorInfo error_info; |
143 error_info.SetReport(err_code, message); | 140 error_info.SetReport(err_code, message); |
144 plugin_->ReportLoadError(error_info); | 141 plugin_->ReportLoadError(error_info); |
145 ExitWithError(); | 142 ExitWithError(); |
146 } | 143 } |
147 | 144 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 // that were delayed (see the delay inserted in BitcodeGotCompiled). | 177 // that were delayed (see the delay inserted in BitcodeGotCompiled). |
181 if (expected_pexe_size_ != -1) { | 178 if (expected_pexe_size_ != -1) { |
182 pexe_bytes_compiled_ = expected_pexe_size_; | 179 pexe_bytes_compiled_ = expected_pexe_size_; |
183 GetNaClInterface()->DispatchEvent(plugin_->pp_instance(), | 180 GetNaClInterface()->DispatchEvent(plugin_->pp_instance(), |
184 PP_NACL_EVENT_PROGRESS, | 181 PP_NACL_EVENT_PROGRESS, |
185 pexe_url_.c_str(), | 182 pexe_url_.c_str(), |
186 PP_TRUE, | 183 PP_TRUE, |
187 pexe_bytes_compiled_, | 184 pexe_bytes_compiled_, |
188 expected_pexe_size_); | 185 expected_pexe_size_); |
189 } | 186 } |
190 int64_t nexe_size = temp_nexe_file_->GetLength(); | 187 int64_t nexe_size = temp_nexe_file_.GetLength(); |
191 // The nexe is written to the temp_nexe_file_. We must Reset() the file | 188 // The nexe is written to the temp_nexe_file_. We must reset the file |
192 // pointer to be able to read it again from the beginning. | 189 // pointer to be able to read it again from the beginning. |
193 temp_nexe_file_->Reset(); | 190 temp_nexe_file_.Seek(base::File::FROM_BEGIN, 0); |
194 | 191 |
195 // Report to the browser that translation finished. The browser will take | 192 // Report to the browser that translation finished. The browser will take |
196 // care of storing the nexe in the cache. | 193 // care of storing the nexe in the cache. |
197 translation_finished_reported_ = true; | 194 translation_finished_reported_ = true; |
198 plugin_->nacl_interface()->ReportTranslationFinished( | 195 plugin_->nacl_interface()->ReportTranslationFinished( |
199 plugin_->pp_instance(), PP_TRUE, pnacl_options_.opt_level, | 196 plugin_->pp_instance(), PP_TRUE, pnacl_options_.opt_level, |
200 pnacl_options_.use_subzero, nexe_size, pexe_size_, | 197 pnacl_options_.use_subzero, nexe_size, pexe_size_, |
201 translate_thread_->GetCompileTime()); | 198 translate_thread_->GetCompileTime()); |
202 | 199 |
203 NexeReadDidOpen(); | 200 NexeReadDidOpen(); |
204 } | 201 } |
205 | 202 |
206 void PnaclCoordinator::NexeReadDidOpen() { | 203 void PnaclCoordinator::NexeReadDidOpen() { |
207 if (!temp_nexe_file_->IsValid()) { | 204 if (!temp_nexe_file_.IsValid()) { |
208 ReportNonPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_OTHER, | 205 ReportNonPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_OTHER, |
209 "Failed to open translated nexe."); | 206 "Failed to open translated nexe."); |
210 return; | 207 return; |
211 } | 208 } |
212 | 209 |
213 translate_notify_callback_.Run(PP_OK); | 210 translate_notify_callback_.Run(PP_OK); |
214 } | 211 } |
215 | 212 |
216 void PnaclCoordinator::OpenBitcodeStream() { | 213 void PnaclCoordinator::OpenBitcodeStream() { |
217 // Even though we haven't started downloading, create the translation | 214 // Even though we haven't started downloading, create the translation |
(...skipping 15 matching lines...) Expand all Loading... |
233 | 230 |
234 void PnaclCoordinator::BitcodeStreamCacheHit(PP_FileHandle handle) { | 231 void PnaclCoordinator::BitcodeStreamCacheHit(PP_FileHandle handle) { |
235 if (handle == PP_kInvalidFileHandle) { | 232 if (handle == PP_kInvalidFileHandle) { |
236 ReportNonPpapiError( | 233 ReportNonPpapiError( |
237 PP_NACL_ERROR_PNACL_CREATE_TEMP, | 234 PP_NACL_ERROR_PNACL_CREATE_TEMP, |
238 std::string( | 235 std::string( |
239 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); | 236 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); |
240 BitcodeStreamDidFinish(PP_ERROR_FAILED); | 237 BitcodeStreamDidFinish(PP_ERROR_FAILED); |
241 return; | 238 return; |
242 } | 239 } |
243 temp_nexe_file_.reset(new TempFile(plugin_, handle)); | 240 temp_nexe_file_ = base::File(handle); |
244 // Open it for reading as the cached nexe file. | |
245 NexeReadDidOpen(); | 241 NexeReadDidOpen(); |
246 } | 242 } |
247 | 243 |
248 void PnaclCoordinator::BitcodeStreamCacheMiss(int64_t expected_pexe_size, | 244 void PnaclCoordinator::BitcodeStreamCacheMiss(int64_t expected_pexe_size, |
249 PP_FileHandle nexe_handle) { | 245 PP_FileHandle nexe_handle) { |
250 // IMPORTANT: Make sure that PnaclResources::StartLoad() is only | 246 // IMPORTANT: Make sure that PnaclResources::StartLoad() is only |
251 // called after you receive a response to a request for a .pexe file. | 247 // called after you receive a response to a request for a .pexe file. |
252 // | 248 // |
253 // The component updater's resource throttles + OnDemand update/install | 249 // The component updater's resource throttles + OnDemand update/install |
254 // should block the URL request until the compiler is present. Now we | 250 // should block the URL request until the compiler is present. Now we |
(...skipping 15 matching lines...) Expand all Loading... |
270 PP_NACL_ERROR_PNACL_RESOURCE_FETCH, | 266 PP_NACL_ERROR_PNACL_RESOURCE_FETCH, |
271 std::string("The Portable Native Client (pnacl) component is not " | 267 std::string("The Portable Native Client (pnacl) component is not " |
272 "installed. Please consult chrome://components for more " | 268 "installed. Please consult chrome://components for more " |
273 "information.")); | 269 "information.")); |
274 return; | 270 return; |
275 } | 271 } |
276 | 272 |
277 expected_pexe_size_ = expected_pexe_size; | 273 expected_pexe_size_ = expected_pexe_size; |
278 | 274 |
279 for (int i = 0; i < split_module_count_; i++) { | 275 for (int i = 0; i < split_module_count_; i++) { |
280 PP_FileHandle obj_handle = | 276 base::File temp_file( |
281 plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance()); | 277 plugin_->nacl_interface()->CreateTemporaryFile(plugin_->pp_instance())); |
282 scoped_ptr<TempFile> temp_file(new TempFile(plugin_, obj_handle)); | 278 if (!temp_file.IsValid()) { |
283 if (!temp_file->IsValid()) { | |
284 ReportNonPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, | 279 ReportNonPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, |
285 "Failed to open scratch object file."); | 280 "Failed to open scratch object file."); |
286 return; | 281 return; |
287 } else { | |
288 obj_files_.push_back(temp_file.release()); | |
289 } | 282 } |
| 283 obj_files_.push_back(std::move(temp_file)); |
290 } | 284 } |
291 | 285 |
292 temp_nexe_file_.reset(new TempFile(plugin_, nexe_handle)); | 286 temp_nexe_file_ = base::File(nexe_handle); |
293 // Open the nexe file for connecting ld and sel_ldr. | 287 // Open the nexe file for connecting ld and sel_ldr. |
294 // Start translation when done with this last step of setup! | 288 // Start translation when done with this last step of setup! |
295 if (!temp_nexe_file_->IsValid()) { | 289 if (!temp_nexe_file_.IsValid()) { |
296 ReportNonPpapiError( | 290 ReportNonPpapiError( |
297 PP_NACL_ERROR_PNACL_CREATE_TEMP, | 291 PP_NACL_ERROR_PNACL_CREATE_TEMP, |
298 std::string( | 292 std::string( |
299 "PnaclCoordinator: Got bad temp file handle from writing nexe")); | 293 "PnaclCoordinator: Got bad temp file handle from writing nexe")); |
300 return; | 294 return; |
301 } | 295 } |
302 LoadCompiler(); | 296 LoadCompiler(); |
303 } | 297 } |
304 | 298 |
305 void PnaclCoordinator::BitcodeStreamGotData(const void* data, int32_t length) { | 299 void PnaclCoordinator::BitcodeStreamGotData(const void* data, int32_t length) { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 | 406 |
413 // Invoke llc followed by ld off the main thread. This allows use of | 407 // Invoke llc followed by ld off the main thread. This allows use of |
414 // blocking RPCs that would otherwise block the JavaScript main thread. | 408 // blocking RPCs that would otherwise block the JavaScript main thread. |
415 pp::CompletionCallback report_translate_finished = | 409 pp::CompletionCallback report_translate_finished = |
416 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); | 410 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); |
417 pp::CompletionCallback compile_finished = | 411 pp::CompletionCallback compile_finished = |
418 callback_factory_.NewCallback(&PnaclCoordinator::LoadLinker); | 412 callback_factory_.NewCallback(&PnaclCoordinator::LoadLinker); |
419 CHECK(translate_thread_ != NULL); | 413 CHECK(translate_thread_ != NULL); |
420 translate_thread_->SetupState( | 414 translate_thread_->SetupState( |
421 report_translate_finished, &compiler_subprocess_, &ld_subprocess_, | 415 report_translate_finished, &compiler_subprocess_, &ld_subprocess_, |
422 &obj_files_, num_threads_, temp_nexe_file_.get(), | 416 &obj_files_, num_threads_, &temp_nexe_file_, |
423 &error_info_, &pnacl_options_, architecture_attributes_, this); | 417 &error_info_, &pnacl_options_, architecture_attributes_, this); |
424 translate_thread_->RunCompile(compile_finished); | 418 translate_thread_->RunCompile(compile_finished); |
425 } | 419 } |
426 | 420 |
427 void PnaclCoordinator::LoadLinker(int32_t pp_error) { | 421 void PnaclCoordinator::LoadLinker(int32_t pp_error) { |
428 PLUGIN_PRINTF( | 422 PLUGIN_PRINTF( |
429 ("PnaclCoordinator::LoadLinker (pp_error=%" NACL_PRId32 ")\n", pp_error)); | 423 ("PnaclCoordinator::LoadLinker (pp_error=%" NACL_PRId32 ")\n", pp_error)); |
430 // Errors in the previous step would have skipped to TranslateFinished | 424 // Errors in the previous step would have skipped to TranslateFinished |
431 // so we only expect PP_OK here. | 425 // so we only expect PP_OK here. |
432 DCHECK(pp_error == PP_OK); | 426 DCHECK(pp_error == PP_OK); |
(...skipping 19 matching lines...) Expand all Loading... |
452 "PnaclCoordinator: Linker process could not be created."); | 446 "PnaclCoordinator: Linker process could not be created."); |
453 return; | 447 return; |
454 } | 448 } |
455 GetNaClInterface()->LogTranslateTime( | 449 GetNaClInterface()->LogTranslateTime( |
456 "NaCl.Perf.PNaClLoadTime.LoadLinker", | 450 "NaCl.Perf.PNaClLoadTime.LoadLinker", |
457 NaClGetTimeOfDayMicroseconds() - ld_load_start_time); | 451 NaClGetTimeOfDayMicroseconds() - ld_load_start_time); |
458 translate_thread_->RunLink(); | 452 translate_thread_->RunLink(); |
459 } | 453 } |
460 | 454 |
461 } // namespace plugin | 455 } // namespace plugin |
OLD | NEW |