Use makePseudoMainExit in more places
[hiphop-php.git] / hphp / runtime / vm / event-hook.h
blob0017a7d2234228246de1bfb493db2f22cd467092
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_VM_EVENT_HOOK_H_
17 #define incl_HPHP_VM_EVENT_HOOK_H_
19 #include "hphp/util/ringbuffer.h"
20 #include "hphp/runtime/base/execution-context.h"
21 #include "hphp/runtime/vm/bytecode.h"
22 #include "hphp/runtime/base/rds.h"
23 #include "hphp/runtime/base/rds-header.h"
25 #include <atomic>
27 namespace HPHP {
29 //////////////////////////////////////////////////////////////////////
31 inline bool checkConditionFlags() {
32 return RDS::header()->conditionFlags.load(std::memory_order_acquire);
35 //////////////////////////////////////////////////////////////////////
37 /**
38 * Event hooks.
40 * All hooks can throw because of multiple possible reasons, such as:
41 * - user-defined signal handlers
42 * - pending destructor exceptions
43 * - pending out of memory exceptions
44 * - pending timeout exceptions
46 class EventHook {
47 public:
48 enum {
49 NormalFunc,
50 PseudoMain,
51 Eval,
54 static void Enable();
55 static void Disable();
56 static void EnableAsync();
57 static void DisableAsync();
58 static void EnableIntercept();
59 static void DisableIntercept();
60 static ssize_t CheckSurprise();
61 static ssize_t GetConditionFlags();
63 /**
64 * Event hooks -- interpreter entry points.
66 static inline bool FunctionCall(const ActRec* ar, int funcType) {
67 ringbufferEnter(ar);
68 return UNLIKELY(checkConditionFlags())
69 ? onFunctionCall(ar, funcType) : true;
71 static inline void FunctionResume(const ActRec* ar) {
72 ringbufferEnter(ar);
73 if (UNLIKELY(checkConditionFlags())) { onFunctionResume(ar); }
75 static inline void FunctionSuspend(const ActRec* ar, bool suspendingResumed) {
76 ringbufferExit(ar);
77 if (UNLIKELY(checkConditionFlags())) {
78 onFunctionSuspend(ar, suspendingResumed);
81 static inline void FunctionReturn(ActRec* ar, const TypedValue& retval) {
82 ringbufferExit(ar);
83 if (UNLIKELY(checkConditionFlags())) { onFunctionReturn(ar, retval); }
85 static inline void FunctionUnwind(const ActRec* ar, const Fault& fault) {
86 ringbufferExit(ar);
87 if (UNLIKELY(checkConditionFlags())) { onFunctionUnwind(ar, fault); }
90 /**
91 * Event hooks -- JIT entry points.
93 static bool onFunctionCall(const ActRec* ar, int funcType);
94 static void onFunctionSuspend(const ActRec* ar, bool suspendingResumed);
95 static void onFunctionReturnJit(ActRec* ar, const TypedValue retval) {
96 onFunctionReturn(ar, retval);
99 private:
100 enum {
101 ProfileEnter,
102 ProfileExit,
105 static void onFunctionResume(const ActRec* ar);
106 static void onFunctionReturn(ActRec* ar, const TypedValue& retval);
107 static void onFunctionUnwind(const ActRec* ar, const Fault& fault);
109 static void onFunctionEnter(const ActRec* ar, int funcType, ssize_t flags);
110 static void onFunctionExit(const ActRec* ar, const TypedValue* retval,
111 const Fault* fault, ssize_t flags);
113 static bool RunInterceptHandler(ActRec* ar);
114 static const char* GetFunctionNameForProfiler(const Func* func,
115 int funcType);
117 static inline void ringbufferEnter(const ActRec* ar) {
118 if (Trace::moduleEnabled(Trace::ringbuffer, 1)) {
119 auto name = ar->m_func->fullName();
120 Trace::ringbufferMsg(name->data(), name->size(), Trace::RBTypeFuncEntry);
123 static inline void ringbufferExit(const ActRec* ar) {
124 if (Trace::moduleEnabled(Trace::ringbuffer, 1)) {
125 auto name = ar->m_func->fullName();
126 Trace::ringbufferMsg(name->data(), name->size(), Trace::RBTypeFuncExit);
131 //////////////////////////////////////////////////////////////////////
135 #endif