summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authordschuff@chromium.org <dschuff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-15 00:36:53 +0000
committerdschuff@chromium.org <dschuff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-15 00:36:53 +0000
commita91b574d029d385afd93652e0fb34b48271eb702 (patch)
treee5438705fa543e8d21e9ef9af79d7d22f6fead46 /ppapi
parent4532c970cc7dd85d59da72ef51e21f3c3b5799c4 (diff)
downloadchromium_src-a91b574d029d385afd93652e0fb34b48271eb702.zip
chromium_src-a91b574d029d385afd93652e0fb34b48271eb702.tar.gz
chromium_src-a91b574d029d385afd93652e0fb34b48271eb702.tar.bz2
PnaclCoordinator: Use llc's module-splitting for pexe compilation
When there is more than 1 core in the system, request extra temp files and use LLC's StreamInitWithSplit rpc to enable module splitting. If the RPC fails, fall back to StreamInitWithOverrides. Add a private Pepper interface to get the cpu count rather than duplicating base::SysInfo in the plugin. TEST=browser_tests --gtest_filter=NaClBrowserTstPnacl.* BUG= https://code.google.com/p/nativeclient/issues/detail?id=3777 R=jschuh@chromium.org, jvoung@chromium.org, teravest@chromium.org Review URL: https://codereview.chromium.org/165433003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251458 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/api/private/ppb_nacl_private.idl3
-rw-r--r--ppapi/c/private/ppb_nacl_private.h4
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc36
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h10
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc142
-rw-r--r--ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h9
-rw-r--r--ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c6
7 files changed, 169 insertions, 41 deletions
diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl
index 6dfbff7..a674328 100644
--- a/ppapi/api/private/ppb_nacl_private.idl
+++ b/ppapi/api/private/ppb_nacl_private.idl
@@ -110,6 +110,9 @@ interface PPB_NaCl_Private {
*/
PP_FileHandle CreateTemporaryFile([in] PP_Instance instance);
+ /* Return the number of processors in the system as reported by the OS */
+ int32_t GetNumberOfProcessors();
+
/* Create a temporary file, which will be deleted by the time the
* last handle is closed (or earlier on POSIX systems), to use for
* the nexe with the cache information given by |pexe_url|,
diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h
index 0001148..dde686b 100644
--- a/ppapi/c/private/ppb_nacl_private.h
+++ b/ppapi/c/private/ppb_nacl_private.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From private/ppb_nacl_private.idl modified Mon Feb 10 11:05:29 2014. */
+/* From private/ppb_nacl_private.idl modified Thu Feb 13 15:50:26 2014. */
#ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
#define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
@@ -127,6 +127,8 @@ struct PPB_NaCl_Private_1_0 {
* returns a posix handle to that temporary file.
*/
PP_FileHandle (*CreateTemporaryFile)(PP_Instance instance);
+ /* Return the number of processors in the system as reported by the OS */
+ int32_t (*GetNumberOfProcessors)(void);
/* Create a temporary file, which will be deleted by the time the
* last handle is closed (or earlier on POSIX systems), to use for
* the nexe with the cache information given by |pexe_url|,
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
index 9e96f0d..91112a0 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.cc
@@ -200,6 +200,9 @@ PnaclCoordinator* PnaclCoordinator::BitcodeToNative(
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
// cache information. We can cancel the request later if there's
@@ -220,6 +223,8 @@ PnaclCoordinator::PnaclCoordinator(
manifest_(new PnaclManifest()),
pexe_url_(pexe_url),
pnacl_options_(pnacl_options),
+ split_module_count_(1),
+ num_object_files_opened_(0),
is_cache_hit_(PP_FALSE),
error_already_reported_(false),
pnacl_init_time_(0),
@@ -248,6 +253,9 @@ PnaclCoordinator::~PnaclCoordinator() {
plugin_->pp_instance(),
PP_FALSE);
}
+ for (int i = 0; i < num_object_files_opened_; i++) {
+ delete obj_files_[i];
+ }
}
nacl::DescWrapper* PnaclCoordinator::ReleaseTranslatedFD() {
@@ -531,10 +539,14 @@ void PnaclCoordinator::NexeFdDidOpen(int32_t pp_error) {
} 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++) {
+ obj_files_.push_back(new TempFile(plugin_));
+
+ pp::CompletionCallback obj_cb =
+ callback_factory_.NewCallback(&PnaclCoordinator::ObjectFileDidOpen);
+ obj_files_[i]->Open(obj_cb, true);
+ }
+ 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
@@ -643,11 +655,14 @@ void PnaclCoordinator::ObjectFileDidOpen(int32_t 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);
+ num_object_files_opened_++;
+ if (num_object_files_opened_ == split_module_count_) {
+ // 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) {
@@ -661,8 +676,9 @@ 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_,
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
index e38cbc0..9475b9e 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h
@@ -77,6 +77,9 @@ class TempFile;
// Complete when NexeReadDidOpen is invoked.
class PnaclCoordinator: public CallbackSource<FileStreamData> {
public:
+ // Maximum number of object files passable to the translator. Cannot be
+ // changed without changing the RPC signatures.
+ const static size_t kMaxTranslatorObjectFiles = 16;
virtual ~PnaclCoordinator();
// The factory method for translations.
@@ -202,7 +205,12 @@ class PnaclCoordinator: public CallbackSource<FileStreamData> {
PnaclOptions pnacl_options_;
// Object file, produced by the translator and consumed by the linker.
- nacl::scoped_ptr<TempFile> obj_file_;
+ std::vector<TempFile*> obj_files_;
+ nacl::scoped_ptr<nacl::DescWrapper> invalid_desc_wrapper_;
+ // Number of split modules (threads) for llc
+ int split_module_count_;
+ int num_object_files_opened_;
+
// Translated nexe file, produced by the linker.
nacl::scoped_ptr<TempFile> temp_nexe_file_;
// Passed to the browser, which sets it to true if there is a translation
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 d51efe4..2093aaf 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.cc
@@ -4,6 +4,8 @@
#include "ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h"
+#include <iterator>
+
#include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
#include "ppapi/native_client/src/trusted/plugin/plugin.h"
#include "ppapi/native_client/src/trusted/plugin/plugin_error.h"
@@ -19,7 +21,7 @@ PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false),
done_(false),
time_stats_(),
manifest_(NULL),
- obj_file_(NULL),
+ obj_files_(NULL),
nexe_file_(NULL),
coordinator_error_info_(NULL),
resources_(NULL),
@@ -33,8 +35,9 @@ PnaclTranslateThread::PnaclTranslateThread() : llc_subprocess_active_(false),
void PnaclTranslateThread::RunTranslate(
const pp::CompletionCallback& finish_callback,
const Manifest* manifest,
- TempFile* obj_file,
+ const std::vector<TempFile*>* obj_files,
TempFile* nexe_file,
+ nacl::DescWrapper* invalid_desc_wrapper,
ErrorInfo* error_info,
PnaclResources* resources,
PnaclOptions* pnacl_options,
@@ -42,8 +45,9 @@ void PnaclTranslateThread::RunTranslate(
Plugin* plugin) {
PLUGIN_PRINTF(("PnaclStreamingTranslateThread::RunTranslate)\n"));
manifest_ = manifest;
- obj_file_ = obj_file;
+ obj_files_ = obj_files;
nexe_file_ = nexe_file;
+ invalid_desc_wrapper_ = invalid_desc_wrapper;
coordinator_error_info_ = error_info;
resources_ = resources;
pnacl_options_ = pnacl_options;
@@ -130,7 +134,14 @@ void WINAPI PnaclTranslateThread::DoTranslateThread(void* arg) {
void PnaclTranslateThread::DoTranslate() {
ErrorInfo error_info;
SrpcParams params;
- nacl::DescWrapper* llc_out_file = obj_file_->write_wrapper();
+ std::vector<nacl::DescWrapper*> llc_out_files;
+ size_t i;
+ for (i = 0; i < obj_files_->size(); i++) {
+ llc_out_files.push_back((*obj_files_)[i]->write_wrapper());
+ }
+ for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) {
+ llc_out_files.push_back(invalid_desc_wrapper_);
+ }
{
nacl::MutexLocker ml(&subprocess_mu_);
@@ -149,19 +160,60 @@ void PnaclTranslateThread::DoTranslate() {
// Run LLC.
PluginReverseInterface* llc_reverse =
llc_subprocess_->service_runtime()->rev_interface();
- llc_reverse->AddTempQuotaManagedFile(obj_file_->identifier());
+ for (size_t i = 0; i < obj_files_->size(); i++) {
+ llc_reverse->AddTempQuotaManagedFile((*obj_files_)[i]->identifier());
+ }
}
int64_t compile_start_time = NaClGetTimeOfDayMicroseconds();
bool init_success;
std::vector<char> options = pnacl_options_->GetOptCommandline();
+
+ // Try to init with splitting
+ // TODO(dschuff): This CL override is ugly. Change llc to default to using
+ // the number of modules specified in the first param, and ignore multiple
+ // uses of -split-module
+ std::vector<char> split_args;
+ nacl::stringstream ss;
+ ss << "-split-module=" << obj_files_->size();
+ nacl::string split_arg = ss.str();
+ std::copy(split_arg.begin(), split_arg.end(), std::back_inserter(split_args));
+ split_args.push_back('\x00');
+ std::copy(options.begin(), options.end(), std::back_inserter(split_args));
+ int modules_used = static_cast<int>(obj_files_->size());
init_success = llc_subprocess_->InvokeSrpcMethod(
- "StreamInitWithOverrides",
- "hC",
+ "StreamInitWithSplit",
+ "ihhhhhhhhhhhhhhhhC",
&params,
- llc_out_file->desc(),
- &options[0],
- options.size());
+ modules_used,
+ llc_out_files[0]->desc(),
+ llc_out_files[1]->desc(),
+ llc_out_files[2]->desc(),
+ llc_out_files[3]->desc(),
+ llc_out_files[4]->desc(),
+ llc_out_files[5]->desc(),
+ llc_out_files[6]->desc(),
+ llc_out_files[7]->desc(),
+ llc_out_files[8]->desc(),
+ llc_out_files[9]->desc(),
+ llc_out_files[10]->desc(),
+ llc_out_files[11]->desc(),
+ llc_out_files[12]->desc(),
+ llc_out_files[13]->desc(),
+ llc_out_files[14]->desc(),
+ llc_out_files[15]->desc(),
+ &split_args[0],
+ split_args.size());
+ if (!init_success) {
+ init_success = llc_subprocess_->InvokeSrpcMethod(
+ "StreamInitWithOverrides",
+ "hC",
+ &params,
+ llc_out_files[0]->desc(),
+ &options[0],
+ options.size());
+ modules_used = 1;
+ }
if (!init_success) {
if (llc_subprocess_->srpc_client()->GetLastError() ==
@@ -256,25 +308,36 @@ void PnaclTranslateThread::DoTranslate() {
llc_subprocess_.reset(NULL);
NaClXMutexUnlock(&subprocess_mu_);
- if(!RunLdSubprocess(is_shared_library, soname, lib_dependencies)) {
+ if(!RunLdSubprocess(
+ modules_used, is_shared_library, soname, lib_dependencies)) {
return;
}
core->CallOnMainThread(0, report_translate_finished_, PP_OK);
}
-bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library,
+bool PnaclTranslateThread::RunLdSubprocess(int modules_used,
+ int is_shared_library,
const nacl::string& soname,
const nacl::string& lib_dependencies
) {
ErrorInfo error_info;
SrpcParams params;
- // Reset object file for reading first.
- if (!obj_file_->Reset()) {
- TranslateFailed(ERROR_PNACL_LD_SETUP,
- "Link process could not reset object file");
- return false;
+
+ std::vector<nacl::DescWrapper*> ld_in_files;
+ size_t i;
+ for (i = 0; i < obj_files_->size(); i++) {
+ // Reset object file for reading first.
+ if (!(*obj_files_)[i]->Reset()) {
+ TranslateFailed(ERROR_PNACL_LD_SETUP,
+ "Link process could not reset object file");
+ return false;
+ }
+ ld_in_files.push_back((*obj_files_)[i]->read_wrapper());
}
- nacl::DescWrapper* ld_in_file = obj_file_->read_wrapper();
+ for (; i < PnaclCoordinator::kMaxTranslatorObjectFiles; i++) {
+ ld_in_files.push_back(invalid_desc_wrapper_);
+ }
+
nacl::DescWrapper* ld_out_file = nexe_file_->write_wrapper();
{
@@ -299,14 +362,41 @@ bool PnaclTranslateThread::RunLdSubprocess(int is_shared_library,
int64_t link_start_time = NaClGetTimeOfDayMicroseconds();
// Run LD.
- if (!ld_subprocess_->InvokeSrpcMethod("RunWithDefaultCommandLine",
- "hhiss",
- &params,
- ld_in_file->desc(),
- ld_out_file->desc(),
- is_shared_library,
- soname.c_str(),
- lib_dependencies.c_str())) {
+ bool success;
+ // If we ran LLC with module splitting, we can't fall back here.
+ if (modules_used > 1) {
+ success = ld_subprocess_->InvokeSrpcMethod("RunWithSplit",
+ "ihhhhhhhhhhhhhhhhh",
+ &params,
+ modules_used,
+ ld_in_files[0]->desc(),
+ ld_in_files[1]->desc(),
+ ld_in_files[2]->desc(),
+ ld_in_files[3]->desc(),
+ ld_in_files[4]->desc(),
+ ld_in_files[5]->desc(),
+ ld_in_files[6]->desc(),
+ ld_in_files[7]->desc(),
+ ld_in_files[8]->desc(),
+ ld_in_files[9]->desc(),
+ ld_in_files[10]->desc(),
+ ld_in_files[11]->desc(),
+ ld_in_files[12]->desc(),
+ ld_in_files[13]->desc(),
+ ld_in_files[14]->desc(),
+ ld_in_files[15]->desc(),
+ ld_out_file->desc());
+ } else {
+ success = ld_subprocess_->InvokeSrpcMethod("RunWithDefaultCommandLine",
+ "hhiss",
+ &params,
+ ld_in_files[0]->desc(),
+ ld_out_file->desc(),
+ is_shared_library,
+ soname.c_str(),
+ lib_dependencies.c_str());
+ }
+ if (!success) {
TranslateFailed(ERROR_PNACL_LD_INTERNAL,
"link failed.");
return false;
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 31981eb..11473b4 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_translate_thread.h
@@ -50,8 +50,9 @@ class PnaclTranslateThread {
// as it is passed in with PutBytes.
void RunTranslate(const pp::CompletionCallback& finish_callback,
const Manifest* manifest,
- TempFile* obj_file,
+ const std::vector<TempFile*>* obj_files,
TempFile* nexe_file,
+ nacl::DescWrapper* invalid_desc_wrapper,
ErrorInfo* error_info,
PnaclResources* resources,
PnaclOptions* pnacl_options,
@@ -85,7 +86,8 @@ class PnaclTranslateThread {
void TranslateFailed(enum PluginErrorCode err_code,
const nacl::string& error_string);
// Run the LD subprocess, returning true on success
- bool RunLdSubprocess(int is_shared_library,
+ bool RunLdSubprocess(int modules_used,
+ int is_shared_library,
const nacl::string& soname,
const nacl::string& lib_dependencies);
@@ -121,8 +123,9 @@ class PnaclTranslateThread {
// Data about the translation files, owned by the coordinator
const Manifest* manifest_;
- TempFile* obj_file_;
+ const std::vector<TempFile*>* obj_files_;
TempFile* nexe_file_;
+ nacl::DescWrapper* invalid_desc_wrapper_;
ErrorInfo* coordinator_error_info_;
PnaclResources* resources_;
PnaclOptions* pnacl_options_;
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index 8696279..330c966 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -3144,6 +3144,11 @@ static PP_FileHandle Pnacl_M25_PPB_NaCl_Private_CreateTemporaryFile(PP_Instance
return iface->CreateTemporaryFile(instance);
}
+static int32_t Pnacl_M25_PPB_NaCl_Private_GetNumberOfProcessors(void) {
+ const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+ return iface->GetNumberOfProcessors();
+}
+
static int32_t Pnacl_M25_PPB_NaCl_Private_GetNexeFd(PP_Instance instance, const char* pexe_url, uint32_t abi_version, uint32_t opt_level, const char* last_modified, const char* etag, PP_Bool has_no_store_header, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback* callback) {
const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
return iface->GetNexeFd(instance, pexe_url, abi_version, opt_level, last_modified, etag, has_no_store_header, is_hit, nexe_handle, *callback);
@@ -5045,6 +5050,7 @@ static struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = {
.BrokerDuplicateHandle = (int32_t (*)(PP_FileHandle source_handle, uint32_t process_id, PP_FileHandle* target_handle, uint32_t desired_access, uint32_t options))&Pnacl_M25_PPB_NaCl_Private_BrokerDuplicateHandle,
.GetReadonlyPnaclFd = (PP_FileHandle (*)(const char* filename))&Pnacl_M25_PPB_NaCl_Private_GetReadonlyPnaclFd,
.CreateTemporaryFile = (PP_FileHandle (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_CreateTemporaryFile,
+ .GetNumberOfProcessors = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_GetNumberOfProcessors,
.GetNexeFd = (int32_t (*)(PP_Instance instance, const char* pexe_url, uint32_t abi_version, uint32_t opt_level, const char* last_modified, const char* etag, PP_Bool has_no_store_header, PP_Bool* is_hit, PP_FileHandle* nexe_handle, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_GetNexeFd,
.ReportTranslationFinished = (void (*)(PP_Instance instance, PP_Bool success))&Pnacl_M25_PPB_NaCl_Private_ReportTranslationFinished,
.ReportNaClError = (PP_ExternalPluginResult (*)(PP_Instance instance, PP_NaClError message_id))&Pnacl_M25_PPB_NaCl_Private_ReportNaClError,