Chromium Code Reviews| 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 |