The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / log.h @ f230a1cf

History | View | Annotate | Download (21.1 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// 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

    
31
#include "allocation.h"
32
#include "objects.h"
33
#include "platform.h"
34
#include "platform/elapsed-timer.h"
35

    
36
namespace v8 {
37
namespace internal {
38

    
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
49
// --log-api, --log-code, --log-gc, and --log-regexp.
50
//
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
//
58
// --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
//
62
// --log-regexp
63
// Log creation and use of regular expressions, Default is off.
64
// --log-regexp implies --log.
65
//
66
// --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.
74
class CodeEventListener;
75
class CompilationInfo;
76
class CpuProfiler;
77
class Isolate;
78
class Log;
79
class PositionsRecorder;
80
class Profiler;
81
class Semaphore;
82
class Ticker;
83
struct TickSample;
84

    
85
#undef LOG
86
#define LOG(isolate, Call)                          \
87
  do {                                              \
88
    v8::internal::Logger* logger =                  \
89
        (isolate)->logger();                        \
90
    if (logger->is_logging())                       \
91
      logger->Call;                                 \
92
  } while (false)
93

    
94
#define LOG_CODE_EVENT(isolate, Call)               \
95
  do {                                              \
96
    v8::internal::Logger* logger =                  \
97
        (isolate)->logger();                        \
98
    if (logger->is_logging_code_events())           \
99
      logger->Call;                                 \
100
  } while (false)
101

    
102

    
103
#define LOG_EVENTS_AND_TAGS_LIST(V)                                     \
104
  V(CODE_CREATION_EVENT,            "code-creation")                    \
105
  V(CODE_MOVE_EVENT,                "code-move")                        \
106
  V(CODE_DELETE_EVENT,              "code-delete")                      \
107
  V(CODE_MOVING_GC,                 "code-moving-gc")                   \
108
  V(SHARED_FUNC_MOVE_EVENT,         "sfi-move")                         \
109
  V(SNAPSHOT_POSITION_EVENT,        "snapshot-pos")                     \
110
  V(SNAPSHOT_CODE_NAME_EVENT,       "snapshot-code-name")               \
111
  V(TICK_EVENT,                     "tick")                             \
112
  V(REPEAT_META_EVENT,              "repeat")                           \
113
  V(BUILTIN_TAG,                    "Builtin")                          \
114
  V(CALL_DEBUG_BREAK_TAG,           "CallDebugBreak")                   \
115
  V(CALL_DEBUG_PREPARE_STEP_IN_TAG, "CallDebugPrepareStepIn")           \
116
  V(CALL_IC_TAG,                    "CallIC")                           \
117
  V(CALL_INITIALIZE_TAG,            "CallInitialize")                   \
118
  V(CALL_MEGAMORPHIC_TAG,           "CallMegamorphic")                  \
119
  V(CALL_MISS_TAG,                  "CallMiss")                         \
120
  V(CALL_NORMAL_TAG,                "CallNormal")                       \
121
  V(CALL_PRE_MONOMORPHIC_TAG,       "CallPreMonomorphic")               \
122
  V(KEYED_CALL_DEBUG_BREAK_TAG,     "KeyedCallDebugBreak")              \
123
  V(KEYED_CALL_DEBUG_PREPARE_STEP_IN_TAG,                               \
124
    "KeyedCallDebugPrepareStepIn")                                      \
125
  V(KEYED_CALL_IC_TAG,              "KeyedCallIC")                      \
126
  V(KEYED_CALL_INITIALIZE_TAG,      "KeyedCallInitialize")              \
127
  V(KEYED_CALL_MEGAMORPHIC_TAG,     "KeyedCallMegamorphic")             \
128
  V(KEYED_CALL_MISS_TAG,            "KeyedCallMiss")                    \
129
  V(KEYED_CALL_NORMAL_TAG,          "KeyedCallNormal")                  \
130
  V(KEYED_CALL_PRE_MONOMORPHIC_TAG, "KeyedCallPreMonomorphic")          \
131
  V(CALLBACK_TAG,                   "Callback")                         \
132
  V(EVAL_TAG,                       "Eval")                             \
133
  V(FUNCTION_TAG,                   "Function")                         \
134
  V(HANDLER_TAG,                    "Handler")                          \
135
  V(KEYED_LOAD_IC_TAG,              "KeyedLoadIC")                      \
136
  V(KEYED_LOAD_POLYMORPHIC_IC_TAG,  "KeyedLoadPolymorphicIC")           \
137
  V(KEYED_EXTERNAL_ARRAY_LOAD_IC_TAG, "KeyedExternalArrayLoadIC")       \
138
  V(KEYED_STORE_IC_TAG,             "KeyedStoreIC")                     \
139
  V(KEYED_STORE_POLYMORPHIC_IC_TAG, "KeyedStorePolymorphicIC")          \
140
  V(KEYED_EXTERNAL_ARRAY_STORE_IC_TAG, "KeyedExternalArrayStoreIC")     \
141
  V(LAZY_COMPILE_TAG,               "LazyCompile")                      \
142
  V(LOAD_IC_TAG,                    "LoadIC")                           \
143
  V(LOAD_POLYMORPHIC_IC_TAG,        "LoadPolymorphicIC")                \
144
  V(REG_EXP_TAG,                    "RegExp")                           \
145
  V(SCRIPT_TAG,                     "Script")                           \
146
  V(STORE_IC_TAG,                   "StoreIC")                          \
147
  V(STORE_POLYMORPHIC_IC_TAG,       "StorePolymorphicIC")               \
148
  V(STUB_TAG,                       "Stub")                             \
149
  V(NATIVE_FUNCTION_TAG,            "Function")                         \
150
  V(NATIVE_LAZY_COMPILE_TAG,        "LazyCompile")                      \
151
  V(NATIVE_SCRIPT_TAG,              "Script")
152
// Note that 'NATIVE_' cases for functions and scripts are mapped onto
153
// original tags when writing to the log.
154

    
155

    
156
class JitLogger;
157
class LowLevelLogger;
158
class Sampler;
159

    
160
class Logger {
161
 public:
162
#define DECLARE_ENUM(enum_item, ignore) enum_item,
163
  enum LogEventsAndTags {
164
    LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM)
165
    NUMBER_OF_LOG_EVENTS
166
  };
167
#undef DECLARE_ENUM
168

    
169
  // Acquires resources for logging if the right flags are set.
170
  bool SetUp(Isolate* isolate);
171

    
172
  // Sets the current code event handler.
173
  void SetCodeEventHandler(uint32_t options,
174
                           JitCodeEventHandler event_handler);
175

    
176
  Sampler* sampler();
177

    
178
  // Frees resources acquired in SetUp.
179
  // When a temporary file is used for the log, returns its stream descriptor,
180
  // leaving the file open.
181
  FILE* TearDown();
182

    
183
  // Emits an event with a string value -> (name, value).
184
  void StringEvent(const char* name, const char* value);
185

    
186
  // Emits an event with an int value -> (name, value).
187
  void IntEvent(const char* name, int value);
188
  void IntPtrTEvent(const char* name, intptr_t value);
189

    
190
  // Emits an event with an handle value -> (name, location).
191
  void HandleEvent(const char* name, Object** location);
192

    
193
  // Emits memory management events for C allocated structures.
194
  void NewEvent(const char* name, void* object, size_t size);
195
  void DeleteEvent(const char* name, void* object);
196

    
197
  // Static versions of the above, operate on current isolate's logger.
198
  // Used in TRACK_MEMORY(TypeName) defined in globals.h
199
  static void NewEventStatic(const char* name, void* object, size_t size);
200
  static void DeleteEventStatic(const char* name, void* object);
201

    
202
  // Emits an event with a tag, and some resource usage information.
203
  // -> (name, tag, <rusage information>).
204
  // Currently, the resource usage information is a process time stamp
205
  // and a real time timestamp.
206
  void ResourceEvent(const char* name, const char* tag);
207

    
208
  // Emits an event that an undefined property was read from an
209
  // object.
210
  void SuspectReadEvent(Name* name, Object* obj);
211

    
212
  // Emits an event when a message is put on or read from a debugging queue.
213
  // DebugTag lets us put a call-site specific label on the event.
214
  void DebugTag(const char* call_site_tag);
215
  void DebugEvent(const char* event_type, Vector<uint16_t> parameter);
216

    
217

    
218
  // ==== Events logged by --log-api. ====
219
  void ApiNamedSecurityCheck(Object* key);
220
  void ApiIndexedSecurityCheck(uint32_t index);
221
  void ApiNamedPropertyAccess(const char* tag, JSObject* holder, Object* name);
222
  void ApiIndexedPropertyAccess(const char* tag,
223
                                JSObject* holder,
224
                                uint32_t index);
225
  void ApiObjectAccess(const char* tag, JSObject* obj);
226
  void ApiEntryCall(const char* name);
227

    
228

    
229
  // ==== Events logged by --log-code. ====
230
  void addCodeEventListener(CodeEventListener* listener);
231
  void removeCodeEventListener(CodeEventListener* listener);
232
  bool hasCodeEventListener(CodeEventListener* listener);
233

    
234

    
235
  // Emits a code event for a callback function.
236
  void CallbackEvent(Name* name, Address entry_point);
237
  void GetterCallbackEvent(Name* name, Address entry_point);
238
  void SetterCallbackEvent(Name* name, Address entry_point);
239
  // Emits a code create event.
240
  void CodeCreateEvent(LogEventsAndTags tag,
241
                       Code* code, const char* source);
242
  void CodeCreateEvent(LogEventsAndTags tag,
243
                       Code* code, Name* name);
244
  void CodeCreateEvent(LogEventsAndTags tag,
245
                       Code* code,
246
                       SharedFunctionInfo* shared,
247
                       CompilationInfo* info,
248
                       Name* name);
249
  void CodeCreateEvent(LogEventsAndTags tag,
250
                       Code* code,
251
                       SharedFunctionInfo* shared,
252
                       CompilationInfo* info,
253
                       Name* source, int line, int column);
254
  void CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count);
255
  void CodeMovingGCEvent();
256
  // Emits a code create event for a RegExp.
257
  void RegExpCodeCreateEvent(Code* code, String* source);
258
  // Emits a code move event.
259
  void CodeMoveEvent(Address from, Address to);
260
  // Emits a code delete event.
261
  void CodeDeleteEvent(Address from);
262
  // Emits a code line info add event with Postion type.
263
  void CodeLinePosInfoAddPositionEvent(void* jit_handler_data,
264
                                       int pc_offset,
265
                                       int position);
266
  // Emits a code line info add event with StatementPostion type.
267
  void CodeLinePosInfoAddStatementPositionEvent(void* jit_handler_data,
268
                                                int pc_offset,
269
                                                int position);
270
  // Emits a code line info start to record event
271
  void CodeStartLinePosInfoRecordEvent(PositionsRecorder* pos_recorder);
272
  // Emits a code line info finish record event.
273
  // It's the callee's responsibility to dispose the parameter jit_handler_data.
274
  void CodeEndLinePosInfoRecordEvent(Code* code, void* jit_handler_data);
275

    
276
  void SharedFunctionInfoMoveEvent(Address from, Address to);
277

    
278
  void CodeNameEvent(Address addr, int pos, const char* code_name);
279
  void SnapshotPositionEvent(Address addr, int pos);
280

    
281
  // ==== Events logged by --log-gc. ====
282
  // Heap sampling events: start, end, and individual types.
283
  void HeapSampleBeginEvent(const char* space, const char* kind);
284
  void HeapSampleEndEvent(const char* space, const char* kind);
285
  void HeapSampleItemEvent(const char* type, int number, int bytes);
286
  void HeapSampleJSConstructorEvent(const char* constructor,
287
                                    int number, int bytes);
288
  void HeapSampleJSRetainersEvent(const char* constructor,
289
                                         const char* event);
290
  void HeapSampleJSProducerEvent(const char* constructor,
291
                                 Address* stack);
292
  void HeapSampleStats(const char* space, const char* kind,
293
                       intptr_t capacity, intptr_t used);
294

    
295
  void SharedLibraryEvent(const char* library_path,
296
                          uintptr_t start,
297
                          uintptr_t end);
298
  void SharedLibraryEvent(const wchar_t* library_path,
299
                          uintptr_t start,
300
                          uintptr_t end);
301

    
302
  // ==== Events logged by --log-timer-events. ====
303
  enum StartEnd { START, END };
304

    
305
  void CodeDeoptEvent(Code* code);
306

    
307
  void TimerEvent(StartEnd se, const char* name);
308

    
309
  static void EnterExternal(Isolate* isolate);
310
  static void LeaveExternal(Isolate* isolate);
311

    
312
  class TimerEventScope {
313
   public:
314
    TimerEventScope(Isolate* isolate, const char* name)
315
        : isolate_(isolate), name_(name) {
316
      if (FLAG_log_internal_timer_events) LogTimerEvent(START);
317
    }
318

    
319
    ~TimerEventScope() {
320
      if (FLAG_log_internal_timer_events) LogTimerEvent(END);
321
    }
322

    
323
    void LogTimerEvent(StartEnd se);
324

    
325
    static const char* v8_recompile_synchronous;
326
    static const char* v8_recompile_concurrent;
327
    static const char* v8_compile_full_code;
328
    static const char* v8_execute;
329
    static const char* v8_external;
330

    
331
   private:
332
    Isolate* isolate_;
333
    const char* name_;
334
  };
335

    
336
  // ==== Events logged by --log-regexp ====
337
  // Regexp compilation and execution events.
338

    
339
  void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache);
340

    
341
  // Log an event reported from generated code
342
  void LogRuntime(Vector<const char> format, JSArray* args);
343

    
344
  bool is_logging() {
345
    return is_logging_;
346
  }
347

    
348
  bool is_logging_code_events() {
349
    return is_logging() || jit_logger_ != NULL;
350
  }
351

    
352
  // Stop collection of profiling data.
353
  // When data collection is paused, CPU Tick events are discarded.
354
  void StopProfiler();
355

    
356
  void LogExistingFunction(Handle<SharedFunctionInfo> shared,
357
                           Handle<Code> code);
358
  // Logs all compiled functions found in the heap.
359
  void LogCompiledFunctions();
360
  // Logs all accessor callbacks found in the heap.
361
  void LogAccessorCallbacks();
362
  // Used for logging stubs found in the snapshot.
363
  void LogCodeObjects();
364

    
365
  // Converts tag to a corresponding NATIVE_... if the script is native.
366
  INLINE(static LogEventsAndTags ToNativeByScript(LogEventsAndTags, Script*));
367

    
368
  // Profiler's sampling interval (in milliseconds).
369
#if defined(ANDROID)
370
  // Phones and tablets have processors that are much slower than desktop
371
  // and laptop computers for which current heuristics are tuned.
372
  static const int kSamplingIntervalMs = 5;
373
#else
374
  static const int kSamplingIntervalMs = 1;
375
#endif
376

    
377
  // Callback from Log, stops profiling in case of insufficient resources.
378
  void LogFailure();
379

    
380
 private:
381
  explicit Logger(Isolate* isolate);
382
  ~Logger();
383

    
384
  // Emits the profiler's first message.
385
  void ProfilerBeginEvent();
386

    
387
  // Emits callback event messages.
388
  void CallbackEventInternal(const char* prefix,
389
                             Name* name,
390
                             Address entry_point);
391

    
392
  // Internal configurable move event.
393
  void MoveEventInternal(LogEventsAndTags event, Address from, Address to);
394

    
395
  // Emits the source code of a regexp. Used by regexp events.
396
  void LogRegExpSource(Handle<JSRegExp> regexp);
397

    
398
  // Used for logging stubs found in the snapshot.
399
  void LogCodeObject(Object* code_object);
400

    
401
  // Helper method. It resets name_buffer_ and add tag name into it.
402
  void InitNameBuffer(LogEventsAndTags tag);
403

    
404
  // Emits a profiler tick event. Used by the profiler thread.
405
  void TickEvent(TickSample* sample, bool overflow);
406

    
407
  void ApiEvent(const char* name, ...);
408

    
409
  // Logs a StringEvent regardless of whether FLAG_log is true.
410
  void UncheckedStringEvent(const char* name, const char* value);
411

    
412
  // Logs an IntEvent regardless of whether FLAG_log is true.
413
  void UncheckedIntEvent(const char* name, int value);
414
  void UncheckedIntPtrTEvent(const char* name, intptr_t value);
415

    
416
  Isolate* isolate_;
417

    
418
  // The sampler used by the profiler and the sliding state window.
419
  Ticker* ticker_;
420

    
421
  // When the statistical profile is active, profiler_
422
  // points to a Profiler, that handles collection
423
  // of samples.
424
  Profiler* profiler_;
425

    
426
  // An array of log events names.
427
  const char* const* log_events_;
428

    
429
  // Internal implementation classes with access to
430
  // private members.
431
  friend class EventLog;
432
  friend class Isolate;
433
  friend class TimeLog;
434
  friend class Profiler;
435
  template <StateTag Tag> friend class VMState;
436
  friend class LoggerTestHelper;
437

    
438
  bool is_logging_;
439
  Log* log_;
440
  LowLevelLogger* ll_logger_;
441
  JitLogger* jit_logger_;
442
  List<CodeEventListener*> listeners_;
443

    
444
  // Guards against multiple calls to TearDown() that can happen in some tests.
445
  // 'true' between SetUp() and TearDown().
446
  bool is_initialized_;
447

    
448
  ElapsedTimer timer_;
449

    
450
  friend class CpuProfiler;
451
};
452

    
453

    
454
class CodeEventListener {
455
 public:
456
  virtual ~CodeEventListener() {}
457

    
458
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
459
                               Code* code,
460
                               const char* comment) = 0;
