Reland D23318594 and D23318592 add recordbasenativesp instr
[hiphop-php.git] / hphp / runtime / vm / event-hook.h
blob5ef830051dc3fe9b7d2a219ab7b720154a5072ff
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 +----------------------------------------------------------------------+
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"
27 #include <atomic>
29 namespace HPHP {
31 //////////////////////////////////////////////////////////////////////
33 /**
34 * Event hooks.
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
42 struct EventHook {
43 enum {
44 NormalFunc,
45 Eval,
47 enum {
48 ProfileEnters = 1,
49 ProfileExits = 2,
50 ProfileDefault = 3,
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,
60 static void Enable();
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();
71 /**
72 * Event hooks -- interpreter entry points.
74 static inline bool FunctionCall(const ActRec* ar, int funcType) {
75 ringbufferEnter(ar);
76 return UNLIKELY(checkSurpriseFlags())
77 ? onFunctionCall(ar, funcType) : true;
79 static inline void FunctionResumeAwait(const ActRec* ar) {
80 ringbufferEnter(ar);
81 if (UNLIKELY(checkSurpriseFlags())) { onFunctionResumeAwait(ar); }
83 static inline void FunctionResumeYield(const ActRec* ar) {
84 ringbufferEnter(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) {
120 ringbufferExit(ar);
121 if (UNLIKELY(checkSurpriseFlags())) { onFunctionReturn(ar, retval); }
123 static inline void FunctionUnwind(ActRec* ar, ObjectData* phpException) {
124 ringbufferExit(ar);
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);
139 private:
140 enum {
141 ProfileEnter,
142 ProfileExit,
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,
157 int funcType);
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 //////////////////////////////////////////////////////////////////////
177 #endif