diff options
Diffstat (limited to 'chromium/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc')
-rw-r--r-- | chromium/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc | 427 |
1 files changed, 136 insertions, 291 deletions
diff --git a/chromium/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/chromium/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc index f892059ad79..b85b44654ef 100644 --- a/chromium/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc +++ b/chromium/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc @@ -16,8 +16,6 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/ppb_uma_private.h" -#include "ppapi/native_client/src/trusted/plugin/manifest.h" -#include "ppapi/native_client/src/trusted/plugin/nacl_http_response_headers.h" #include "ppapi/native_client/src/trusted/plugin/plugin.h" #include "ppapi/native_client/src/trusted/plugin/plugin_error.h" #include "ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h" @@ -26,89 +24,8 @@ namespace plugin { -////////////////////////////////////////////////////////////////////// -// Pnacl-specific manifest support. -////////////////////////////////////////////////////////////////////// - -// The PNaCl linker gets file descriptors via the service runtime's -// reverse service lookup. The reverse service lookup requires a manifest. -// Normally, that manifest is an NMF containing mappings for shared libraries. -// Here, we provide a manifest that redirects to PNaCl component files -// that are part of Chrome. -class PnaclManifest : public Manifest { - public: - PnaclManifest() : manifest_base_url_(PnaclUrls::GetBaseUrl()) { } - virtual ~PnaclManifest() { } - - virtual bool GetProgramURL(nacl::string* full_url, - PnaclOptions* pnacl_options, - ErrorInfo* error_info) const { - // Does not contain program urls. - UNREFERENCED_PARAMETER(full_url); - UNREFERENCED_PARAMETER(pnacl_options); - UNREFERENCED_PARAMETER(error_info); - PLUGIN_PRINTF(("PnaclManifest does not contain a program\n")); - error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, - "pnacl manifest does not contain a program."); - return false; - } - - virtual bool ResolveURL(const nacl::string& relative_url, - nacl::string* full_url, - ErrorInfo* error_info) const { - // Does not do general URL resolution, simply appends relative_url to - // the end of manifest_base_url_. - UNREFERENCED_PARAMETER(error_info); - *full_url = manifest_base_url_ + relative_url; - return true; - } - - virtual bool GetFileKeys(std::set<nacl::string>* keys) const { - // Does not support enumeration. - PLUGIN_PRINTF(("PnaclManifest does not support key enumeration\n")); - UNREFERENCED_PARAMETER(keys); - return false; - } - - virtual bool ResolveKey(const nacl::string& key, - nacl::string* full_url, - PnaclOptions* pnacl_options, - ErrorInfo* error_info) const { - // All of the component files are native (do not require pnacl translate). - pnacl_options->set_translate(false); - // We can only resolve keys in the files/ namespace. - const nacl::string kFilesPrefix = "files/"; - size_t files_prefix_pos = key.find(kFilesPrefix); - if (files_prefix_pos == nacl::string::npos) { - error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, - "key did not start with files/"); - return false; - } - // Resolve the full URL to the file. Provide it with a platform-specific - // prefix. - nacl::string key_basename = key.substr(kFilesPrefix.length()); - return ResolveURL(PnaclUrls::PrependPlatformPrefix(key_basename), - full_url, error_info); - } - - private: - NACL_DISALLOW_COPY_AND_ASSIGN(PnaclManifest); - - nacl::string manifest_base_url_; -}; - -////////////////////////////////////////////////////////////////////// -// UMA stat helpers. -////////////////////////////////////////////////////////////////////// - namespace { -// Assume translation time metrics *can be* large. -// Up to 12 minutes. -const int64_t kTimeLargeMin = 10; // in ms -const int64_t kTimeLargeMax = 720000; // in ms -const uint32_t kTimeLargeBuckets = 100; - const int32_t kSizeKBMin = 1; const int32_t kSizeKBMax = 512*1024; // very large .pexe / .nexe. const uint32_t kSizeKBBuckets = 100; @@ -117,98 +34,37 @@ const int32_t kRatioMin = 10; const int32_t kRatioMax = 10*100; // max of 10x difference. const uint32_t kRatioBuckets = 100; -const int32_t kKBPSMin = 1; -const int32_t kKBPSMax = 30*1000; // max of 30 MB / sec. -const uint32_t kKBPSBuckets = 100; - -const PPB_UMA_Private* uma_interface = NULL; - -const PPB_UMA_Private* GetUMAInterface() { - if (uma_interface != NULL) { - return uma_interface; - } - pp::Module *module = pp::Module::Get(); - DCHECK(module); - uma_interface = static_cast<const PPB_UMA_Private*>( - module->GetBrowserInterface(PPB_UMA_PRIVATE_INTERFACE)); - return uma_interface; -} - -void HistogramTime(const std::string& name, int64_t ms) { - if (ms < 0) return; - - const PPB_UMA_Private* ptr = GetUMAInterface(); - if (ptr == NULL) return; - - ptr->HistogramCustomTimes(pp::Var(name).pp_var(), - ms, - kTimeLargeMin, kTimeLargeMax, - kTimeLargeBuckets); -} - -void HistogramSizeKB(const std::string& name, int32_t kb) { +void HistogramSizeKB(pp::UMAPrivate& uma, + const nacl::string& name, int32_t kb) { if (kb < 0) return; - - const PPB_UMA_Private* ptr = GetUMAInterface(); - if (ptr == NULL) return; - - ptr->HistogramCustomCounts(pp::Var(name).pp_var(), - kb, - kSizeKBMin, kSizeKBMax, - kSizeKBBuckets); + uma.HistogramCustomCounts(name, + kb, + kSizeKBMin, kSizeKBMax, + kSizeKBBuckets); } -void HistogramRatio(const std::string& name, int64_t a, int64_t b) { +void HistogramRatio(pp::UMAPrivate& uma, + const nacl::string& name, int64_t a, int64_t b) { if (a < 0 || b <= 0) return; - - const PPB_UMA_Private* ptr = GetUMAInterface(); - if (ptr == NULL) return; - - ptr->HistogramCustomCounts(pp::Var(name).pp_var(), - 100 * a / b, - kRatioMin, kRatioMax, - kRatioBuckets); + uma.HistogramCustomCounts(name, + 100 * a / b, + kRatioMin, kRatioMax, + kRatioBuckets); } -void HistogramKBPerSec(const std::string& name, double kb, double s) { - if (kb < 0.0 || s <= 0.0) return; - - const PPB_UMA_Private* ptr = GetUMAInterface(); - if (ptr == NULL) return; - - ptr->HistogramCustomCounts(pp::Var(name).pp_var(), - static_cast<int64_t>(kb / s), - kKBPSMin, kKBPSMax, - kKBPSBuckets); +void HistogramEnumerateTranslationCache(pp::UMAPrivate& uma, bool hit) { + uma.HistogramEnumeration("NaCl.Perf.PNaClCache.IsHit", + hit, 2); } -void HistogramEnumerateTranslationCache(bool hit) { - const PPB_UMA_Private* ptr = GetUMAInterface(); - if (ptr == NULL) return; - ptr->HistogramEnumeration(pp::Var("NaCl.Perf.PNaClCache.IsHit").pp_var(), - hit, 2); -} - -// Opt level is expected to be 0 to 3. Treating 4 as unknown. -const int8_t kOptUnknown = 4; - -void HistogramOptLevel(int8_t opt_level) { - const PPB_UMA_Private* ptr = GetUMAInterface(); - if (ptr == NULL) return; - if (opt_level < 0 || opt_level > 3) { - opt_level = kOptUnknown; - } - ptr->HistogramEnumeration(pp::Var("NaCl.Options.PNaCl.OptLevel").pp_var(), - opt_level, kOptUnknown+1); +nacl::string GetArchitectureAttributes(Plugin* plugin) { + pp::Var attrs_var(pp::PASS_REF, + plugin->nacl_interface()->GetCpuFeatureAttrs()); + return attrs_var.AsString(); } } // namespace - -////////////////////////////////////////////////////////////////////// -// The coordinator class. -////////////////////////////////////////////////////////////////////// - // Out-of-line destructor to keep it from getting put in every .o where // callback_source.h is included template<> @@ -217,7 +73,7 @@ CallbackSource<FileStreamData>::~CallbackSource() {} PnaclCoordinator* PnaclCoordinator::BitcodeToNative( Plugin* plugin, const nacl::string& pexe_url, - const PnaclOptions& pnacl_options, + const PP_PNaClOptions& pnacl_options, const pp::CompletionCallback& translate_notify_callback) { PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", static_cast<void*>(plugin), pexe_url.c_str())); @@ -225,9 +81,10 @@ PnaclCoordinator* PnaclCoordinator::BitcodeToNative( new PnaclCoordinator(plugin, pexe_url, pnacl_options, translate_notify_callback); + coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds(); - PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p, ", - reinterpret_cast<const void*>(coordinator->manifest_.get()))); + int cpus = plugin->nacl_interface()->GetNumberOfProcessors(); + coordinator->split_module_count_ = std::min(4, std::max(1, cpus)); // First start a network request for the pexe, to tickle the component // updater's On-Demand resource throttler, and to get Last-Modified/ETag @@ -240,15 +97,16 @@ PnaclCoordinator* PnaclCoordinator::BitcodeToNative( PnaclCoordinator::PnaclCoordinator( Plugin* plugin, const nacl::string& pexe_url, - const PnaclOptions& pnacl_options, + const PP_PNaClOptions& pnacl_options, const pp::CompletionCallback& translate_notify_callback) : translate_finish_error_(PP_OK), plugin_(plugin), translate_notify_callback_(translate_notify_callback), translation_finished_reported_(false), - manifest_(new PnaclManifest()), pexe_url_(pexe_url), pnacl_options_(pnacl_options), + architecture_attributes_(GetArchitectureAttributes(plugin)), + split_module_count_(1), is_cache_hit_(PP_FALSE), error_already_reported_(false), pnacl_init_time_(0), @@ -269,42 +127,48 @@ PnaclCoordinator::~PnaclCoordinator() { // running from the main thread, and by the time it exits, callback_factory_ // will have been destroyed. This will result in the cancellation of // translation_complete_callback_, so no notification will be delivered. - if (translate_thread_.get() != NULL) { + if (translate_thread_.get() != NULL) translate_thread_->AbortSubprocesses(); - } if (!translation_finished_reported_) { plugin_->nacl_interface()->ReportTranslationFinished( plugin_->pp_instance(), - PP_FALSE); + PP_FALSE, 0, 0, 0, 0); } + // Force deleting the translate_thread now. It must be deleted + // before any scoped_* fields hanging off of PnaclCoordinator + // since the thread may be accessing those fields. + // It will also be accessing obj_files_. + translate_thread_.reset(NULL); + for (size_t i = 0; i < obj_files_.size(); i++) + delete obj_files_[i]; } -nacl::DescWrapper* PnaclCoordinator::ReleaseTranslatedFD() { +PP_FileHandle PnaclCoordinator::TakeTranslatedFileHandle() { DCHECK(temp_nexe_file_ != NULL); - return temp_nexe_file_->release_read_wrapper(); + return temp_nexe_file_->TakeFileHandle(); } -void PnaclCoordinator::ReportNonPpapiError(enum PluginErrorCode err_code, +void PnaclCoordinator::ReportNonPpapiError(PP_NaClError err_code, const nacl::string& message) { - error_info_.SetReport(err_code, message); + ErrorInfo error_info; + error_info.SetReport(err_code, message); + plugin_->ReportLoadError(error_info); ExitWithError(); } -void PnaclCoordinator::ReportPpapiError(enum PluginErrorCode err_code, +void PnaclCoordinator::ReportPpapiError(PP_NaClError err_code, int32_t pp_error, const nacl::string& message) { nacl::stringstream ss; ss << "PnaclCoordinator: " << message << " (pp_error=" << pp_error << ")."; - error_info_.SetReport(err_code, ss.str()); + ErrorInfo error_info; + error_info.SetReport(err_code, ss.str()); + plugin_->ReportLoadError(error_info); ExitWithError(); } void PnaclCoordinator::ExitWithError() { - PLUGIN_PRINTF(("PnaclCoordinator::ExitWithError (error_code=%d, " - "message='%s')\n", - error_info_.error_code(), - error_info_.message().c_str())); - plugin_->ReportLoadError(error_info_); + PLUGIN_PRINTF(("PnaclCoordinator::ExitWithError\n")); // Free all the intermediate callbacks we ever created. // Note: this doesn't *cancel* the callbacks from the factories attached // to the various helper classes (e.g., pnacl_resources). Thus, those @@ -317,7 +181,7 @@ void PnaclCoordinator::ExitWithError() { translation_finished_reported_ = true; plugin_->nacl_interface()->ReportTranslationFinished( plugin_->pp_instance(), - PP_FALSE); + PP_FALSE, 0, 0, 0, 0); translate_notify_callback_.Run(PP_ERROR_FAILED); } else { PLUGIN_PRINTF(("PnaclCoordinator::ExitWithError an earlier error was " @@ -332,37 +196,22 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) { // Bail out if there was an earlier error (e.g., pexe load failure), // or if there is an error from the translation thread. if (translate_finish_error_ != PP_OK || pp_error != PP_OK) { + plugin_->ReportLoadError(error_info_); ExitWithError(); return; } + // Send out one last progress event, to finish up the progress events // that were delayed (see the delay inserted in BitcodeGotCompiled). - if (ExpectedProgressKnown()) { + if (expected_pexe_size_ != -1) { pexe_bytes_compiled_ = expected_pexe_size_; - plugin_->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, - pexe_url_, - plugin::Plugin::LENGTH_IS_COMPUTABLE, - pexe_bytes_compiled_, - expected_pexe_size_); + GetNaClInterface()->DispatchEvent(plugin_->pp_instance(), + PP_NACL_EVENT_PROGRESS, + pexe_url_.c_str(), + PP_TRUE, + pexe_bytes_compiled_, + expected_pexe_size_); } - - // If there are no errors, report stats from this thread (the main thread). - HistogramOptLevel(pnacl_options_.opt_level()); - const plugin::PnaclTimeStats& time_stats = translate_thread_->GetTimeStats(); - HistogramTime("NaCl.Perf.PNaClLoadTime.LoadCompiler", - time_stats.pnacl_llc_load_time / NACL_MICROS_PER_MILLI); - HistogramTime("NaCl.Perf.PNaClLoadTime.CompileTime", - time_stats.pnacl_compile_time / NACL_MICROS_PER_MILLI); - HistogramKBPerSec("NaCl.Perf.PNaClLoadTime.CompileKBPerSec", - pexe_size_ / 1024.0, - time_stats.pnacl_compile_time / 1000000.0); - HistogramTime("NaCl.Perf.PNaClLoadTime.LoadLinker", - time_stats.pnacl_ld_load_time / NACL_MICROS_PER_MILLI); - HistogramTime("NaCl.Perf.PNaClLoadTime.LinkTime", - time_stats.pnacl_link_time / NACL_MICROS_PER_MILLI); - HistogramSizeKB("NaCl.Perf.Size.Pexe", - static_cast<int64_t>(pexe_size_ / 1024)); - struct nacl_abi_stat stbuf; struct NaClDesc* desc = temp_nexe_file_->read_wrapper()->desc(); int stat_ret; @@ -371,27 +220,23 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::TranslateFinished can't stat nexe.\n")); } else { size_t nexe_size = stbuf.nacl_abi_st_size; - HistogramSizeKB("NaCl.Perf.Size.PNaClTranslatedNexe", + HistogramSizeKB(plugin_->uma_interface(), + "NaCl.Perf.Size.PNaClTranslatedNexe", static_cast<int64_t>(nexe_size / 1024)); - HistogramRatio("NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); + HistogramRatio(plugin_->uma_interface(), + "NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); } - - int64_t total_time = NaClGetTimeOfDayMicroseconds() - pnacl_init_time_; - HistogramTime("NaCl.Perf.PNaClLoadTime.TotalUncachedTime", - total_time / NACL_MICROS_PER_MILLI); - HistogramKBPerSec("NaCl.Perf.PNaClLoadTime.TotalUncachedKBPerSec", - pexe_size_ / 1024.0, - total_time / 1000000.0); - // The nexe is written to the temp_nexe_file_. We must Reset() the file // pointer to be able to read it again from the beginning. temp_nexe_file_->Reset(); + int64_t total_time = NaClGetTimeOfDayMicroseconds() - pnacl_init_time_; // Report to the browser that translation finished. The browser will take // care of storing the nexe in the cache. translation_finished_reported_ = true; plugin_->nacl_interface()->ReportTranslationFinished( - plugin_->pp_instance(), PP_TRUE); + plugin_->pp_instance(), PP_TRUE, pnacl_options_.opt_level, + pexe_size_, translate_thread_->GetCompileTime(), total_time); NexeReadDidOpen(PP_OK); } @@ -401,18 +246,18 @@ void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { NACL_PRId32 ")\n", pp_error)); if (pp_error != PP_OK) { if (pp_error == PP_ERROR_FILENOTFOUND) { - ReportPpapiError(ERROR_PNACL_CACHE_FETCH_NOTFOUND, + ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_NOTFOUND, pp_error, "Failed to open translated nexe (not found)."); return; } if (pp_error == PP_ERROR_NOACCESS) { - ReportPpapiError(ERROR_PNACL_CACHE_FETCH_NOACCESS, + ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_NOACCESS, pp_error, "Failed to open translated nexe (no access)."); return; } - ReportPpapiError(ERROR_PNACL_CACHE_FETCH_OTHER, + ReportPpapiError(PP_NACL_ERROR_PNACL_CACHE_FETCH_OTHER, pp_error, "Failed to open translated nexe."); return; @@ -423,8 +268,7 @@ void PnaclCoordinator::NexeReadDidOpen(int32_t pp_error) { void PnaclCoordinator::OpenBitcodeStream() { // Now open the pexe stream. - streaming_downloader_.reset(new FileDownloader()); - streaming_downloader_->Initialize(plugin_); + streaming_downloader_.reset(new FileDownloader(plugin_)); // Mark the request as requesting a PNaCl bitcode file, // so that component updater can detect this user action. streaming_downloader_->set_request_headers( @@ -437,7 +281,7 @@ void PnaclCoordinator::OpenBitcodeStream() { translate_thread_.reset(new PnaclTranslateThread()); if (translate_thread_ == NULL) { ReportNonPpapiError( - ERROR_PNACL_THREAD_CREATE, + PP_NACL_ERROR_PNACL_THREAD_CREATE, "PnaclCoordinator: could not allocate translation thread."); return; } @@ -446,7 +290,7 @@ void PnaclCoordinator::OpenBitcodeStream() { callback_factory_.NewCallback(&PnaclCoordinator::BitcodeStreamDidOpen); if (!streaming_downloader_->OpenStream(pexe_url_, cb, this)) { ReportNonPpapiError( - ERROR_PNACL_PEXE_FETCH_OTHER, + PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER, nacl::string("PnaclCoordinator: failed to open stream ") + pexe_url_); return; } @@ -464,19 +308,22 @@ void PnaclCoordinator::BitcodeStreamDidOpen(int32_t pp_error) { // The component updater's resource throttles + OnDemand update/install // should block the URL request until the compiler is present. Now we // can load the resources (e.g. llc and ld nexes). - resources_.reset(new PnaclResources(plugin_, this, this->manifest_.get())); + resources_.reset(new PnaclResources(plugin_)); CHECK(resources_ != NULL); // The first step of loading resources: read the resource info file. pp::CompletionCallback resource_info_read_cb = callback_factory_.NewCallback(&PnaclCoordinator::ResourceInfoWasRead); - resources_->ReadResourceInfo(PnaclUrls::GetResourceInfoUrl(), - resource_info_read_cb); + resources_->ReadResourceInfo(resource_info_read_cb); } void PnaclCoordinator::ResourceInfoWasRead(int32_t pp_error) { PLUGIN_PRINTF(("PluginCoordinator::ResourceInfoWasRead (pp_error=%" NACL_PRId32 ")\n", pp_error)); + if (pp_error != PP_OK) { + ExitWithError(); + return; + } // Second step of loading resources: call StartLoad to load pnacl-llc // and pnacl-ld, based on the filenames found in the resource info file. pp::CompletionCallback resources_cb = @@ -488,8 +335,11 @@ void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::ResourcesDidLoad (pp_error=%" NACL_PRId32 ")\n", pp_error)); if (pp_error != PP_OK) { - // Finer-grained error code should have already been reported by - // the PnaclResources class. + ReportNonPpapiError( + PP_NACL_ERROR_PNACL_RESOURCE_FETCH, + nacl::string("The Portable Native Client (pnacl) component is not " + "installed. Please consult chrome://components for more " + "information.")); return; } @@ -498,8 +348,6 @@ void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { // get the cache key from the response headers and from the // compiler's version metadata. nacl::string headers = streaming_downloader_->GetResponseHeaders(); - NaClHttpResponseHeaders parser; - parser.Parse(headers); temp_nexe_file_.reset(new TempFile(plugin_)); pp::CompletionCallback cb = @@ -507,65 +355,74 @@ void PnaclCoordinator::ResourcesDidLoad(int32_t pp_error) { int32_t nexe_fd_err = plugin_->nacl_interface()->GetNexeFd( plugin_->pp_instance(), - streaming_downloader_->url().c_str(), + streaming_downloader_->full_url().c_str(), // TODO(dschuff): Get this value from the pnacl json file after it // rolls in from NaCl. 1, - pnacl_options_.opt_level(), - parser.GetHeader("last-modified").c_str(), - parser.GetHeader("etag").c_str(), - PP_FromBool(parser.CacheControlNoStore()), + pnacl_options_.opt_level, + headers.c_str(), + architecture_attributes_.c_str(), // Extra compile flags. &is_cache_hit_, - temp_nexe_file_->existing_handle(), + temp_nexe_file_->internal_handle(), cb.pp_completion_callback()); if (nexe_fd_err < PP_OK_COMPLETIONPENDING) { - ReportPpapiError(ERROR_PNACL_CREATE_TEMP, nexe_fd_err, + ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, nexe_fd_err, nacl::string("Call to GetNexeFd failed")); } } void PnaclCoordinator::NexeFdDidOpen(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::NexeFdDidOpen (pp_error=%" - NACL_PRId32 ", hit=%d, handle=%d)\n", pp_error, - is_cache_hit_ == PP_TRUE, - *temp_nexe_file_->existing_handle())); + NACL_PRId32 ", hit=%d)\n", pp_error, + is_cache_hit_ == PP_TRUE)); if (pp_error < PP_OK) { - ReportPpapiError(ERROR_PNACL_CREATE_TEMP, pp_error, + ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, pp_error, nacl::string("GetNexeFd failed")); return; } - if (*temp_nexe_file_->existing_handle() == PP_kInvalidFileHandle) { + if (*temp_nexe_file_->internal_handle() == PP_kInvalidFileHandle) { ReportNonPpapiError( - ERROR_PNACL_CREATE_TEMP, + PP_NACL_ERROR_PNACL_CREATE_TEMP, nacl::string( "PnaclCoordinator: Got bad temp file handle from GetNexeFd")); return; } - HistogramEnumerateTranslationCache(is_cache_hit_); + HistogramEnumerateTranslationCache(plugin_->uma_interface(), is_cache_hit_); if (is_cache_hit_ == PP_TRUE) { // Cache hit -- no need to stream the rest of the file. streaming_downloader_.reset(NULL); // Open it for reading as the cached nexe file. - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::NexeReadDidOpen); - temp_nexe_file_->Open(cb, false); + NexeReadDidOpen(temp_nexe_file_->Open(false)); } else { // Open an object file first so the translator can start writing to it // during streaming translation. - obj_file_.reset(new TempFile(plugin_)); - pp::CompletionCallback obj_cb = - callback_factory_.NewCallback(&PnaclCoordinator::ObjectFileDidOpen); - obj_file_->Open(obj_cb, true); + for (int i = 0; i < split_module_count_; i++) { + nacl::scoped_ptr<TempFile> temp_file(new TempFile(plugin_)); + int32_t pp_error = temp_file->Open(true); + if (pp_error != PP_OK) { + ReportPpapiError(PP_NACL_ERROR_PNACL_CREATE_TEMP, + pp_error, + "Failed to open scratch object file."); + return; + } else { + obj_files_.push_back(temp_file.release()); + } + } + invalid_desc_wrapper_.reset(plugin_->wrapper_factory()->MakeInvalid()); // Meanwhile, a miss means we know we need to stream the bitcode, so stream - // the rest of it now. (Calling FinishStreaming means that the downloader + // the rest of it now. (Calling BeginStreaming means that the downloader // will begin handing data to the coordinator, which is safe any time after // the translate_thread_ object has been initialized). pp::CompletionCallback finish_cb = callback_factory_.NewCallback( &PnaclCoordinator::BitcodeStreamDidFinish); - streaming_downloader_->FinishStreaming(finish_cb); + streaming_downloader_->BeginStreaming(finish_cb); + + // Open the nexe file for connecting ld and sel_ldr. + // Start translation when done with this last step of setup! + RunTranslate(temp_nexe_file_->Open(true)); } } @@ -578,21 +435,22 @@ void PnaclCoordinator::BitcodeStreamDidFinish(int32_t pp_error) { // objects or writing to the files. translate_finish_error_ = pp_error; if (pp_error == PP_ERROR_ABORTED) { - error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_ABORTED, + error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_ABORTED, "PnaclCoordinator: pexe load failed (aborted)."); } if (pp_error == PP_ERROR_NOACCESS) { - error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_NOACCESS, + error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_NOACCESS, "PnaclCoordinator: pexe load failed (no access)."); } else { nacl::stringstream ss; ss << "PnaclCoordinator: pexe load failed (pp_error=" << pp_error << ")."; - error_info_.SetReport(ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); + error_info_.SetReport(PP_NACL_ERROR_PNACL_PEXE_FETCH_OTHER, ss.str()); } translate_thread_->AbortSubprocesses(); } else { // Compare download completion pct (100% now), to compile completion pct. - HistogramRatio("NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", + HistogramRatio(plugin_->uma_interface(), + "NaCl.Perf.PNaClLoadTime.PctCompiledWhenFullyDownloaded", pexe_bytes_compiled_, pexe_size_); } } @@ -605,9 +463,8 @@ void PnaclCoordinator::BitcodeStreamGotData(int32_t pp_error, translate_thread_->PutBytes(data, pp_error); // If pp_error > 0, then it represents the number of bytes received. - if (data && pp_error > 0) { + if (data && pp_error > 0) pexe_size_ += pp_error; - } } StreamCallback PnaclCoordinator::GetCallback() { @@ -617,9 +474,10 @@ StreamCallback PnaclCoordinator::GetCallback() { void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error, int64_t bytes_compiled) { + DCHECK(pp_error == PP_OK); pexe_bytes_compiled_ += bytes_compiled; // If we don't know the expected total yet, ask. - if (!ExpectedProgressKnown()) { + if (expected_pexe_size_ == -1) { int64_t amount_downloaded; // dummy variable. streaming_downloader_->GetDownloadProgress(&amount_downloaded, &expected_pexe_size_); @@ -627,20 +485,22 @@ void PnaclCoordinator::BitcodeGotCompiled(int32_t pp_error, // Hold off reporting the last few bytes of progress, since we don't know // when they are actually completely compiled. "bytes_compiled" only means // that bytes were sent to the compiler. - if (ExpectedProgressKnown()) { + if (expected_pexe_size_ != -1) { if (!ShouldDelayProgressEvent()) { - plugin_->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, - pexe_url_, - plugin::Plugin::LENGTH_IS_COMPUTABLE, - pexe_bytes_compiled_, - expected_pexe_size_); + GetNaClInterface()->DispatchEvent(plugin_->pp_instance(), + PP_NACL_EVENT_PROGRESS, + pexe_url_.c_str(), + PP_TRUE, + pexe_bytes_compiled_, + expected_pexe_size_); } } else { - plugin_->EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS, - pexe_url_, - plugin::Plugin::LENGTH_IS_NOT_COMPUTABLE, - pexe_bytes_compiled_, - expected_pexe_size_); + GetNaClInterface()->DispatchEvent(plugin_->pp_instance(), + PP_NACL_EVENT_PROGRESS, + pexe_url_.c_str(), + PP_FALSE, + pexe_bytes_compiled_, + expected_pexe_size_); } } @@ -656,22 +516,6 @@ void PnaclCoordinator::GetCurrentProgress(int64_t* bytes_loaded, *bytes_total = expected_pexe_size_; } -void PnaclCoordinator::ObjectFileDidOpen(int32_t pp_error) { - PLUGIN_PRINTF(("PnaclCoordinator::ObjectFileDidOpen (pp_error=%" - NACL_PRId32 ")\n", pp_error)); - if (pp_error != PP_OK) { - ReportPpapiError(ERROR_PNACL_CREATE_TEMP, - pp_error, - "Failed to open scratch object file."); - return; - } - // Open the nexe file for connecting ld and sel_ldr. - // Start translation when done with this last step of setup! - pp::CompletionCallback cb = - callback_factory_.NewCallback(&PnaclCoordinator::RunTranslate); - temp_nexe_file_->Open(cb, true); -} - void PnaclCoordinator::RunTranslate(int32_t pp_error) { PLUGIN_PRINTF(("PnaclCoordinator::RunTranslate (pp_error=%" NACL_PRId32 ")\n", pp_error)); @@ -682,12 +526,13 @@ void PnaclCoordinator::RunTranslate(int32_t pp_error) { CHECK(translate_thread_ != NULL); translate_thread_->RunTranslate(report_translate_finished, - manifest_.get(), - obj_file_.get(), + &obj_files_, temp_nexe_file_.get(), + invalid_desc_wrapper_.get(), &error_info_, resources_.get(), &pnacl_options_, + architecture_attributes_, this, plugin_); } |