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 "components/nacl/renderer/plugin/pnacl_translate_thread.h" | 5 #include "components/nacl/renderer/plugin/pnacl_translate_thread.h" |
| 6 | 6 |
| 7 #include <iterator> | 7 #include <iterator> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "components/nacl/renderer/plugin/plugin.h" | 10 #include "components/nacl/renderer/plugin/plugin.h" |
| 11 #include "components/nacl/renderer/plugin/plugin_error.h" | 11 #include "components/nacl/renderer/plugin/plugin_error.h" |
| 12 #include "components/nacl/renderer/plugin/pnacl_resources.h" | 12 #include "components/nacl/renderer/plugin/pnacl_resources.h" |
| 13 #include "components/nacl/renderer/plugin/srpc_params.h" | 13 #include "components/nacl/renderer/plugin/srpc_params.h" |
| 14 #include "components/nacl/renderer/plugin/temporary_file.h" | 14 #include "components/nacl/renderer/plugin/temporary_file.h" |
| 15 #include "components/nacl/renderer/plugin/utility.h" | 15 #include "components/nacl/renderer/plugin/utility.h" |
| 16 #include "native_client/src/shared/platform/nacl_check.h" | 16 #include "native_client/src/shared/platform/nacl_check.h" |
| 17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" | 17 #include "native_client/src/trusted/desc/nacl_desc_wrapper.h" |
| 18 #include "ppapi/cpp/var.h" | 18 #include "ppapi/cpp/var.h" |
| 19 | 19 |
| 20 namespace plugin { | 20 namespace plugin { |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 template <typename Val> | 23 template <typename Val> |
| 24 std::string MakeCommandLineArg(const char* key, const Val val) { | 24 std::string MakeCommandLineArg(const char* key, const Val val) { |
| 25 std::stringstream ss; | 25 std::stringstream ss; |
| 26 ss << key << val; | 26 ss << key << val; |
| 27 return ss.str(); | 27 return ss.str(); |
| 28 } | 28 } |
| 29 | 29 |
| 30 void GetLlcCommandLine(Plugin* plugin, | 30 void GetLlcCommandLine(std::vector<char>* split_args, |
| 31 std::vector<char>* split_args, | |
| 32 size_t obj_files_size, | 31 size_t obj_files_size, |
| 33 int32_t opt_level, | 32 int32_t opt_level, |
| 34 bool is_debug, | 33 bool is_debug, |
| 35 const std::string &architecture_attributes) { | 34 const std::string& architecture_attributes) { |
| 36 typedef std::vector<std::string> Args; | 35 typedef std::vector<std::string> Args; |
| 37 Args args; | 36 Args args; |
| 38 | 37 |
| 39 // TODO(dschuff): This CL override is ugly. Change llc to default to | 38 // TODO(dschuff): This CL override is ugly. Change llc to default to |
| 40 // using the number of modules specified in the first param, and | 39 // using the number of modules specified in the first param, and |
| 41 // ignore multiple uses of -split-module | 40 // ignore multiple uses of -split-module |
| 42 args.push_back(MakeCommandLineArg("-split-module=", obj_files_size)); | 41 args.push_back(MakeCommandLineArg("-split-module=", obj_files_size)); |
| 43 args.push_back(MakeCommandLineArg("-O=", opt_level)); | 42 args.push_back(MakeCommandLineArg("-O", opt_level)); |
| 44 if (is_debug) | 43 if (is_debug) |
| 45 args.push_back("-bitcode-format=llvm"); | 44 args.push_back("-bitcode-format=llvm"); |
| 46 if (!architecture_attributes.empty()) | 45 if (!architecture_attributes.empty()) |
| 47 args.push_back("-mattr=" + architecture_attributes); | 46 args.push_back("-mattr=" + architecture_attributes); |
| 48 | 47 |
| 49 for (Args::const_iterator arg(args.begin()); arg != args.end(); ++arg) { | 48 for (Args::const_iterator arg(args.begin()); arg != args.end(); ++arg) { |
| 50 std::copy(arg->begin(), arg->end(), std::back_inserter(*split_args)); | 49 std::copy(arg->begin(), arg->end(), std::back_inserter(*split_args)); |
| 51 split_args->push_back('\x00'); | 50 split_args->push_back('\x00'); |
| 52 } | 51 } |
| 53 } | 52 } |
| 54 | 53 |
| 54 void GetSubzeroCommandLine(std::vector<char>* split_args, | |
| 55 int32_t opt_level, | |
| 56 bool is_debug, | |
| 57 const std::string& architecture_attributes) { | |
| 58 typedef std::vector<std::string> Args; | |
| 59 Args args; | |
| 60 | |
| 61 args.push_back(MakeCommandLineArg("-O", opt_level)); | |
| 62 DCHECK(!is_debug); | |
| 63 // TODO(stichnot): enable this once the mattr flag formatting is | |
| 64 // compatible: https://code.google.com/p/nativeclient/issues/detail?id=4132 | |
| 65 // if (!architecture_attributes.empty()) | |
| 66 // args.push_back("-mattr=" + architecture_attributes); | |
| 67 | |
| 68 for (Args::const_iterator arg(args.begin()); arg != args.end(); ++arg) { | |
|
Derek Schuff
2015/03/30 16:39:47
range-for?
jvoung (off chromium)
2015/03/30 20:26:40
Done.
| |
| 69 std::copy(arg->begin(), arg->end(), std::back_inserter(*split_args)); | |
| 70 split_args->push_back('\x00'); | |
| 71 } | |
| 72 } | |
| 73 | |
| 55 } // namespace | 74 } // namespace |
| 56 | 75 |
| 57 PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false), | 76 PnaclTranslateThread::PnaclTranslateThread() |
| 58 ld_subprocess_active_(false), | 77 : compiler_subprocess_active_(false), |
| 59 subprocesses_aborted_(false), | 78 ld_subprocess_active_(false), |
| 60 done_(false), | 79 subprocesses_aborted_(false), |
| 61 compile_time_(0), | 80 done_(false), |
| 62 obj_files_(NULL), | 81 compile_time_(0), |
| 63 nexe_file_(NULL), | 82 obj_files_(NULL), |
| 64 coordinator_error_info_(NULL), | 83 num_threads_(0), |
| 65 resources_(NULL), | 84 nexe_file_(NULL), |
| 66 coordinator_(NULL), | 85 coordinator_error_info_(NULL), |
| 67 plugin_(NULL) { | 86 resources_(NULL), |
| 87 coordinator_(NULL), | |
| 88 plugin_(NULL) { | |
| 68 NaClXMutexCtor(&subprocess_mu_); | 89 NaClXMutexCtor(&subprocess_mu_); |
| 69 NaClXMutexCtor(&cond_mu_); | 90 NaClXMutexCtor(&cond_mu_); |
| 70 NaClXCondVarCtor(&buffer_cond_); | 91 NaClXCondVarCtor(&buffer_cond_); |
| 71 } | 92 } |
| 72 | 93 |
| 73 void PnaclTranslateThread::RunTranslate( | 94 void PnaclTranslateThread::RunTranslate( |
| 74 const pp::CompletionCallback& finish_callback, | 95 const pp::CompletionCallback& finish_callback, |
| 75 const std::vector<TempFile*>* obj_files, | 96 const std::vector<TempFile*>* obj_files, |
| 97 uint32_t num_threads, | |
| 76 TempFile* nexe_file, | 98 TempFile* nexe_file, |
| 77 nacl::DescWrapper* invalid_desc_wrapper, | 99 nacl::DescWrapper* invalid_desc_wrapper, |
| 78 ErrorInfo* error_info, | 100 ErrorInfo* error_info, |
| 79 PnaclResources* resources, | 101 PnaclResources* resources, |
| 80 PP_PNaClOptions* pnacl_options, | 102 PP_PNaClOptions* pnacl_options, |
| 81 const std::string &architecture_attributes, | 103 const std::string& architecture_attributes, |
| 82 PnaclCoordinator* coordinator, | 104 PnaclCoordinator* coordinator, |
| 83 Plugin* plugin) { | 105 Plugin* plugin) { |
| 84 PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n")); | 106 PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n")); |
| 85 obj_files_ = obj_files; | 107 obj_files_ = obj_files; |
| 108 num_threads_ = num_threads; | |
| 86 nexe_file_ = nexe_file; | 109 nexe_file_ = nexe_file; |
| 87 invalid_desc_wrapper_ = invalid_desc_wrapper; | 110 invalid_desc_wrapper_ = invalid_desc_wrapper; |
| 88 coordinator_error_info_ = error_info; | 111 coordinator_error_info_ = error_info; |
| 89 resources_ = resources; | 112 resources_ = resources; |
| 90 pnacl_options_ = pnacl_options; | 113 pnacl_options_ = pnacl_options; |
| 91 architecture_attributes_ = architecture_attributes; | 114 architecture_attributes_ = architecture_attributes; |
| 92 coordinator_ = coordinator; | 115 coordinator_ = coordinator; |
| 93 plugin_ = plugin; | 116 plugin_ = plugin; |
| 94 | 117 |
| 95 // Invoke llc followed by ld off the main thread. This allows use of | 118 // Invoke llc followed by ld off the main thread. This allows use of |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 | 156 |
| 134 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { | 157 void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) { |
| 135 PnaclTranslateThread* translator = | 158 PnaclTranslateThread* translator = |
| 136 reinterpret_cast<PnaclTranslateThread*>(arg); | 159 reinterpret_cast<PnaclTranslateThread*>(arg); |
| 137 translator->DoTranslate(); | 160 translator->DoTranslate(); |
| 138 } | 161 } |
| 139 | 162 |
| 140 void PnaclTranslateThread::DoTranslate() { | 163 void PnaclTranslateThread::DoTranslate() { |
| 141 ErrorInfo error_info; | 164 ErrorInfo error_info; |
| 142 SrpcParams params; | 165 SrpcParams params; |
| 143 std::vector<nacl::DescWrapper*> llc_out_files; | 166 std::vector<nacl::DescWrapper*> compile_out_files; |
| 144 size_t i; | 167 size_t i; |
| 145 for (i = 0; i < obj_files_->size(); i++) | 168 for (i = 0; i < obj_files_->size(); i++) |
| 146 llc_out_files.push_back((*obj_files_)[i]->write_wrapper()); | 169 compile_out_files.push_back((*obj_files_)[i]->write_wrapper()); |
| 147 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) | 170 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) |
| 148 llc_out_files.push_back(invalid_desc_wrapper_); | 171 compile_out_files.push_back(invalid_desc_wrapper_); |
| 172 | |
| 173 PLUGIN_PRINTF( | |
| 174 ("DoTranslate using subzero: %d\n", pnacl_options_->use_subzero)); | |
| 149 | 175 |
| 150 pp::Core* core = pp::Module::Get()->core(); | 176 pp::Core* core = pp::Module::Get()->core(); |
| 151 int64_t llc_start_time = NaClGetTimeOfDayMicroseconds(); | 177 int64_t compiler_load_start_time = NaClGetTimeOfDayMicroseconds(); |
| 152 PP_NaClFileInfo llc_file_info = resources_->TakeLlcFileInfo(); | 178 PnaclResources::ResourceType compiler_type = pnacl_options_->use_subzero |
| 153 // On success, ownership of llc_file_info is transferred. | 179 ? PnaclResources::kSubzero |
| 154 NaClSubprocess* llc_subprocess = plugin_->LoadHelperNaClModule( | 180 : PnaclResources::kLLC; |
| 155 resources_->GetLlcUrl(), llc_file_info, &error_info); | 181 // On success, ownership of file_info is transferred. |
| 156 if (llc_subprocess == NULL) { | 182 PP_NaClFileInfo file_info = resources_->TakeFileInfo(compiler_type); |
| 157 if (llc_file_info.handle != PP_kInvalidFileHandle) | 183 const std::string& url = resources_->GetUrl(compiler_type); |
| 158 CloseFileHandle(llc_file_info.handle); | 184 NaClSubprocess* compiler_subprocess = |
| 185 plugin_->LoadHelperNaClModule(url, file_info, &error_info); | |
| 186 if (compiler_subprocess == NULL) { | |
| 187 if (file_info.handle != PP_kInvalidFileHandle) | |
| 188 CloseFileHandle(file_info.handle); | |
| 159 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_SETUP, | 189 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_SETUP, |
| 160 "Compile process could not be created: " + | 190 "Compile process could not be created: " + |
| 161 error_info.message()); | 191 error_info.message()); |
| 162 return; | 192 return; |
| 163 } | 193 } |
| 164 GetNaClInterface()->LogTranslateTime( | 194 GetNaClInterface()->LogTranslateTime( |
| 165 "NaCl.Perf.PNaClLoadTime.LoadCompiler", | 195 "NaCl.Perf.PNaClLoadTime.LoadCompiler", |
| 166 NaClGetTimeOfDayMicroseconds() - llc_start_time); | 196 NaClGetTimeOfDayMicroseconds() - compiler_load_start_time); |
| 167 | 197 |
| 168 { | 198 { |
| 169 nacl::MutexLocker ml(&subprocess_mu_); | 199 nacl::MutexLocker ml(&subprocess_mu_); |
| 170 // If we received a call to AbortSubprocesses() before we had a chance to | 200 // If we received a call to AbortSubprocesses() before we had a chance to |
| 171 // set llc_subprocess_, shut down and clean up the subprocess started here. | 201 // set compiler_subprocess_, shut down and clean up the subprocess started |
| 202 // here. | |
| 172 if (subprocesses_aborted_) { | 203 if (subprocesses_aborted_) { |
| 173 llc_subprocess->service_runtime()->Shutdown(); | 204 compiler_subprocess->service_runtime()->Shutdown(); |
| 174 delete llc_subprocess; | 205 delete compiler_subprocess; |
| 175 return; | 206 return; |
| 176 } | 207 } |
| 177 llc_subprocess_.reset(llc_subprocess); | 208 compiler_subprocess_.reset(compiler_subprocess); |
| 178 llc_subprocess = NULL; | 209 compiler_subprocess = NULL; |
| 179 llc_subprocess_active_ = true; | 210 compiler_subprocess_active_ = true; |
| 180 } | 211 } |
| 181 | 212 |
| 182 int64_t compile_start_time = NaClGetTimeOfDayMicroseconds(); | 213 int64_t do_compile_start_time = NaClGetTimeOfDayMicroseconds(); |
| 183 bool init_success; | 214 bool init_success; |
| 184 | 215 |
| 185 std::vector<char> split_args; | 216 std::vector<char> split_args; |
| 186 GetLlcCommandLine(plugin_, | 217 if (pnacl_options_->use_subzero) { |
| 187 &split_args, | 218 GetSubzeroCommandLine(&split_args, pnacl_options_->opt_level, |
| 188 obj_files_->size(), | 219 pnacl_options_->is_debug, architecture_attributes_); |
| 189 pnacl_options_->opt_level, | 220 } else { |
| 190 pnacl_options_->is_debug, | 221 GetLlcCommandLine(&split_args, obj_files_->size(), |
| 191 architecture_attributes_); | 222 pnacl_options_->opt_level, pnacl_options_->is_debug, |
| 192 init_success = llc_subprocess_->InvokeSrpcMethod( | 223 architecture_attributes_); |
| 193 "StreamInitWithSplit", | 224 } |
| 194 "ihhhhhhhhhhhhhhhhC", | 225 init_success = compiler_subprocess_->InvokeSrpcMethod( |
| 195 ¶ms, | 226 "StreamInitWithSplit", "ihhhhhhhhhhhhhhhhC", ¶ms, |
| 196 static_cast<int>(obj_files_->size()), | 227 static_cast<int>(num_threads_), compile_out_files[0]->desc(), |
|
jvoung (off chromium)
2015/03/30 20:26:40
Reverted this back to an "int" field to avoid the
| |
| 197 llc_out_files[0]->desc(), | 228 compile_out_files[1]->desc(), compile_out_files[2]->desc(), |
| 198 llc_out_files[1]->desc(), | 229 compile_out_files[3]->desc(), compile_out_files[4]->desc(), |
| 199 llc_out_files[2]->desc(), | 230 compile_out_files[5]->desc(), compile_out_files[6]->desc(), |
| 200 llc_out_files[3]->desc(), | 231 compile_out_files[7]->desc(), compile_out_files[8]->desc(), |
| 201 llc_out_files[4]->desc(), | 232 compile_out_files[9]->desc(), compile_out_files[10]->desc(), |
| 202 llc_out_files[5]->desc(), | 233 compile_out_files[11]->desc(), compile_out_files[12]->desc(), |
| 203 llc_out_files[6]->desc(), | 234 compile_out_files[13]->desc(), compile_out_files[14]->desc(), |
| 204 llc_out_files[7]->desc(), | 235 compile_out_files[15]->desc(), &split_args[0], split_args.size()); |
| 205 llc_out_files[8]->desc(), | |
| 206 llc_out_files[9]->desc(), | |
| 207 llc_out_files[10]->desc(), | |
| 208 llc_out_files[11]->desc(), | |
| 209 llc_out_files[12]->desc(), | |
| 210 llc_out_files[13]->desc(), | |
| 211 llc_out_files[14]->desc(), | |
| 212 llc_out_files[15]->desc(), | |
| 213 &split_args[0], | |
| 214 split_args.size()); | |
| 215 if (!init_success) { | 236 if (!init_success) { |
| 216 if (llc_subprocess_->srpc_client()->GetLastError() == | 237 if (compiler_subprocess_->srpc_client()->GetLastError() == |
| 217 NACL_SRPC_RESULT_APP_ERROR) { | 238 NACL_SRPC_RESULT_APP_ERROR) { |
| 218 // The error message is only present if the error was returned from llc | 239 // The error message is only present if the error was returned from llc |
| 219 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, | 240 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, |
| 220 std::string("Stream init failed: ") + | 241 std::string("Stream init failed: ") + |
| 221 std::string(params.outs()[0]->arrays.str)); | 242 std::string(params.outs()[0]->arrays.str)); |
| 222 } else { | 243 } else { |
| 223 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, | 244 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, |
| 224 "Stream init internal error"); | 245 "Stream init internal error"); |
| 225 } | 246 } |
| 226 return; | 247 return; |
| 227 } | 248 } |
| 228 PLUGIN_PRINTF(("PnaclCoordinator: StreamInit successful\n")); | 249 PLUGIN_PRINTF(("PnaclCoordinator: StreamInit successful\n")); |
| 229 | 250 |
| 230 // llc process is started. | 251 // llc process is started. |
| 231 while(!done_ || data_buffers_.size() > 0) { | 252 while(!done_ || data_buffers_.size() > 0) { |
| 232 NaClXMutexLock(&cond_mu_); | 253 NaClXMutexLock(&cond_mu_); |
| 233 while(!done_ && data_buffers_.size() == 0) { | 254 while(!done_ && data_buffers_.size() == 0) { |
| 234 NaClXCondVarWait(&buffer_cond_, &cond_mu_); | 255 NaClXCondVarWait(&buffer_cond_, &cond_mu_); |
| 235 } | 256 } |
| 236 PLUGIN_PRINTF(("PnaclTranslateThread awake (done=%d, size=%" NACL_PRIuS | 257 PLUGIN_PRINTF(("PnaclTranslateThread awake (done=%d, size=%" NACL_PRIuS |
| 237 ")\n", | 258 ")\n", |
| 238 done_, data_buffers_.size())); | 259 done_, data_buffers_.size())); |
| 239 if (data_buffers_.size() > 0) { | 260 if (data_buffers_.size() > 0) { |
| 240 std::vector<char> data; | 261 std::vector<char> data; |
| 241 data.swap(data_buffers_.front()); | 262 data.swap(data_buffers_.front()); |
| 242 data_buffers_.pop_front(); | 263 data_buffers_.pop_front(); |
| 243 NaClXMutexUnlock(&cond_mu_); | 264 NaClXMutexUnlock(&cond_mu_); |
| 244 PLUGIN_PRINTF(("StreamChunk\n")); | 265 PLUGIN_PRINTF(("StreamChunk\n")); |
| 245 if (!llc_subprocess_->InvokeSrpcMethod("StreamChunk", | 266 if (!compiler_subprocess_->InvokeSrpcMethod("StreamChunk", "C", ¶ms, |
| 246 "C", | 267 &data[0], data.size())) { |
| 247 ¶ms, | 268 if (compiler_subprocess_->srpc_client()->GetLastError() != |
| 248 &data[0], | |
| 249 data.size())) { | |
| 250 if (llc_subprocess_->srpc_client()->GetLastError() != | |
| 251 NACL_SRPC_RESULT_APP_ERROR) { | 269 NACL_SRPC_RESULT_APP_ERROR) { |
| 252 // If the error was reported by the translator, then we fall through | 270 // If the error was reported by the translator, then we fall through |
| 253 // and call StreamEnd, which returns a string describing the error, | 271 // and call StreamEnd, which returns a string describing the error, |
| 254 // which we can then send to the Javascript console. Otherwise just | 272 // which we can then send to the Javascript console. Otherwise just |
| 255 // fail here, since the translator has probably crashed or asserted. | 273 // fail here, since the translator has probably crashed or asserted. |
| 256 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, | 274 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, |
| 257 "Compile stream chunk failed. " | 275 "Compile stream chunk failed. " |
| 258 "The PNaCl translator has probably crashed."); | 276 "The PNaCl translator has probably crashed."); |
| 259 return; | 277 return; |
| 260 } | 278 } |
| 261 break; | 279 break; |
| 262 } else { | 280 } else { |
| 263 PLUGIN_PRINTF(("StreamChunk Successful\n")); | 281 PLUGIN_PRINTF(("StreamChunk Successful\n")); |
| 264 core->CallOnMainThread( | 282 core->CallOnMainThread( |
| 265 0, | 283 0, |
| 266 coordinator_->GetCompileProgressCallback(data.size()), | 284 coordinator_->GetCompileProgressCallback(data.size()), |
| 267 PP_OK); | 285 PP_OK); |
| 268 } | 286 } |
| 269 } else { | 287 } else { |
| 270 NaClXMutexUnlock(&cond_mu_); | 288 NaClXMutexUnlock(&cond_mu_); |
| 271 } | 289 } |
| 272 } | 290 } |
| 273 PLUGIN_PRINTF(("PnaclTranslateThread done with chunks\n")); | 291 PLUGIN_PRINTF(("PnaclTranslateThread done with chunks\n")); |
| 274 // Finish llc. | 292 // Finish llc. |
| 275 if (!llc_subprocess_->InvokeSrpcMethod("StreamEnd", std::string(), ¶ms)) { | 293 if (!compiler_subprocess_->InvokeSrpcMethod("StreamEnd", std::string(), |
| 294 ¶ms)) { | |
| 276 PLUGIN_PRINTF(("PnaclTranslateThread StreamEnd failed\n")); | 295 PLUGIN_PRINTF(("PnaclTranslateThread StreamEnd failed\n")); |
| 277 if (llc_subprocess_->srpc_client()->GetLastError() == | 296 if (compiler_subprocess_->srpc_client()->GetLastError() == |
| 278 NACL_SRPC_RESULT_APP_ERROR) { | 297 NACL_SRPC_RESULT_APP_ERROR) { |
| 279 // The error string is only present if the error was sent back from llc. | 298 // The error string is only present if the error was sent back from llc. |
| 280 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, | 299 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, |
| 281 params.outs()[3]->arrays.str); | 300 params.outs()[3]->arrays.str); |
| 282 } else { | 301 } else { |
| 283 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, | 302 TranslateFailed(PP_NACL_ERROR_PNACL_LLC_INTERNAL, |
| 284 "Compile StreamEnd internal error"); | 303 "Compile StreamEnd internal error"); |
| 285 } | 304 } |
| 286 return; | 305 return; |
| 287 } | 306 } |
| 288 compile_time_ = NaClGetTimeOfDayMicroseconds() - compile_start_time; | 307 compile_time_ = NaClGetTimeOfDayMicroseconds() - do_compile_start_time; |
| 289 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.CompileTime", | 308 GetNaClInterface()->LogTranslateTime("NaCl.Perf.PNaClLoadTime.CompileTime", |
| 290 compile_time_); | 309 compile_time_); |
| 291 | 310 |
| 292 // Shut down the llc subprocess. | 311 // Shut down the llc subprocess. |
| 293 NaClXMutexLock(&subprocess_mu_); | 312 NaClXMutexLock(&subprocess_mu_); |
| 294 llc_subprocess_active_ = false; | 313 compiler_subprocess_active_ = false; |
| 295 llc_subprocess_.reset(NULL); | 314 compiler_subprocess_.reset(NULL); |
| 296 NaClXMutexUnlock(&subprocess_mu_); | 315 NaClXMutexUnlock(&subprocess_mu_); |
| 297 | 316 |
| 298 if(!RunLdSubprocess()) { | 317 if(!RunLdSubprocess()) { |
| 299 return; | 318 return; |
| 300 } | 319 } |
| 301 core->CallOnMainThread(0, report_translate_finished_, PP_OK); | 320 core->CallOnMainThread(0, report_translate_finished_, PP_OK); |
| 302 } | 321 } |
| 303 | 322 |
| 304 bool PnaclTranslateThread::RunLdSubprocess() { | 323 bool PnaclTranslateThread::RunLdSubprocess() { |
| 305 ErrorInfo error_info; | 324 ErrorInfo error_info; |
| 306 SrpcParams params; | 325 SrpcParams params; |
| 307 | 326 |
| 308 std::vector<nacl::DescWrapper*> ld_in_files; | 327 std::vector<nacl::DescWrapper*> ld_in_files; |
| 309 size_t i; | 328 size_t i; |
| 310 for (i = 0; i < obj_files_->size(); i++) { | 329 for (i = 0; i < obj_files_->size(); i++) { |
| 311 // Reset object file for reading first. | 330 // Reset object file for reading first. |
| 312 if (!(*obj_files_)[i]->Reset()) { | 331 if (!(*obj_files_)[i]->Reset()) { |
| 313 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, | 332 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, |
| 314 "Link process could not reset object file"); | 333 "Link process could not reset object file"); |
| 315 return false; | 334 return false; |
| 316 } | 335 } |
| 317 ld_in_files.push_back((*obj_files_)[i]->read_wrapper()); | 336 ld_in_files.push_back((*obj_files_)[i]->read_wrapper()); |
| 318 } | 337 } |
| 319 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) | 338 for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) |
| 320 ld_in_files.push_back(invalid_desc_wrapper_); | 339 ld_in_files.push_back(invalid_desc_wrapper_); |
| 321 | 340 |
| 322 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); | 341 nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper(); |
| 323 int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); | 342 int64_t ld_start_time = NaClGetTimeOfDayMicroseconds(); |
| 324 PP_NaClFileInfo ld_file_info = resources_->TakeLdFileInfo(); | 343 PP_NaClFileInfo ld_file_info = resources_->TakeFileInfo(PnaclResources::kLD); |
| 325 // On success, ownership of ld_file_info is transferred. | 344 // On success, ownership of ld_file_info is transferred. |
| 326 nacl::scoped_ptr<NaClSubprocess> ld_subprocess( | 345 nacl::scoped_ptr<NaClSubprocess> ld_subprocess(plugin_->LoadHelperNaClModule( |
| 327 plugin_->LoadHelperNaClModule(resources_->GetLdUrl(), | 346 resources_->GetUrl(PnaclResources::kLD), ld_file_info, &error_info)); |
| 328 ld_file_info, | |
| 329 &error_info)); | |
| 330 if (ld_subprocess.get() == NULL) { | 347 if (ld_subprocess.get() == NULL) { |
| 331 if (ld_file_info.handle != PP_kInvalidFileHandle) | 348 if (ld_file_info.handle != PP_kInvalidFileHandle) |
| 332 CloseFileHandle(ld_file_info.handle); | 349 CloseFileHandle(ld_file_info.handle); |
| 333 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, | 350 TranslateFailed(PP_NACL_ERROR_PNACL_LD_SETUP, |
| 334 "Link process could not be created: " + | 351 "Link process could not be created: " + |
| 335 error_info.message()); | 352 error_info.message()); |
| 336 return false; | 353 return false; |
| 337 } | 354 } |
| 338 GetNaClInterface()->LogTranslateTime( | 355 GetNaClInterface()->LogTranslateTime( |
| 339 "NaCl.Perf.PNaClLoadTime.LoadLinker", | 356 "NaCl.Perf.PNaClLoadTime.LoadLinker", |
| 340 NaClGetTimeOfDayMicroseconds() - ld_start_time); | 357 NaClGetTimeOfDayMicroseconds() - ld_start_time); |
| 341 { | 358 { |
| 342 nacl::MutexLocker ml(&subprocess_mu_); | 359 nacl::MutexLocker ml(&subprocess_mu_); |
| 343 // If we received a call to AbortSubprocesses() before we had a chance to | 360 // If we received a call to AbortSubprocesses() before we had a chance to |
| 344 // set llc_subprocess_, shut down and clean up the subprocess started here. | 361 // set ld_subprocess_, shut down and clean up the subprocess started here. |
| 345 if (subprocesses_aborted_) { | 362 if (subprocesses_aborted_) { |
| 346 ld_subprocess->service_runtime()->Shutdown(); | 363 ld_subprocess->service_runtime()->Shutdown(); |
| 347 return false; | 364 return false; |
| 348 } | 365 } |
| 349 DCHECK(ld_subprocess_.get() == NULL); | 366 DCHECK(ld_subprocess_.get() == NULL); |
| 350 ld_subprocess_.swap(ld_subprocess); | 367 ld_subprocess_.swap(ld_subprocess); |
| 351 ld_subprocess_active_ = true; | 368 ld_subprocess_active_ = true; |
| 352 } | 369 } |
| 353 | 370 |
| 354 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); | 371 int64_t link_start_time = NaClGetTimeOfDayMicroseconds(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 coordinator_error_info_->SetReport(err_code, | 422 coordinator_error_info_->SetReport(err_code, |
| 406 std::string("PnaclCoordinator: ") + | 423 std::string("PnaclCoordinator: ") + |
| 407 error_string); | 424 error_string); |
| 408 } | 425 } |
| 409 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED); | 426 core->CallOnMainThread(0, report_translate_finished_, PP_ERROR_FAILED); |
| 410 } | 427 } |
| 411 | 428 |
| 412 void PnaclTranslateThread::AbortSubprocesses() { | 429 void PnaclTranslateThread::AbortSubprocesses() { |
| 413 PLUGIN_PRINTF(("PnaclTranslateThread::AbortSubprocesses\n")); | 430 PLUGIN_PRINTF(("PnaclTranslateThread::AbortSubprocesses\n")); |
| 414 NaClXMutexLock(&subprocess_mu_); | 431 NaClXMutexLock(&subprocess_mu_); |
| 415 if (llc_subprocess_ != NULL && llc_subprocess_active_) { | 432 if (compiler_subprocess_ != NULL && compiler_subprocess_active_) { |
| 416 llc_subprocess_->service_runtime()->Shutdown(); | 433 compiler_subprocess_->service_runtime()->Shutdown(); |
| 417 llc_subprocess_active_ = false; | 434 compiler_subprocess_active_ = false; |
| 418 } | 435 } |
| 419 if (ld_subprocess_ != NULL && ld_subprocess_active_) { | 436 if (ld_subprocess_ != NULL && ld_subprocess_active_) { |
| 420 ld_subprocess_->service_runtime()->Shutdown(); | 437 ld_subprocess_->service_runtime()->Shutdown(); |
| 421 ld_subprocess_active_ = false; | 438 ld_subprocess_active_ = false; |
| 422 } | 439 } |
| 423 subprocesses_aborted_ = true; | 440 subprocesses_aborted_ = true; |
| 424 NaClXMutexUnlock(&subprocess_mu_); | 441 NaClXMutexUnlock(&subprocess_mu_); |
| 425 nacl::MutexLocker ml(&cond_mu_); | 442 nacl::MutexLocker ml(&cond_mu_); |
| 426 done_ = true; | 443 done_ = true; |
| 427 // Free all buffered bitcode chunks | 444 // Free all buffered bitcode chunks |
| 428 data_buffers_.clear(); | 445 data_buffers_.clear(); |
| 429 NaClXCondVarSignal(&buffer_cond_); | 446 NaClXCondVarSignal(&buffer_cond_); |
| 430 } | 447 } |
| 431 | 448 |
| 432 PnaclTranslateThread::~PnaclTranslateThread() { | 449 PnaclTranslateThread::~PnaclTranslateThread() { |
| 433 PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this)); | 450 PLUGIN_PRINTF(("~PnaclTranslateThread (translate_thread=%p)\n", this)); |
| 434 AbortSubprocesses(); | 451 AbortSubprocesses(); |
| 435 if (translate_thread_ != NULL) | 452 if (translate_thread_ != NULL) |
| 436 NaClThreadJoin(translate_thread_.get()); | 453 NaClThreadJoin(translate_thread_.get()); |
| 437 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); | 454 PLUGIN_PRINTF(("~PnaclTranslateThread joined\n")); |
| 438 NaClCondVarDtor(&buffer_cond_); | 455 NaClCondVarDtor(&buffer_cond_); |
| 439 NaClMutexDtor(&cond_mu_); | 456 NaClMutexDtor(&cond_mu_); |
| 440 NaClMutexDtor(&subprocess_mu_); | 457 NaClMutexDtor(&subprocess_mu_); |
| 441 } | 458 } |
| 442 | 459 |
| 443 } // namespace plugin | 460 } // namespace plugin |
| OLD | NEW |