Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Unified Diff: src/IceBrowserCompileServer.cpp

Issue 997773002: Refactor Subzero initialization and add a browser callback handler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: more stuff Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceBrowserCompileServer.cpp
diff --git a/src/IceBrowserCompileServer.cpp b/src/IceBrowserCompileServer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..911b491eff91564005b07ae6c48a0615bf2c3386
--- /dev/null
+++ b/src/IceBrowserCompileServer.cpp
@@ -0,0 +1,165 @@
+//===- subzero/src/IceBrowserCompileServer.cpp - Browser Compile server ---===//
Jim Stichnoth 2015/03/25 16:34:06 lowercase compile?
jvoung (off chromium) 2015/03/25 18:14:35 Done.
+//
+// The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the browser-based compile server.
+//
+//===----------------------------------------------------------------------===//
+
+// Can only compile this with the NaCl compiler (needs irt.h, and the
+// unsandboxed LLVM build using the trusted compiler does not have irt.h).
+#if PNACL_BROWSER_TRANSLATOR
+
+#include <argz.h>
+#include <cstring>
+#include <cstdlib>
+#include <irt.h>
+#include <irt_dev.h>
+#include <thread>
+
+#include "llvm/Support/QueueStreamer.h"
+
+#include "IceBrowserCompileServer.h"
+
+namespace Ice {
+
+// Create C wrappers around callback handlers for the IRT interface.
+namespace {
+
+BrowserCompileServer *gCompileServer;
+struct nacl_irt_private_pnacl_translator_compile gIRTFuncs;
+
+void getIRTInterfaces() {
+ size_t QueryResult =
+ nacl_interface_query(NACL_IRT_PRIVATE_PNACL_TRANSLATOR_COMPILE_v0_1,
+ &gIRTFuncs, sizeof(gIRTFuncs));
+ if (QueryResult != sizeof(gIRTFuncs))
+ llvm::report_fatal_error("Failed to get translator_subzero IRT interface");
Jim Stichnoth 2015/03/25 16:34:06 Is "translator_subzero" still an accurate descript
jvoung (off chromium) 2015/03/25 18:14:35 Done.
+}
+
+int onInitCallback(uint32_t NumThreads, int *ObjFileFDs, size_t ObjFileFDCount,
+ const char *CmdFlags, size_t CmdFlagsLen) {
+ if (ObjFileFDCount < 1) {
+ llvm::errs() << "Invalid number of FDs for onInitCallback "
+ << ObjFileFDCount << "\n";
+ return 1;
+ }
+ int ObjFileFD = ObjFileFDs[0];
+ if (ObjFileFD < 0) {
+ llvm::errs() << "Invalid number of FD given for onInitCallback "
+ << ObjFileFD << "\n";
+ return 1;
+ }
+ // CmdFlags is a caller owned string, so we make copies.
+ std::vector<char *> CmdFlagList;
+ // Push some dummy argument for the program name to satisfy
+ // the argument parser.
+ CmdFlagList.push_back(strdup("pnacl-sz"));
+ const char *NextEntry = CmdFlags;
+ while (NextEntry != nullptr && CmdFlagsLen) {
+ CmdFlagList.push_back(strdup(NextEntry));
+ // re: const cast -- the string pointed-to by each "NextEntry" is
+ // only used temporarily by getParsedFlags(), and we make a
+ // copy anyway.
+ NextEntry = argz_next(const_cast<char *>(CmdFlags), CmdFlagsLen, NextEntry);
+ }
+ // Make an argv array from the CmdFlagList, parse and then free.
+ size_t argc = CmdFlagList.size();
+ char **argv = new char *[argc + 1];
+ for (size_t i = 0; i < argc; ++i)
+ argv[i] = CmdFlagList[i];
+ argv[argc] = nullptr;
+ gCompileServer->getParsedFlags(NumThreads, argc, argv);
+ for (size_t i = 0; i < argc; ++i)
+ free(argv[i]);
+ delete[] argv;
+ gCompileServer->startCompileThread(ObjFileFD);
+ return 0;
+}
+
+int onDataCallback(unsigned char *Data, size_t NumBytes) {
+ return gCompileServer->pushInputBytes(Data, NumBytes) ? 1 : 0;
+}
+
+int onEndCallback() {
+ gCompileServer->endInputStream();
+ gCompileServer->waitForCompileThread();
+ // TODO(jvoung): Also return an error string, and UMA data.
+ // Set up a report_fatal_error handler to grab that string.
+ return gCompileServer->getErrorCode().value();
+}
+
+struct irt_pnacl_compile_funcs SubzeroCallbacks {
+ &onInitCallback, &onDataCallback, &onEndCallback
+};
+
+std::unique_ptr<llvm::raw_fd_ostream> getOutputStream(int FD) {
+ if (FD <= 0)
+ llvm::report_fatal_error("Invalid output FD");
+ const bool CloseOnDtor = true;
+ const bool Unbuffered = false;
+ return std::unique_ptr<llvm::raw_fd_ostream>(
+ new llvm::raw_fd_ostream(FD, CloseOnDtor, Unbuffered));
+}
+
+} // end of anonymous namespace
+
+BrowserCompileServer::~BrowserCompileServer() {}
+
+void BrowserCompileServer::run() {
+ gCompileServer = this;
+ // TODO(jvoung): make a useful fatal error handler that can
+ // exit all *worker* threads, keep the server thread alive,
+ // and be able to handle a server request for the last error string.
+ getIRTInterfaces();
+ gIRTFuncs.serve_translate_request(&SubzeroCallbacks);
+}
+
+void BrowserCompileServer::getParsedFlags(uint32_t NumThreads, int argc,
+ char **argv) {
+ ClFlags::parseFlags(argc, argv);
+ ClFlags::getParsedClFlags(Flags);
+ ClFlags::getParsedClFlagsExtra(ExtraFlags);
+ // Set some defaults which aren't specified via the argv string.
+ Flags.setNumTranslationThreads(NumThreads);
+ Flags.setUseSandboxing(true);
+ Flags.setOutFileType(FT_Elf);
+ // TODO(jvoung): allow setting different target arches.
+ Flags.setTargetArch(Target_X8632);
+ ExtraFlags.setBuildOnRead(true);
+ ExtraFlags.setInputFileFormat(llvm::PNaClFormat);
+}
+
+bool BrowserCompileServer::pushInputBytes(unsigned char *Data,
+ size_t NumBytes) {
+ return InputStream->PutBytes(Data, NumBytes) != NumBytes;
+}
+
+void BrowserCompileServer::endInputStream() { InputStream->SetDone(); }
+
+void BrowserCompileServer::startCompileThread(int ObjFD) {
+ InputStream = new llvm::QueueStreamer();
+ LogStream = getOutputStream(STDOUT_FILENO);
+ LogStream->SetUnbuffered();
+ EmitStream = getOutputStream(ObjFD);
+ EmitStream->SetBufferSize(1 << 14);
+ ELFStream.reset(new ELFStreamer(*EmitStream.get()));
+ Ctx.reset(new GlobalContext(LogStream.get(), EmitStream.get(),
+ ELFStream.get(), Flags));
+ CompileThread = std::thread([this]() {
+ Ctx->initParserThread();
+ this->getCompiler().run(ExtraFlags, *Ctx.get(),
+ // Retain original reference, but the compiler
+ // (LLVM's MemoryObject) wants to handle deletion.
+ std::unique_ptr<llvm::DataStreamer>(InputStream));
+ });
+}
+
+} // end of namespace Ice
+
+#endif // PNACL_BROWSER_TRANSLATOR

Powered by Google App Engine
This is Rietveld 408576698