13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_LOG_H_
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_LOG_H_
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <string>
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/allocation.h"
11bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#include "src/base/compiler-specific.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/elapsed-timer.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h"
1413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/code-events.h"
1513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#include "src/isolate.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/objects.h"
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
20f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochstruct TickSample;
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochnamespace sampler {
2313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass Sampler;
2413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
2513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Logger is used for collecting logging information from V8 during
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// execution. The result is dumped to a file.
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Available command line flags:
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//  --log
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Minimal logging (no API, code, or GC sample events), default is off.
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --log-all
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Log all events to the file, default is off.  This is the same as combining
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --log-api, --log-code, --log-gc, and --log-regexp.
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --log-api
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Log API events to the logfile, default is off.  --log-api implies --log.
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --log-code
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Log code (create, move, and delete) events to the logfile, default is off.
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --log-code implies --log.
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --log-gc
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Log GC heap samples after each GC that can be processed by hp2ps, default
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// is off.  --log-gc implies --log.
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --log-regexp
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Log creation and use of regular expressions, Default is off.
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --log-regexp implies --log.
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --logfile <filename>
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Specify the name of the logfile, default is "v8.log".
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --prof
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Collect statistical profiling information (ticks), default is off.  The
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// tick profiler requires code events, so --prof implies --log-code.
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declarations.
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeEventListener;
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CpuProfiler;
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Isolate;
66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass JitLogger;
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Log;
68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass LowLevelLogger;
69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass PerfBasicLogger;
70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass PerfJitLogger;
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Profiler;
72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass ProfilerListener;
7313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass RuntimeCallTimer;
74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass Ticker;
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef LOG
7713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define LOG(isolate, Call)                              \
7813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {                                                  \
7913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    v8::internal::Logger* logger = (isolate)->logger(); \
8013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (logger->is_logging()) logger->Call;             \
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } while (false)
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define LOG_CODE_EVENT(isolate, Call)                   \
8413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {                                                  \
8513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    v8::internal::Logger* logger = (isolate)->logger(); \
8613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (logger->is_logging_code_events()) logger->Call; \
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (false)
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass Logger : public CodeEventListener {
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum StartEnd { START = 0, END = 1 };
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Acquires resources for logging if the right flags are set.
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool SetUp(Isolate* isolate);
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Sets the current code event handler.
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetCodeEventHandler(uint32_t options,
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           JitCodeEventHandler event_handler);
9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
10013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Sets up ProfilerListener.
10113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void SetUpProfilerListener();
10213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
10313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Tear down ProfilerListener if it has no observers.
10413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void TearDownProfilerListener();
10513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
10613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  sampler::Sampler* sampler();
10713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
10813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ProfilerListener* profiler_listener() { return profiler_listener_.get(); }
109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Frees resources acquired in SetUp.
1113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // When a temporary file is used for the log, returns its stream descriptor,
1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // leaving the file open.
1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  FILE* TearDown();
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits an event with a string value -> (name, value).
11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void StringEvent(const char* name, const char* value);
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits an event with an int value -> (name, value).
11944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void IntEvent(const char* name, int value);
12044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void IntPtrTEvent(const char* name, intptr_t value);
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits an event with an handle value -> (name, location).
12344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void HandleEvent(const char* name, Object** location);
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits memory management events for C allocated structures.
12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void NewEvent(const char* name, void* object, size_t size);
12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void DeleteEvent(const char* name, void* object);
12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits an event with a tag, and some resource usage information.
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // -> (name, tag, <rusage information>).
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Currently, the resource usage information is a process time stamp
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and a real time timestamp.
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ResourceEvent(const char* name, const char* tag);
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits an event that an undefined property was read from an
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object.
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SuspectReadEvent(Name* name, Object* obj);
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ==== Events logged by --log-api. ====
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ApiSecurityCheck();
14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ApiNamedPropertyAccess(const char* tag, JSObject* holder, Object* name);
14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ApiIndexedPropertyAccess(const char* tag,
14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                JSObject* holder,
14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                uint32_t index);
14544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ApiObjectAccess(const char* tag, JSObject* obj);
14644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ApiEntryCall(const char* name);
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ==== Events logged by --log-code. ====
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void addCodeEventListener(CodeEventListener* listener);
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void removeCodeEventListener(CodeEventListener* listener);
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Emits a code event for a callback function.
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CallbackEvent(Name* name, Address entry_point);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GetterCallbackEvent(Name* name, Address entry_point);
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void SetterCallbackEvent(Name* name, Address entry_point);
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a code create event.
15713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
15813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       AbstractCode* code, const char* source);
15913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
16013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       AbstractCode* code, Name* name);
16113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
16213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       AbstractCode* code, SharedFunctionInfo* shared,
16313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       Name* name);
16413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
16513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       AbstractCode* code, SharedFunctionInfo* shared,
16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       Name* source, int line, int column);
16713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
16813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                       AbstractCode* code, int args_count);
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Emits a code deoptimization event.
1703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void CodeDisableOptEvent(AbstractCode* code, SharedFunctionInfo* shared);
17144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void CodeMovingGCEvent();
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a code create event for a RegExp.
1733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void RegExpCodeCreateEvent(AbstractCode* code, String* source);
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a code move event.
1753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void CodeMoveEvent(AbstractCode* from, Address to);
176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Emits a code line info record event.
177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void CodeLinePosInfoRecordEvent(AbstractCode* code,
178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                  ByteArray* source_position_table);
179e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void SharedFunctionInfoMoveEvent(Address from, Address to);
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CodeNameEvent(Address addr, int pos, const char* code_name);
183e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
18413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta);
18513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void ICEvent(const char* type, bool keyed, const Address pc, int line,
18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               int column, Map* map, Object* key, char old_state,
18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               char new_state, const char* modifier,
18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               const char* slow_stub_reason);
19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void CompareIC(const Address pc, int line, int column, Code* stub,
19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                 const char* op, const char* old_left, const char* old_right,
19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                 const char* old_state, const char* new_left,
19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                 const char* new_right, const char* new_state);
19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void BinaryOpIC(const Address pc, int line, int column, Code* stub,
19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  const char* old_state, const char* new_state,
19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  AllocationSite* allocation_site);
19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void ToBooleanIC(const Address pc, int line, int column, Code* stub,
19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   const char* old_state, const char* new_state);
19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void PatchIC(const Address pc, const Address test, int delta);
20062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ==== Events logged by --log-gc. ====
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Heap sampling events: start, end, and individual types.
20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void HeapSampleBeginEvent(const char* space, const char* kind);
20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void HeapSampleEndEvent(const char* space, const char* kind);
20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void HeapSampleItemEvent(const char* type, int number, int bytes);
20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void HeapSampleJSConstructorEvent(const char* constructor,
20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                    int number, int bytes);
20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void HeapSampleJSRetainersEvent(const char* constructor,
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                         const char* event);
21044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void HeapSampleJSProducerEvent(const char* constructor,
21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                 Address* stack);
21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void HeapSampleStats(const char* space, const char* kind,
21344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                       intptr_t capacity, intptr_t used);
21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
215bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void SharedLibraryEvent(const std::string& library_path, uintptr_t start,
216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                          uintptr_t end, intptr_t aslr_slide);
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CurrentTimeEvent();
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void TimerEvent(StartEnd se, const char* name);
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void EnterExternal(Isolate* isolate);
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void LeaveExternal(Isolate* isolate);
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static void DefaultEventLoggerSentinel(const char* name, int event) {}
226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  INLINE(static void CallEventLogger(Isolate* isolate, const char* name,
228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                     StartEnd se, bool expose_to_api));
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool is_logging() {
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return is_logging_;
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_logging_code_events() {
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return is_logging() || jit_logger_ != NULL;
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Stop collection of profiling data.
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // When data collection is paused, CPU Tick events are discarded.
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void StopProfiler();
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
242589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void LogExistingFunction(Handle<SharedFunctionInfo> shared,
2433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                           Handle<AbstractCode> code);
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Logs all compiled functions found in the heap.
24544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void LogCompiledFunctions();
246d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Logs all accessor callbacks found in the heap.
24744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void LogAccessorCallbacks();
248d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Used for logging stubs found in the snapshot.
24944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void LogCodeObjects();
2503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Used for logging bytecode handlers found in the snapshot.
2513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void LogBytecodeHandlers();
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Converts tag to a corresponding NATIVE_... if the script is native.
25413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  INLINE(static CodeEventListener::LogEventsAndTags ToNativeByScript(
25513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      CodeEventListener::LogEventsAndTags, Script*));
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Profiler's sampling interval (in milliseconds).
2587549248b8e9ff356d1d3fa834020a789897aa139Ben Murdoch#if defined(ANDROID)
2597549248b8e9ff356d1d3fa834020a789897aa139Ben Murdoch  // Phones and tablets have processors that are much slower than desktop
2607549248b8e9ff356d1d3fa834020a789897aa139Ben Murdoch  // and laptop computers for which current heuristics are tuned.
2617549248b8e9ff356d1d3fa834020a789897aa139Ben Murdoch  static const int kSamplingIntervalMs = 5;
2627549248b8e9ff356d1d3fa834020a789897aa139Ben Murdoch#else
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kSamplingIntervalMs = 1;
2647549248b8e9ff356d1d3fa834020a789897aa139Ben Murdoch#endif
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
26644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Callback from Log, stops profiling in case of insufficient resources.
26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void LogFailure();
26844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
2696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block private:
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit Logger(Isolate* isolate);
27144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ~Logger();
2726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits the profiler's first message.
27444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void ProfilerBeginEvent();
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
276d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Emits callback event messages.
27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void CallbackEventInternal(const char* prefix,
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             Name* name,
27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                             Address entry_point);
280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
281d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Internal configurable move event.
28213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void MoveEventInternal(CodeEventListener::LogEventsAndTags event,
28313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                         Address from, Address to);
284d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
2853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Used for logging stubs found in the snapshot.
28644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void LogCodeObject(Object* code_object);
2873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Helper method. It resets name_buffer_ and add tag name into it.
28913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void InitNameBuffer(CodeEventListener::LogEventsAndTags tag);
290f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emits a profiler tick event. Used by the profiler thread.
29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void TickEvent(TickSample* sample, bool overflow);
29313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void RuntimeCallTimerEvent();
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
295bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  PRINTF_FORMAT(2, 3) void ApiEvent(const char* format, ...);
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Logs a StringEvent regardless of whether FLAG_log is true.
29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void UncheckedStringEvent(const char* name, const char* value);
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Logs an IntEvent regardless of whether FLAG_log is true.
30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void UncheckedIntEvent(const char* name, int value);
30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void UncheckedIntPtrTEvent(const char* name, intptr_t value);
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate_;
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The sampler used by the profiler and the sliding state window.
30744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Ticker* ticker_;
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // When the statistical profile is active, profiler_
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // points to a Profiler, that handles collection
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of samples.
31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Profiler* profiler_;
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // An array of log events names.
31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  const char* const* log_events_;
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Internal implementation classes with access to
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // private members.
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class EventLog;
32044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  friend class Isolate;
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class TimeLog;
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class Profiler;
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template <StateTag Tag> friend class VMState;
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  friend class LoggerTestHelper;
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_logging_;
32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Log* log_;
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PerfBasicLogger* perf_basic_logger_;
3293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  PerfJitLogger* perf_jit_logger_;
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LowLevelLogger* ll_logger_;
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JitLogger* jit_logger_;
33213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  std::unique_ptr<ProfilerListener> profiler_listener_;
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<CodeEventListener*> listeners_;
334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Guards against multiple calls to TearDown() that can happen in some tests.
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // 'true' between SetUp() and TearDown().
33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool is_initialized_;
33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::ElapsedTimer timer_;
3406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  friend class CpuProfiler;
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define TIMER_EVENTS_LIST(V)    \
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(RecompileSynchronous, true) \
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(RecompileConcurrent, true)  \
3473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  V(CompileIgnition, true)      \
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CompileFullCode, true)      \
349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  V(OptimizeCode, true)         \
350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  V(CompileCode, true)          \
351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  V(DeoptimizeCode, true)       \
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Execute, true)              \
353c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  V(External, true)
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V(TimerName, expose)                                                  \
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class TimerEvent##TimerName : public AllStatic {                            \
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:                                                                    \
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    static const char* name(void* unused = NULL) { return "V8." #TimerName; } \
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    static bool expose_to_api() { return expose; }                            \
36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  };
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTIMER_EVENTS_LIST(V)
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef V
36344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate <class TimerEvent>
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass TimerEventScope {
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit TimerEventScope(Isolate* isolate) : isolate_(isolate) {
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LogTimerEvent(Logger::START);
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ~TimerEventScope() { LogTimerEvent(Logger::END); }
37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block private:
375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void LogTimerEvent(Logger::StartEnd se);
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate_;
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CodeEventLogger : public CodeEventListener {
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CodeEventLogger();
3823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ~CodeEventLogger() override;
3833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
38413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
3853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                       const char* comment) override;
38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
3873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                       Name* name) override;
38813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
3893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                       int args_count) override;
39013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
391bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                       SharedFunctionInfo* shared, Name* name) override;
39213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
393bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                       SharedFunctionInfo* shared, Name* source, int line,
394bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                       int column) override;
3953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void RegExpCodeCreateEvent(AbstractCode* code, String* source) override;
3963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
3973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void CallbackEvent(Name* name, Address entry_point) override {}
3983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void GetterCallbackEvent(Name* name, Address entry_point) override {}
3993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void SetterCallbackEvent(Name* name, Address entry_point) override {}
4003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void SharedFunctionInfoMoveEvent(Address from, Address to) override {}
4013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  void CodeMovingGCEvent() override {}
40213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta) override {}
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class NameBuffer;
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  virtual void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared,
4083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 const char* name, int length) = 0;
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NameBuffer* name_buffer_;
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_LOG_H_
419