| 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(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(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(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(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(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(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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 if (ExpectedProgressKnown()) { | 311 if (ExpectedProgressKnown()) { |
| 341 pexe_bytes_compiled_ = expected_pexe_size_; | 312 pexe_bytes_compiled_ = expected_pexe_size_; |
| 342 plugin_->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, | 313 plugin_->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, |
| 343 pexe_url_, | 314 pexe_url_, |
| 344 plugin::Plugin::LENGTH_IS_COMPUTABLE, | 315 plugin::Plugin::LENGTH_IS_COMPUTABLE, |
| 345 pexe_bytes_compiled_, | 316 pexe_bytes_compiled_, |
| 346 expected_pexe_size_); | 317 expected_pexe_size_); |
| 347 } | 318 } |
| 348 | 319 |
| 349 // If there are no errors, report stats from this thread (the main thread). | 320 // If there are no errors, report stats from this thread (the main thread). |
| 350 HistogramOptLevel(pnacl_options_.opt_level()); | 321 HistogramOptLevel(plugin_->uma_interface(), pnacl_options_.opt_level()); |
| 351 const plugin::PnaclTimeStats& time_stats = translate_thread_->GetTimeStats(); | 322 const plugin::PnaclTimeStats& time_stats = translate_thread_->GetTimeStats(); |
| 352 HistogramTime("NaCl.Perf.PNaClLoadTime.LoadCompiler", | 323 HistogramTime(plugin_->uma_interface(), |
| 324 "NaCl.Perf.PNaClLoadTime.LoadCompiler", |
| 353 time_stats.pnacl_llc_load_time / NACL_MICROS_PER_MILLI); | 325 time_stats.pnacl_llc_load_time / NACL_MICROS_PER_MILLI); |
| 354 HistogramTime("NaCl.Perf.PNaClLoadTime.CompileTime", | 326 HistogramTime(plugin_->uma_interface(), "NaCl.Perf.PNaClLoadTime.CompileTime", |
| 355 time_stats.pnacl_compile_time / NACL_MICROS_PER_MILLI); | 327 time_stats.pnacl_compile_time / NACL_MICROS_PER_MILLI); |
| 356 HistogramKBPerSec("NaCl.Perf.PNaClLoadTime.CompileKBPerSec", | 328 HistogramKBPerSec(plugin_->uma_interface(), |
| 329 "NaCl.Perf.PNaClLoadTime.CompileKBPerSec", |
| 357 pexe_size_ / 1024.0, | 330 pexe_size_ / 1024.0, |
| 358 time_stats.pnacl_compile_time / 1000000.0); | 331 time_stats.pnacl_compile_time / 1000000.0); |
| 359 HistogramTime("NaCl.Perf.PNaClLoadTime.LoadLinker", | 332 HistogramTime(plugin_->uma_interface(), "NaCl.Perf.PNaClLoadTime.LoadLinker", |
| 360 time_stats.pnacl_ld_load_time / NACL_MICROS_PER_MILLI); | 333 time_stats.pnacl_ld_load_time / NACL_MICROS_PER_MILLI); |
| 361 HistogramTime("NaCl.Perf.PNaClLoadTime.LinkTime", | 334 HistogramTime(plugin_->uma_interface(), "NaCl.Perf.PNaClLoadTime.LinkTime", |
| 362 time_stats.pnacl_link_time / NACL_MICROS_PER_MILLI); | 335 time_stats.pnacl_link_time / NACL_MICROS_PER_MILLI); |
| 363 HistogramSizeKB("NaCl.Perf.Size.Pexe", | 336 HistogramSizeKB(plugin_->uma_interface(), "NaCl.Perf.Size.Pexe", |
| 364 static_cast<int64_t>(pexe_size_ / 1024)); | 337 static_cast<int64_t>(pexe_size_ / 1024)); |
| 365 | 338 |
| 366 struct nacl_abi_stat stbuf; | 339 struct nacl_abi_stat stbuf; |
| 367 struct NaClDesc* desc = temp_nexe_file_->read_wrapper()->desc(); | 340 struct NaClDesc* desc = temp_nexe_file_->read_wrapper()->desc(); |
| 368 int stat_ret; | 341 int stat_ret; |
| 369 if (0 != (stat_ret = (*((struct NaClDescVtbl const *) desc->base.vtbl)-> | 342 if (0 != (stat_ret = (*((struct NaClDescVtbl const *) desc->base.vtbl)-> |
| 370 Fstat)(desc, &stbuf))) { | 343 Fstat)(desc, &stbuf))) { |
| 371 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished can't stat nexe.\n")); | 344 PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished can't stat nexe.\n")); |
| 372 } else { | 345 } else { |
| 373 size_t nexe_size = stbuf.nacl_abi_st_size; | 346 size_t nexe_size = stbuf.nacl_abi_st_size; |
| 374 HistogramSizeKB("NaCl.Perf.Size.PNaClTranslatedNexe", | 347 HistogramSizeKB(plugin_->uma_interface(), |
| 348 "NaCl.Perf.Size.PNaClTranslatedNexe", |
| 375 static_cast<int64_t>(nexe_size / 1024)); | 349 static_cast<int64_t>(nexe_size / 1024)); |
| 376 HistogramRatio("NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); | 350 HistogramRatio(plugin_->uma_interface(), |
| 351 "NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); |
| 377 } | 352 } |
| 378 | 353 |
| 379 int64_t total_time = NaClGetTimeOfDayMicroseconds() - pnacl_init_time_; | 354 int64_t total_time = NaClGetTimeOfDayMicroseconds() - pnacl_init_time_; |
| 380 HistogramTime("NaCl.Perf.PNaClLoadTime.TotalUncachedTime", | 355 HistogramTime(plugin_->uma_interface(), |
| 356 "NaCl.Perf.PNaClLoadTime.TotalUncachedTime", |
| 381 total_time / NACL_MICROS_PER_MILLI); | 357 total_time / NACL_MICROS_PER_MILLI); |
| 382 HistogramKBPerSec("NaCl.Perf.PNaClLoadTime.TotalUncachedKBPerSec", | 358 HistogramKBPerSec(plugin_->uma_interface(), |
| 359 "NaCl.Perf.PNaClLoadTime.TotalUncachedKBPerSec", |
| 383 pexe_size_ / 1024.0, | 360 pexe_size_ / 1024.0, |
| 384 total_time / 1000000.0); | 361 total_time / 1000000.0); |
| 385 | 362 |
| 386 // The nexe is written to the temp_nexe_file_. We must Reset() the file | 363 // The nexe is written to the temp_nexe_file_. We must Reset() the file |
| 387 // pointer to be able to read it again from the beginning. | 364 // pointer to be able to read it again from the beginning. |
| 388 temp_nexe_file_->Reset(); | 365 temp_nexe_file_->Reset(); |
| 389 | 366 |
| 390 // Report to the browser that translation finished. The browser will take | 367 // Report to the browser that translation finished. The browser will take |
| 391 // care of storing the nexe in the cache. | 368 // care of storing the nexe in the cache. |
| 392 translation_finished_reported_ = true; | 369 translation_finished_reported_ = true; |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 return; | 512 return; |
| 536 } | 513 } |
| 537 | 514 |
| 538 if (*temp_nexe_file_->existing_handle() == PP_kInvalidFileHandle) { | 515 if (*temp_nexe_file_->existing_handle() == PP_kInvalidFileHandle) { |
| 539 ReportNonPpapiError( | 516 ReportNonPpapiError( |
| 540 ERROR_PNACL_CREATE_TEMP, | 517 ERROR_PNACL_CREATE_TEMP, |
| 541 nacl::string( | 518 nacl::string( |
| 542 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); | 519 "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); |
| 543 return; | 520 return; |
| 544 } | 521 } |
| 545 HistogramEnumerateTranslationCache(is_cache_hit_); | 522 HistogramEnumerateTranslationCache(plugin_->uma_interface(), is_cache_hit_); |
| 546 | 523 |
| 547 if (is_cache_hit_ == PP_TRUE) { | 524 if (is_cache_hit_ == PP_TRUE) { |
| 548 // Cache hit -- no need to stream the rest of the file. | 525 // Cache hit -- no need to stream the rest of the file. |
| 549 streaming_downloader_.reset(NULL); | 526 streaming_downloader_.reset(NULL); |
| 550 // Open it for reading as the cached nexe file. | 527 // Open it for reading as the cached nexe file. |
| 551 pp::CompletionCallback cb = | 528 pp::CompletionCallback cb = |
| 552 callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); | 529 callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); |
| 553 temp_nexe_file_->Open(cb, false); | 530 temp_nexe_file_->Open(cb, false); |
| 554 } else { | 531 } else { |
| 555 // Open an object file first so the translator can start writing to it | 532 // Open an object file first so the translator can start writing to it |
| (...skipping 29 matching lines...) Expand all Loading... |
| 585 error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_NOACCESS, | 562 error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_NOACCESS, |
| 586 "PnaclCoordinator: pexe load failed (no access)."); | 563 "PnaclCoordinator: pexe load failed (no access)."); |
| 587 } else { | 564 } else { |
| 588 nacl::stringstream ss; | 565 nacl::stringstream ss; |
| 589 ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; | 566 ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; |
| 590 error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); | 567 error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); |
| 591 } | 568 } |
| 592 translate_thread_->AbortSubprocesses(); | 569 translate_thread_->AbortSubprocesses(); |
| 593 } else { | 570 } else { |
| 594 // Compare download completion pct (100% now), to compile completion pct. | 571 // Compare download completion pct (100% now), to compile completion pct. |
| 595 HistogramRatio("NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", | 572 HistogramRatio(plugin_->uma_interface(), |
| 573 "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", |
| 596 pexe_bytes_compiled_, pexe_size_); | 574 pexe_bytes_compiled_, pexe_size_); |
| 597 } | 575 } |
| 598 } | 576 } |
| 599 | 577 |
| 600 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, | 578 void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, |
| 601 FileStreamData data) { | 579 FileStreamData data) { |
| 602 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%" | 580 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeStreamGotData (pp_error=%" |
| 603 NACL_PRId32 ", data=%p)\n", pp_error, data ? &(*data)[0] : 0)); | 581 NACL_PRId32 ", data=%p)\n", pp_error, data ? &(*data)[0] : 0)); |
| 604 DCHECK(translate_thread_.get()); | 582 DCHECK(translate_thread_.get()); |
| 605 | 583 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 obj_file_.get(), | 664 obj_file_.get(), |
| 687 temp_nexe_file_.get(), | 665 temp_nexe_file_.get(), |
| 688 &error_info_, | 666 &error_info_, |
| 689 resources_.get(), | 667 resources_.get(), |
| 690 &pnacl_options_, | 668 &pnacl_options_, |
| 691 this, | 669 this, |
| 692 plugin_); | 670 plugin_); |
| 693 } | 671 } |
| 694 | 672 |
| 695 } // namespace plugin | 673 } // namespace plugin |
| OLD | NEW |