| 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_coordinator.h" | 5 #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "native_client/src/include/checked_cast.h" | 10 #include "native_client/src/include/checked_cast.h" |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 const uint32_t kSizeKBBuckets = 100; | 114 const uint32_t kSizeKBBuckets = 100; |
| 115 | 115 |
| 116 const int32_t kRatioMin = 10; | 116 const int32_t kRatioMin = 10; |
| 117 const int32_t kRatioMax = 10*100; // max of 10x difference. | 117 const int32_t kRatioMax = 10*100; // max of 10x difference. |
| 118 const uint32_t kRatioBuckets = 100; | 118 const uint32_t kRatioBuckets = 100; |
| 119 | 119 |
| 120 const int32_t kKBPSMin = 1; | 120 const int32_t kKBPSMin = 1; |
| 121 const int32_t kKBPSMax = 30*1000; // max of 30 MB / sec. | 121 const int32_t kKBPSMax = 30*1000; // max of 30 MB / sec. |
| 122 const uint32_t kKBPSBuckets = 100; | 122 const uint32_t kKBPSBuckets = 100; |
| 123 | 123 |
| 124 const PPB_UMA_Private* uma_interface = NULL; | 124 void HistogramTime(const pp::UMAPrivate& uma, |
| 125 | 125 const std::string& name, int64_t ms) { |
| 126 const PPB_UMA_Private* GetUMAInterface() { | 126 if (ms < 0) return; |
| 127 if (uma_interface != NULL) { | 127 uma.HistogramCustomTimes(name, |
| 128 return uma_interface; | 128 ms, |
| 129 } | 129 kTimeLargeMin, kTimeLargeMax, |
| 130 pp::Module *module = pp::Module::Get(); | 130 kTimeLargeBuckets); |
| 131 DCHECK(module); | |
| 132 uma_interface = static_cast<const PPB_UMA_Private*>( | |
| 133 module->GetBrowserInterface(PPB_UMA_PRIVATE_INTERFACE)); | |
| 134 return uma_interface; | |
| 135 } | 131 } |
| 136 | 132 |
| 137 void HistogramTime(const std::string& name, int64_t ms) { | 133 void HistogramSizeKB(const pp::UMAPrivate& uma, |
| 138 if (ms < 0) return; | 134 const std::string& name, int32_t kb) { |
| 139 | 135 if (kb < 0) return; |
| 140 const PPB_UMA_Private* ptr = GetUMAInterface(); | 136 uma.HistogramCustomCounts(name, |
| 141 if (ptr == NULL) return; | 137 kb, |
| 142 | 138 kSizeKBMin, kSizeKBMax, |
| 143 ptr->HistogramCustomTimes(pp::Var(name).pp_var(), | 139 kSizeKBBuckets); |
| 144 ms, | |
| 145 kTimeLargeMin, kTimeLargeMax, | |
| 146 kTimeLargeBuckets); | |
| 147 } | 140 } |
| 148 | 141 |
| 149 void HistogramSizeKB(const std::string& name, int32_t kb) { | 142 void HistogramRatio(const pp::UMAPrivate& uma, |
| 150 if (kb < 0) return; | 143 const std::string& name, int64_t a, int64_t b) { |
| 151 | 144 if (a < 0 || b <= 0) return; |
| 152 const PPB_UMA_Private* ptr = GetUMAInterface(); | 145 uma.HistogramCustomCounts(name, |
| 153 if (ptr == NULL) return; | 146 100 * a / b, |
| 154 | 147 kRatioMin, kRatioMax, |
| 155 ptr->HistogramCustomCounts(pp::Var(name).pp_var(), | 148 kRatioBuckets); |
| 156 kb, | |
| 157 kSizeKBMin, kSizeKBMax, | |
| 158 kSizeKBBuckets); | |
| 159 } | 149 } |
| 160 | 150 |
| 161 void HistogramRatio(const std::string& name, int64_t a, int64_t b) { | 151 void HistogramKBPerSec(const pp::UMAPrivate& uma, |
| 162 if (a < 0 || b <= 0) return; | 152 const std::string& name, double kb, double s) { |
| 163 | 153 if (kb < 0.0 || s <= 0.0) return; |
| 164 const PPB_UMA_Private* ptr = GetUMAInterface(); | 154 uma.HistogramCustomCounts(name, |
| 165 if (ptr == NULL) return; | 155 static_cast<int64_t>(kb / s), |
| 166 | 156 kKBPSMin, kKBPSMax, |
| 167 ptr->HistogramCustomCounts(pp::Var(name).pp_var(), | 157 kKBPSBuckets); |
| 168 100 * a / b, | |
| 169 kRatioMin, kRatioMax, | |
| 170 kRatioBuckets); | |
| 171 } | 158 } |
| 172 | 159 |
| 173 void HistogramKBPerSec(const std::string& name, double kb, double s) { | 160 void HistogramEnumerateTranslationCache(const pp::UMAPrivate& uma, bool hit) { |
| 174 if (kb < 0.0 || s <= 0.0) return; | 161 uma.HistogramEnumeration("NaCl.Perf.PNaClCache.IsHit", |
| 175 | 162 hit, 2); |
| 176 const PPB_UMA_Private* ptr = GetUMAInterface(); | |
| 177 if (ptr == NULL) return; | |
| 178 | |
| 179 ptr->HistogramCustomCounts(pp::Var(name).pp_var(), | |
| 180 static_cast<int64_t>(kb / s), | |
| 181 kKBPSMin, kKBPSMax, | |
| 182 kKBPSBuckets); | |
| 183 } | |
| 184 | |
| 185 void HistogramEnumerateTranslationCache(bool hit) { | |
| 186 const PPB_UMA_Private* ptr = GetUMAInterface(); | |
| 187 if (ptr == NULL) return; | |
| 188 ptr->HistogramEnumeration(pp::Var("NaCl.Perf.PNaClCache.IsHit").pp_var(), | |
| 189 hit, 2); | |
| 190 } | 163 } |
| 191 | 164 |
| 192 // Opt level is expected to be 0 to 3. Treating 4 as unknown. | 165 // Opt level is expected to be 0 to 3. Treating 4 as unknown. |
| 193 const int8_t kOptUnknown = 4; | 166 const int8_t kOptUnknown = 4; |
| 194 | 167 |
| 195 void HistogramOptLevel(int8_t opt_level) { | 168 void HistogramOptLevel(const pp::UMAPrivate& uma, int8_t opt_level) { |
| 196 const PPB_UMA_Private* ptr = GetUMAInterface(); | |
| 197 if (ptr == NULL) return; | |
| 198 if (opt_level < 0 || opt_level > 3) { | 169 if (opt_level < 0 || opt_level > 3) { |
| 199 opt_level = kOptUnknown; | 170 opt_level = kOptUnknown; |
| 200 } | 171 } |
| 201 ptr->HistogramEnumeration(pp::Var("NaCl.Options.PNaCl.OptLevel").pp_var(), | 172 uma.HistogramEnumeration("NaCl.Options.PNaCl.OptLevel", |
| 202 opt_level, kOptUnknown+1); | 173 opt_level, kOptUnknown+1); |
| 203 } | 174 } |
| 204 | 175 |
| 205 } // namespace | 176 } // namespace |
| 206 | 177 |
| 207 | 178 |
| 208 ////////////////////////////////////////////////////////////////////// | 179 ////////////////////////////////////////////////////////////////////// |
| 209 // The coordinator class. | 180 // The coordinator class. |
| 210 ////////////////////////////////////////////////////////////////////// | 181 ////////////////////////////////////////////////////////////////////// |
| 211 | 182 |
| 212 // Out-of-line destructor to keep it from getting put in every .o where | 183 // Out-of-line destructor to keep it from getting put in every .o where |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 if (ExpectedProgressKnown()) { | 316 if (ExpectedProgressKnown()) { |
| 346 pexe_bytes_compiled_ = expected_pexe_size_; | 317 pexe_bytes_compiled_ = expected_pexe_size_; |
| 347 plugin_->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, | 318 plugin_->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, |
| 348 pexe_url_, | 319 pexe_url_, |
| 349 plugin::Plugin::LENGTH_IS_COMPUTABLE, | 320 plugin::Plugin::LENGTH_IS_COMPUTABLE, |
| 350 pexe_bytes_compiled_, | 321 pexe_bytes_compiled_, |
| 351 expected_pexe_size_); | 322 expected_pexe_size_); |
| 352 } | 323 } |
| 353 | 324 |
| 354 // If there are no errors, report stats from this thread (the main thread). | 325 // If there are no errors, report stats from this thread (the main thread). |
| 355 HistogramOptLevel(pnacl_options_.opt_level()); | 326 HistogramOptLevel(plugin_->uma_interface(), pnacl_options_.opt_level()); |
| 356 const plugin::PnaclTimeStats& time_stats = translate_thread_->GetTimeStats(); | 327 const plugin::PnaclTimeStats& time_stats = translate_thread_->GetTimeStats(); |
| 357 HistogramTime("NaCl.Perf.PNaClLoadTime.LoadCompiler", | 328 HistogramTime(plugin_->uma_interface(), |
| 329 "NaCl.Perf.PNaClLoadTime.LoadCompiler", |
| 358 time_stats.pnacl_llc_load_time / NACL_MICROS_PER_MILLI); | 330 time_stats.pnacl_llc_load_time / NACL_MICROS_PER_MILLI); |
| 359 HistogramTime("NaCl.Perf.PNaClLoadTime.CompileTime", | 331 HistogramTime(plugin_->uma_interface(), "NaCl.Perf.PNaClLoadTime.CompileTime", |
| 360 time_stats.pnacl_compile_time / NACL_MICROS_PER_MILLI); | 332 time_stats.pnacl_compile_time / NACL_MICROS_PER_MILLI); |
| 361 HistogramKBPerSec("NaCl.Perf.PNaClLoadTime.CompileKBPerSec", | 333 HistogramKBPerSec(plugin_->uma_interface(), |
| 334 "NaCl.Perf.PNaClLoadTime.CompileKBPerSec", |
| 362 pexe_size_ / 1024.0, | 335 pexe_size_ / 1024.0, |
| 363 time_stats.pnacl_compile_time / 1000000.0); | 336 time_stats.pnacl_compile_time / 1000000.0); |
| 364 HistogramTime("NaCl.Perf.PNaClLoadTime.LoadLinker", | 337 HistogramTime(plugin_->uma_interface(), "NaCl.Perf.PNaClLoadTime.LoadLinker", |
| 365 time_stats.pnacl_ld_load_time / NACL_MICROS_PER_MILLI); | 338 time_stats.pnacl_ld_load_time / NACL_MICROS_PER_MILLI); |
| 366 HistogramTime("NaCl.Perf.PNaClLoadTime.LinkTime", | 339 HistogramTime(plugin_->uma_interface(), "NaCl.Perf.PNaClLoadTime.LinkTime", |
| 367 time_stats.pnacl_link_time / NACL_MICROS_PER_MILLI); | 340 time_stats.pnacl_link_time / NACL_MICROS_PER_MILLI); |
| 368 HistogramSizeKB("NaCl.Perf.Size.Pexe", | 341 HistogramSizeKB(plugin_->uma_interface(), "NaCl.Perf.Size.Pexe", |
| 369 static_cast<int64_t>(pexe_size_ / 1024)); | 342 static_cast<int64_t>(pexe_size_ / 1024)); |
| 370 | 343 |
| 371 struct nacl_abi_stat stbuf; | 344 struct nacl_abi_stat stbuf; |
| 372 struct NaClDesc* desc = temp_nexe_file_->read_wrapper()->desc(); | 345 struct NaClDesc* desc = temp_nexe_file_->read_wrapper()->desc(); |
| 373 int stat_ret; | 346 int stat_ret; |
| 374 if (0 != (stat_ret = (*((struct NaClDescVtbl const *) desc->base.vtbl)-> | 347 if (0 != (stat_ret = (*((struct NaClDescVtbl const *) desc->base.vtbl)-> |
| 375 Fstat)(desc, &stbuf))) { | 348 Fstat)(desc, &stbuf))) { |
| 376 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished can't stat nexe.\n")); | 349 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished can't stat nexe.\n")); |
| 377 } else { | 350 } else { |
| 378 size_t nexe_size = stbuf.nacl_abi_st_size; | 351 size_t nexe_size = stbuf.nacl_abi_st_size; |
| 379 HistogramSizeKB("NaCl.Perf.Size.PNaClTranslatedNexe", | 352 HistogramSizeKB(plugin_->uma_interface(), |
| 353 "NaCl.Perf.Size.PNaClTranslatedNexe", |
| 380 static_cast<int64_t>(nexe_size / 1024)); | 354 static_cast<int64_t>(nexe_size / 1024)); |
| 381 HistogramRatio("NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); | 355 HistogramRatio(plugin_->uma_interface(), |
| 356 "NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); |
| 382 } | 357 } |
| 383 | 358 |
| 384 int64_t total_time = NaClGetTimeOfDayMicroseconds() - pnacl_init_time_; | 359 int64_t total_time = NaClGetTimeOfDayMicroseconds() - pnacl_init_time_; |
| 385 HistogramTime("NaCl.Perf.PNaClLoadTime.TotalUncachedTime", | 360 HistogramTime(plugin_->uma_interface(), |
| 361 "NaCl.Perf.PNaClLoadTime.TotalUncachedTime", |
| 386 total_time / NACL_MICROS_PER_MILLI); | 362 total_time / NACL_MICROS_PER_MILLI); |
| 387 HistogramKBPerSec("NaCl.Perf.PNaClLoadTime.TotalUncachedKBPerSec", | 363 HistogramKBPerSec(plugin_->uma_interface(), |
| 364 "NaCl.Perf.PNaClLoadTime.TotalUncachedKBPerSec", |
| 388 pexe_size_ / 1024.0, | 365 pexe_size_ / 1024.0, |
| 389 total_time / 1000000.0); | 366 total_time / 1000000.0); |
| 390 | 367 |
| 391 // The nexe is written to the temp_nexe_file_. We must Reset() the file | 368 // The nexe is written to the temp_nexe_file_. We must Reset() the file |
| 392 // pointer to be able to read it again from the beginning. | 369 // pointer to be able to read it again from the beginning. |
| 393 temp_nexe_file_->Reset(); | 370 temp_nexe_file_->Reset(); |
| 394 | 371 |
| 395 // Report to the browser that translation finished. The browser will take | 372 // Report to the browser that translation finished. The browser will take |
| 396 // care of storing the nexe in the cache. | 373 // care of storing the nexe in the cache. |
| 397 translation_finished_reported_ = true; | 374 translation_finished_reported_ = true; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 return; | 517 return; |
| 541 } | 518 } |
| 542 | 519 |
| 543 if (*temp_nexe_file_->existing_handle() == PP_kInvalidFileHandle) { | 520 if (*temp_nexe_file_->existing_handle() == PP_kInvalidFileHandle) { |
| 544 ReportNonPpapiError( | 521 ReportNonPpapiError( |
| 545 ERROR_PNACL_CREATE_TEMP, | 522 ERROR_PNACL_CREATE_TEMP, |
| 546 nacl::string( | 523 nacl::string( |
| 547 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); | 524 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); |
| 548 return; | 525 return; |
| 549 } | 526 } |
| 550 HistogramEnumerateTranslationCache(is_cache_hit_); | 527 HistogramEnumerateTranslationCache(plugin_->uma_interface(), is_cache_hit_); |
| 551 | 528 |
| 552 if (is_cache_hit_ == PP_TRUE) { | 529 if (is_cache_hit_ == PP_TRUE) { |
| 553 // Cache hit -- no need to stream the rest of the file. | 530 // Cache hit -- no need to stream the rest of the file. |
| 554 streaming_downloader_.reset(NULL); | 531 streaming_downloader_.reset(NULL); |
| 555 // Open it for reading as the cached nexe file. | 532 // Open it for reading as the cached nexe file. |
| 556 pp::CompletionCallback cb = | 533 pp::CompletionCallback cb = |
| 557 callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); | 534 callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); |
| 558 temp_nexe_file_->Open(cb, false); | 535 temp_nexe_file_->Open(cb, false); |
| 559 } else { | 536 } else { |
| 560 // Open an object file first so the translator can start writing to it | 537 // Open an object file first so the translator can start writing to it |
| (...skipping 29 matching lines...) Expand all Loading... |
| 590 error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_NOACCESS, | 567 error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_NOACCESS, |
| 591 "PnaclCoordinator: pexe load failed (no access)."); | 568 "PnaclCoordinator: pexe load failed (no access)."); |
| 592 } else { | 569 } else { |
| 593 nacl::stringstream ss; | 570 nacl::stringstream ss; |
| 594 ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; | 571 ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; |
| 595 error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); | 572 error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); |
| 596 } | 573 } |
| 597 translate_thread_->AbortSubprocesses(); | 574 translate_thread_->AbortSubprocesses(); |
| 598 } else { | 575 } else { |
| 599 // Compare download completion pct (100% now), to compile completion pct. | 576 // Compare download completion pct (100% now), to compile completion pct. |
| 600 HistogramRatio("NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", | 577 HistogramRatio(plugin_->uma_interface(), |
| 578 "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", |
| 601 pexe_bytes_compiled_, pexe_size_); | 579 pexe_bytes_compiled_, pexe_size_); |
| 602 } | 580 } |
| 603 } | 581 } |
| 604 | 582 |
| 605 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, | 583 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, |
| 606 FileStreamData data) { | 584 FileStreamData data) { |
| 607 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%" | 585 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%" |
| 608 NACL_PRId32 ", data=%p)\n", pp_error, data ? &(*data)[0] : 0)); | 586 NACL_PRId32 ", data=%p)\n", pp_error, data ? &(*data)[0] : 0)); |
| 609 DCHECK(translate_thread_.get()); | 587 DCHECK(translate_thread_.get()); |
| 610 | 588 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 691 obj_file_.get(), | 669 obj_file_.get(), |
| 692 temp_nexe_file_.get(), | 670 temp_nexe_file_.get(), |
| 693 &error_info_, | 671 &error_info_, |
| 694 resources_.get(), | 672 resources_.get(), |
| 695 &pnacl_options_, | 673 &pnacl_options_, |
| 696 this, | 674 this, |
| 697 plugin_); | 675 plugin_); |
| 698 } | 676 } |
| 699 | 677 |
| 700 } // namespace plugin | 678 } // namespace plugin |
| OLD | NEW |