461
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
462
                               Code* code,
463
                               Name* name) = 0;
464
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
465
                               Code* code,
466
                               SharedFunctionInfo* shared,
467
                               CompilationInfo* info,
468
                               Name* name) = 0;
469
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
470
                               Code* code,
471
                               SharedFunctionInfo* shared,
472
                               CompilationInfo* info,
473
                               Name* source,
474
                               int line, int column) = 0;
475
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
476
                               Code* code,
477
                               int args_count) = 0;
478
  virtual void CallbackEvent(Name* name, Address entry_point) = 0;
479
  virtual void GetterCallbackEvent(Name* name, Address entry_point) = 0;
480
  virtual void SetterCallbackEvent(Name* name, Address entry_point) = 0;
481
  virtual void RegExpCodeCreateEvent(Code* code, String* source) = 0;
482
  virtual void CodeMoveEvent(Address from, Address to) = 0;
483
  virtual void CodeDeleteEvent(Address from) = 0;
484
  virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
485
  virtual void CodeMovingGCEvent() = 0;
486
};
487

    
488

    
489
class CodeEventLogger : public CodeEventListener {
490
 public:
491
  CodeEventLogger();
492
  virtual ~CodeEventLogger();
493

    
494
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
495
                               Code* code,
496
                               const char* comment);
