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) { |
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 25 matching lines...) Expand all Loading... | |
81 if (count <= PP_OK) { | 81 if (count <= PP_OK) { |
82 NaClXMutexLock(&cond_mu_); | 82 NaClXMutexLock(&cond_mu_); |
83 done_ = true; | 83 done_ = true; |
84 NaClXCondVarSignal(&buffer_cond_); | 84 NaClXCondVarSignal(&buffer_cond_); |
85 NaClXMutexUnlock(&cond_mu_); | 85 NaClXMutexUnlock(&cond_mu_); |
86 return; | 86 return; |
87 } | 87 } |
88 | 88 |
89 CHECK(bytes != NULL); | 89 CHECK(bytes != NULL); |
90 // Ensure that the buffer we send to the translation thread is the right size | 90 // Ensure that the buffer we send to the translation thread is the right size |
91 // (count can be < the buffer size). This can be done without the lock. | 91 // (count can be < the buffer size). This can be |
jvoung (off chromium)
2014/02/14 00:46:49
can be... ?
Derek Schuff
2014/02/14 01:01:51
Done.
| |
92 buffer_size = bytes->size(); | 92 buffer_size = bytes->size(); |
93 bytes->resize(count); | 93 bytes->resize(count); |
94 | 94 |
95 NaClXMutexLock(&cond_mu_); | 95 NaClXMutexLock(&cond_mu_); |
96 | 96 |
97 data_buffers_.push_back(std::vector<char>()); | 97 data_buffers_.push_back(std::vector<char>()); |
98 bytes->swap(data_buffers_.back()); // Avoid copying the buffer data. | 98 bytes->swap(data_buffers_.back()); // Avoid copying the buffer data. |
99 | 99 |
100 NaClXCondVarSignal(&buffer_cond_); | 100 NaClXCondVarSignal(&buffer_cond_); |
101 NaClXMutexUnlock(&cond_mu_); | 101 NaClXMutexUnlock(&cond_mu_); |
(...skipping 21 matching lines...) Expand all 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 fprintf(stderr, "StreamInit split=%lu\n", obj_files_->size()); | |
168 | |
169 // Try to init with splitting | |
170 // TODO(dschuff): This CL override is ugly. Change llc to default to using | |
171 // the number of modules specified in the first param, and ignore multiple | |
172 // uses of -split-module | |
173 std::vector<char> split_args; | |
174 nacl::stringstream ss; | |
175 ss << "-split-module=" << obj_files_->size(); | |
176 nacl::string split_arg = ss.str(); | |
177 std::copy(split_arg.begin(), split_arg.end(), std::back_inserter(split_args)); | |
178 split_args.push_back('\x00'); | |
179 std::copy(options.begin(), options.end(), std::back_inserter(split_args)); | |
180 int modules_used = static_cast<int>(obj_files_->size()); | |
158 init_success = llc_subprocess_->InvokeSrpcMethod( | 181 init_success = llc_subprocess_->InvokeSrpcMethod( |
159 "StreamInitWithOverrides", | 182 "StreamInitWithSplit", |
160 "hC", | 183 "ihhhhhhhhhhhhhhhhC", |
161 ¶ms, | 184 ¶ms, |
162 llc_out_file->desc(), | 185 modules_used, |
163 &options[0], | 186 llc_out_files[0]->desc(), |
164 options.size()); | 187 llc_out_files[1]->desc(), |
188 llc_out_files[2]->desc(), | |
189 llc_out_files[3]->desc(), | |
190 llc_out_files[4]->desc(), | |
191 llc_out_files[5]->desc(), | |
192 llc_out_files[6]->desc(), | |
193 llc_out_files[7]->desc(), | |
194 llc_out_files[8]->desc(), | |
195 llc_out_files[9]->desc(), | |
196 llc_out_files[10]->desc(), | |
197 llc_out_files[11]->desc(), | |
198 llc_out_files[12]->desc(), | |
199 llc_out_files[13]->desc(), | |
200 llc_out_files[14]->desc(), | |
201 llc_out_files[15]->desc(), | |
202 &split_args[0], | |
203 split_args.size()); | |
204 if (!init_success) { | |
205 fprintf(stderr, "Falling back to StreamInitWithOverrides\n"); | |
206 init_success = llc_subprocess_->InvokeSrpcMethod( | |
207 "StreamInitWithOverrides", | |
208 "hC", | |
209 ¶ms, | |
210 llc_out_files[0]->desc(), | |
211 &options[0], | |
212 options.size()); | |
213 modules_used = 1; | |
214 } | |
165 | 215 |
166 if (!init_success) { | 216 if (!init_success) { |
167 if (llc_subprocess_->srpc_client()->GetLastError() == | 217 if (llc_subprocess_->srpc_client()->GetLastError() == |
168 NACL_SRPC_RESULT_APP_ERROR) { | 218 NACL_SRPC_RESULT_APP_ERROR) { |
169 // The error message is only present if the error was returned from llc | 219 // The error message is only present if the error was returned from llc |
170 TranslateFailed(ERROR_PNACL_LLC_INTERNAL, | 220 TranslateFailed(ERROR_PNACL_LLC_INTERNAL, |
171 nacl::string("Stream init failed: ") + | 221 nacl::string("Stream init failed: ") + |
172 nacl::string(params.outs()[0]->arrays.str)); | 222 nacl::string(params.outs()[0]->arrays.str)); |
173 } else { | 223 } else { |
174 TranslateFailed(ERROR_PNACL_LLC_INTERNAL, | 224 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", | 299 " is_shared_library=%d, soname='%s', lib_dependencies='%s')\n", |
250 this, is_shared_library, soname.c_str(), | 300 this, is_shared_library, soname.c_str(), |
251 lib_dependencies.c_str())); | 301 lib_dependencies.c_str())); |
252 | 302 |
253 // Shut down the llc subprocess. | 303 // Shut down the llc subprocess. |
254 NaClXMutexLock(&subprocess_mu_); | 304 NaClXMutexLock(&subprocess_mu_); |
255 llc_subprocess_active_ = false; | 305 llc_subprocess_active_ = false; |
256 llc_subprocess_.reset(NULL); | 306 llc_subprocess_.reset(NULL); |
257 NaClXMutexUnlock(&subprocess_mu_); | 307 NaClXMutexUnlock(&subprocess_mu_); |
258 | 308 |
259 if(!RunLdSubprocess(is_shared_library, soname, lib_dependencies)) { | 309 if(!RunLdSubprocess(modules_used, is_shared_library, soname, lib_dependencies) ) { |
260 return; | 310 return; |
261 } | 311 } |
262 core->CallOnMainThread(0, report_translate_finished_, PP_OK); | 312 core->CallOnMainThread(0, report_translate_finished_, PP_OK); |
263 } | 313 } |
264 | 314 |
265 bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library, | 315 bool PnaclTranslateThread::RunLdSubprocess(int modules_used, |
316 int is_shared_library, | |
266 const nacl::string& soname, | 317 const nacl::string& soname, |
267 const nacl::string& lib_dependencies | 318 const nacl::string& lib_dependencies |
268 ) { | 319 ) { |
269 ErrorInfo error_info; | 320 ErrorInfo error_info; |
270 SrpcParams params; | 321 SrpcParams params; |
271 // Reset object file for reading first. | 322 |
272 if (!obj_file_->Reset()) { | 323 std::vector<nacl::DescWrapper*> ld_in_files; |
273 TranslateFailed(ERROR_PNACL_LD_SETUP, | 324 size_t i; |
274 "Link process could not reset object file"); | 325 for (i = 0; i < obj_files_->size(); i++) { |
275 return false; | 326 // Reset object file for reading first. |
327 if (!(*obj_files_)[i]->Reset()) { | |
328 TranslateFailed(ERROR_PNACL_LD_SETUP, | |
329 "Link process could not reset object file"); | |
330 return false; | |
331 } | |
332 ld_in_files.push_back((*obj_files_)[i]->read_wrapper()); | |
276 } | 333 } |
277 nacl::DescWrapper* ld_in_file = obj_file_->read_wrapper(); | 334 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) { |
335 ld_in_files.push_back(plugin_->wrapper_factory()->MakeInvalid()); | |
336 } | |
337 | |
278 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); | 338 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); |
279 | 339 |
280 { | 340 { |
281 // Create LD process | 341 // Create LD process |
282 nacl::MutexLocker ml(&subprocess_mu_); | 342 nacl::MutexLocker ml(&subprocess_mu_); |
283 int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); | 343 int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); |
284 ld_subprocess_.reset( | 344 ld_subprocess_.reset( |
285 StartSubprocess(resources_->GetLdUrl(), manifest_, &error_info)); | 345 StartSubprocess(resources_->GetLdUrl(), manifest_, &error_info)); |
286 if (ld_subprocess_ == NULL) { | 346 if (ld_subprocess_ == NULL) { |
287 TranslateFailed(ERROR_PNACL_LD_SETUP, | 347 TranslateFailed(ERROR_PNACL_LD_SETUP, |
288 "Link process could not be created: " + | 348 "Link process could not be created: " + |
289 error_info.message()); | 349 error_info.message()); |
290 return false; | 350 return false; |
291 } | 351 } |
292 ld_subprocess_active_ = true; | 352 ld_subprocess_active_ = true; |
293 time_stats_.pnacl_ld_load_time = | 353 time_stats_.pnacl_ld_load_time = |
294 (NaClGetTimeOfDayMicroseconds() - ld_start_time); | 354 (NaClGetTimeOfDayMicroseconds() - ld_start_time); |
295 PluginReverseInterface* ld_reverse = | 355 PluginReverseInterface* ld_reverse = |
296 ld_subprocess_->service_runtime()->rev_interface(); | 356 ld_subprocess_->service_runtime()->rev_interface(); |
297 ld_reverse->AddTempQuotaManagedFile(nexe_file_->identifier()); | 357 ld_reverse->AddTempQuotaManagedFile(nexe_file_->identifier()); |
298 } | 358 } |
299 | 359 |
300 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); | 360 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); |
301 // Run LD. | 361 // Run LD. |
302 if (!ld_subprocess_->InvokeSrpcMethod("RunWithDefaultCommandLine", | 362 bool success; |
303 "hhiss", | 363 // If we ran LLC with module splitting, we can't fall back here. |
304 ¶ms, | 364 if (modules_used > 1) { |
305 ld_in_file->desc(), | 365 success = ld_subprocess_->InvokeSrpcMethod("RunWithSplit", |
306 ld_out_file->desc(), | 366 "ihhhhhhhhhhhhhhhhh", |
307 is_shared_library, | 367 ¶ms, |
308 soname.c_str(), | 368 modules_used, |
309 lib_dependencies.c_str())) { | 369 ld_in_files[0]->desc(), |
370 ld_in_files[1]->desc(), | |
371 ld_in_files[2]->desc(), | |
372 ld_in_files[3]->desc(), | |
373 ld_in_files[4]->desc(), | |
374 ld_in_files[5]->desc(), | |
375 ld_in_files[6]->desc(), | |
376 ld_in_files[7]->desc(), | |
377 ld_in_files[8]->desc(), | |
378 ld_in_files[9]->desc(), | |
379 ld_in_files[10]->desc(), | |
380 ld_in_files[11]->desc(), | |
381 ld_in_files[12]->desc(), | |
382 ld_in_files[13]->desc(), | |
383 ld_in_files[14]->desc(), | |
384 ld_in_files[15]->desc(), | |
385 ld_out_file->desc()); | |
386 } else { | |
387 success = ld_subprocess_->InvokeSrpcMethod("RunWithDefaultCommandLine", | |
388 "hhiss", | |
389 ¶ms, | |
390 ld_in_files[0]->desc(), | |
391 ld_out_file->desc(), | |
392 is_shared_library, | |
393 soname.c_str(), | |
394 lib_dependencies.c_str()); | |
395 } | |
396 if (!success) { | |
310 TranslateFailed(ERROR_PNACL_LD_INTERNAL, | 397 TranslateFailed(ERROR_PNACL_LD_INTERNAL, |
311 "link failed."); | 398 "link failed."); |
312 return false; | 399 return false; |
313 } | 400 } |
314 time_stats_.pnacl_link_time = | 401 time_stats_.pnacl_link_time = |
315 NaClGetTimeOfDayMicroseconds() - link_start_time; | 402 NaClGetTimeOfDayMicroseconds() - link_start_time; |
316 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n", | 403 PLUGIN_PRINTF(("PnaclCoordinator: link (translator=%p) succeeded\n", |
317 this)); | 404 this)); |
318 // Shut down the ld subprocess. | 405 // Shut down the ld subprocess. |
319 NaClXMutexLock(&subprocess_mu_); | 406 NaClXMutexLock(&subprocess_mu_); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
363 AbortSubprocesses(); | 450 AbortSubprocesses(); |
364 if (translate_thread_ != NULL) | 451 if (translate_thread_ != NULL) |
365 NaClThreadJoin(translate_thread_.get()); | 452 NaClThreadJoin(translate_thread_.get()); |
366 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); | 453 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); |
367 NaClCondVarDtor(&buffer_cond_); | 454 NaClCondVarDtor(&buffer_cond_); |
368 NaClMutexDtor(&cond_mu_); | 455 NaClMutexDtor(&cond_mu_); |
369 NaClMutexDtor(&subprocess_mu_); | 456 NaClMutexDtor(&subprocess_mu_); |
370 } | 457 } |
371 | 458 |
372 } // namespace plugin | 459 } // namespace plugin |
OLD | NEW |