1 //===- subzero/src/IceBrowserCompileServer.h - Browser server ---*- C++ -*-===// 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 /// \file 11 /// \brief Declares the browser-based compile server. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H 16 #define SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H 17 18 #include "IceClFlags.h" 19 #include "IceCompileServer.h" 20 #include "IceDefs.h" 21 #include "IceELFStreamer.h" 22 23 #include <atomic> 24 #include <thread> 25 26 namespace llvm { 27 class QueueStreamer; 28 class raw_fd_ostream; 29 } // end of namespace llvm 30 31 namespace Ice { 32 33 /// The browser variant of the compile server. Compared to the commandline 34 /// version, this version gets compile requests over IPC. Each compile request 35 /// will have a slimmed down version of argc, argv while other flags are set to 36 /// defaults that make sense in the browser case. The output file is specified 37 /// via a posix FD, and input bytes are pushed to the server. 38 class BrowserCompileServer : public CompileServer { 39 BrowserCompileServer(const BrowserCompileServer &) = delete; 40 BrowserCompileServer &operator=(const BrowserCompileServer &) = delete; 41 class StringStream; 42 43 public: BrowserCompileServer()44 BrowserCompileServer() : HadError(false) {} 45 46 ~BrowserCompileServer() final; 47 48 void run() final; 49 50 ErrorCode &getErrorCode() final; 51 52 /// Parse and set up the flags for compile jobs. 53 void getParsedFlags(bool UseNumThreadsFromBrowser, uint32_t NumThreads, 54 int argc, const char *const *argv); 55 56 /// Creates the streams + context and starts the compile thread, handing off 57 /// the streams + context. 58 void startCompileThread(int OutFD); 59 60 /// Call to push more bytes to the current input stream. Returns false on 61 /// success and true on error. 62 bool pushInputBytes(const void *Data, size_t NumBytes); 63 64 /// Notify the input stream of EOF. 65 void endInputStream(); 66 67 /// Wait for the compile thread to complete then reset the state. waitForCompileThread()68 void waitForCompileThread() { 69 CompileThread.join(); 70 if (Ctx->getErrorStatus()->value()) 71 LastError.assign(Ctx->getErrorStatus()->value()); 72 // Reset some state. The InputStream is deleted by the compiler so only 73 // reset this to nullptr. Free and flush the rest of the streams. 74 InputStream = nullptr; 75 EmitStream.reset(nullptr); 76 ELFStream.reset(nullptr); 77 } 78 getErrorStream()79 StringStream &getErrorStream() { return *ErrorStream; } 80 81 void setFatalError(const std::string &Reason); 82 83 private: 84 class StringStream { 85 public: StringStream()86 StringStream() : StrBuf(Buffer) {} getContents()87 const std::string &getContents() { return StrBuf.str(); } getStream()88 Ostream &getStream() { return StrBuf; } 89 90 private: 91 std::string Buffer; 92 llvm::raw_string_ostream StrBuf; 93 }; 94 /// This currently only handles a single compile request, hence one copy of 95 /// the state. 96 std::unique_ptr<GlobalContext> Ctx; 97 /// A borrowed reference to the current InputStream. The compiler owns the 98 /// actual reference so the server must be careful not to access after the 99 /// compiler is done. 100 llvm::QueueStreamer *InputStream = nullptr; 101 std::unique_ptr<Ostream> LogStream; 102 std::unique_ptr<llvm::raw_fd_ostream> EmitStream; 103 std::unique_ptr<StringStream> ErrorStream; 104 std::unique_ptr<ELFStreamer> ELFStream; 105 std::thread CompileThread; 106 std::atomic<bool> HadError; 107 }; 108 109 } // end of namespace Ice 110 111 #endif // SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H 112