Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 1 | // Copyright 2012 the V8 project authors. All rights reserved. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 4 | |
| 5 | #ifndef V8_LOG_H_ |
| 6 | #define V8_LOG_H_ |
| 7 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 8 | #include <string> |
| 9 | |
| 10 | #include "src/allocation.h" |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 11 | #include "src/base/compiler-specific.h" |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 12 | #include "src/base/platform/elapsed-timer.h" |
| 13 | #include "src/base/platform/platform.h" |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 14 | #include "src/code-events.h" |
| 15 | #include "src/isolate.h" |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 16 | #include "src/objects.h" |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 17 | |
| 18 | namespace v8 { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 19 | |
| 20 | namespace base { |
| 21 | class Semaphore; |
| 22 | } |
| 23 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 24 | namespace sampler { |
| 25 | class Sampler; |
| 26 | } |
| 27 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 28 | namespace internal { |
| 29 | |
| 30 | // Logger is used for collecting logging information from V8 during |
| 31 | // execution. The result is dumped to a file. |
| 32 | // |
| 33 | // Available command line flags: |
| 34 | // |
| 35 | // --log |
| 36 | // Minimal logging (no API, code, or GC sample events), default is off. |
| 37 | // |
| 38 | // --log-all |
| 39 | // Log all events to the file, default is off. This is the same as combining |
| 40 | // --log-api, --log-code, --log-gc, and --log-regexp. |
| 41 | // |
| 42 | // --log-api |
| 43 | // Log API events to the logfile, default is off. --log-api implies --log. |
| 44 | // |
| 45 | // --log-code |
| 46 | // Log code (create, move, and delete) events to the logfile, default is off. |
| 47 | // --log-code implies --log. |
| 48 | // |
| 49 | // --log-gc |
| 50 | // Log GC heap samples after each GC that can be processed by hp2ps, default |
| 51 | // is off. --log-gc implies --log. |
| 52 | // |
| 53 | // --log-regexp |
| 54 | // Log creation and use of regular expressions, Default is off. |
| 55 | // --log-regexp implies --log. |
| 56 | // |
| 57 | // --logfile <filename> |
| 58 | // Specify the name of the logfile, default is "v8.log". |
| 59 | // |
| 60 | // --prof |
| 61 | // Collect statistical profiling information (ticks), default is off. The |
| 62 | // tick profiler requires code events, so --prof implies --log-code. |
| 63 | |
| 64 | // Forward declarations. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 65 | class CodeEventListener; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 66 | class CpuProfiler; |
| 67 | class Isolate; |
| 68 | class Log; |
| 69 | class PositionsRecorder; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 70 | class Profiler; |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 71 | class Ticker; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 72 | struct TickSample; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 73 | class RuntimeCallTimer; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 74 | |
| 75 | #undef LOG |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 76 | #define LOG(isolate, Call) \ |
| 77 | do { \ |
| 78 | v8::internal::Logger* logger = (isolate)->logger(); \ |
| 79 | if (logger->is_logging()) logger->Call; \ |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 80 | } while (false) |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 81 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 82 | #define LOG_CODE_EVENT(isolate, Call) \ |
| 83 | do { \ |
| 84 | v8::internal::Logger* logger = (isolate)->logger(); \ |
| 85 | if (logger->is_logging_code_events()) logger->Call; \ |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 86 | } while (false) |
| 87 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 88 | class JitLogger; |
| 89 | class PerfBasicLogger; |
| 90 | class LowLevelLogger; |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 91 | class PerfJitLogger; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 92 | class ProfilerListener; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 93 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 94 | class Logger : public CodeEventListener { |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 95 | public: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 96 | enum StartEnd { START = 0, END = 1 }; |
| 97 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 98 | // Acquires resources for logging if the right flags are set. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 99 | bool SetUp(Isolate* isolate); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 100 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 101 | // Sets the current code event handler. |
| 102 | void SetCodeEventHandler(uint32_t options, |
| 103 | JitCodeEventHandler event_handler); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 104 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 105 | // Sets up ProfilerListener. |
| 106 | void SetUpProfilerListener(); |
| 107 | |
| 108 | // Tear down ProfilerListener if it has no observers. |
| 109 | void TearDownProfilerListener(); |
| 110 | |
| 111 | sampler::Sampler* sampler(); |
| 112 | |
| 113 | ProfilerListener* profiler_listener() { return profiler_listener_.get(); } |
Ben Murdoch | b0fe162 | 2011-05-05 13:52:32 +0100 | [diff] [blame] | 114 | |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 115 | // Frees resources acquired in SetUp. |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 116 | // When a temporary file is used for the log, returns its stream descriptor, |
| 117 | // leaving the file open. |
| 118 | FILE* TearDown(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 119 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 120 | // Emits an event with a string value -> (name, value). |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 121 | void StringEvent(const char* name, const char* value); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 122 | |
| 123 | // Emits an event with an int value -> (name, value). |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 124 | void IntEvent(const char* name, int value); |
| 125 | void IntPtrTEvent(const char* name, intptr_t value); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 126 | |
| 127 | // Emits an event with an handle value -> (name, location). |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 128 | void HandleEvent(const char* name, Object** location); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 129 | |
| 130 | // Emits memory management events for C allocated structures. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 131 | void NewEvent(const char* name, void* object, size_t size); |
| 132 | void DeleteEvent(const char* name, void* object); |
| 133 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 134 | // Emits an event with a tag, and some resource usage information. |
| 135 | // -> (name, tag, <rusage information>). |
| 136 | // Currently, the resource usage information is a process time stamp |
| 137 | // and a real time timestamp. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 138 | void ResourceEvent(const char* name, const char* tag); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 139 | |
| 140 | // Emits an event that an undefined property was read from an |
| 141 | // object. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 142 | void SuspectReadEvent(Name* name, Object* obj); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 143 | |
| 144 | // Emits an event when a message is put on or read from a debugging queue. |
| 145 | // DebugTag lets us put a call-site specific label on the event. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 146 | void DebugTag(const char* call_site_tag); |
| 147 | void DebugEvent(const char* event_type, Vector<uint16_t> parameter); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 148 | |
| 149 | |
| 150 | // ==== Events logged by --log-api. ==== |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 151 | void ApiSecurityCheck(); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 152 | void ApiNamedPropertyAccess(const char* tag, JSObject* holder, Object* name); |
| 153 | void ApiIndexedPropertyAccess(const char* tag, |
| 154 | JSObject* holder, |
| 155 | uint32_t index); |
| 156 | void ApiObjectAccess(const char* tag, JSObject* obj); |
| 157 | void ApiEntryCall(const char* name); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 158 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 159 | // ==== Events logged by --log-code. ==== |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 160 | void addCodeEventListener(CodeEventListener* listener); |
| 161 | void removeCodeEventListener(CodeEventListener* listener); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 162 | |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 163 | // Emits a code event for a callback function. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 164 | void CallbackEvent(Name* name, Address entry_point); |
| 165 | void GetterCallbackEvent(Name* name, Address entry_point); |
| 166 | void SetterCallbackEvent(Name* name, Address entry_point); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 167 | // Emits a code create event. |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 168 | void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
| 169 | AbstractCode* code, const char* source); |
| 170 | void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
| 171 | AbstractCode* code, Name* name); |
| 172 | void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
| 173 | AbstractCode* code, SharedFunctionInfo* shared, |
| 174 | Name* name); |
| 175 | void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
| 176 | AbstractCode* code, SharedFunctionInfo* shared, |
| 177 | Name* source, int line, int column); |
| 178 | void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, |
| 179 | AbstractCode* code, int args_count); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 180 | // Emits a code deoptimization event. |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 181 | void CodeDisableOptEvent(AbstractCode* code, SharedFunctionInfo* shared); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 182 | void CodeMovingGCEvent(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 183 | // Emits a code create event for a RegExp. |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 184 | void RegExpCodeCreateEvent(AbstractCode* code, String* source); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 185 | // Emits a code move event. |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 186 | void CodeMoveEvent(AbstractCode* from, Address to); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 187 | // Emits a code line info add event with Postion type. |
| 188 | void CodeLinePosInfoAddPositionEvent(void* jit_handler_data, |
| 189 | int pc_offset, |
| 190 | int position); |
| 191 | // Emits a code line info add event with StatementPostion type. |
| 192 | void CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data, |
| 193 | int pc_offset, |
| 194 | int position); |
| 195 | // Emits a code line info start to record event |
| 196 | void CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder); |
| 197 | // Emits a code line info finish record event. |
| 198 | // It's the callee's responsibility to dispose the parameter jit_handler_data. |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 199 | void CodeEndLinePosInfoRecordEvent(AbstractCode* code, |
| 200 | void* jit_handler_data); |
Ben Murdoch | e0cee9b | 2011-05-25 10:26:03 +0100 | [diff] [blame] | 201 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 202 | void SharedFunctionInfoMoveEvent(Address from, Address to); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 203 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 204 | void CodeNameEvent(Address addr, int pos, const char* code_name); |
Leon Clarke | e46be81 | 2010-01-19 14:06:41 +0000 | [diff] [blame] | 205 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 206 | void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta); |
| 207 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 208 | // ==== Events logged by --log-gc. ==== |
| 209 | // Heap sampling events: start, end, and individual types. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 210 | void HeapSampleBeginEvent(const char* space, const char* kind); |
| 211 | void HeapSampleEndEvent(const char* space, const char* kind); |
| 212 | void HeapSampleItemEvent(const char* type, int number, int bytes); |
| 213 | void HeapSampleJSConstructorEvent(const char* constructor, |
| 214 | int number, int bytes); |
| 215 | void HeapSampleJSRetainersEvent(const char* constructor, |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 216 | const char* event); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 217 | void HeapSampleJSProducerEvent(const char* constructor, |
| 218 | Address* stack); |
| 219 | void HeapSampleStats(const char* space, const char* kind, |
| 220 | intptr_t capacity, intptr_t used); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 221 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 222 | void SharedLibraryEvent(const std::string& library_path, uintptr_t start, |
| 223 | uintptr_t end, intptr_t aslr_slide); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 224 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 225 | void CurrentTimeEvent(); |
| 226 | |
| 227 | void TimerEvent(StartEnd se, const char* name); |
| 228 | |
| 229 | static void EnterExternal(Isolate* isolate); |
| 230 | static void LeaveExternal(Isolate* isolate); |
| 231 | |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 232 | static void DefaultEventLoggerSentinel(const char* name, int event) {} |
| 233 | |
| 234 | INLINE(static void CallEventLogger(Isolate* isolate, const char* name, |
| 235 | StartEnd se, bool expose_to_api)); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 236 | |
| 237 | // ==== Events logged by --log-regexp ==== |
| 238 | // Regexp compilation and execution events. |
| 239 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 240 | void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 241 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 242 | bool is_logging() { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 243 | return is_logging_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 244 | } |
| 245 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 246 | bool is_logging_code_events() { |
| 247 | return is_logging() || jit_logger_ != NULL; |
| 248 | } |
| 249 | |
| 250 | // Stop collection of profiling data. |
| 251 | // When data collection is paused, CPU Tick events are discarded. |
| 252 | void StopProfiler(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 253 | |
Ben Murdoch | 589d697 | 2011-11-30 16:04:58 +0000 | [diff] [blame] | 254 | void LogExistingFunction(Handle<SharedFunctionInfo> shared, |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 255 | Handle<AbstractCode> code); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 256 | // Logs all compiled functions found in the heap. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 257 | void LogCompiledFunctions(); |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 258 | // Logs all accessor callbacks found in the heap. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 259 | void LogAccessorCallbacks(); |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 260 | // Used for logging stubs found in the snapshot. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 261 | void LogCodeObjects(); |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 262 | // Used for logging bytecode handlers found in the snapshot. |
| 263 | void LogBytecodeHandlers(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 264 | |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 265 | // Converts tag to a corresponding NATIVE_... if the script is native. |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 266 | INLINE(static CodeEventListener::LogEventsAndTags ToNativeByScript( |
| 267 | CodeEventListener::LogEventsAndTags, Script*)); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 268 | |
| 269 | // Profiler's sampling interval (in milliseconds). |
Ben Murdoch | 7549248 | 2011-12-01 11:18:12 +0000 | [diff] [blame] | 270 | #if defined(ANDROID) |
| 271 | // Phones and tablets have processors that are much slower than desktop |
| 272 | // and laptop computers for which current heuristics are tuned. |
| 273 | static const int kSamplingIntervalMs = 5; |
| 274 | #else |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 275 | static const int kSamplingIntervalMs = 1; |
Ben Murdoch | 7549248 | 2011-12-01 11:18:12 +0000 | [diff] [blame] | 276 | #endif |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 277 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 278 | // Callback from Log, stops profiling in case of insufficient resources. |
| 279 | void LogFailure(); |
| 280 | |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 281 | private: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 282 | explicit Logger(Isolate* isolate); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 283 | ~Logger(); |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 284 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 285 | // Emits the profiler's first message. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 286 | void ProfilerBeginEvent(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 287 | |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 288 | // Emits callback event messages. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 289 | void CallbackEventInternal(const char* prefix, |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 290 | Name* name, |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 291 | Address entry_point); |
Steve Block | d0582a6 | 2009-12-15 09:54:21 +0000 | [diff] [blame] | 292 | |
Leon Clarke | d91b9f7 | 2010-01-27 17:25:45 +0000 | [diff] [blame] | 293 | // Internal configurable move event. |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 294 | void MoveEventInternal(CodeEventListener::LogEventsAndTags event, |
| 295 | Address from, Address to); |
Leon Clarke | d91b9f7 | 2010-01-27 17:25:45 +0000 | [diff] [blame] | 296 | |
Andrei Popescu | 3100271 | 2010-02-23 13:46:05 +0000 | [diff] [blame] | 297 | // Used for logging stubs found in the snapshot. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 298 | void LogCodeObject(Object* code_object); |
Andrei Popescu | 3100271 | 2010-02-23 13:46:05 +0000 | [diff] [blame] | 299 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 300 | // Helper method. It resets name_buffer_ and add tag name into it. |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 301 | void InitNameBuffer(CodeEventListener::LogEventsAndTags tag); |
Ben Murdoch | f87a203 | 2010-10-22 12:50:53 +0100 | [diff] [blame] | 302 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 303 | // Emits a profiler tick event. Used by the profiler thread. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 304 | void TickEvent(TickSample* sample, bool overflow); |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 305 | void RuntimeCallTimerEvent(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 306 | |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 307 | PRINTF_FORMAT(2, 3) void ApiEvent(const char* format, ...); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 308 | |
| 309 | // Logs a StringEvent regardless of whether FLAG_log is true. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 310 | void UncheckedStringEvent(const char* name, const char* value); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 311 | |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 312 | // Logs an IntEvent regardless of whether FLAG_log is true. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 313 | void UncheckedIntEvent(const char* name, int value); |
| 314 | void UncheckedIntPtrTEvent(const char* name, intptr_t value); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 315 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 316 | Isolate* isolate_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 317 | |
| 318 | // The sampler used by the profiler and the sliding state window. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 319 | Ticker* ticker_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 320 | |
| 321 | // When the statistical profile is active, profiler_ |
| 322 | // points to a Profiler, that handles collection |
| 323 | // of samples. |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 324 | Profiler* profiler_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 325 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 326 | // An array of log events names. |
| 327 | const char* const* log_events_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 328 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 329 | // Internal implementation classes with access to |
| 330 | // private members. |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 331 | friend class EventLog; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 332 | friend class Isolate; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 333 | friend class TimeLog; |
| 334 | friend class Profiler; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 335 | template <StateTag Tag> friend class VMState; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 336 | friend class LoggerTestHelper; |
| 337 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 338 | bool is_logging_; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 339 | Log* log_; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 340 | PerfBasicLogger* perf_basic_logger_; |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 341 | PerfJitLogger* perf_jit_logger_; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 342 | LowLevelLogger* ll_logger_; |
| 343 | JitLogger* jit_logger_; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 344 | std::unique_ptr<ProfilerListener> profiler_listener_; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 345 | List<CodeEventListener*> listeners_; |
Ben Murdoch | 257744e | 2011-11-30 15:57:28 +0000 | [diff] [blame] | 346 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 347 | // Guards against multiple calls to TearDown() that can happen in some tests. |
Ben Murdoch | 3ef787d | 2012-04-12 10:51:47 +0100 | [diff] [blame] | 348 | // 'true' between SetUp() and TearDown(). |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 349 | bool is_initialized_; |
| 350 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 351 | base::ElapsedTimer timer_; |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 352 | |
| 353 | friend class CpuProfiler; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 354 | }; |
| 355 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 356 | #define TIMER_EVENTS_LIST(V) \ |
| 357 | V(RecompileSynchronous, true) \ |
| 358 | V(RecompileConcurrent, true) \ |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 359 | V(CompileIgnition, true) \ |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 360 | V(CompileFullCode, true) \ |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 361 | V(OptimizeCode, true) \ |
| 362 | V(CompileCode, true) \ |
| 363 | V(DeoptimizeCode, true) \ |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 364 | V(Execute, true) \ |
| 365 | V(External, true) \ |
| 366 | V(IcMiss, false) |
| 367 | |
| 368 | #define V(TimerName, expose) \ |
| 369 | class TimerEvent##TimerName : public AllStatic { \ |
| 370 | public: \ |
| 371 | static const char* name(void* unused = NULL) { return "V8." #TimerName; } \ |
| 372 | static bool expose_to_api() { return expose; } \ |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 373 | }; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 374 | TIMER_EVENTS_LIST(V) |
| 375 | #undef V |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 376 | |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 377 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 378 | template <class TimerEvent> |
| 379 | class TimerEventScope { |
| 380 | public: |
| 381 | explicit TimerEventScope(Isolate* isolate) : isolate_(isolate) { |
| 382 | LogTimerEvent(Logger::START); |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 383 | } |
| 384 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 385 | ~TimerEventScope() { LogTimerEvent(Logger::END); } |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 386 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 387 | void LogTimerEvent(Logger::StartEnd se); |
| 388 | |
| 389 | private: |
| 390 | Isolate* isolate_; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 391 | }; |
| 392 | |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 393 | class PositionsRecorder BASE_EMBEDDED { |
| 394 | public: |
| 395 | PositionsRecorder() { jit_handler_data_ = NULL; } |
| 396 | |
| 397 | void AttachJITHandlerData(void* user_data) { jit_handler_data_ = user_data; } |
| 398 | |
| 399 | void* DetachJITHandlerData() { |
| 400 | void* old_data = jit_handler_data_; |
| 401 | jit_handler_data_ = NULL; |
| 402 | return old_data; |
| 403 | } |
| 404 | |
| 405 | protected: |
| 406 | // Currently jit_handler_data_ is used to store JITHandler-specific data |
| 407 | // over the lifetime of a PositionsRecorder |
| 408 | void* jit_handler_data_; |
| 409 | |
| 410 | private: |
| 411 | DISALLOW_COPY_AND_ASSIGN(PositionsRecorder); |
| 412 | }; |
Steve Block | 44f0eee | 2011-05-26 01:26:41 +0100 | [diff] [blame] | 413 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 414 | class CodeEventLogger : public CodeEventListener { |
| 415 | public: |
| 416 | CodeEventLogger(); |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 417 | ~CodeEventLogger() override; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 418 | |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 419 | void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 420 | const char* comment) override; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 421 | void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 422 | Name* name) override; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 423 | void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 424 | int args_count) override; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 425 | void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 426 | SharedFunctionInfo* shared, Name* name) override; |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 427 | void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code, |
Ben Murdoch | c561043 | 2016-08-08 18:44:38 +0100 | [diff] [blame] | 428 | SharedFunctionInfo* shared, Name* source, int line, |
| 429 | int column) override; |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 430 | void RegExpCodeCreateEvent(AbstractCode* code, String* source) override; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 431 | |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 432 | void CallbackEvent(Name* name, Address entry_point) override {} |
| 433 | void GetterCallbackEvent(Name* name, Address entry_point) override {} |
| 434 | void SetterCallbackEvent(Name* name, Address entry_point) override {} |
| 435 | void SharedFunctionInfoMoveEvent(Address from, Address to) override {} |
| 436 | void CodeMovingGCEvent() override {} |
Ben Murdoch | 61f157c | 2016-09-16 13:49:30 +0100 | [diff] [blame^] | 437 | void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) override {} |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 438 | |
| 439 | private: |
| 440 | class NameBuffer; |
| 441 | |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 442 | virtual void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared, |
| 443 | const char* name, int length) = 0; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 444 | |
| 445 | NameBuffer* name_buffer_; |
| 446 | }; |
| 447 | |
| 448 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 449 | } // namespace internal |
| 450 | } // namespace v8 |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 451 | |
Steve Block | 6ded16b | 2010-05-10 14:33:55 +0100 | [diff] [blame] | 452 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 453 | #endif // V8_LOG_H_ |