Home | History | Annotate | Download | only in src
      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:
     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.
     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 
     79   StringStream &getErrorStream() { return *ErrorStream; }
     80 
     81   void setFatalError(const std::string &Reason);
     82 
     83 private:
     84   class StringStream {
     85   public:
     86     StringStream() : StrBuf(Buffer) {}
     87     const std::string &getContents() { return StrBuf.str(); }
     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