3/[thrift][be]move ResponsePayload type to it's own file
[hiphop-php.git] / hphp / runtime / vm / jit / vasm-gen.h
blob92e24b70298f4e2233549e78d62c6905e3693533
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #pragma once
19 #include "hphp/runtime/vm/jit/cg-meta.h"
20 #include "hphp/runtime/vm/jit/containers.h"
21 #include "hphp/runtime/vm/jit/types.h"
22 #include "hphp/runtime/vm/jit/vasm-text.h"
23 #include "hphp/runtime/vm/jit/vasm-unit.h"
24 #include "hphp/runtime/vm/jit/vasm.h"
26 #include "hphp/util/data-block.h"
28 #include <boost/type_traits.hpp>
30 namespace HPHP::jit {
31 ///////////////////////////////////////////////////////////////////////////////
33 struct IRInstruction;
34 struct Vinstr;
35 struct Vreg;
37 ///////////////////////////////////////////////////////////////////////////////
40 * Writer stream for adding instructions to a Vblock.
42 struct Vout {
43 Vout(Vunit& u, Vlabel b,
44 Optional<Vinstr::ir_context> irctx = std::nullopt)
45 : m_unit(u)
46 , m_block(b)
47 , m_irctx ( irctx ? *irctx
48 : Vinstr::ir_context { nullptr, Vinstr::kInvalidVoff } )
51 Vout(Vout&&) = default;
52 Vout(const Vout&) = delete;
54 Vout& operator=(const Vout&);
55 Vout& operator=(Vlabel);
58 * Implicit cast to label for initializing branch instructions.
60 /* implicit */ operator Vlabel() const;
63 * Instruction emitter.
65 Vout& operator<<(const Vinstr& inst);
68 * Create a stream connected to a new empty block.
70 Vout makeBlock();
72 /////////////////////////////////////////////////////////////////////////////
75 * Whether the stream is empty or terminated (because a block-terminating
76 * instruction has been emitted).
78 bool empty() const;
79 bool closed() const;
82 * Return the managed Vunit.
84 Vunit& unit() { return m_unit; }
87 * Return the code area of the currently-managed block.
89 AreaIndex area() const;
92 * Set the current block and Vinstr origin.
94 void use(Vlabel b) { m_block = b; }
95 void setOrigin(const IRInstruction* i) { m_irctx.origin = i; }
97 const IRInstruction* getOrigin() const { return m_irctx.origin; }
100 * Add a scaling factor. The weight of the current block and all
101 * future blocks created from this Vout will be multiplied by the
102 * total scaling factor.
104 void addWeightScale(uint64_t);
107 * Vunit delegations.
109 Vreg makeReg();
110 Vaddr makeAddr();
111 Vtuple makeTuple(const VregList& regs) const;
112 Vtuple makeTuple(VregList&& regs) const;
113 VcallArgsId makeVcallArgs(VcallArgs&& args) const;
114 template<class T> Vreg cns(T v);
115 template<class T, class... Args> T* allocData(Args&&... args);
117 private:
118 Vout(Vunit& u, Vlabel b, Vinstr::ir_context irctx, uint64_t scale)
119 : m_unit{u}
120 , m_block{b}
121 , m_irctx{irctx}
122 , m_weight_scale{scale} {}
124 Vunit& m_unit;
125 Vlabel m_block;
126 Vinstr::ir_context m_irctx;
127 uint64_t m_weight_scale = 1;
130 ///////////////////////////////////////////////////////////////////////////////
133 * Vasm assembler.
135 * A Vasm manages Vout streams for a Vunit.
137 struct Vasm {
138 explicit Vasm(Vunit& unit) : m_unit(unit) { m_outs.reserve(kNumAreas); }
141 * Obtain the managed Vunit.
143 Vunit& unit() { return m_unit; }
146 * Get or create the stream for the corresponding Varea.
148 Vout& main() { return out(AreaIndex::Main); }
149 Vout& cold() { return out(AreaIndex::Cold); }
150 Vout& frozen() { return out(AreaIndex::Frozen); }
152 private:
153 Vout& out(AreaIndex i);
155 private:
156 Vunit& m_unit;
157 jit::vector<Vout> m_outs; // one for each AreaIndex
160 ///////////////////////////////////////////////////////////////////////////////
163 * Helper for emitting small amounts of machine code using vasm.
165 * Vauto manages a Vunit with a single area. When the Vauto goes out of scope,
166 * it will finalize and emit any code it contains.
168 struct Vauto {
169 explicit Vauto(CodeBlock& main, CodeBlock& cold, DataBlock& data,
170 CGMeta& fixups, CodeKind kind = CodeKind::Helper,
171 const char* name = nullptr,
172 bool relocate = false, bool* wasFull = nullptr)
173 : m_text{main, cold, data}
174 , m_fixups(fixups)
175 , m_main{m_unit, m_unit.makeBlock(AreaIndex::Main)}
176 , m_cold{m_unit, m_unit.makeBlock(AreaIndex::Cold)}
177 , m_kind{kind}
178 , m_relocate{relocate}
179 , m_wasFull{wasFull}
181 m_unit.entry = Vlabel(this->main());
182 m_unit.name = name;
185 Vunit& unit() { return m_unit; }
186 Vout& main() { return m_main; }
187 Vout& cold() { return m_cold; }
189 ~Vauto();
191 private:
192 Vunit m_unit;
193 Vtext m_text;
194 CGMeta& m_fixups;
195 Vout m_main;
196 Vout m_cold;
197 CodeKind m_kind;
198 bool m_relocate;
199 bool* m_wasFull;
202 namespace detail {
203 template<class GenFunc>
204 TCA vwrap_impl(CodeBlock& main, CodeBlock& cold, DataBlock& data,
205 CGMeta* meta, GenFunc gen,
206 const char* name,
207 CodeKind kind = CodeKind::CrossTrace,
208 bool relocate = true,
209 bool nullOnFull = false);
213 * Convenience wrappers around Vauto for cross-trace or helper code.
215 * The relocate parameter attempts to generate code into a temporary
216 * buffer allocated from cb, and then relocate it to the start of cb -
217 * which can reduce the code size. If there isn't enough room in cb,
218 * the parameter will be ignored.
220 template<class GenFunc>
221 TCA vwrap(CodeBlock& cb, DataBlock& data, CGMeta& meta, GenFunc gen,
222 const char* name = nullptr,
223 CodeKind kind = CodeKind::CrossTrace, bool relocate = true) {
224 return detail::vwrap_impl(cb, cb, data, &meta,
225 [&] (Vout& v, Vout&) { gen(v); }, name,
226 kind, relocate);
228 template<class GenFunc>
229 TCA vwrap(CodeBlock& cb, DataBlock& data, GenFunc gen,
230 const char* name = nullptr,
231 bool relocate = true, bool nullOnFull = false) {
232 return detail::vwrap_impl(cb, cb, data, nullptr,
233 [&] (Vout& v, Vout&) { gen(v); },
234 name, CodeKind::CrossTrace, relocate, nullOnFull);
236 template<class GenFunc>
237 TCA vwrap2(CodeBlock& main, CodeBlock& cold, DataBlock& data,
238 CGMeta& meta, GenFunc gen, const char* name = nullptr) {
239 return detail::vwrap_impl(main, cold, data, &meta, gen, name);
241 template<class GenFunc>
242 TCA vwrap2(CodeBlock& main, CodeBlock& cold, DataBlock& data, GenFunc gen,
243 const char* name = nullptr) {
244 return detail::vwrap_impl(main, cold, data, nullptr, gen, name);
248 * Multiplying factors used to compute the block weights for each code area.
249 * We multiply the corresponding IR block's profile counter by the following
250 * factors, depending on the code area the block is assigned to.
252 uint64_t areaWeightFactor(AreaIndex area);
254 ///////////////////////////////////////////////////////////////////////////////
257 #include "hphp/runtime/vm/jit/vasm-gen-inl.h"