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 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : class AbstractCode;
17 : class Name;
18 : class SharedFunctionInfo;
19 : class String;
20 :
21 : #define LOG_EVENTS_AND_TAGS_LIST(V) \
22 : V(CODE_CREATION_EVENT, "code-creation") \
23 : V(CODE_DISABLE_OPT_EVENT, "code-disable-optimization") \
24 : V(CODE_MOVE_EVENT, "code-move") \
25 : V(CODE_DELETE_EVENT, "code-delete") \
26 : V(CODE_MOVING_GC, "code-moving-gc") \
27 : V(SHARED_FUNC_MOVE_EVENT, "sfi-move") \
28 : V(SNAPSHOT_CODE_NAME_EVENT, "snapshot-code-name") \
29 : V(TICK_EVENT, "tick") \
30 : V(REPEAT_META_EVENT, "repeat") \
31 : V(BUILTIN_TAG, "Builtin") \
32 : V(CALL_DEBUG_BREAK_TAG, "CallDebugBreak") \
33 : V(CALL_DEBUG_PREPARE_STEP_IN_TAG, "CallDebugPrepareStepIn") \
34 : V(CALL_INITIALIZE_TAG, "CallInitialize") \
35 : V(CALL_MEGAMORPHIC_TAG, "CallMegamorphic") \
36 : V(CALL_MISS_TAG, "CallMiss") \
37 : V(CALL_NORMAL_TAG, "CallNormal") \
38 : V(LOAD_INITIALIZE_TAG, "LoadInitialize") \
39 : V(LOAD_MEGAMORPHIC_TAG, "LoadMegamorphic") \
40 : V(STORE_INITIALIZE_TAG, "StoreInitialize") \
41 : V(STORE_GENERIC_TAG, "StoreGeneric") \
42 : V(STORE_MEGAMORPHIC_TAG, "StoreMegamorphic") \
43 : V(KEYED_CALL_DEBUG_BREAK_TAG, "KeyedCallDebugBreak") \
44 : V(KEYED_CALL_DEBUG_PREPARE_STEP_IN_TAG, "KeyedCallDebugPrepareStepIn") \
45 : V(KEYED_CALL_INITIALIZE_TAG, "KeyedCallInitialize") \
46 : V(KEYED_CALL_MEGAMORPHIC_TAG, "KeyedCallMegamorphic") \
47 : V(KEYED_CALL_MISS_TAG, "KeyedCallMiss") \
48 : V(KEYED_CALL_NORMAL_TAG, "KeyedCallNormal") \
49 : V(CALLBACK_TAG, "Callback") \
50 : V(EVAL_TAG, "Eval") \
51 : V(FUNCTION_TAG, "Function") \
52 : V(HANDLER_TAG, "Handler") \
53 : V(BYTECODE_HANDLER_TAG, "BytecodeHandler") \
54 : V(KEYED_LOAD_IC_TAG, "KeyedLoadIC") \
55 : V(KEYED_LOAD_POLYMORPHIC_IC_TAG, "KeyedLoadPolymorphicIC") \
56 : V(KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG, "KeyedExternalArrayLoadIC") \
57 : V(KEYED_STORE_IC_TAG, "KeyedStoreIC") \
58 : V(KEYED_STORE_POLYMORPHIC_IC_TAG, "KeyedStorePolymorphicIC") \
59 : V(KEYED_EXTERNAL_ARRAY_STORE_IC_TAG, "KeyedExternalArrayStoreIC") \
60 : V(LAZY_COMPILE_TAG, "LazyCompile") \
61 : V(CALL_IC_TAG, "CallIC") \
62 : V(LOAD_IC_TAG, "LoadIC") \
63 : V(LOAD_GLOBAL_IC_TAG, "LoadGlobalIC") \
64 : V(LOAD_POLYMORPHIC_IC_TAG, "LoadPolymorphicIC") \
65 : V(REG_EXP_TAG, "RegExp") \
66 : V(SCRIPT_TAG, "Script") \
67 : V(STORE_IC_TAG, "StoreIC") \
68 : V(STORE_GLOBAL_IC_TAG, "StoreGlobalIC") \
69 : V(STORE_POLYMORPHIC_IC_TAG, "StorePolymorphicIC") \
70 : V(STUB_TAG, "Stub") \
71 : V(NATIVE_FUNCTION_TAG, "Function") \
72 : V(NATIVE_LAZY_COMPILE_TAG, "LazyCompile") \
73 : V(NATIVE_SCRIPT_TAG, "Script")
74 : // Note that 'NATIVE_' cases for functions and scripts are mapped onto
75 : // original tags when writing to the log.
76 :
77 : #define PROFILE(the_isolate, Call) (the_isolate)->code_event_dispatcher()->Call;
78 :
79 61405 : class CodeEventListener {
80 : public:
81 : #define DECLARE_ENUM(enum_item, _) enum_item,
82 : enum LogEventsAndTags {
83 : LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM) NUMBER_OF_LOG_EVENTS
84 : };
85 : #undef DECLARE_ENUM
86 :
87 59888 : virtual ~CodeEventListener() {}
88 :
89 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
90 : const char* comment) = 0;
91 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
92 : Name* name) = 0;
93 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
94 : SharedFunctionInfo* shared, Name* source) = 0;
95 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
96 : SharedFunctionInfo* shared, Name* source,
97 : int line, int column) = 0;
98 : virtual void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
99 : int args_count) = 0;
100 : virtual void CallbackEvent(Name* name, Address entry_point) = 0;
101 : virtual void GetterCallbackEvent(Name* name, Address entry_point) = 0;
102 : virtual void SetterCallbackEvent(Name* name, Address entry_point) = 0;
103 : virtual void RegExpCodeCreateEvent(AbstractCode* code, String* source) = 0;
104 : virtual void CodeMoveEvent(AbstractCode* from, Address to) = 0;
105 : virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
106 : virtual void CodeMovingGCEvent() = 0;
107 : virtual void CodeDisableOptEvent(AbstractCode* code,
108 : SharedFunctionInfo* shared) = 0;
109 : enum DeoptKind { kSoft, kLazy, kEager };
110 : virtual void CodeDeoptEvent(Code* code, DeoptKind kind, Address pc,
111 : int fp_to_sp_delta) = 0;
112 : };
113 :
114 118570 : class CodeEventDispatcher {
115 : public:
116 : using LogEventsAndTags = CodeEventListener::LogEventsAndTags;
117 :
118 121564 : CodeEventDispatcher() {}
119 :
120 653 : bool AddListener(CodeEventListener* listener) {
121 653 : base::LockGuard<base::Mutex> guard(&mutex_);
122 1306 : return listeners_.insert(listener).second;
123 : }
124 861 : void RemoveListener(CodeEventListener* listener) {
125 861 : base::LockGuard<base::Mutex> guard(&mutex_);
126 : listeners_.erase(listener);
127 861 : }
128 :
129 : #define CODE_EVENT_DISPATCH(code) \
130 : base::LockGuard<base::Mutex> guard(&mutex_); \
131 : for (auto it = listeners_.begin(); it != listeners_.end(); ++it) (*it)->code
132 :
133 400224 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
134 : const char* comment) {
135 1268740 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, comment));
136 400224 : }
137 38698 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, Name* name) {
138 116094 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, name));
139 38698 : }
140 1491876 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
141 : SharedFunctionInfo* shared, Name* name) {
142 4626551 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, shared, name));
143 1491881 : }
144 4051 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
145 : SharedFunctionInfo* shared, Name* source, int line,
146 : int column) {
147 20313 : CODE_EVENT_DISPATCH(
148 8160 : CodeCreateEvent(tag, code, shared, source, line, column));
149 4051 : }
150 : void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
151 : int args_count) {
152 : CODE_EVENT_DISPATCH(CodeCreateEvent(tag, code, args_count));
153 : }
154 7340 : void CallbackEvent(Name* name, Address entry_point) {
155 29360 : CODE_EVENT_DISPATCH(CallbackEvent(name, entry_point));
156 7340 : }
157 17796 : void GetterCallbackEvent(Name* name, Address entry_point) {
158 71184 : CODE_EVENT_DISPATCH(GetterCallbackEvent(name, entry_point));
159 17796 : }
160 17790 : void SetterCallbackEvent(Name* name, Address entry_point) {
161 71160 : CODE_EVENT_DISPATCH(SetterCallbackEvent(name, entry_point));
162 17790 : }
163 92258 : void RegExpCodeCreateEvent(AbstractCode* code, String* source) {
164 276774 : CODE_EVENT_DISPATCH(RegExpCodeCreateEvent(code, source));
165 92258 : }
166 238 : void CodeMoveEvent(AbstractCode* from, Address to) {
167 952 : CODE_EVENT_DISPATCH(CodeMoveEvent(from, to));
168 238 : }
169 : void SharedFunctionInfoMoveEvent(Address from, Address to) {
170 : CODE_EVENT_DISPATCH(SharedFunctionInfoMoveEvent(from, to));
171 : }
172 213582 : void CodeMovingGCEvent() { CODE_EVENT_DISPATCH(CodeMovingGCEvent()); }
173 57075 : void CodeDisableOptEvent(AbstractCode* code, SharedFunctionInfo* shared) {
174 171251 : CODE_EVENT_DISPATCH(CodeDisableOptEvent(code, shared));
175 57075 : }
176 124580 : void CodeDeoptEvent(Code* code, CodeEventListener::DeoptKind kind, Address pc,
177 : int fp_to_sp_delta) {
178 373781 : CODE_EVENT_DISPATCH(CodeDeoptEvent(code, kind, pc, fp_to_sp_delta));
179 124580 : }
180 : #undef CODE_EVENT_DISPATCH
181 :
182 : private:
183 : std::unordered_set<CodeEventListener*> listeners_;
184 : base::Mutex mutex_;
185 :
186 : DISALLOW_COPY_AND_ASSIGN(CodeEventDispatcher);
187 : };
188 :
189 : } // namespace internal
190 : } // namespace v8
191 :
192 : #endif // V8_CODE_EVENTS_H_
|