Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_CODE_EVENTS_H_
6 : #define V8_CODE_EVENTS_H_
7 :
8 : #include <unordered_set>
9 :
10 : #include "src/base/platform/mutex.h"
11 : #include "src/globals.h"
12 : #include "src/objects/code.h"
13 : #include "src/objects/name.h"
14 : #include "src/objects/shared-function-info.h"
15 : #include "src/objects/string.h"
16 : #include "src/vector.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 : class AbstractCode;
22 : class Name;
23 : class SharedFunctionInfo;
24 : class String;
25 :
26 : namespace wasm {
27 : class WasmCode;
28 : using WasmName = Vector<const char>;
29 : } // namespace wasm
30 :
31 : #define LOG_EVENTS_LIST(V) \
32 : V(CODE_CREATION_EVENT, code-creation) \
33 : V(CODE_DISABLE_OPT_EVENT, code-disable-optimization) \
34 : V(CODE_MOVE_EVENT, code-move) \
35 : V(CODE_DELETE_EVENT, code-delete) \
36 : V(CODE_MOVING_GC, code-moving-gc) \
37 : V(SHARED_FUNC_MOVE_EVENT, sfi-move) \
38 : V(SNAPSHOT_CODE_NAME_EVENT, snapshot-code-name) \
39 : V(TICK_EVENT, tick)
40 :
41 : #define TAGS_LIST(V) \
42 : V(BUILTIN_TAG, Builtin) \
43 : V(CALLBACK_TAG, Callback) \
44 : V(EVAL_TAG, Eval) \
45 : V(FUNCTION_TAG, Function) \
46 : V(INTERPRETED_FUNCTION_TAG, InterpretedFunction) \
47 : V(HANDLER_TAG, Handler) \
48 : V(BYTECODE_HANDLER_TAG, BytecodeHandler) \
49 : V(LAZY_COMPILE_TAG, LazyCompile) \
50 : V(REG_EXP_TAG, RegExp) \
51 : V(SCRIPT_TAG, Script) \
52 : V(STUB_TAG, Stub) \
53 : V(NATIVE_FUNCTION_TAG, Function) \
54 : V(NATIVE_LAZY_COMPILE_TAG, LazyCompile) \
55 : V(NATIVE_SCRIPT_TAG, Script)
56 : // Note that 'NATIVE_' cases for functions and scripts are mapped onto
57 : // original tags when writing to the log.
58 :
59 : #define LOG_EVENTS_AND_TAGS_LIST(V) \
60 : LOG_EVENTS_LIST(V) \
61 : TAGS_LIST(V)
62 :
63 : #define PROFILE(the_isolate, Call) (the_isolate)->code_event_dispatcher()->Call;
64 :
65 64192 : class CodeEventListener {
66 : public:
67 : #define DECLARE_ENUM(enum_item, _) enum_item,
68 : enum LogEventsAndTags {
69 : LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM) NUMBER_OF_LOG_EVENTS
70 : };
71 : #undef DECLARE_ENUM
72 :
73 64177 : virtual ~CodeEventListener() = default;
74 :
75 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
76 : const char* comment) = 0;
77 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
78 : Name name) = 0;
79 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
80 : SharedFunctionInfo shared, Name source) = 0;
81 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
82 : SharedFunctionInfo shared, Name source, int line,
83 : int column) = 0;
84 : virtual void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
85 : wasm::WasmName name) = 0;
86 : virtual void CallbackEvent(Name name, Address entry_point) = 0;
87 : virtual void GetterCallbackEvent(Name name, Address entry_point) = 0;
88 : virtual void SetterCallbackEvent(Name name, Address entry_point) = 0;
89 : virtual void RegExpCodeCreateEvent(AbstractCode code, String source) = 0;
90 : virtual void CodeMoveEvent(AbstractCode from, AbstractCode to) = 0;
91 : virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
92 : virtual void CodeMovingGCEvent() = 0;
93 : virtual void CodeDisableOptEvent(AbstractCode code,
94 : SharedFunctionInfo shared) = 0;
95 : virtual void CodeDeoptEvent(Code code, DeoptimizeKind kind, Address pc,
96 : int fp_to_sp_delta) = 0;
97 :
98 0 : virtual bool is_listening_to_code_events() { return false; }
99 : };
100 :
101 125736 : class CodeEventDispatcher {
102 : public:
103 : using LogEventsAndTags = CodeEventListener::LogEventsAndTags;
104 :
105 125766 : CodeEventDispatcher() = default;
106 :
107 1361 : bool AddListener(CodeEventListener* listener) {
108 1361 : base::MutexGuard guard(&mutex_);
109 2722 : return listeners_.insert(listener).second;
110 : }
111 1295 : void RemoveListener(CodeEventListener* listener) {
112 1295 : base::MutexGuard guard(&mutex_);
113 : listeners_.erase(listener);
114 1295 : }
115 : bool IsListeningToCodeEvents() {
116 2540659 : for (auto it : listeners_) {
117 44 : if (it->is_listening_to_code_events()) {
118 : return true;
119 : }
120 : }
121 : return false;
122 : }
123 :
124 : #define CODE_EVENT_DISPATCH(code) \
125 : base::MutexGuard guard(&mutex_); \
126 : for (auto it = listeners_.begin(); it != listeners_.end(); ++it) (*it)->code
127 :
128 147391 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
129 : const char* comment) {
130 478404 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, comment));
131 147391 : }
132 0 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code, Name name) {
133 0 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, name));
134 0 : }
135 0 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
136 : SharedFunctionInfo shared, Name name) {
137 0 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, shared, name));
138 0 : }
139 603944 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
140 : SharedFunctionInfo shared, Name source, int line,
141 : int column) {
142 3019748 : CODE_EVENT_DISPATCH(
143 1207916 : CodeCreateEvent(tag, code, shared, source, line, column));
144 603944 : }
145 0 : void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
146 : wasm::WasmName name) {
147 0 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, name));
148 0 : }
149 18767 : void CallbackEvent(Name name, Address entry_point) {
150 75068 : CODE_EVENT_DISPATCH(CallbackEvent(name, entry_point));
151 18767 : }
152 8843 : void GetterCallbackEvent(Name name, Address entry_point) {
153 35427 : CODE_EVENT_DISPATCH(GetterCallbackEvent(name, entry_point));
154 8843 : }
155 8838 : void SetterCallbackEvent(Name name, Address entry_point) {
156 35407 : CODE_EVENT_DISPATCH(SetterCallbackEvent(name, entry_point));
157 8838 : }
158 85333 : void RegExpCodeCreateEvent(AbstractCode code, String source) {
159 255999 : CODE_EVENT_DISPATCH(RegExpCodeCreateEvent(code, source));
160 85333 : }
161 208 : void CodeMoveEvent(AbstractCode from, AbstractCode to) {
162 795 : CODE_EVENT_DISPATCH(CodeMoveEvent(from, to));
163 208 : }
164 : void SharedFunctionInfoMoveEvent(Address from, Address to) {
165 : CODE_EVENT_DISPATCH(SharedFunctionInfoMoveEvent(from, to));
166 : }
167 334219 : void CodeMovingGCEvent() { CODE_EVENT_DISPATCH(CodeMovingGCEvent()); }
168 20123 : void CodeDisableOptEvent(AbstractCode code, SharedFunctionInfo shared) {
169 60380 : CODE_EVENT_DISPATCH(CodeDisableOptEvent(code, shared));
170 20123 : }
171 141231 : void CodeDeoptEvent(Code code, DeoptimizeKind kind, Address pc,
172 : int fp_to_sp_delta) {
173 423699 : CODE_EVENT_DISPATCH(CodeDeoptEvent(code, kind, pc, fp_to_sp_delta));
174 141231 : }
175 : #undef CODE_EVENT_DISPATCH
176 :
177 : private:
178 : std::unordered_set<CodeEventListener*> listeners_;
179 : base::Mutex mutex_;
180 :
181 : DISALLOW_COPY_AND_ASSIGN(CodeEventDispatcher);
182 : };
183 :
184 : } // namespace internal
185 : } // namespace v8
186 :
187 : #endif // V8_CODE_EVENTS_H_
|