Refactor back ends into implementations of BackEnd.
[hiphop-php.git] / hphp / runtime / vm / jit / service-requests.h
blobb095040bc6beaaa956999fdf481aab4d3f76fc0f
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_RUNTIME_VM_SERVICE_REQUESTS_H_
17 #define incl_HPHP_RUNTIME_VM_SERVICE_REQUESTS_H_
19 #include "hphp/runtime/base/smart-containers.h"
20 #include "hphp/runtime/vm/jit/translator-inline.h"
21 #include "hphp/runtime/vm/jit/types.h"
22 #include "hphp/runtime/vm/srckey.h"
23 #include "hphp/util/asm-x64.h"
25 namespace HPHP { namespace JIT {
27 #define SERVICE_REQUESTS \
29 * Return from this nested VM invocation to the previous invocation.
30 * (Ending the program if there is no previous invocation.)
31 */ \
32 REQ(EXIT) \
35 * BIND_* all are requests for the first time a call, jump, or
36 * whatever is needed. This generally involves translating new code
37 * and then patching an address supplied as a service request
38 * argument.
39 */ \
40 REQ(BIND_CALL) \
41 REQ(BIND_JMP) \
42 REQ(BIND_JCC) \
43 REQ(BIND_ADDR) \
44 REQ(BIND_SIDE_EXIT) \
45 REQ(BIND_JMPCC_FIRST) \
46 REQ(BIND_JMPCC_SECOND) \
49 * When all translations don't support the incoming types, a
50 * retranslate request is made.
51 */ \
52 REQ(RETRANSLATE) \
55 * When PGO is enabled, this retranslates previous translations leveraging
56 * profiling data.
57 */ \
58 REQ(RETRANSLATE_OPT) \
61 * If the max translations is reached for a SrcKey, the last
62 * translation in the chain will jump to an interpret request stub.
63 * This instructs enterTC to punt to the interpreter.
64 */ \
65 REQ(INTERPRET) \
68 * When the interpreter pushes an ActRec, the return address for
69 * this ActRec will be set to a stub that raises POST_INTERP_RET,
70 * since it doesn't have a TCA to return to.
72 * This request is raised in the case that translated machine code
73 * executes the RetC for a frame that was pushed by the interpreter.
74 */ \
75 REQ(POST_INTERP_RET) \
78 * Raised when the execution stack overflowed.
79 */ \
80 REQ(STACK_OVERFLOW) \
83 * Resume restarts execution at the current PC. This is used after
84 * an interpOne of an instruction that changes the PC, and in some
85 * cases with FCall.
86 */ \
87 REQ(RESUME)
89 enum ServiceRequest {
90 #define REQ(nm) REQ_##nm,
91 SERVICE_REQUESTS
92 #undef REQ
95 // ID to name mapping for tracing.
96 inline const char* serviceReqName(int req) {
97 static const char* reqNames[] = {
98 #define REQ(nm) #nm,
99 SERVICE_REQUESTS
100 #undef REQ
102 return reqNames[req];
105 #undef SERVICE_REQUESTS
108 * Various flags that are passed to emitServiceReq. May be or'd
109 * together.
111 enum class SRFlags {
112 None = 0,
115 * Indicates the service request should be aligned.
117 Align = 1 << 0,
120 * For some service requests (returning from interpreted frames),
121 * using a ret instruction to get back to enterTCHelper will
122 * unbalance the return stack buffer---in these cases use a jmp.
124 JmpInsteadOfRet = 1 << 1,
127 inline bool operator&(SRFlags a, SRFlags b) {
128 return int(a) & int(b);
131 inline SRFlags operator|(SRFlags a, SRFlags b) {
132 return SRFlags(int(a) | int(b));
136 * Req machinery. We sometimes emit code that is unable to proceed
137 * without translator assistance; e.g., a basic block whose successor is
138 * unknown. We leave one of these request arg blobs in m_data, and point
139 * to it at callout-time.
142 // REQ_BIND_CALL
143 struct ReqBindCall {
144 SrcKey m_sourceInstr;
145 JIT::TCA m_toSmash;
146 int m_nArgs;
147 bool m_isImmutable; // call was to known func.
151 struct ServiceReqArgInfo {
152 enum {
153 Immediate,
154 CondCode,
155 } m_kind;
156 union {
157 uint64_t m_imm;
158 JIT::ConditionCode m_cc;
162 typedef smart::vector<ServiceReqArgInfo> ServiceReqArgVec;
166 #endif