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 "ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h" | 5 #include "ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h" |
6 | 6 |
7 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 7 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
8 #include "ppapi/native_client/src/trusted/plugin/plugin.h" | 8 #include "ppapi/native_client/src/trusted/plugin/plugin.h" |
9 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" | 9 #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" |
10 #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" | 10 #include "ppapi/native_client/src/trusted/plugin/pnacl_resources.h" |
11 #include "ppapi/native_client/src/trusted/plugin/srpc_params.h" | 11 #include "ppapi/native_client/src/trusted/plugin/srpc_params.h" |
12 #include "ppapi/native_client/src/trusted/plugin/temporary_file.h" | 12 #include "ppapi/native_client/src/trusted/plugin/temporary_file.h" |
13 #include "ppapi/native_client/src/trusted/plugin/utility.h" | 13 #include "ppapi/native_client/src/trusted/plugin/utility.h" |
14 | 14 |
15 namespace plugin { | 15 namespace plugin { |
16 | 16 |
17 PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false), | 17 PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false), |
18 ld_subprocess_active_(false), | 18 ld_subprocess_active_(false), |
19 done_(false), | 19 done_(false), |
20 time_stats_(), | 20 time_stats_(), |
21 manifest_(NULL), | 21 manifest_(NULL), |
22 obj_file_(NULL), | 22 obj_files_(NULL), |
23 nexe_file_(NULL), | 23 nexe_file_(NULL), |
24 coordinator_error_info_(NULL), | 24 coordinator_error_info_(NULL), |
25 resources_(NULL), | 25 resources_(NULL), |
26 coordinator_(NULL), | 26 coordinator_(NULL), |
27 plugin_(NULL) { | 27 plugin_(NULL) { |
28 NaClXMutexCtor(&subprocess_mu_); | 28 NaClXMutexCtor(&subprocess_mu_); |
29 NaClXMutexCtor(&cond_mu_); | 29 NaClXMutexCtor(&cond_mu_); |
30 NaClXCondVarCtor(&buffer_cond_); | 30 NaClXCondVarCtor(&buffer_cond_); |
31 } | 31 } |
32 | 32 |
33 void PnaclTranslateThread::RunTranslate( | 33 void PnaclTranslateThread::RunTranslate( |
34 const pp::CompletionCallback& finish_callback, | 34 const pp::CompletionCallback& finish_callback, |
35 const Manifest* manifest, | 35 const Manifest* manifest, |
36 TempFile* obj_file, | 36 const std::vector<TempFile*> *obj_files, |
37 TempFile* nexe_file, | 37 TempFile* nexe_file, |
38 ErrorInfo* error_info, | 38 ErrorInfo* error_info, |
39 PnaclResources* resources, | 39 PnaclResources* resources, |
40 PnaclOptions* pnacl_options, | 40 PnaclOptions* pnacl_options, |
41 PnaclCoordinator* coordinator, | 41 PnaclCoordinator* coordinator, |
42 Plugin* plugin) { | 42 Plugin* plugin) { |
jvoung (off chromium)
2014/02/14 01:43:44
extra space
Derek Schuff
2014/02/14 06:11:23
Done.
| |
43 PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n")); | 43 PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n")); |
44 manifest_ = manifest; | 44 manifest_ = manifest; |
45 obj_file_ = obj_file; | 45 obj_files_ = obj_files; |
46 nexe_file_ = nexe_file; | 46 nexe_file_ = nexe_file; |
47 coordinator_error_info_ = error_info; | 47 coordinator_error_info_ = error_info; |
48 resources_ = resources; | 48 resources_ = resources; |
49 pnacl_options_ = pnacl_options; | 49 pnacl_options_ = pnacl_options; |
50 coordinator_ = coordinator; | 50 coordinator_ = coordinator; |
51 plugin_ = plugin; | 51 plugin_ = plugin; |
52 | 52 |
53 // Invoke llc followed by ld off the main thread. This allows use of | 53 // Invoke llc followed by ld off the main thread. This allows use of |
54 // blocking RPCs that would otherwise block the JavaScript main thread. | 54 // blocking RPCs that would otherwise block the JavaScript main thread. |
55 report_translate_finished_ = finish_callback; | 55 report_translate_finished_ = finish_callback; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 | 123 |
124 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { | 124 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { |
125 PnaclTranslateThread* translator = | 125 PnaclTranslateThread* translator = |
126 reinterpret_cast<PnaclTranslateThread*>(arg); | 126 reinterpret_cast<PnaclTranslateThread*>(arg); |
127 translator->DoTranslate(); | 127 translator->DoTranslate(); |
128 } | 128 } |
129 | 129 |
130 void PnaclTranslateThread::DoTranslate() { | 130 void PnaclTranslateThread::DoTranslate() { |
131 ErrorInfo error_info; | 131 ErrorInfo error_info; |
132 SrpcParams params; | 132 SrpcParams params; |
133 nacl::DescWrapper* llc_out_file = obj_file_->write_wrapper(); | 133 std::vector<nacl::DescWrapper*> llc_out_files; |
134 size_t i; | |
135 for (i = 0; i < obj_files_->size(); i++) { | |
136 llc_out_files.push_back((*obj_files_)[i]->write_wrapper()); | |
137 } | |
138 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) { | |
139 llc_out_files.push_back(plugin_->wrapper_factory()->MakeInvalid()); | |
140 } | |
134 | 141 |
135 { | 142 { |
136 nacl::MutexLocker ml(&subprocess_mu_); | 143 nacl::MutexLocker ml(&subprocess_mu_); |
137 int64_t llc_start_time = NaClGetTimeOfDayMicroseconds(); | 144 int64_t llc_start_time = NaClGetTimeOfDayMicroseconds(); |
138 llc_subprocess_.reset( | 145 llc_subprocess_.reset( |
139 StartSubprocess(resources_->GetLlcUrl(), manifest_, &error_info)); | 146 StartSubprocess(resources_->GetLlcUrl(), manifest_, &error_info)); |
140 if (llc_subprocess_ == NULL) { | 147 if (llc_subprocess_ == NULL) { |
141 TranslateFailed(ERROR_PNACL_LLC_SETUP, | 148 TranslateFailed(ERROR_PNACL_LLC_SETUP, |
142 "Compile process could not be created: " + | 149 "Compile process could not be created: " + |
143 error_info.message()); | 150 error_info.message()); |
144 return; | 151 return; |
145 } | 152 } |
146 llc_subprocess_active_ = true; | 153 llc_subprocess_active_ = true; |
147 time_stats_.pnacl_llc_load_time = | 154 time_stats_.pnacl_llc_load_time = |
148 (NaClGetTimeOfDayMicroseconds() - llc_start_time); | 155 (NaClGetTimeOfDayMicroseconds() - llc_start_time); |
149 // Run LLC. | 156 // Run LLC. |
150 PluginReverseInterface* llc_reverse = | 157 PluginReverseInterface* llc_reverse = |
151 llc_subprocess_->service_runtime()->rev_interface(); | 158 llc_subprocess_->service_runtime()->rev_interface(); |
152 llc_reverse->AddTempQuotaManagedFile(obj_file_->identifier()); | 159 for (size_t i = 0; i < obj_files_->size(); i++) { |
160 llc_reverse->AddTempQuotaManagedFile((*obj_files_)[i]->identifier()); | |
161 } | |
153 } | 162 } |
154 | 163 |
155 int64_t compile_start_time = NaClGetTimeOfDayMicroseconds(); | 164 int64_t compile_start_time = NaClGetTimeOfDayMicroseconds(); |
156 bool init_success; | 165 bool init_success; |
157 std::vector<char> options = pnacl_options_->GetOptCommandline(); | 166 std::vector<char> options = pnacl_options_->GetOptCommandline(); |
167 | |
168 // Try to init with splitting | |
169 // TODO(dschuff): This CL override is ugly. Change llc to default to using | |
170 // the number of modules specified in the first param, and ignore multiple | |
171 // uses of -split-module | |
172 std::vector<char> split_args; | |
173 nacl::stringstream ss; | |
174 ss << "-split-module=" << obj_files_->size(); | |
175 nacl::string split_arg = ss.str(); | |
176 std::copy(split_arg.begin(), split_arg.end(), std::back_inserter(split_args)); | |
jvoung (off chromium)
2014/02/14 01:43:44
<iterator> for back_inserter
Derek Schuff
2014/02/14 06:11:23
Done.
| |
177 split_args.push_back('\x00'); | |
178 std::copy(options.begin(), options.end(), std::back_inserter(split_args)); | |
179 int modules_used = static_cast<int>(obj_files_->size()); | |
158 init_success = llc_subprocess_->InvokeSrpcMethod( | 180 init_success = llc_subprocess_->InvokeSrpcMethod( |
159 "StreamInitWithOverrides", | 181 "StreamInitWithSplit", |
160 "hC", | 182 "ihhhhhhhhhhhhhhhhC", |
161 ¶ms, | 183 ¶ms, |
162 llc_out_file->desc(), | 184 modules_used, |
163 &options[0], | 185 llc_out_files[0]->desc(), |
164 options.size()); | 186 llc_out_files[1]->desc(), |
187 llc_out_files[2]->desc(), | |
188 llc_out_files[3]->desc(), | |
189 llc_out_files[4]->desc(), | |
190 llc_out_files[5]->desc(), | |
191 llc_out_files[6]->desc(), | |
192 llc_out_files[7]->desc(), | |
193 llc_out_files[8]->desc(), | |
194 llc_out_files[9]->desc(), | |
195 llc_out_files[10]->desc(), | |
196 llc_out_files[11]->desc(), | |
197 llc_out_files[12]->desc(), | |
198 llc_out_files[13]->desc(), | |
199 llc_out_files[14]->desc(), | |
200 llc_out_files[15]->desc(), | |
201 &split_args[0], | |
202 split_args.size()); | |
203 if (!init_success) { | |
204 init_success = llc_subprocess_->InvokeSrpcMethod( | |
205 "StreamInitWithOverrides", | |
206 "hC", | |
207 ¶ms, | |
208 llc_out_files[0]->desc(), | |
209 &options[0], | |
210 options.size()); | |
211 modules_used = 1; | |
212 } | |
165 | 213 |
166 if (!init_success) { | 214 if (!init_success) { |
167 if (llc_subprocess_->srpc_client()->GetLastError() == | 215 if (llc_subprocess_->srpc_client()->GetLastError() == |
168 NACL_SRPC_RESULT_APP_ERROR) { | 216 NACL_SRPC_RESULT_APP_ERROR) { |
169 // The error message is only present if the error was returned from llc | 217 // The error message is only present if the error was returned from llc |
170 TranslateFailed(ERROR_PNACL_LLC_INTERNAL, | 218 TranslateFailed(ERROR_PNACL_LLC_INTERNAL, |
171 nacl::string("Stream init failed: ") + | 219 nacl::string("Stream init failed: ") + |
172 nacl::string(params.outs()[0]->arrays.str)); | 220 nacl::string(params.outs()[0]->arrays.str)); |
173 } else { | 221 } else { |
174 TranslateFailed(ERROR_PNACL_LLC_INTERNAL, | 222 TranslateFailed(ERROR_PNACL_LLC_INTERNAL, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
249 " is_shared_library=%d, soname='%s', lib_dependencies='%s')\n", | 297 " is_shared_library=%d, soname='%s', lib_dependencies='%s')\n", |
250 this, is_shared_library, soname.c_str(), | 298 this, is_shared_library, soname.c_str(), |
251 lib_dependencies.c_str())); | 299 lib_dependencies.c_str())); |
252 | 300 |
253 // Shut down the llc subprocess. | 301 // Shut down the llc subprocess. |
254 NaClXMutexLock(&subprocess_mu_); | 302 NaClXMutexLock(&subprocess_mu_); |
255 llc_subprocess_active_ = false; | 303 llc_subprocess_active_ = false; |
256 llc_subprocess_.reset(NULL); | 304 llc_subprocess_.reset(NULL); |
257 NaClXMutexUnlock(&subprocess_mu_); | 305 NaClXMutexUnlock(&subprocess_mu_); |
258 | 306 |
259 if(!RunLdSubprocess(is_shared_library, soname, lib_dependencies)) { | 307 if(!RunLdSubprocess( |
308 modules_used, is_shared_library, soname, lib_dependencies)) { | |
260 return; | 309 return; |
261 } | 310 } |
262 core->CallOnMainThread(0, report_translate_finished_, PP_OK); | 311 core->CallOnMainThread(0, report_translate_finished_, PP_OK); |
263 } | 312 } |
264 | 313 |
265 bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library, | 314 bool PnaclTranslateThread::RunLdSubprocess(int modules_used, |
315 int is_shared_library, | |
266 const nacl::string& soname, | 316 const nacl::string& soname, |
267 const nacl::string& lib_dependencies | 317 const nacl::string& lib_dependencies |
268 ) { | 318 ) { |
269 ErrorInfo error_info; | 319 ErrorInfo error_info; |
270 SrpcParams params; | 320 SrpcParams params; |
271 // Reset object file for reading first. | 321 |
272 if (!obj_file_->Reset()) { | 322 std::vector<nacl::DescWrapper*> ld_in_files; |
273 TranslateFailed(ERROR_PNACL_LD_SETUP, | 323 size_t i; |
274 "Link process could not reset object file"); | 324 for (i = 0; i < obj_files_->size(); i++) { |
275 return false; | 325 // Reset object file for reading first. |
326 if (!(*obj_files_)[i]->Reset()) { | |
327 TranslateFailed(ERROR_PNACL_LD_SETUP, | |
328 "Link process could not reset object file"); | |
329 return false; | |
330 } | |
331 ld_in_files.push_back((*obj_files_)[i]->read_wrapper()); | |
276 } | 332 } |
277 nacl::DescWrapper* ld_in_file = obj_file_->read_wrapper(); | 333 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) { |
334 ld_in_files.push_back(plugin_->wrapper_factory()->MakeInvalid()); | |
jvoung (off chromium)
2014/02/14 01:43:44
remember to delete these too -- it looks like even
Derek Schuff
2014/02/14 06:11:23
Looks like it doesn't need to be unique. switched
| |
335 } | |
336 | |
278 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); | 337 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); |
279 | 338 |
280 { | 339 { |
281 // Create LD process | 340 // Create LD process |
282 nacl::MutexLocker ml(&subprocess_mu_); | 341 nacl::MutexLocker ml(&subprocess_mu_); |
283 int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); | 342 int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); |
284 ld_subprocess_.reset( | 343 ld_subprocess_.reset( |
285 StartSubprocess(resources_->GetLdUrl(), manifest_, &error_info)); | 344 StartSubprocess(resources_->GetLdUrl(), manifest_, &error_info)); |
286 if (ld_subprocess_ == NULL) { | 345 if (ld_subprocess_ == NULL) { |
287 TranslateFailed(ERROR_PNACL_LD_SETUP, | 346 TranslateFailed(ERROR_PNACL_LD_SETUP, |
288 "Link process could not be created: " + | 347 "Link process could not be created: " + |
289 error_info.message()); | 348 error_info.message()); |
290 return false; | 349 return false; |
291 } | 350 } |
292 ld_subprocess_active_ = true; | 351 ld_subprocess_active_ = true; |
293 time_stats_.pnacl_ld_load_time = | 352 time_stats_.pnacl_ld_load_time = |
294 (NaClGetTimeOfDayMicroseconds() - ld_start_time); | 353 (NaClGetTimeOfDayMicroseconds() - ld_start_time); |
295 PluginReverseInterface* ld_reverse = | 354 PluginReverseInterface* ld_reverse = |
296 ld_subprocess_->service_runtime()->rev_interface(); | 355 ld_subprocess_->service_runtime()->rev_interface(); |
297 ld_reverse->AddTempQuotaManagedFile(nexe_file_->identifier()); | 356 ld_reverse->AddTempQuotaManagedFile(nexe_file_->identifier()); |
298 } | 357 } |
299 | 358 |
300 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); | 359 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); |
301 // Run LD. | 360 // Run LD. |
302 if (!ld_subprocess_->InvokeSrpcMethod("RunWithDefaultCommandLine", | 361 bool success; |
303 "hhiss", | 362 // If we ran LLC with module splitting, we can't fall back here. |
304 ¶ms, | 363 if (modules_used > 1) { |
305 ld_in_file->desc(), | 364 success = ld_subprocess_->InvokeSrpcMethod("RunWithSplit", |
306 ld_out_file->desc(), | 365 "ihhhhhhhhhhhhhhhhh", |
307 is_shared_library, | 366 ¶ms, |
308 soname.c_str(), | 367 modules_used, |
309 lib_dependencies.c_str())) { | 368 ld_in_files[0]->desc(), |
369 ld_in_files[1]->desc(), | |
370 ld_in_files[2]->desc(), | |
371 ld_in_files[3]->desc(), | |
372 ld_in_files[4]->desc(), | |
373 ld_in_files[5]->desc(), | |
374 ld_in_files[6]->desc(), | |
375 ld_in_files[7]->desc(), | |
376 ld_in_files[8]->desc(), | |
377 ld_in_files[9]->desc(), | |
378 ld_in_files[10]->desc(), | |
379 ld_in_files[11]->desc(), | |
380 ld_in_files[12]->desc(), | |
381 ld_in_files[13]->desc(), | |
382 ld_in_files[14]->desc(), | |
383 ld_in_files[15]->desc(), | |
384 ld_out_file->desc()); | |
385 } else { | |
386 success = ld_subprocess_->InvokeSrpcMethod("RunWithDefaultCommandLine", | |
387 "hhiss", | |
388 ¶ms, | |
389 ld_in_files[0]->desc(), | |
390 ld_out_file->desc(), | |
391 is_shared_library, | |
392 soname.c_str(), | |
393 lib_dependencies.c_str()); | |
394 } | |
395 if (!success) { | |
310 TranslateFailed(ERROR_PNACL_LD_INTERNAL, | 396 TranslateFailed(ERROR_PNACL_LD_INTERNAL, |
311 "link failed."); | 397 "link failed."); |
312 return false; | 398 return false; |
313 } | 399 } |
314 time_stats_.pnacl_link_time = | 400 time_stats_.pnacl_link_time = |
315 NaClGetTimeOfDayMicroseconds() - link_start_time; | 401 NaClGetTimeOfDayMicroseconds() - link_start_time; |
316 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n", | 402 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n", |
317 this)); | 403 this)); |
318 // Shut down the ld subprocess. | 404 // Shut down the ld subprocess. |
319 NaClXMutexLock(&subprocess_mu_); | 405 NaClXMutexLock(&subprocess_mu_); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 AbortSubprocesses(); | 449 AbortSubprocesses(); |
364 if (translate_thread_ != NULL) | 450 if (translate_thread_ != NULL) |
365 NaClThreadJoin(translate_thread_.get()); | 451 NaClThreadJoin(translate_thread_.get()); |
366 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); | 452 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); |
367 NaClCondVarDtor(&buffer_cond_); | 453 NaClCondVarDtor(&buffer_cond_); |
368 NaClMutexDtor(&cond_mu_); | 454 NaClMutexDtor(&cond_mu_); |
369 NaClMutexDtor(&subprocess_mu_); | 455 NaClMutexDtor(&subprocess_mu_); |
370 } | 456 } |
371 | 457 |
372 } // namespace plugin | 458 } // namespace plugin |
OLD | NEW |