summaryrefslogtreecommitdiffstats
path: root/chromium/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
diff options
context:
space:
mode:
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.cc427
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_);
}