blob: 217ad9ed836afa917ac724fca5c82eee1d9c505b [file] [log] [blame]
Jan Voung44c3a802015-03-27 16:29:08 -07001//===- 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//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Declares the browser-based compile server.
Andrew Scull9612d322015-07-06 14:53:25 -070012///
Jan Voung44c3a802015-03-27 16:29:08 -070013//===----------------------------------------------------------------------===//
14
15#ifndef SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H
16#define SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H
17
Jan Voung44c3a802015-03-27 16:29:08 -070018#include "IceClFlags.h"
Jan Voung44c3a802015-03-27 16:29:08 -070019#include "IceCompileServer.h"
20#include "IceDefs.h"
21#include "IceELFStreamer.h"
22
John Porto67f8de92015-06-25 10:14:17 -070023#include <atomic>
24#include <thread>
25
Jan Voung44c3a802015-03-27 16:29:08 -070026namespace llvm {
27class QueueStreamer;
28class raw_fd_ostream;
John Porto67f8de92015-06-25 10:14:17 -070029} // end of namespace llvm
Jan Voung44c3a802015-03-27 16:29:08 -070030
31namespace Ice {
32
Andrew Scull57e12682015-09-16 11:30:19 -070033/// 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.
Jan Voung44c3a802015-03-27 16:29:08 -070038class BrowserCompileServer : public CompileServer {
Jan Voung44c3a802015-03-27 16:29:08 -070039 BrowserCompileServer(const BrowserCompileServer &) = delete;
40 BrowserCompileServer &operator=(const BrowserCompileServer &) = delete;
Karl Schimpf2f67b922015-04-22 15:20:16 -070041 class StringStream;
Jan Voung44c3a802015-03-27 16:29:08 -070042
43public:
Karl Schimpfd4699942016-04-02 09:55:31 -070044 BrowserCompileServer() : HadError(false) {}
Jan Voung44c3a802015-03-27 16:29:08 -070045
46 ~BrowserCompileServer() final;
47
48 void run() final;
49
Jan Voung2f7f2b72015-06-03 17:50:20 -070050 ErrorCode &getErrorCode() final;
51
Andrew Scull9612d322015-07-06 14:53:25 -070052 /// Parse and set up the flags for compile jobs.
Jim Stichnothfd07ad02016-04-20 10:12:46 -070053 void getParsedFlags(bool UseNumThreadsFromBrowser, uint32_t NumThreads,
54 int argc, const char *const *argv);
Jan Voung44c3a802015-03-27 16:29:08 -070055
Andrew Scull57e12682015-09-16 11:30:19 -070056 /// Creates the streams + context and starts the compile thread, handing off
57 /// the streams + context.
Jan Voung44c3a802015-03-27 16:29:08 -070058 void startCompileThread(int OutFD);
59
Andrew Scull57e12682015-09-16 11:30:19 -070060 /// Call to push more bytes to the current input stream. Returns false on
61 /// success and true on error.
Jan Voung44c3a802015-03-27 16:29:08 -070062 bool pushInputBytes(const void *Data, size_t NumBytes);
63
Andrew Scull9612d322015-07-06 14:53:25 -070064 /// Notify the input stream of EOF.
Jan Voung44c3a802015-03-27 16:29:08 -070065 void endInputStream();
66
Andrew Scull9612d322015-07-06 14:53:25 -070067 /// Wait for the compile thread to complete then reset the state.
Jan Voung44c3a802015-03-27 16:29:08 -070068 void waitForCompileThread() {
69 CompileThread.join();
Jan Voung2f7f2b72015-06-03 17:50:20 -070070 if (Ctx->getErrorStatus()->value())
71 LastError.assign(Ctx->getErrorStatus()->value());
Andrew Scull57e12682015-09-16 11:30:19 -070072 // 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.
Jan Voung44c3a802015-03-27 16:29:08 -070074 InputStream = nullptr;
75 EmitStream.reset(nullptr);
76 ELFStream.reset(nullptr);
77 }
78
Jim Stichnoth620ad732015-04-28 14:12:20 -070079 StringStream &getErrorStream() { return *ErrorStream; }
Karl Schimpf2f67b922015-04-22 15:20:16 -070080
Jim Stichnoth467ffe52016-03-29 15:01:06 -070081 void setFatalError(const std::string &Reason);
Jan Voung2f7f2b72015-06-03 17:50:20 -070082
Jan Voung44c3a802015-03-27 16:29:08 -070083private:
Karl Schimpf2f67b922015-04-22 15:20:16 -070084 class StringStream {
85 public:
86 StringStream() : StrBuf(Buffer) {}
Jim Stichnoth467ffe52016-03-29 15:01:06 -070087 const std::string &getContents() { return StrBuf.str(); }
Karl Schimpf2f67b922015-04-22 15:20:16 -070088 Ostream &getStream() { return StrBuf; }
Jim Stichnoth620ad732015-04-28 14:12:20 -070089
Karl Schimpf2f67b922015-04-22 15:20:16 -070090 private:
91 std::string Buffer;
92 llvm::raw_string_ostream StrBuf;
93 };
Andrew Scull57e12682015-09-16 11:30:19 -070094 /// This currently only handles a single compile request, hence one copy of
95 /// the state.
Jan Voung44c3a802015-03-27 16:29:08 -070096 std::unique_ptr<GlobalContext> Ctx;
Andrew Scull57e12682015-09-16 11:30:19 -070097 /// 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.
Jim Stichnotheafb56c2015-06-22 10:35:22 -0700100 llvm::QueueStreamer *InputStream = nullptr;
Jan Voung44c3a802015-03-27 16:29:08 -0700101 std::unique_ptr<Ostream> LogStream;
102 std::unique_ptr<llvm::raw_fd_ostream> EmitStream;
Karl Schimpf2f67b922015-04-22 15:20:16 -0700103 std::unique_ptr<StringStream> ErrorStream;
Jan Voung44c3a802015-03-27 16:29:08 -0700104 std::unique_ptr<ELFStreamer> ELFStream;
Jan Voung44c3a802015-03-27 16:29:08 -0700105 std::thread CompileThread;
Jan Voung2f7f2b72015-06-03 17:50:20 -0700106 std::atomic<bool> HadError;
Jan Voung44c3a802015-03-27 16:29:08 -0700107};
108
109} // end of namespace Ice
110
111#endif // SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H