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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 //===- 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.
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the browser-based compile server.
11 //
12 //===----------------------------------------------------------------------===//
13
14 // Can only compile this with the NaCl compiler (needs irt.h, and the
15 // unsandboxed LLVM build using the trusted compiler does not have irt.h).
16 #if PNACL_BROWSER_TRANSLATOR
17
18 #include <argz.h>
19 #include <cstring>
20 #include <cstdlib>
21 #include <irt.h>
22 #include <irt_dev.h>
23 #include <thread>
24
25 #include "llvm/Support/QueueStreamer.h"
26
27 #include "IceBrowserCompileServer.h"
28
29 namespace Ice {
30
31 // Create C wrappers around callback handlers for the IRT interface.
32 namespace {
33
34 BrowserCompileServer *gCompileServer;
35 struct nacl_irt_private_pnacl_translator_compile gIRTFuncs;
36
37 void getIRTInterfaces() {
38 size_t QueryResult =
39 nacl_interface_query(NACL_IRT_PRIVATE_PNACL_TRANSLATOR_COMPILE_v0_1,
40 &gIRTFuncs, sizeof(gIRTFuncs));
41 if (QueryResult != sizeof(gIRTFuncs))
42 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.
43 }
44
45 int onInitCallback(uint32_t NumThreads, int *ObjFileFDs, size_t ObjFileFDCount,
46 const char *CmdFlags, size_t CmdFlagsLen) {
47 if (ObjFileFDCount < 1) {
48 llvm::errs() << "Invalid number of FDs for onInitCallback "
49 << ObjFileFDCount << "\n";
50 return 1;
51 }
52 int ObjFileFD = ObjFileFDs[0];
53 if (ObjFileFD < 0) {
54 llvm::errs() << "Invalid number of FD given for onInitCallback "
55 << ObjFileFD << "\n";
56 return 1;
57 }
58 // CmdFlags is a caller owned string, so we make copies.
59 std::vector<char *> CmdFlagList;
60 // Push some dummy argument for the program name to satisfy
61 // the argument parser.
62 CmdFlagList.push_back(strdup("pnacl-sz"));
63 const char *NextEntry = CmdFlags;
64 while (NextEntry != nullptr && CmdFlagsLen) {
65 CmdFlagList.push_back(strdup(NextEntry));
66 // re: const cast -- the string pointed-to by each "NextEntry" is
67 // only used temporarily by getParsedFlags(), and we make a
68 // copy anyway.
69 NextEntry = argz_next(const_cast<char *>(CmdFlags), CmdFlagsLen, NextEntry);
70 }
71 // Make an argv array from the CmdFlagList, parse and then free.
72 size_t argc = CmdFlagList.size();
73 char **argv = new char *[argc + 1];
74 for (size_t i = 0; i < argc; ++i)
75 argv[i] = CmdFlagList[i];
76 argv[argc] = nullptr;
77 gCompileServer->getParsedFlags(NumThreads, argc, argv);
78 for (size_t i = 0; i < argc; ++i)
79 free(argv[i]);
80 delete[] argv;
81 gCompileServer->startCompileThread(ObjFileFD);
82 return 0;
83 }
84
85 int onDataCallback(unsigned char *Data, size_t NumBytes) {
86 return gCompileServer->pushInputBytes(Data, NumBytes) ? 1 : 0;
87 }
88
89 int onEndCallback() {
90 gCompileServer->endInputStream();
91 gCompileServer->waitForCompileThread();
92 // TODO(jvoung): Also return an error string, and UMA data.
93 // Set up a report_fatal_error handler to grab that string.
94 return gCompileServer->getErrorCode().value();
95 }
96
97 struct irt_pnacl_compile_funcs SubzeroCallbacks {
98 &onInitCallback, &onDataCallback, &onEndCallback
99 };
100
101 std::unique_ptr<llvm::raw_fd_ostream> getOutputStream(int FD) {
102 if (FD <= 0)
103 llvm::report_fatal_error("Invalid output FD");
104 const bool CloseOnDtor = true;
105 const bool Unbuffered = false;
106 return std::unique_ptr<llvm::raw_fd_ostream>(
107 new llvm::raw_fd_ostream(FD, CloseOnDtor, Unbuffered));
108 }
109
110 } // end of anonymous namespace
111
112 BrowserCompileServer::~BrowserCompileServer() {}
113
114 void BrowserCompileServer::run() {
115 gCompileServer = this;
116 // TODO(jvoung): make a useful fatal error handler that can
117 // exit all *worker* threads, keep the server thread alive,
118 // and be able to handle a server request for the last error string.
119 getIRTInterfaces();
120 gIRTFuncs.serve_translate_request(&SubzeroCallbacks);
121 }
122
123 void BrowserCompileServer::getParsedFlags(uint32_t NumThreads, int argc,
124 char **argv) {
125 ClFlags::parseFlags(argc, argv);
126 ClFlags::getParsedClFlags(Flags);
127 ClFlags::getParsedClFlagsExtra(ExtraFlags);
128 // Set some defaults which aren't specified via the argv string.
129 Flags.setNumTranslationThreads(NumThreads);
130 Flags.setUseSandboxing(true);
131 Flags.setOutFileType(FT_Elf);
132 // TODO(jvoung): allow setting different target arches.
133 Flags.setTargetArch(Target_X8632);
134 ExtraFlags.setBuildOnRead(true);
135 ExtraFlags.setInputFileFormat(llvm::PNaClFormat);
136 }
137
138 bool BrowserCompileServer::pushInputBytes(unsigned char *Data,
139 size_t NumBytes) {
140 return InputStream->PutBytes(Data, NumBytes) != NumBytes;
141 }
142
143 void BrowserCompileServer::endInputStream() { InputStream->SetDone(); }
144
145 void BrowserCompileServer::startCompileThread(int ObjFD) {
146 InputStream = new llvm::QueueStreamer();
147 LogStream = getOutputStream(STDOUT_FILENO);
148 LogStream->SetUnbuffered();
149 EmitStream = getOutputStream(ObjFD);
150 EmitStream->SetBufferSize(1 << 14);
151 ELFStream.reset(new ELFStreamer(*EmitStream.get()));
152 Ctx.reset(new GlobalContext(LogStream.get(), EmitStream.get(),
153 ELFStream.get(), Flags));
154 CompileThread = std::thread([this]() {
155 Ctx->initParserThread();
156 this->getCompiler().run(ExtraFlags, *Ctx.get(),
157 // Retain original reference, but the compiler
158 // (LLVM's MemoryObject) wants to handle deletion.
159 std::unique_ptr<llvm::DataStreamer>(InputStream));
160 });
161 }
162
163 } // end of namespace Ice
164
165 #endif // PNACL_BROWSER_TRANSLATOR
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698