2 +----------------------------------------------------------------------+
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 #ifndef incl_HPHP_TRANSL_TYPES_H_
18 #define incl_HPHP_TRANSL_TYPES_H_
22 #include "hphp/runtime/base/runtime-option.h"
23 #include "hphp/runtime/base/types.h"
25 #include "hphp/util/assertions.h"
26 #include "hphp/util/hash-map-typedefs.h"
28 namespace HPHP
{ namespace jit
{
30 ///////////////////////////////////////////////////////////////////////////////
35 typedef unsigned char* TCA
; // "Translation cache address."
36 typedef const unsigned char* CTCA
;
38 using LowTCA
= LowPtr
<uint8_t>;
39 using AtomicLowTCA
= AtomicLowPtr
<uint8_t,
40 std::memory_order_acquire
,
41 std::memory_order_release
>;
43 struct ctca_identity_hash
{
44 size_t operator()(CTCA val
) const {
45 // Experiments show that this is a sufficient "hash function" on
46 // TCAs for now; using stronger functions didn't help given current
47 // data. Patterns of code emission in the translator could invalidate
48 // this finding going forward, though; e.g., if we frequently emit
49 // a call instruction N bytes into a cache-aligned region.
50 return uintptr_t(val
);
54 ///////////////////////////////////////////////////////////////////////////////
56 using TransIDSet
= hphp_hash_set
<TransID
>;
57 using TransIDVec
= std::vector
<TransID
>;
59 using Annotation
= std::pair
<std::string
, std::string
>;
60 using Annotations
= std::vector
<Annotation
>;
62 ///////////////////////////////////////////////////////////////////////////////
65 * The different kinds of translations that the JIT generates:
67 * - Anchor : a service request for retranslating
68 * - Interp : a service request to interpret at least one instruction
69 * - Live : translate one tracelet by inspecting live VM state
70 * - Profile : translate one block by inspecting live VM state and
71 * inserting profiling counters
72 * - Optimize : translate one region performing optimizations that may
73 * leverage data collected by Profile translations
74 * - LivePrologue : prologue for a function being JITed in Live mode
75 * - ProfPrologue : prologue for a function being JITed in Profile mode
76 * - OptPrologue : prologue for a function being JITed in Optimize mode
89 enum class TransKind {
90 #define DO(KIND) KIND,
95 constexpr size_t NumTransKinds
=
101 inline std::string
show(TransKind k
) {
102 #define DO(name) case TransKind::name: return "Trans" #name;
103 switch (k
) { TRANS_KINDS
}
108 inline bool isProfiling(TransKind k
) {
110 case TransKind::Profile
:
111 case TransKind::ProfPrologue
:
114 case TransKind::Anchor
:
115 case TransKind::Interp
:
116 case TransKind::Live
:
117 case TransKind::LivePrologue
:
118 case TransKind::Optimize
:
119 case TransKind::OptPrologue
:
120 case TransKind::Invalid
:
123 always_assert(false);
126 inline bool isPrologue(TransKind k
) {
128 case TransKind::LivePrologue
:
129 case TransKind::ProfPrologue
:
130 case TransKind::OptPrologue
:
133 case TransKind::Anchor
:
134 case TransKind::Interp
:
135 case TransKind::Live
:
136 case TransKind::Profile
:
137 case TransKind::Optimize
:
138 case TransKind::Invalid
:
141 always_assert(false);
145 * Compact flags which may be threaded through a service request to provide
146 * hints or demands for retranslations.
149 /* implicit */ TransFlags(uint64_t flags
= 0) : packed(flags
) {}
153 bool noinlineSingleton
: 1;
154 bool noProfiledFPush
: 1;
160 static_assert(sizeof(TransFlags
) <= sizeof(uint64_t), "Too many TransFlags!");
162 ///////////////////////////////////////////////////////////////////////////////
165 * The "kind" of code being generated.
167 * Different contexts of code generation constrain codegen differently; e.g.,
168 * cross-trace code has fewer available registers.
170 enum class CodeKind
: uint8_t {
172 * Normal PHP code in the TC.
177 * Code at the TC boundaries, e.g., service requests, unique stubs.
182 * Helper code that uses native scratch registers only.
184 * This roughly means unreserved, caller-saved, non-argument registers---but
185 * best to just look at the helper ABI in the appropriate abi-*.cpp file.
191 * Enumeration representing the various areas that we emit code.
193 * kNumAreas must be kept up to date.
195 enum class AreaIndex
: uint8_t { Main
, Cold
, Frozen
};
196 constexpr size_t kNumAreas
= 3;
198 inline std::string
areaAsString(AreaIndex area
) {
200 case AreaIndex::Main
:
202 case AreaIndex::Cold
:
204 case AreaIndex::Frozen
:
207 always_assert(false);
211 * Multiplying factors used to compute the block weights for each code area.
212 * We multiply the corresponding IR block's profile counter by the following
213 * factors, depending on the code area the block is assigned to.
215 inline uint64_t areaWeightFactor(AreaIndex area
) {
217 case AreaIndex::Main
: return RuntimeOption::EvalJitLayoutMainFactor
;
218 case AreaIndex::Cold
: return RuntimeOption::EvalJitLayoutColdFactor
;
219 case AreaIndex::Frozen
: return 1;
221 always_assert(false);
224 ///////////////////////////////////////////////////////////////////////////////
227 * Some data structures are accessed often enough from translated code that we
228 * have shortcuts for getting offsets into them.
230 #define TVOFF(nm) int(offsetof(TypedValue, nm))
231 #define AROFF(nm) int(offsetof(ActRec, nm))
232 #define AFWHOFF(nm) int(offsetof(c_AsyncFunctionWaitHandle, nm))
233 #define GENDATAOFF(nm) int(offsetof(Generator, nm))
235 ///////////////////////////////////////////////////////////////////////////////
238 * Generalization of Status Flag bits encoded in Vinstr and used by the
239 * annotateSFUses() pass and platform-specific lowerers/emitters.
241 * In order for a platform to utilize the pass, they'll need to implement
242 * mappings between ConditionCodes and an operator|-able bit sequence held in a
243 * Vflags byte. This implies that the platform will need to define their
244 * status flag bits as well. See required_flags() in abi-arm.h for an example.
246 using Vflags
= uint8_t;
248 ///////////////////////////////////////////////////////////////////////////////
251 * Information attached to an assertion in emitted code.
258 inline std::string
show(const Reason
&r
) {
259 return folly::sformat("{}:{}", r
.file
, r
.line
);