summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorjvoung@chromium.org <jvoung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-13 03:52:09 +0000
committerjvoung@chromium.org <jvoung@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-13 03:52:09 +0000
commit7539285b1aa7d67f5c78d402c3de6c884a2478b3 (patch)
tree459b19c5a56cb61779d5483039cada9d87034d0d /ppapi
parent808957c05986a64232b7bb9c108ed43fa09d1fb7 (diff)
downloadchromium_src-7539285b1aa7d67f5c78d402c3de6c884a2478b3.zip
chromium_src-7539285b1aa7d67f5c78d402c3de6c884a2478b3.tar.gz
chromium_src-7539285b1aa7d67f5c78d402c3de6c884a2478b3.tar.bz2
Allow PNaCl NMF to set translator optimization options for experimentation.
This adds two fields: (1) "-O": i (2) "experimentation_flags": "arbitrary flags" We may want to remove (2) soon... or just omit it. The optimization flag is separated and made a uint so that it can be tracked as a UMA stat more easily. Also set default to -O0 for now. TEST= browser_tests --gtest_filter=*Pnacl*Options* This only tests that the plugin doesn't barf on those new NMF options. To really test it we'd need to instrument LLC to know that it's really getting these flags and get output from LLC confirming that. For now I have a manual test: http://www/~jvoung/IrrLicht/testirrnacl_portable.html showing that it works though. BUG= http://code.google.com/p/nativeclient/issues/detail?id=3325 Review URL: https://chromiumcodereview.appspot.com/12623004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@187764 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/native_client/src/trusted/plugin/json_manifest.cc83
-rw-r--r--ppapi/native_client/src/trusted/plugin/json_manifest.h17
-rw-r--r--ppapi/native_client/src/trusted/plugin/manifest.h20
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.cc10
-rw-r--r--ppapi/native_client/src/trusted/plugin/plugin.gypi1
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc68
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h12
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_options.cc82
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_options.h66
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc25
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h3
-rw-r--r--ppapi/native_client/src/trusted/plugin/service_runtime.cc17
-rw-r--r--ppapi/native_client/src/trusted/plugin/service_runtime.h2
13 files changed, 288 insertions, 118 deletions
diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.cc b/ppapi/native_client/src/trusted/plugin/json_manifest.cc
index aeea96d..730562f 100644
--- a/ppapi/native_client/src/trusted/plugin/json_manifest.cc
+++ b/ppapi/native_client/src/trusted/plugin/json_manifest.cc
@@ -16,6 +16,7 @@
#include "native_client/src/include/portability.h"
#include "native_client/src/shared/platform/nacl_check.h"
#include "native_client/src/trusted/plugin/plugin_error.h"
+#include "native_client/src/trusted/plugin/pnacl_options.h"
#include "native_client/src/trusted/plugin/utility.h"
#include "ppapi/cpp/dev/url_util_dev.h"
#include "ppapi/cpp/var.h"
@@ -39,8 +40,10 @@ const char* const kPortableKey = "portable";
const char* const kPnaclTranslateKey = "pnacl-translate";
const char* const kUrlKey = "url";
-// Cache support keys
+// Pnacl keys
const char* const kCacheIdentityKey = "sha256";
+const char* const kOptLevelKey = "-O";
+const char* const kPnaclExperimentalFlags = "experimental_flags";
// Sample manifest file:
// {
@@ -51,7 +54,8 @@ const char* const kCacheIdentityKey = "sha256";
// "portable": {
// "pnacl-translate": {
// "url": "myprogram.pexe",
-// "sha256": "..."
+// "sha256": "...",
+// "-O": 0
// }
// }
// },
@@ -254,8 +258,9 @@ bool IsValidISADictionary(const Json::Value& dictionary,
bool has_portable = dictionary.isMember(kPortableKey);
if (!has_isa && !has_portable) {
- error_info->SetReport(ERROR_MANIFEST_PROGRAM_MISSING_ARCH,
- nacl::string("manifest: no version of ") + parent_key+
+ error_info->SetReport(
+ ERROR_MANIFEST_PROGRAM_MISSING_ARCH,
+ nacl::string("manifest: no version of ") + parent_key +
" given for current arch and no portable version found.");
return false;
}
@@ -263,12 +268,23 @@ bool IsValidISADictionary(const Json::Value& dictionary,
return true;
}
-void GrabUrlAndCacheIdentity(const Json::Value& url_spec,
- nacl::string* url,
- nacl::string* cache_identity) {
+void GrabUrlAndPnaclOptions(const Json::Value& url_spec,
+ nacl::string* url,
+ PnaclOptions* pnacl_options) {
*url = url_spec[kUrlKey].asString();
if (url_spec.isMember(kCacheIdentityKey)) {
- *cache_identity = url_spec[kCacheIdentityKey].asString();
+ pnacl_options->set_bitcode_hash(url_spec[kCacheIdentityKey].asString());
+ }
+ if (url_spec.isMember(kOptLevelKey)) {
+ uint32_t opt_raw = url_spec[kOptLevelKey].asUInt();
+ // Clamp the opt value to fit into an int8_t.
+ if (opt_raw > 3)
+ opt_raw = 3;
+ pnacl_options->set_opt_level(static_cast<int8_t>(opt_raw));
+ }
+ if (url_spec.isMember(kPnaclExperimentalFlags)) {
+ pnacl_options->set_experimental_flags(
+ url_spec[kPnaclExperimentalFlags].asString());
}
}
@@ -277,19 +293,15 @@ bool GetURLFromISADictionary(const Json::Value& dictionary,
const nacl::string& sandbox_isa,
bool prefer_portable,
nacl::string* url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) {
- if (url == NULL || cache_identity == NULL ||
- error_info == NULL || pnacl_translate == NULL)
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) {
+ if (url == NULL || pnacl_options == NULL || error_info == NULL)
return false;
if (!IsValidISADictionary(dictionary, parent_key, sandbox_isa, error_info))
return false;
*url = "";
- *cache_identity = "";
- *pnacl_translate = false;
// The call to IsValidISADictionary() above guarantees that either
// sandbox_isa or kPortableKey is present in the dictionary.
@@ -305,11 +317,11 @@ bool GetURLFromISADictionary(const Json::Value& dictionary,
// Check if this requires a pnacl-translate, otherwise just grab the URL.
// We may have pnacl-translate for isa-specific bitcode for CPU tuning.
if (isa_spec.isMember(kPnaclTranslateKey)) {
- GrabUrlAndCacheIdentity(isa_spec[kPnaclTranslateKey], url, cache_identity);
- *pnacl_translate = true;
+ GrabUrlAndPnaclOptions(isa_spec[kPnaclTranslateKey], url, pnacl_options);
+ pnacl_options->set_translate(true);
} else {
- GrabUrlAndCacheIdentity(isa_spec, url, cache_identity);
- *pnacl_translate = false;
+ *url = isa_spec[kUrlKey].asString();
+ pnacl_options->set_translate(false);
}
return true;
@@ -321,9 +333,8 @@ bool GetKeyUrl(const Json::Value& dictionary,
const Manifest* manifest,
bool prefer_portable,
nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) {
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) {
CHECK(full_url != NULL && error_info != NULL);
if (!dictionary.isMember(key)) {
error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL,
@@ -333,8 +344,7 @@ bool GetKeyUrl(const Json::Value& dictionary,
const Json::Value& isa_dict = dictionary[key];
nacl::string relative_url;
if (!GetURLFromISADictionary(isa_dict, key, sandbox_isa, prefer_portable,
- &relative_url, cache_identity,
- error_info, pnacl_translate)) {
+ &relative_url, pnacl_options, error_info)) {
return false;
}
return manifest->ResolveURL(relative_url, full_url, error_info);
@@ -455,11 +465,9 @@ bool JsonManifest::ResolveURL(const nacl::string& relative_url,
}
bool JsonManifest::GetProgramURL(nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const {
- if (full_url == NULL || cache_identity == NULL ||
- error_info == NULL || pnacl_translate == NULL)
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const {
+ if (full_url == NULL || pnacl_options == NULL || error_info == NULL)
return false;
Json::Value program = dictionary_[kProgramKey];
@@ -472,9 +480,8 @@ bool JsonManifest::GetProgramURL(nacl::string* full_url,
sandbox_isa_,
prefer_portable_,
&nexe_url,
- cache_identity,
- error_info,
- pnacl_translate)) {
+ pnacl_options,
+ error_info)) {
return false;
}
@@ -497,19 +504,17 @@ bool JsonManifest::GetFileKeys(std::set<nacl::string>* keys) const {
bool JsonManifest::ResolveKey(const nacl::string& key,
nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const {
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const {
NaClLog(3, "JsonManifest::ResolveKey(%s)\n", key.c_str());
// key must be one of kProgramKey or kFileKey '/' file-section-key
- if (full_url == NULL || cache_identity == NULL ||
- error_info == NULL || pnacl_translate == NULL)
+ if (full_url == NULL || pnacl_options == NULL || error_info == NULL)
return false;
if (key == kProgramKey) {
return GetKeyUrl(dictionary_, key, sandbox_isa_, this, prefer_portable_,
- full_url, cache_identity, error_info, pnacl_translate);
+ full_url, pnacl_options, error_info);
}
nacl::string::const_iterator p = find(key.begin(), key.end(), '/');
if (p == key.end()) {
@@ -544,7 +549,7 @@ bool JsonManifest::ResolveKey(const nacl::string& key,
return false;
}
return GetKeyUrl(files, rest, sandbox_isa_, this, prefer_portable_,
- full_url, cache_identity, error_info, pnacl_translate);
+ full_url, pnacl_options, error_info);
}
} // namespace plugin
diff --git a/ppapi/native_client/src/trusted/plugin/json_manifest.h b/ppapi/native_client/src/trusted/plugin/json_manifest.h
index df04c88..e2e4fbc 100644
--- a/ppapi/native_client/src/trusted/plugin/json_manifest.h
+++ b/ppapi/native_client/src/trusted/plugin/json_manifest.h
@@ -25,6 +25,7 @@ class URLUtil_Dev;
namespace plugin {
class ErrorInfo;
+class PnaclOptions;
class JsonManifest : public Manifest {
public:
@@ -44,12 +45,10 @@ class JsonManifest : public Manifest {
bool Init(const nacl::string& json, ErrorInfo* error_info);
// Gets the full program URL for the current sandbox ISA from the
- // manifest file. Sets |pnacl_translate| to |true| if the program is
- // portable bitcode that must be translated.
+ // manifest file.
virtual bool GetProgramURL(nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const;
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const;
// Resolves a URL relative to the manifest base URL
virtual bool ResolveURL(const nacl::string& relative_url,
@@ -64,14 +63,12 @@ class JsonManifest : public Manifest {
// Resolves a key from the "files" section to a fully resolved URL,
// i.e., relative URL values are fully expanded relative to the
- // manifest's URL (via ResolveURL). |pnacl_translate| tells the caller
- // whether the resolution requires a pnacl translation step.
+ // manifest's URL (via ResolveURL).
// If there was an error, details are reported via error_info.
virtual bool ResolveKey(const nacl::string& key,
nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const;
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const;
private:
NACL_DISALLOW_COPY_AND_ASSIGN(JsonManifest);
diff --git a/ppapi/native_client/src/trusted/plugin/manifest.h b/ppapi/native_client/src/trusted/plugin/manifest.h
index bce0a19..b828aea 100644
--- a/ppapi/native_client/src/trusted/plugin/manifest.h
+++ b/ppapi/native_client/src/trusted/plugin/manifest.h
@@ -24,6 +24,7 @@ class URLUtil_Dev;
namespace plugin {
class ErrorInfo;
+class PnaclOptions;
class Manifest {
public:
@@ -38,12 +39,11 @@ class Manifest {
// a resource in the extension origin.
// Gets the full program URL for the current sandbox ISA from the
- // manifest file. Sets |pnacl_translate| to |true| if the program is
- // requires pnacl translation.
+ // manifest file. Fills in |pnacl_options| if the program requires
+ // PNaCl translation.
virtual bool GetProgramURL(nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const = 0;
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const = 0;
// Resolves a URL relative to the manifest base URL
virtual bool ResolveURL(const nacl::string& relative_url,
@@ -58,14 +58,14 @@ class Manifest {
// Resolves a key from the "files" section to a fully resolved URL,
// i.e., relative URL values are fully expanded relative to the
- // manifest's URL (via ResolveURL). |pnacl_translate| tells
- // the caller whether the resolution requires a pnacl translation step.
+ // manifest's URL (via ResolveURL). Fills in |pnacl_options| if
+ // the resolved key requires a pnacl translation step to obtain
+ // the final requested resource.
// If there was an error, details are reported via error_info.
virtual bool ResolveKey(const nacl::string& key,
nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const = 0;
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const = 0;
protected:
NACL_DISALLOW_COPY_AND_ASSIGN(Manifest);
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc
index 90c5644..e1f3ad9 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.cc
+++ b/ppapi/native_client/src/trusted/plugin/plugin.cc
@@ -1174,21 +1174,19 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) {
HistogramSizeKB("NaCl.Perf.Size.Manifest",
static_cast<int32_t>(manifest_json.length() / 1024));
nacl::string program_url;
- nacl::string cache_identity;
- bool is_portable;
+ PnaclOptions pnacl_options;
ErrorInfo error_info;
if (!SetManifestObject(manifest_json, &error_info)) {
ReportLoadError(error_info);
return;
}
- if (manifest_->GetProgramURL(&program_url, &cache_identity,
- &error_info, &is_portable)) {
+ if (manifest_->GetProgramURL(&program_url, &pnacl_options, &error_info)) {
is_installed_ = GetUrlScheme(program_url) == SCHEME_CHROME_EXTENSION;
set_nacl_ready_state(LOADING);
// Inform JavaScript that we found a nexe URL to load.
EnqueueProgressEvent(kProgressEventProgress);
- if (is_portable) {
+ if (pnacl_options.translate()) {
if (this->nacl_interface()->IsPnaclEnabled()) {
pp::CompletionCallback translate_callback =
callback_factory_.NewCallback(&Plugin::BitcodeDidTranslate);
@@ -1196,7 +1194,7 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) {
pnacl_coordinator_.reset(
PnaclCoordinator::BitcodeToNative(this,
program_url,
- cache_identity,
+ pnacl_options,
translate_callback));
return;
} else {
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.gypi b/ppapi/native_client/src/trusted/plugin/plugin.gypi
index bd908a9..4532f2f 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.gypi
+++ b/ppapi/native_client/src/trusted/plugin/plugin.gypi
@@ -13,6 +13,7 @@
'nacl_subprocess.cc',
'plugin.cc',
'pnacl_coordinator.cc',
+ 'pnacl_options.cc',
'pnacl_resources.cc',
'pnacl_translate_thread.cc',
'scriptable_plugin.cc',
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
index 1fb30a3..cc2ea36 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
@@ -48,14 +48,12 @@ class PnaclManifest : public Manifest {
virtual ~PnaclManifest() { }
virtual bool GetProgramURL(nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const {
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const {
// Does not contain program urls.
UNREFERENCED_PARAMETER(full_url);
- UNREFERENCED_PARAMETER(cache_identity);
+ UNREFERENCED_PARAMETER(pnacl_options);
UNREFERENCED_PARAMETER(error_info);
- UNREFERENCED_PARAMETER(pnacl_translate);
PLUGIN_PRINTF(("PnaclManifest does not contain a program\n"));
error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL,
"pnacl manifest does not contain a program.");
@@ -81,13 +79,10 @@ class PnaclManifest : public Manifest {
virtual bool ResolveKey(const nacl::string& key,
nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const {
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const {
// All of the extension files are native (do not require pnacl translate).
- *pnacl_translate = false;
- // Do not cache these entries.
- *cache_identity = "";
+ 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);
@@ -125,15 +120,14 @@ class PnaclLDManifest : public Manifest {
virtual ~PnaclLDManifest() { }
virtual bool GetProgramURL(nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const {
- if (nexe_manifest_->GetProgramURL(full_url, cache_identity,
- error_info, pnacl_translate)) {
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const {
+ if (nexe_manifest_->GetProgramURL(full_url, pnacl_options, error_info)) {
return true;
}
- return extension_manifest_->GetProgramURL(full_url, cache_identity,
- error_info, pnacl_translate);
+ return extension_manifest_->GetProgramURL(full_url,
+ pnacl_options,
+ error_info);
}
virtual bool ResolveURL(const nacl::string& relative_url,
@@ -154,15 +148,14 @@ class PnaclLDManifest : public Manifest {
virtual bool ResolveKey(const nacl::string& key,
nacl::string* full_url,
- nacl::string* cache_identity,
- ErrorInfo* error_info,
- bool* pnacl_translate) const {
- if (nexe_manifest_->ResolveKey(key, full_url, cache_identity,
- error_info, pnacl_translate)) {
+ PnaclOptions* pnacl_options,
+ ErrorInfo* error_info) const {
+ if (nexe_manifest_->ResolveKey(key, full_url, pnacl_options, error_info)) {
return true;
}
- return extension_manifest_->ResolveKey(key, full_url, cache_identity,
- error_info, pnacl_translate);
+ return extension_manifest_->ResolveKey(key, full_url,
+ pnacl_options,
+ error_info);
}
private:
@@ -273,13 +266,14 @@ CallbackSource<FileStreamData>::~CallbackSource() {}
PnaclCoordinator* PnaclCoordinator::BitcodeToNative(
Plugin* plugin,
const nacl::string& pexe_url,
- const nacl::string& cache_identity,
+ const 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()));
PnaclCoordinator* coordinator =
new PnaclCoordinator(plugin, pexe_url,
- cache_identity, translate_notify_callback);
+ pnacl_options,
+ translate_notify_callback);
coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds();
coordinator->off_the_record_ =
plugin->nacl_interface()->IsOffTheRecord();
@@ -331,7 +325,7 @@ int32_t PnaclCoordinator::GetLoadedFileDesc(int32_t pp_error,
PnaclCoordinator::PnaclCoordinator(
Plugin* plugin,
const nacl::string& pexe_url,
- const nacl::string& cache_identity,
+ const PnaclOptions& pnacl_options,
const pp::CompletionCallback& translate_notify_callback)
: translate_finish_error_(PP_OK),
plugin_(plugin),
@@ -341,7 +335,7 @@ PnaclCoordinator::PnaclCoordinator(
plugin->url_util(),
plugin::PnaclUrls::UsePnaclExtension(plugin))),
pexe_url_(pexe_url),
- cache_identity_(cache_identity),
+ pnacl_options_(pnacl_options),
error_already_reported_(false),
off_the_record_(false),
pnacl_init_time_(0),
@@ -454,10 +448,10 @@ void PnaclCoordinator::TranslateFinished(int32_t pp_error) {
// pointer to be able to read it again from the beginning.
temp_nexe_file_->Reset();
- if (cache_identity_ != "" && cached_nexe_file_ != NULL) {
+ if (pnacl_options_.HasCacheKey() && cached_nexe_file_ != NULL) {
// We are using a cache, but had a cache miss, which is why we did the
// translation. Reset cached_nexe_file_ to have a random name,
- // for scratch purposes, before renaming to the final cache_identity_.
+ // for scratch purposes, before renaming to the final cache_identity.
cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(),
nacl::string(kPnaclTempDir)));
pp::CompletionCallback cb = callback_factory_.NewCallback(
@@ -608,7 +602,7 @@ void PnaclCoordinator::NexeWasCopiedToCache(int32_t pp_error) {
// Rename the cached_nexe_file_ file to the cache id, to finalize.
pp::CompletionCallback cb =
callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed);
- cached_nexe_file_->Rename(cache_identity_, cb);
+ cached_nexe_file_->Rename(pnacl_options_.GetCacheKey(), cb);
}
void PnaclCoordinator::CorruptCacheFileWasDeleted(int32_t delete_pp_error,
@@ -809,10 +803,11 @@ void PnaclCoordinator::DirectoryWasCreated(int32_t pp_error) {
"PNaCl translation cache directory creation/check failed.");
return;
}
- if (cache_identity_ != "") {
- cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(),
- nacl::string(kPnaclTempDir),
- cache_identity_));
+ if (pnacl_options_.HasCacheKey()) {
+ cached_nexe_file_.reset(new LocalTempFile(
+ plugin_, file_system_.get(),
+ nacl::string(kPnaclTempDir),
+ pnacl_options_.GetCacheKey()));
pp::CompletionCallback cb =
callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen);
cached_nexe_file_->OpenRead(cb);
@@ -971,6 +966,7 @@ void PnaclCoordinator::RunTranslate(int32_t pp_error) {
temp_nexe_file_.get(),
&error_info_,
resources_.get(),
+ &pnacl_options_,
this,
plugin_);
}
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
index 0113d01..784b8c7 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
@@ -22,6 +22,7 @@
#include "native_client/src/trusted/plugin/local_temp_file.h"
#include "native_client/src/trusted/plugin/nacl_subprocess.h"
#include "native_client/src/trusted/plugin/plugin_error.h"
+#include "native_client/src/trusted/plugin/pnacl_options.h"
#include "native_client/src/trusted/plugin/pnacl_resources.h"
#include "ppapi/c/pp_file_info.h"
@@ -45,6 +46,7 @@ class TempFile;
// (1) Invoke the factory method, e.g.,
// PnaclCoordinator* coord = BitcodeToNative(plugin,
// "http://foo.com/my.pexe",
+// pnacl_options,
// TranslateNotifyCallback);
// (2) TranslateNotifyCallback gets invoked when translation is complete.
// If the translation was successful, the pp_error argument is PP_OK.
@@ -101,7 +103,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
static PnaclCoordinator* BitcodeToNative(
Plugin* plugin,
const nacl::string& pexe_url,
- const nacl::string& cache_identity,
+ const PnaclOptions& pnacl_options,
const pp::CompletionCallback& translate_notify_callback);
// Call this to take ownership of the FD of the translated nexe after
@@ -148,7 +150,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
// Therefore the constructor is private.
PnaclCoordinator(Plugin* plugin,
const nacl::string& pexe_url,
- const nacl::string& cache_identity,
+ const PnaclOptions& pnacl_options,
const pp::CompletionCallback& translate_notify_callback);
// Callback for when llc and ld have been downloaded.
@@ -232,8 +234,9 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
// The URL for the pexe file.
nacl::string pexe_url_;
- // Optional cache identity for translation caching.
- nacl::string cache_identity_;
+ // Options for translation.
+ PnaclOptions pnacl_options_;
+
// Object file, produced by the translator and consumed by the linker.
nacl::scoped_ptr<TempFile> obj_file_;
// Translated nexe file, produced by the linker.
@@ -248,6 +251,7 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
// Used to report information when errors (PPAPI or otherwise) are reported.
ErrorInfo error_info_;
+
// True if an error was already reported, and translate_notify_callback_
// was already run/consumed.
bool error_already_reported_;
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_options.cc b/ppapi/native_client/src/trusted/plugin/pnacl_options.cc
new file mode 100644
index 0000000..05eecf2
--- /dev/null
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_options.cc
@@ -0,0 +1,82 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "native_client/src/trusted/plugin/pnacl_options.h"
+
+#include <iterator>
+#include <vector>
+
+#include "native_client/src/include/nacl_string.h"
+
+namespace plugin {
+
+// Default to -O0 for now.
+PnaclOptions::PnaclOptions() : translate_(false), opt_level_(0) { }
+
+PnaclOptions::~PnaclOptions() {
+}
+
+nacl::string PnaclOptions::GetCacheKey() {
+ // TODO(jvoung): We need to read the PNaCl translator's manifest
+ // to grab the NaCl / PNaCl ABI version too.
+ nacl::stringstream ss;
+ // Cast opt_level_ as int so that it doesn't think it's a char.
+ ss << "-O:" << static_cast<int>(opt_level_)
+ << ";flags:" << experimental_flags_
+ << ";bitcode_hash:" << bitcode_hash_;
+ return ss.str();
+}
+
+void PnaclOptions::set_opt_level(int8_t l) {
+ if (l < 0) {
+ opt_level_ = 0;
+ return;
+ }
+ if (l > 3) {
+ opt_level_ = 3;
+ return;
+ }
+ opt_level_ = l;
+}
+
+std::vector<char> PnaclOptions::GetOptCommandline() {
+ std::vector<char> result;
+ std::vector<nacl::string> tokens;
+
+ // Split the experimental_flags_ + the -On along whitespace.
+ // Mostly a copy of "base/string_util.h", but avoid importing
+ // base into the PPAPI plugin for now.
+ nacl::string delim(" ");
+ nacl::string str = experimental_flags_;
+
+ if (opt_level_ != -1) {
+ nacl::stringstream ss;
+ // Cast as int so that it doesn't think it's a char.
+ ss << " -O" << static_cast<int>(opt_level_);
+ str += ss.str();
+ }
+
+ size_t start = str.find_first_not_of(delim);
+ while (start != nacl::string::npos) {
+ size_t end = str.find_first_of(delim, start + 1);
+ if (end == nacl::string::npos) {
+ tokens.push_back(str.substr(start));
+ break;
+ } else {
+ tokens.push_back(str.substr(start, end - start));
+ start = str.find_first_not_of(delim, end + 1);
+ }
+ }
+
+ for (size_t i = 0; i < tokens.size(); ++i) {
+ nacl::string t = tokens[i];
+ result.reserve(result.size() + t.size());
+ std::copy(t.begin(), t.end(), std::back_inserter(result));
+ result.push_back('\x00');
+ }
+
+ return result;
+}
+
+} // namespace plugin
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_options.h b/ppapi/native_client/src/trusted/plugin/pnacl_options.h
new file mode 100644
index 0000000..55bbbb9
--- /dev/null
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_options.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_OPTIONS_H_
+#define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_OPTIONS_H_
+
+#include <vector>
+
+#include "native_client/src/include/nacl_string.h"
+#include "native_client/src/include/portability.h"
+
+namespace plugin {
+
+// Options for PNaCl translation.
+class PnaclOptions {
+
+ public:
+ PnaclOptions();
+ ~PnaclOptions();
+
+ // Return true if we know the hash of the bitcode, for caching.
+ bool HasCacheKey() { return bitcode_hash_ != ""; }
+
+ // Return the cache key (which takes into account the bitcode hash,
+ // as well as the commandline options).
+ nacl::string GetCacheKey();
+
+ // Return true if the manifest did not specify any special options
+ // (just using the default).
+ bool HasDefaultOpts() {
+ return opt_level_ == -1 && experimental_flags_ == "";
+ }
+
+ // Return a character array of \x00 delimited commandline options.
+ std::vector<char> GetOptCommandline();
+
+ bool translate() { return translate_; }
+ void set_translate(bool t) { translate_ = t; }
+
+ uint8_t opt_level() { return opt_level_; }
+ void set_opt_level(int8_t l);
+
+ nacl::string experimental_flags() {
+ return experimental_flags_;
+ }
+ void set_experimental_flags(const nacl::string& f) {
+ experimental_flags_ = f;
+ }
+
+ void set_bitcode_hash(const nacl::string& c) {
+ bitcode_hash_ = c;
+ }
+
+ private:
+ // NOTE: There are users of this class that use the copy constructor.
+ // Currently the default copy constructor is good enough, but
+ // double-check that it is the case when more fields are added.
+ bool translate_;
+ int8_t opt_level_;
+ nacl::string experimental_flags_;
+ nacl::string bitcode_hash_;
+};
+
+} // namespace plugin;
+#endif // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PNACL_OPTIONS_H_
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
index 2be9968..a7d3f24 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
@@ -39,6 +39,7 @@ void PnaclTranslateThread::RunTranslate(
TempFile* nexe_file,
ErrorInfo* error_info,
PnaclResources* resources,
+ PnaclOptions* pnacl_options,
PnaclCoordinator* coordinator,
Plugin* plugin) {
PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n"));
@@ -48,6 +49,7 @@ void PnaclTranslateThread::RunTranslate(
nexe_file_ = nexe_file;
coordinator_error_info_ = error_info;
resources_ = resources;
+ pnacl_options_ = pnacl_options;
coordinator_ = coordinator;
plugin_ = plugin;
@@ -153,10 +155,25 @@ void PnaclTranslateThread::DoTranslate() {
}
int64_t compile_start_time = NaClGetTimeOfDayMicroseconds();
- if (!llc_subprocess_->InvokeSrpcMethod("StreamInit",
- "h",
- &params,
- llc_out_file->desc())) {
+ bool init_success;
+ if (pnacl_options_->HasDefaultOpts()) {
+ PLUGIN_PRINTF(("PnaclCoordinator: StreamInit with default options\n"));
+ init_success = llc_subprocess_->InvokeSrpcMethod("StreamInit",
+ "h",
+ &params,
+ llc_out_file->desc());
+ } else {
+ std::vector<char> options = pnacl_options_->GetOptCommandline();
+ init_success = llc_subprocess_->InvokeSrpcMethod(
+ "StreamInitWithOverrides",
+ "hC",
+ &params,
+ llc_out_file->desc(),
+ &options[0],
+ options.size());
+ }
+
+ if (!init_success) {
if (llc_subprocess_->srpc_client()->GetLastError() ==
NACL_SRPC_RESULT_APP_ERROR) {
// The error message is only present if the error was returned from llc
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
index bb3ea8c..39e7ba4 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
@@ -29,6 +29,7 @@ class Manifest;
class NaClSubprocess;
class Plugin;
class PnaclCoordinator;
+class PnaclOptions;
class PnaclResources;
class TempFile;
@@ -53,6 +54,7 @@ class PnaclTranslateThread {
TempFile* nexe_file,
ErrorInfo* error_info,
PnaclResources* resources,
+ PnaclOptions* pnacl_options,
PnaclCoordinator* coordinator,
Plugin* plugin);
@@ -124,6 +126,7 @@ class PnaclTranslateThread {
TempFile* nexe_file_;
ErrorInfo* coordinator_error_info_;
PnaclResources* resources_;
+ PnaclOptions* pnacl_options_;
PnaclCoordinator* coordinator_;
Plugin* plugin_;
private:
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
index ea7c262..00f64c7 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc
@@ -259,9 +259,9 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
NaClLog(4, "Entered OpenManifestEntry_MainThreadContinuation\n");
std::string mapped_url;
- std::string cache_identity;
- if (!manifest_->ResolveKey(p->url, &mapped_url, &cache_identity,
- p->error_info, &p->pnacl_translate)) {
+ PnaclOptions pnacl_options;
+ if (!manifest_->ResolveKey(p->url, &mapped_url,
+ &pnacl_options, p->error_info)) {
NaClLog(4, "OpenManifestEntry_MainThreadContinuation: ResolveKey failed\n");
// Failed, and error_info has the details on what happened. Wake
// up requesting thread -- we are done.
@@ -274,18 +274,18 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
NaClLog(4,
"OpenManifestEntry_MainThreadContinuation: "
"ResolveKey: %s -> %s (pnacl_translate(%d))\n",
- p->url.c_str(), mapped_url.c_str(), p->pnacl_translate);
+ p->url.c_str(), mapped_url.c_str(), pnacl_options.translate());
open_cont = new OpenManifestEntryResource(*p); // copy ctor!
CHECK(open_cont != NULL);
open_cont->url = mapped_url;
- if (!open_cont->pnacl_translate) {
+ if (!pnacl_options.translate()) {
pp::CompletionCallback stream_cc = WeakRefNewCallback(
anchor_,
this,
&PluginReverseInterface::StreamAsFile_MainThreadContinuation,
open_cont);
- //
+ // Normal files.
if (!PnaclUrls::IsPnaclComponent(mapped_url)) {
if (!plugin_->StreamAsFile(mapped_url,
stream_cc.pp_completion_callback())) {
@@ -303,6 +303,8 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
NaClLog(4,
"OpenManifestEntry_MainThreadContinuation: StreamAsFile okay\n");
} else {
+ // Special PNaCl support files, that are installed on the
+ // user machine.
int32_t fd = PnaclResources::GetPnaclFD(
plugin_,
PnaclUrls::PnaclComponentURLToFilename(mapped_url).c_str());
@@ -325,6 +327,7 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
"OpenManifestEntry_MainThreadContinuation: GetPnaclFd okay\n");
}
} else {
+ // Requires PNaCl translation.
NaClLog(4,
"OpenManifestEntry_MainThreadContinuation: "
"pulling down and translating.\n");
@@ -339,7 +342,7 @@ void PluginReverseInterface::OpenManifestEntry_MainThreadContinuation(
pnacl_coordinator_.reset(
PnaclCoordinator::BitcodeToNative(plugin_,
mapped_url,
- cache_identity,
+ pnacl_options,
translate_callback));
} else {
nacl::MutexLocker take(&mu_);
diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h
index 4934d4f..f11346e 100644
--- a/ppapi/native_client/src/trusted/plugin/service_runtime.h
+++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h
@@ -69,12 +69,10 @@ struct OpenManifestEntryResource {
: url(target_url),
out_desc(descp),
error_info(infop),
- pnacl_translate(false),
op_complete_ptr(op_complete) {}
std::string url;
int32_t* out_desc;
ErrorInfo* error_info;
- bool pnacl_translate;
bool* op_complete_ptr;
};