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 63768 : 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 63754 : 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 124814 : class CodeEventDispatcher {
102 : public:
103 : using LogEventsAndTags = CodeEventListener::LogEventsAndTags;
104 :
105 62422 : CodeEventDispatcher() = default;
106 :
107 1408 : bool AddListener(CodeEventListener* listener) {
108 1408 : base::MutexGuard guard(&mutex_);
109 2816 : return listeners_.insert(listener).second;
110 : }
111 1344 : void RemoveListener(CodeEventListener* listener) {
112 1344 : base::MutexGuard guard(&mutex_);
113 : listeners_.erase(listener);
114 1344 : }
115 : bool IsListeningToCodeEvents() {
116 2554194 : for (auto it : listeners_) {
117 42 : 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 148371 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
129 : const char* comment) {
130 333393 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, comment));
131 148371 : }
132 4 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code, Name name) {
133 12 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, name));
134 4 : }
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 604354 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode code,
140 : SharedFunctionInfo shared, Name source, int line,
141 : int column) {
142 2417430 : CODE_EVENT_DISPATCH(
143 1208722 : CodeCreateEvent(tag, code, shared, source, line, column));
144 604354 : }
145 11 : void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
146 : wasm::WasmName name) {
147 33 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, name));
148 11 : }
149 16337 : void CallbackEvent(Name name, Address entry_point) {
150 48759 : CODE_EVENT_DISPATCH(CallbackEvent(name, entry_point));
151 16337 : }
152 9068 : void GetterCallbackEvent(Name name, Address entry_point) {
153 27314 : CODE_EVENT_DISPATCH(GetterCallbackEvent(name, entry_point));
154 9068 : }
155 9063 : void SetterCallbackEvent(Name name, Address entry_point) {
156 27299 : CODE_EVENT_DISPATCH(SetterCallbackEvent(name, entry_point));
157 9063 : }
158 82173 : void RegExpCodeCreateEvent(AbstractCode code, String source) {
159 164346 : CODE_EVENT_DISPATCH(RegExpCodeCreateEvent(code, source));
160 82173 : }
161 276 : void CodeMoveEvent(AbstractCode from, AbstractCode to) {
162 750 : CODE_EVENT_DISPATCH(CodeMoveEvent(from, to));
163 276 : }
164 : void SharedFunctionInfoMoveEvent(Address from, Address to) {
165 : CODE_EVENT_DISPATCH(SharedFunctionInfoMoveEvent(from, to));
166 : }
167 206848 : void CodeMovingGCEvent() { CODE_EVENT_DISPATCH(CodeMovingGCEvent()); }
168 20881 : void CodeDisableOptEvent(AbstractCode code, SharedFunctionInfo shared) {
169 41773 : CODE_EVENT_DISPATCH(CodeDisableOptEvent(code, shared));
170 20881 : }
171 53080 : void CodeDeoptEvent(Code code, DeoptimizeKind kind, Address pc,
172 : int fp_to_sp_delta) {
173 106172 : CODE_EVENT_DISPATCH(CodeDeoptEvent(code, kind, pc, fp_to_sp_delta));
174 53080 : }
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_
|