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) { |
| 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 |