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