Spicy
jit.h
1 // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <deque>
6 #include <iostream>
7 #include <map>
8 #include <memory>
9 #include <string>
10 #include <tuple>
11 #include <vector>
12 
13 #include <hilti/rt/filesystem.h>
14 #include <hilti/rt/library.h>
15 
16 #include <hilti/base/util.h>
17 #include <hilti/compiler/context.h>
18 #include <hilti/compiler/detail/cxx/unit.h>
19 
20 namespace reproc {
21 class process;
22 }
23 
24 namespace hilti {
25 
26 namespace logging::debug {
27 inline const DebugStream Jit("jit");
28 } // namespace logging::debug
29 
30 namespace detail::jit {
31 class Cxx;
32 } // namespace detail::jit
33 
35 class CxxCode {
36 public:
42  CxxCode(const hilti::rt::filesystem::path& path) { load(path); }
43 
50  CxxCode(const std::string& id, std::istream& code) { load(id, code); }
51 
57  explicit CxxCode(const detail::cxx::Unit& u);
58 
65  bool save(const hilti::rt::filesystem::path& p) const;
66 
73  bool save(std::ostream& out) const;
74 
76  const auto& code() const { return _code; }
77 
79  auto isLoaded() const { return _code.has_value(); }
80 
86  const std::string& id() const { return _id; }
87 
89  std::size_t hash() const { return _hash; }
90 
91 protected:
98  bool load(const hilti::rt::filesystem::path& path);
99 
107  bool load(const std::string& id, std::istream& in);
108 
109 private:
110  std::string _id;
111  std::optional<std::string> _code;
112  std::size_t _hash = 0;
113 };
114 
115 using hilti::rt::Library;
116 
123 class JIT {
124 public:
129  explicit JIT(const std::shared_ptr<Context>& context, bool dump_code = false);
130  ~JIT();
131 
132  JIT() = delete;
133  JIT(const JIT&) = delete;
134  JIT(JIT&&) noexcept = delete;
135  JIT& operator=(const JIT&) = delete;
136  JIT& operator=(JIT&&) noexcept = delete;
137 
144  void add(CxxCode d);
145 
152  void add(const hilti::rt::filesystem::path& p);
153 
158  bool hasInputs() { return _codes.size() || _files.size(); }
159 
166 
168  auto context() const { return _context.lock(); }
169 
171  auto options() const { return context()->options(); }
172 
173 private:
174  // Check if we have a working compiler.
175  hilti::Result<Nothing> _checkCompiler();
176 
177  // Compile C++ to object files.
178  hilti::Result<Nothing> _compile();
179 
180  // Link object files into shared library.
182 
183  // Clean up after compilation.
184  void _finish();
185 
186  std::weak_ptr<Context> _context; // global context for options
187  bool _dump_code; // save all C++ code for debugging
188 
189  std::vector<hilti::rt::filesystem::path> _files; // all added source files
190  std::vector<CxxCode> _codes; // all C++ code units to be compiled
191  std::vector<hilti::rt::filesystem::path> _objects;
192 
193  struct Job {
194  ~Job();
195 
196  std::string cmdline;
197  std::unique_ptr<reproc::process> process;
198  hilti::rt::filesystem::path output; // path to file capturing process output; file will be deleted by destructor
199  };
200 
201  struct JobRunner {
202  JobRunner();
203 
204  using JobID = uint64_t;
205 
206  Result<JobID> _scheduleJob(const hilti::rt::filesystem::path& cmd, std::vector<std::string> args);
207  Result<Nothing> _spawnJob();
208  Result<Nothing> _waitForJobs();
209  void _recordUserDiagnostics(JobID jid, const Job& job);
210  void finish();
211 
212  using CmdLine = std::vector<std::string>;
213  std::deque<std::tuple<JobID, CmdLine>> jobs_pending;
214 
215  JobID job_counter = 0;
216 
217  std::map<JobID, Job> jobs;
218  };
219 
220  JobRunner _runner;
221  std::size_t _hash = 0;
222 };
223 
224 } // namespace hilti
Definition: jit.h:35
std::size_t hash() const
Definition: jit.h:89
const auto & code() const
Definition: jit.h:76
auto isLoaded() const
Definition: jit.h:79
bool load(const hilti::rt::filesystem::path &path)
Definition: jit.cc:121
const std::string & id() const
Definition: jit.h:86
CxxCode(const std::string &id, std::istream &code)
Definition: jit.h:50
CxxCode(const hilti::rt::filesystem::path &path)
Definition: jit.h:42
bool save(const hilti::rt::filesystem::path &p) const
Definition: jit.cc:147
Definition: jit.h:123
bool hasInputs()
Definition: jit.h:158
Result< std::shared_ptr< const Library > > build()
Definition: jit.cc:182
void add(CxxCode d)
Definition: jit.cc:694
auto context() const
Definition: jit.h:168
auto options() const
Definition: jit.h:171
Definition: unit.h:67
Definition: library.h:59
Definition: result.h:71