blob: 718dc02be8f335b3757e8b2fbfe79688a2bae5ad [file] [log] [blame]
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_LOG_H_
29#define V8_LOG_H_
30
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000032#include "objects.h"
ager@chromium.org3e875802009-06-29 08:26:34 +000033#include "platform.h"
34#include "log-utils.h"
35
kasperl@chromium.org71affb52009-05-26 05:44:31 +000036namespace v8 {
37namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000038
39// Logger is used for collecting logging information from V8 during
40// execution. The result is dumped to a file.
41//
42// Available command line flags:
43//
44// --log
45// Minimal logging (no API, code, or GC sample events), default is off.
46//
47// --log-all
48// Log all events to the file, default is off. This is the same as combining
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000049// --log-api, --log-code, --log-gc, and --log-regexp.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000050//
51// --log-api
52// Log API events to the logfile, default is off. --log-api implies --log.
53//
54// --log-code
55// Log code (create, move, and delete) events to the logfile, default is off.
56// --log-code implies --log.
57//
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000058// --log-gc
59// Log GC heap samples after each GC that can be processed by hp2ps, default
60// is off. --log-gc implies --log.
61//
kasperl@chromium.orgb9123622008-09-17 14:05:56 +000062// --log-regexp
63// Log creation and use of regular expressions, Default is off.
64// --log-regexp implies --log.
65//
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066// --logfile <filename>
67// Specify the name of the logfile, default is "v8.log".
68//
69// --prof
70// Collect statistical profiling information (ticks), default is off. The
71// tick profiler requires code events, so --prof implies --log-code.
72
73// Forward declarations.
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +000074class LogMessageBuilder;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000075class Profiler;
76class Semaphore;
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +000077class Ticker;
danno@chromium.org1f34ad32012-11-26 14:53:56 +000078class Isolate;
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +000079class PositionsRecorder;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080
81#undef LOG
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000082#define LOG(isolate, Call) \
83 do { \
84 v8::internal::Logger* logger = \
85 (isolate)->logger(); \
86 if (logger->is_logging()) \
87 logger->Call; \
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +000088 } while (false)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000089
yangguo@chromium.org355cfd12012-08-29 15:32:24 +000090#define LOG_CODE_EVENT(isolate, Call) \
91 do { \
92 v8::internal::Logger* logger = \
93 (isolate)->logger(); \
94 if (logger->is_logging_code_events()) \
95 logger->Call; \
96 } while (false)
97
98
ager@chromium.orgea91cc52011-05-23 06:06:11 +000099#define LOG_EVENTS_AND_TAGS_LIST(V) \
100 V(CODE_CREATION_EVENT, "code-creation") \
101 V(CODE_MOVE_EVENT, "code-move") \
102 V(CODE_DELETE_EVENT, "code-delete") \
103 V(CODE_MOVING_GC, "code-moving-gc") \
104 V(SHARED_FUNC_MOVE_EVENT, "sfi-move") \
105 V(SNAPSHOT_POSITION_EVENT, "snapshot-pos") \
106 V(SNAPSHOT_CODE_NAME_EVENT, "snapshot-code-name") \
107 V(TICK_EVENT, "tick") \
108 V(REPEAT_META_EVENT, "repeat") \
109 V(BUILTIN_TAG, "Builtin") \
110 V(CALL_DEBUG_BREAK_TAG, "CallDebugBreak") \
111 V(CALL_DEBUG_PREPARE_STEP_IN_TAG, "CallDebugPrepareStepIn") \
112 V(CALL_IC_TAG, "CallIC") \
113 V(CALL_INITIALIZE_TAG, "CallInitialize") \
114 V(CALL_MEGAMORPHIC_TAG, "CallMegamorphic") \
115 V(CALL_MISS_TAG, "CallMiss") \
116 V(CALL_NORMAL_TAG, "CallNormal") \
117 V(CALL_PRE_MONOMORPHIC_TAG, "CallPreMonomorphic") \
118 V(KEYED_CALL_DEBUG_BREAK_TAG, "KeyedCallDebugBreak") \
119 V(KEYED_CALL_DEBUG_PREPARE_STEP_IN_TAG, \
120 "KeyedCallDebugPrepareStepIn") \
121 V(KEYED_CALL_IC_TAG, "KeyedCallIC") \
122 V(KEYED_CALL_INITIALIZE_TAG, "KeyedCallInitialize") \
123 V(KEYED_CALL_MEGAMORPHIC_TAG, "KeyedCallMegamorphic") \
124 V(KEYED_CALL_MISS_TAG, "KeyedCallMiss") \
125 V(KEYED_CALL_NORMAL_TAG, "KeyedCallNormal") \
126 V(KEYED_CALL_PRE_MONOMORPHIC_TAG, "KeyedCallPreMonomorphic") \
127 V(CALLBACK_TAG, "Callback") \
128 V(EVAL_TAG, "Eval") \
129 V(FUNCTION_TAG, "Function") \
130 V(KEYED_LOAD_IC_TAG, "KeyedLoadIC") \
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000131 V(KEYED_LOAD_POLYMORPHIC_IC_TAG, "KeyedLoadPolymorphicIC") \
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000132 V(KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG, "KeyedExternalArrayLoadIC") \
133 V(KEYED_STORE_IC_TAG, "KeyedStoreIC") \
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000134 V(KEYED_STORE_POLYMORPHIC_IC_TAG, "KeyedStorePolymorphicIC") \
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000135 V(KEYED_EXTERNAL_ARRAY_STORE_IC_TAG, "KeyedExternalArrayStoreIC") \
136 V(LAZY_COMPILE_TAG, "LazyCompile") \
137 V(LOAD_IC_TAG, "LoadIC") \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +0000138 V(LOAD_POLYMORPHIC_IC_TAG, "LoadPolymorphicIC") \
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000139 V(REG_EXP_TAG, "RegExp") \
140 V(SCRIPT_TAG, "Script") \
141 V(STORE_IC_TAG, "StoreIC") \
142 V(STUB_TAG, "Stub") \
143 V(NATIVE_FUNCTION_TAG, "Function") \
144 V(NATIVE_LAZY_COMPILE_TAG, "LazyCompile") \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000145 V(NATIVE_SCRIPT_TAG, "Script")
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000146// Note that 'NATIVE_' cases for functions and scripts are mapped onto
147// original tags when writing to the log.
148
ager@chromium.org357bf652010-04-12 11:30:10 +0000149
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000150class Sampler;
151
152
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000153class Logger {
154 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000155#define DECLARE_ENUM(enum_item, ignore) enum_item,
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000156 enum LogEventsAndTags {
157 LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM)
158 NUMBER_OF_LOG_EVENTS
159 };
160#undef DECLARE_ENUM
161
ager@chromium.org9085a012009-05-11 19:22:57 +0000162 // Acquires resources for logging if the right flags are set.
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000163 bool SetUp();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000164
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000165 // Sets the current code event handler.
166 void SetCodeEventHandler(uint32_t options,
167 JitCodeEventHandler event_handler);
168
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000169 void EnsureTickerStarted();
170 void EnsureTickerStopped();
171
172 Sampler* sampler();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000173
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000174 // Frees resources acquired in SetUp.
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000175 // When a temporary file is used for the log, returns its stream descriptor,
176 // leaving the file open.
177 FILE* TearDown();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000178
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000179 // Emits an event with a string value -> (name, value).
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000180 void StringEvent(const char* name, const char* value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000181
182 // Emits an event with an int value -> (name, value).
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000183 void IntEvent(const char* name, int value);
184 void IntPtrTEvent(const char* name, intptr_t value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000185
186 // Emits an event with an handle value -> (name, location).
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000187 void HandleEvent(const char* name, Object** location);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000188
189 // Emits memory management events for C allocated structures.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000190 void NewEvent(const char* name, void* object, size_t size);
191 void DeleteEvent(const char* name, void* object);
192
193 // Static versions of the above, operate on current isolate's logger.
194 // Used in TRACK_MEMORY(TypeName) defined in globals.h
195 static void NewEventStatic(const char* name, void* object, size_t size);
196 static void DeleteEventStatic(const char* name, void* object);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000197
198 // Emits an event with a tag, and some resource usage information.
199 // -> (name, tag, <rusage information>).
200 // Currently, the resource usage information is a process time stamp
201 // and a real time timestamp.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000202 void ResourceEvent(const char* name, const char* tag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000203
204 // Emits an event that an undefined property was read from an
205 // object.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000206 void SuspectReadEvent(String* name, Object* obj);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000207
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000208 // Emits an event when a message is put on or read from a debugging queue.
209 // DebugTag lets us put a call-site specific label on the event.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000210 void DebugTag(const char* call_site_tag);
211 void DebugEvent(const char* event_type, Vector<uint16_t> parameter);
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000212
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000213
214 // ==== Events logged by --log-api. ====
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000215 void ApiNamedSecurityCheck(Object* key);
216 void ApiIndexedSecurityCheck(uint32_t index);
217 void ApiNamedPropertyAccess(const char* tag, JSObject* holder, Object* name);
218 void ApiIndexedPropertyAccess(const char* tag,
219 JSObject* holder,
220 uint32_t index);
221 void ApiObjectAccess(const char* tag, JSObject* obj);
222 void ApiEntryCall(const char* name);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000223
224
225 // ==== Events logged by --log-code. ====
ager@chromium.org01beca72009-11-24 14:29:16 +0000226 // Emits a code event for a callback function.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000227 void CallbackEvent(String* name, Address entry_point);
228 void GetterCallbackEvent(String* name, Address entry_point);
229 void SetterCallbackEvent(String* name, Address entry_point);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000230 // Emits a code create event.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000231 void CodeCreateEvent(LogEventsAndTags tag,
232 Code* code, const char* source);
233 void CodeCreateEvent(LogEventsAndTags tag,
234 Code* code, String* name);
235 void CodeCreateEvent(LogEventsAndTags tag,
236 Code* code,
237 SharedFunctionInfo* shared,
238 String* name);
239 void CodeCreateEvent(LogEventsAndTags tag,
240 Code* code,
241 SharedFunctionInfo* shared,
242 String* source, int line);
243 void CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count);
244 void CodeMovingGCEvent();
ager@chromium.org71daaf62009-04-01 07:22:49 +0000245 // Emits a code create event for a RegExp.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000246 void RegExpCodeCreateEvent(Code* code, String* source);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247 // Emits a code move event.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000248 void CodeMoveEvent(Address from, Address to);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000249 // Emits a code delete event.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000250 void CodeDeleteEvent(Address from);
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000251 // Emits a code line info add event with Postion type.
252 void CodeLinePosInfoAddPositionEvent(void* jit_handler_data,
253 int pc_offset,
254 int position);
255 // Emits a code line info add event with StatementPostion type.
256 void CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data,
257 int pc_offset,
258 int position);
259 // Emits a code line info start to record event
260 void CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder);
261 // Emits a code line info finish record event.
262 // It's the callee's responsibility to dispose the parameter jit_handler_data.
263 void CodeEndLinePosInfoRecordEvent(Code* code, void* jit_handler_data);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000264
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000265 void SharedFunctionInfoMoveEvent(Address from, Address to);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000266
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000267 void SnapshotPositionEvent(Address addr, int pos);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268
269 // ==== Events logged by --log-gc. ====
270 // Heap sampling events: start, end, and individual types.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000271 void HeapSampleBeginEvent(const char* space, const char* kind);
272 void HeapSampleEndEvent(const char* space, const char* kind);
273 void HeapSampleItemEvent(const char* type, int number, int bytes);
274 void HeapSampleJSConstructorEvent(const char* constructor,
275 int number, int bytes);
276 void HeapSampleJSRetainersEvent(const char* constructor,
christian.plesner.hansen@gmail.com2bc58ef2009-09-22 10:00:30 +0000277 const char* event);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000278 void HeapSampleJSProducerEvent(const char* constructor,
279 Address* stack);
280 void HeapSampleStats(const char* space, const char* kind,
281 intptr_t capacity, intptr_t used);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000282
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000283 void SharedLibraryEvent(const char* library_path,
284 uintptr_t start,
285 uintptr_t end);
286 void SharedLibraryEvent(const wchar_t* library_path,
287 uintptr_t start,
288 uintptr_t end);
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000289
290 // ==== Events logged by --log-timer-events. ====
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000291 enum StartEnd { START, END };
292
293 void TimerEvent(StartEnd se, const char* name);
svenpanne@chromium.org83130cf2012-11-30 10:13:25 +0000294
295 static void EnterExternal();
296 static void LeaveExternal();
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000297
298 class TimerEventScope {
299 public:
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000300 TimerEventScope(Isolate* isolate, const char* name)
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000301 : isolate_(isolate), name_(name) {
302 if (FLAG_log_internal_timer_events) LogTimerEvent(START);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000303 }
304
305 ~TimerEventScope() {
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000306 if (FLAG_log_internal_timer_events) LogTimerEvent(END);
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000307 }
308
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000309 void LogTimerEvent(StartEnd se);
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000310
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000311 static const char* v8_recompile_synchronous;
312 static const char* v8_recompile_parallel;
313 static const char* v8_compile_full_code;
314 static const char* v8_execute;
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000315 static const char* v8_external;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000316
317 private:
danno@chromium.org1f34ad32012-11-26 14:53:56 +0000318 Isolate* isolate_;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000319 const char* name_;
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000320 };
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000321
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000322 // ==== Events logged by --log-regexp ====
323 // Regexp compilation and execution events.
324
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000325 void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000326
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000327 // Log an event reported from generated code
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000328 void LogRuntime(Isolate* isolate, Vector<const char> format, JSArray* args);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000329
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000330 bool is_logging() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000331 return logging_nesting_ > 0;
ager@chromium.org3e875802009-06-29 08:26:34 +0000332 }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000333
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000334 bool is_code_event_handler_enabled() {
335 return code_event_handler_ != NULL;
336 }
337
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000338 bool is_logging_code_events() {
339 return is_logging() || code_event_handler_ != NULL;
340 }
341
iposva@chromium.org245aa852009-02-10 00:49:54 +0000342 // Pause/Resume collection of profiling data.
sgjesse@chromium.orgb9d7da12009-08-05 08:38:10 +0000343 // When data collection is paused, CPU Tick events are discarded until
iposva@chromium.org245aa852009-02-10 00:49:54 +0000344 // data collection is Resumed.
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000345 void PauseProfiler();
346 void ResumeProfiler();
347 bool IsProfilerPaused();
iposva@chromium.org245aa852009-02-10 00:49:54 +0000348
lrn@chromium.org34e60782011-09-15 07:25:40 +0000349 void LogExistingFunction(Handle<SharedFunctionInfo> shared,
350 Handle<Code> code);
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000351 // Logs all compiled functions found in the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000352 void LogCompiledFunctions();
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000353 // Logs all accessor callbacks found in the heap.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000354 void LogAccessorCallbacks();
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000355 // Used for logging stubs found in the snapshot.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000356 void LogCodeObjects();
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000357
ager@chromium.org357bf652010-04-12 11:30:10 +0000358 // Converts tag to a corresponding NATIVE_... if the script is native.
359 INLINE(static LogEventsAndTags ToNativeByScript(LogEventsAndTags, Script*));
360
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000361 // Profiler's sampling interval (in milliseconds).
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +0000362#if defined(ANDROID)
363 // Phones and tablets have processors that are much slower than desktop
364 // and laptop computers for which current heuristics are tuned.
365 static const int kSamplingIntervalMs = 5;
366#else
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000367 static const int kSamplingIntervalMs = 1;
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +0000368#endif
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000369
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000370 // Callback from Log, stops profiling in case of insufficient resources.
371 void LogFailure();
372
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000373 private:
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000374 class NameBuffer;
375 class NameMap;
376
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000377 explicit Logger(Isolate* isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000378 ~Logger();
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000379
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000380 // Issue code notifications.
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000381 void IssueCodeAddedEvent(Code* code,
382 Script* script,
383 const char* name,
384 size_t name_len);
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000385 void IssueCodeMovedEvent(Address from, Address to);
386 void IssueCodeRemovedEvent(Address from);
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000387 void IssueAddCodeLinePosInfoEvent(void* jit_handler_data,
388 int pc_offset,
389 int position,
390 JitCodeEvent::PositionType position_Type);
391 void* IssueStartCodePosInfoEvent();
392 void IssueEndCodePosInfoEvent(Code* code, void* jit_handler_data);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000393 // Emits the profiler's first message.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000394 void ProfilerBeginEvent();
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000395
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000396 // Emits callback event messages.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000397 void CallbackEventInternal(const char* prefix,
398 const char* name,
399 Address entry_point);
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +0000400
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000401 // Internal configurable move event.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000402 void MoveEventInternal(LogEventsAndTags event, Address from, Address to);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000403
404 // Internal configurable move event.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000405 void DeleteEventInternal(LogEventsAndTags event, Address from);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000406
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000407 // Emits the source code of a regexp. Used by regexp events.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000408 void LogRegExpSource(Handle<JSRegExp> regexp);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000409
ager@chromium.org5c838252010-02-19 08:53:10 +0000410 // Used for logging stubs found in the snapshot.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000411 void LogCodeObject(Object* code_object);
ager@chromium.org5c838252010-02-19 08:53:10 +0000412
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000413 // Emits general information about generated code.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000414 void LogCodeInfo();
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000415
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000416 void RegisterSnapshotCodeName(Code* code, const char* name, int name_size);
417
418 // Low-level logging support.
419
420 void LowLevelCodeCreateEvent(Code* code, const char* name, int name_size);
421
422 void LowLevelCodeMoveEvent(Address from, Address to);
423
424 void LowLevelCodeDeleteEvent(Address from);
425
426 void LowLevelSnapshotPositionEvent(Address addr, int pos);
427
428 void LowLevelLogWriteBytes(const char* bytes, int size);
429
430 template <typename T>
431 void LowLevelLogWriteStruct(const T& s) {
432 char tag = T::kTag;
433 LowLevelLogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag));
434 LowLevelLogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s));
435 }
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000436
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000437 // Emits a profiler tick event. Used by the profiler thread.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000438 void TickEvent(TickSample* sample, bool overflow);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000439
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000440 void ApiEvent(const char* name, ...);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000441
ager@chromium.org6f10e412009-02-13 10:11:16 +0000442 // Logs a StringEvent regardless of whether FLAG_log is true.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000443 void UncheckedStringEvent(const char* name, const char* value);
ager@chromium.org6f10e412009-02-13 10:11:16 +0000444
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000445 // Logs an IntEvent regardless of whether FLAG_log is true.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000446 void UncheckedIntEvent(const char* name, int value);
447 void UncheckedIntPtrTEvent(const char* name, intptr_t value);
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000448
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000449 // Returns whether profiler's sampler is active.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000450 bool IsProfilerSamplerActive();
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000451
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000452 Isolate* isolate_;
453
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454 // The sampler used by the profiler and the sliding state window.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000455 Ticker* ticker_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000456
457 // When the statistical profile is active, profiler_
458 // points to a Profiler, that handles collection
459 // of samples.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000460 Profiler* profiler_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000461
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000462 // An array of log events names.
463 const char* const* log_events_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464
465 // Internal implementation classes with access to
466 // private members.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 friend class EventLog;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000468 friend class Isolate;
469 friend class LogMessageBuilder;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000470 friend class TimeLog;
471 friend class Profiler;
ager@chromium.org01beca72009-11-24 14:29:16 +0000472 friend class StackTracer;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000473 friend class VMState;
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000474
475 friend class LoggerTestHelper;
ager@chromium.org3e875802009-06-29 08:26:34 +0000476
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000477
478 int logging_nesting_;
479 int cpu_profiler_nesting_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000480
481 Log* log_;
482
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000483 NameBuffer* name_buffer_;
484
485 NameMap* address_to_name_map_;
486
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000487 // Guards against multiple calls to TearDown() that can happen in some tests.
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000488 // 'true' between SetUp() and TearDown().
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000489 bool is_initialized_;
490
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000491 // The code event handler - if any.
492 JitCodeEventHandler code_event_handler_;
493
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000494 // Support for 'incremental addresses' in compressed logs:
495 // LogMessageBuilder::AppendAddress(Address addr)
496 Address last_address_;
497 // Logger::TickEvent(...)
498 Address prev_sp_;
499 Address prev_function_;
500 // Logger::MoveEventInternal(...)
501 Address prev_to_;
502 // Logger::FunctionCreateEvent(...)
503 Address prev_code_;
lrn@chromium.org25156de2010-04-06 13:10:27 +0000504
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000505 int64_t epoch_;
506
lrn@chromium.org25156de2010-04-06 13:10:27 +0000507 friend class CpuProfiler;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000508};
509
510
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000511// Process wide registry of samplers.
512class SamplerRegistry : public AllStatic {
513 public:
514 enum State {
515 HAS_NO_SAMPLERS,
516 HAS_SAMPLERS,
517 HAS_CPU_PROFILING_SAMPLERS
518 };
519
fschneider@chromium.org7d10be52012-04-10 12:30:14 +0000520 static void SetUp();
521
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000522 typedef void (*VisitSampler)(Sampler*, void*);
523
524 static State GetState();
525
526 // Iterates over all active samplers keeping the internal lock held.
527 // Returns whether there are any active samplers.
528 static bool IterateActiveSamplers(VisitSampler func, void* param);
529
530 // Adds/Removes an active sampler.
531 static void AddActiveSampler(Sampler* sampler);
532 static void RemoveActiveSampler(Sampler* sampler);
533
534 private:
535 static bool ActiveSamplersExist() {
536 return active_samplers_ != NULL && !active_samplers_->is_empty();
537 }
538
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000539 static List<Sampler*>* active_samplers_;
540
541 DISALLOW_IMPLICIT_CONSTRUCTORS(SamplerRegistry);
542};
543
544
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000545// Class that extracts stack trace, used for profiling.
ager@chromium.orge2902be2009-06-08 12:21:35 +0000546class StackTracer : public AllStatic {
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000547 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000548 static void Trace(Isolate* isolate, TickSample* sample);
kasperl@chromium.org061ef742009-02-27 12:16:20 +0000549};
550
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000551} } // namespace v8::internal
552
lrn@chromium.org25156de2010-04-06 13:10:27 +0000553
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000554#endif // V8_LOG_H_