Spicy
jit.h
1 // Copyright (c) 2020-2021 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 <utility>
12 #include <vector>
13 
14 #include <hilti/rt/filesystem.h>
15 #include <hilti/rt/library.h>
16 
17 #include <hilti/base/util.h>
18 #include <hilti/compiler/context.h>
19 #include <hilti/compiler/detail/cxx/unit.h>
20 
21 namespace reproc {
22 class process;
23 }
24 
25 namespace hilti {
26 
27 namespace logging::debug {
28 inline const DebugStream Jit("jit");
29 } // namespace logging::debug
30 
31 namespace detail::jit {
32 class Cxx;
33 } // namespace detail::jit
34 
36 class CxxCode {
37 public:
43  CxxCode(const hilti::rt::filesystem::path& path) { load(path); }
44 
51  CxxCode(const std::string& id, std::istream& code) { load(id, code); }
52 
58  explicit CxxCode(const detail::cxx::Unit& u);
59 
66  bool save(const hilti::rt::filesystem::path& p) const;
67 
74  bool save(std::ostream& out) const;
75 
77  auto code() const { return _code; }
78 
80  auto isLoaded() const { return _code.has_value(); }
81 
87  const std::string& id() const { return _id; }
88 
90  std::size_t hash() const { return _hash; }
91 
92 protected:
99  bool load(const hilti::rt::filesystem::path& path);
100 
108  bool load(const std::string& id, std::istream& in);
109 
110 private:
111  std::string _id;
112  std::optional<std::string> _code;
113  std::size_t _hash = 0;
114 };
115 
116 using hilti::rt::Library;
117 
124 class JIT {
125 public:
130  explicit JIT(const std::shared_ptr<Context>& context, bool dump_code = false);
131  ~JIT();
132 
133  JIT() = delete;
134  JIT(const JIT&) = delete;
135  JIT(JIT&&) noexcept = delete;
136  JIT& operator=(const JIT&) = delete;
137  JIT& operator=(JIT&&) noexcept = delete;
138 
145  void add(CxxCode d);
146 
153  void add(const hilti::rt::filesystem::path& p);
154 
159  bool hasInputs() { return _codes.size() || _files.size(); }
160 
167 
169  auto context() const { return _context.lock(); }
170 
172  auto options() const { return context()->options(); }
173 
174 private:
175  // Check if we have a working compiler.
176  hilti::Result<Nothing> _checkCompiler();
177 
178  // Compile C++ to object files.
179  hilti::Result<Nothing> _compile();
180 
181  // Link object files into shared library.
183 
184  // Clean up after compilation.
185  void _finish();
186 
187  std::weak_ptr<Context> _context; // global context for options
188  bool _dump_code; // save all C++ code for debugging
189 
190  std::vector<hilti::rt::filesystem::path> _files; // all added source files
191  std::vector<CxxCode> _codes; // all C++ code units to be compiled
192  std::vector<hilti::rt::filesystem::path> _objects;
193 
194  struct Job {
195  std::unique_ptr<reproc::process> process;
196  std::string stdout_;
197  std::string stderr_;
198 
199  void collectOutputs(int events);
200  };
201 
202  struct JobRunner {
203  using JobID = uint64_t;
204 
205  Result<JobID> _scheduleJob(const hilti::rt::filesystem::path& cmd, std::vector<std::string> args);
206  Result<Nothing> _spawnJob();
207  Result<Nothing> _waitForJobs();
208  void finish();
209 
210  using CmdLine = std::vector<std::string>;
211  std::deque<std::tuple<JobID, CmdLine>> _jobs_pending;
212 
213  JobID _job_counter = 0;
214 
215  std::map<JobID, Job> _jobs;
216  };
217  JobRunner _runner;
218 
219  std::size_t _hash = 0;
220 };
221 
222 } // namespace hilti
auto context() const
Definition: jit.h:169
const std::string & id() const
Definition: jit.h:87
CxxCode(const hilti::rt::filesystem::path &path)
Definition: jit.h:43
Definition: jit.h:21
CxxCode(const std::string &id, std::istream &code)
Definition: jit.h:51
Definition: unit.h:65
Definition: jit.h:124
Definition: library.h:59
bool hasInputs()
Definition: jit.h:159
auto code() const
Definition: jit.h:77
Definition: jit.h:36
std::size_t hash() const
Definition: jit.h:90
auto options() const
Definition: jit.h:172
Definition: result.h:67
auto isLoaded() const
Definition: jit.h:80