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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_VM_EVENT_HOOK_H_
17 #define incl_HPHP_VM_EVENT_HOOK_H_
19 #include "hphp/runtime/base/execution-context.h"
20 #include "hphp/runtime/base/rds-header.h"
21 #include "hphp/runtime/base/rds.h"
22 #include "hphp/runtime/base/surprise-flags.h"
23 #include "hphp/runtime/vm/act-rec.h"
25 #include "hphp/util/ringbuffer.h"
31 //////////////////////////////////////////////////////////////////////
36 * All hooks can throw because of multiple possible reasons, such as:
37 * - user-defined signal handlers
38 * - pending destructor exceptions
39 * - pending out of memory exceptions
40 * - pending timeout exceptions
51 ProfileFramePointers
= 4,
52 ProfileConstructors
= 8,
53 ProfileResumeAware
= 16,
54 /* This flag enables access to $this when profiling instance methods. It
55 * is used for internal profiling tools. It *may break* in the future. */
56 ProfileThisObject
= 32,
61 static void Disable();
62 static void EnableAsync();
63 static void DisableAsync();
64 static void EnableDebug();
65 static void DisableDebug();
66 static void EnableIntercept();
67 static void DisableIntercept();
69 static void DoMemoryThresholdCallback();
72 * Event hooks -- interpreter entry points.
74 static inline bool FunctionCall(const ActRec
* ar
, int funcType
) {
76 return UNLIKELY(checkSurpriseFlags())
77 ? onFunctionCall(ar
, funcType
) : true;
79 static inline void FunctionResumeAwait(const ActRec
* ar
) {
81 if (UNLIKELY(checkSurpriseFlags())) { onFunctionResumeAwait(ar
); }
83 static inline void FunctionResumeYield(const ActRec
* ar
) {
85 if (UNLIKELY(checkSurpriseFlags())) { onFunctionResumeYield(ar
); }
87 static void FunctionSuspendAwaitEF(ActRec
* suspending
,
88 const ActRec
* resumableAR
) {
89 ringbufferExit(resumableAR
);
90 if (UNLIKELY(checkSurpriseFlags())) {
91 onFunctionSuspendAwaitEF(suspending
, resumableAR
);
94 static void FunctionSuspendAwaitEG(ActRec
* suspending
) {
95 ringbufferExit(suspending
);
96 if (UNLIKELY(checkSurpriseFlags())) {
97 onFunctionSuspendAwaitEG(suspending
);
100 static void FunctionSuspendAwaitR(ActRec
* suspending
, ObjectData
* child
) {
101 ringbufferExit(suspending
);
102 if (UNLIKELY(checkSurpriseFlags())) {
103 onFunctionSuspendAwaitR(suspending
, child
);
106 static void FunctionSuspendCreateCont(ActRec
* suspending
,
107 const ActRec
* resumableAR
) {
108 ringbufferExit(resumableAR
);
109 if (UNLIKELY(checkSurpriseFlags())) {
110 onFunctionSuspendCreateCont(suspending
, resumableAR
);
113 static void FunctionSuspendYield(ActRec
* suspending
) {
114 ringbufferExit(suspending
);
115 if (UNLIKELY(checkSurpriseFlags())) {
116 onFunctionSuspendYield(suspending
);
119 static inline void FunctionReturn(ActRec
* ar
, TypedValue retval
) {
121 if (UNLIKELY(checkSurpriseFlags())) { onFunctionReturn(ar
, retval
); }
123 static inline void FunctionUnwind(ActRec
* ar
, ObjectData
* phpException
) {
125 if (UNLIKELY(checkSurpriseFlags())) { onFunctionUnwind(ar
, phpException
); }
129 * Event hooks -- JIT entry points.
131 static bool onFunctionCall(const ActRec
* ar
, int funcType
);
132 static void onFunctionSuspendAwaitEF(ActRec
*, const ActRec
*);
133 static void onFunctionSuspendAwaitEG(ActRec
*);
134 static void onFunctionSuspendAwaitR(ActRec
*, ObjectData
*);
135 static void onFunctionSuspendCreateCont(ActRec
*, const ActRec
*);
136 static void onFunctionSuspendYield(ActRec
*);
137 static void onFunctionReturn(ActRec
* ar
, TypedValue retval
);
145 static void onFunctionResumeAwait(const ActRec
* ar
);
146 static void onFunctionResumeYield(const ActRec
* ar
);
147 static void onFunctionUnwind(ActRec
* ar
, ObjectData
* phpException
);
149 static void onFunctionEnter(const ActRec
* ar
, int funcType
,
150 ssize_t flags
, bool isResume
);
151 static void onFunctionExit(const ActRec
* ar
, const TypedValue
* retval
,
152 bool unwind
, ObjectData
* phpException
,
153 size_t flags
, bool isSuspend
);
155 static bool RunInterceptHandler(ActRec
* ar
);
156 static const char* GetFunctionNameForProfiler(const Func
* func
,
159 static inline void ringbufferEnter(const ActRec
* ar
) {
160 if (Trace::moduleEnabled(Trace::ringbuffer
, 1)) {
161 auto name
= ar
->func()->fullName();
162 Trace::ringbufferMsg(name
->data(), name
->size(), Trace::RBTypeFuncEntry
);
165 static inline void ringbufferExit(const ActRec
* ar
) {
166 if (Trace::moduleEnabled(Trace::ringbuffer
, 1)) {
167 auto name
= ar
->func()->fullName();
168 Trace::ringbufferMsg(name
->data(), name
->size(), Trace::RBTypeFuncExit
);
173 //////////////////////////////////////////////////////////////////////