497
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
498
                               Code* code,
499
                               Name* name);
500
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
501
                               Code* code,
502
                               int args_count);
503
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
504
                               Code* code,
505
                               SharedFunctionInfo* shared,
506
                               CompilationInfo* info,
507
                               Name* name);
508
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
509
                               Code* code,
510
                               SharedFunctionInfo* shared,
511
                               CompilationInfo* info,
512
                               Name* source,
513
                               int line, int column);
514
  virtual void RegExpCodeCreateEvent(Code* code, String* source);
515

    
516
  virtual void CallbackEvent(Name* name, Address entry_point) { }
517
  virtual void GetterCallbackEvent(Name* name, Address entry_point) { }
518
  virtual void SetterCallbackEvent(Name* name, Address entry_point) { }
519
  virtual void SharedFunctionInfoMoveEvent(Address from, Address to) { }
520
  virtual void CodeMovingGCEvent() { }
521

    
522
 private:
523
  class NameBuffer;
524

    
525
  virtual void LogRecordedBuffer(Code* code,
526
                                 SharedFunctionInfo* shared,
527
                                 const char* name,
528
                                 int length) = 0;
529

    
530
  NameBuffer* name_buffer_;
531
};
532

    
533

    
534
} }  // namespace v8::internal
535

    
536

    
537
#endif  // V8_LOG_H_