log.h 14.7 KB
Newer Older
1
// Copyright 2006-2008 the V8 project authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef V8_LOG_H_
#define V8_LOG_H_

31 32 33
#include "platform.h"
#include "log-utils.h"

34 35
namespace v8 {
namespace internal {
36 37 38 39 40 41 42 43 44 45 46

// Logger is used for collecting logging information from V8 during
// execution. The result is dumped to a file.
//
// Available command line flags:
//
//  --log
// Minimal logging (no API, code, or GC sample events), default is off.
//
// --log-all
// Log all events to the file, default is off.  This is the same as combining
47
// --log-api, --log-code, --log-gc, and --log-regexp.
48 49 50 51 52 53 54 55 56 57 58 59
//
// --log-api
// Log API events to the logfile, default is off.  --log-api implies --log.
//
// --log-code
// Log code (create, move, and delete) events to the logfile, default is off.
// --log-code implies --log.
//
// --log-gc
// Log GC heap samples after each GC that can be processed by hp2ps, default
// is off.  --log-gc implies --log.
//
60
// --log-regexp
61
// Log creation and use of regular expressions, Default is off.
62 63
// --log-regexp implies --log.
//
64 65 66 67 68 69 70 71 72 73 74 75
// --logfile <filename>
// Specify the name of the logfile, default is "v8.log".
//
// --prof
// Collect statistical profiling information (ticks), default is off.  The
// tick profiler requires code events, so --prof implies --log-code.

// Forward declarations.
class Ticker;
class Profiler;
class Semaphore;
class SlidingStateWindow;
76
class LogMessageBuilder;
77
class CompressionHelper;
78 79 80

#undef LOG
#ifdef ENABLE_LOGGING_AND_PROFILING
81 82
#define LOG(Call)                           \
  do {                                      \
83
    if (v8::internal::Logger::is_logging()) \
84 85
      v8::internal::Logger::Call;           \
  } while (false)
86 87 88 89
#else
#define LOG(Call) ((void) 0)
#endif

mikhail.naganov@gmail.com's avatar
mikhail.naganov@gmail.com committed
90
#define LOG_EVENTS_AND_TAGS_LIST(V) \
91 92 93
  V(CODE_CREATION_EVENT,            "code-creation",          "cc")       \
  V(CODE_MOVE_EVENT,                "code-move",              "cm")       \
  V(CODE_DELETE_EVENT,              "code-delete",            "cd")       \
94 95 96
  V(FUNCTION_CREATION_EVENT,        "function-creation",      "fc")       \
  V(FUNCTION_MOVE_EVENT,            "function-move",          "fm")       \
  V(FUNCTION_DELETE_EVENT,          "function-delete",        "fd")       \
97
  V(SNAPSHOT_POSITION_EVENT,        "snapshot-pos",           "sp")       \
98
  V(TICK_EVENT,                     "tick",                   "t")        \
99
  V(REPEAT_META_EVENT,              "repeat",                 "r")        \
100 101 102 103 104 105 106 107 108
  V(BUILTIN_TAG,                    "Builtin",                "bi")       \
  V(CALL_DEBUG_BREAK_TAG,           "CallDebugBreak",         "cdb")      \
  V(CALL_DEBUG_PREPARE_STEP_IN_TAG, "CallDebugPrepareStepIn", "cdbsi")    \
  V(CALL_IC_TAG,                    "CallIC",                 "cic")      \
  V(CALL_INITIALIZE_TAG,            "CallInitialize",         "ci")       \
  V(CALL_MEGAMORPHIC_TAG,           "CallMegamorphic",        "cmm")      \
  V(CALL_MISS_TAG,                  "CallMiss",               "cm")       \
  V(CALL_NORMAL_TAG,                "CallNormal",             "cn")       \
  V(CALL_PRE_MONOMORPHIC_TAG,       "CallPreMonomorphic",     "cpm")      \
109
  V(CALLBACK_TAG,                   "Callback",               "cb")       \
110 111 112 113 114 115 116 117 118
  V(EVAL_TAG,                       "Eval",                   "e")        \
  V(FUNCTION_TAG,                   "Function",               "f")        \
  V(KEYED_LOAD_IC_TAG,              "KeyedLoadIC",            "klic")     \
  V(KEYED_STORE_IC_TAG,             "KeyedStoreIC",           "ksic")     \
  V(LAZY_COMPILE_TAG,               "LazyCompile",            "lc")       \
  V(LOAD_IC_TAG,                    "LoadIC",                 "lic")      \
  V(REG_EXP_TAG,                    "RegExp",                 "re")       \
  V(SCRIPT_TAG,                     "Script",                 "sc")       \
  V(STORE_IC_TAG,                   "StoreIC",                "sic")      \
mikhail.naganov@gmail.com's avatar
mikhail.naganov@gmail.com committed
119
  V(STUB_TAG,                       "Stub",                   "s")        \
120 121 122
  V(NATIVE_FUNCTION_TAG,            "Function",               "f")        \
  V(NATIVE_LAZY_COMPILE_TAG,        "LazyCompile",            "lc")       \
  V(NATIVE_SCRIPT_TAG,              "Script",                 "sc")
mikhail.naganov@gmail.com's avatar
mikhail.naganov@gmail.com committed
123 124 125
// Note that 'NATIVE_' cases for functions and scripts are mapped onto
// original tags when writing to the log.

126

127 128
class Logger {
 public:
129 130 131 132 133 134 135
#define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
  enum LogEventsAndTags {
    LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM)
    NUMBER_OF_LOG_EVENTS
  };
#undef DECLARE_ENUM

136
  // Acquires resources for logging if the right flags are set.
137 138
  static bool Setup();

139
  // Frees resources acquired in Setup.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
  static void TearDown();

  // Enable the computation of a sliding window of states.
  static void EnableSlidingStateWindow();

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

  // Emits an event with an int value -> (name, value).
  static void IntEvent(const char* name, int value);

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

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

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

  // Emits an event that an undefined property was read from an
  // object.
166
  static void SuspectReadEvent(String* name, Object* obj);
167

168 169 170 171 172
  // Emits an event when a message is put on or read from a debugging queue.
  // DebugTag lets us put a call-site specific label on the event.
  static void DebugTag(const char* call_site_tag);
  static void DebugEvent(const char* event_type, Vector<uint16_t> parameter);

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

  // ==== Events logged by --log-api. ====
  static void ApiNamedSecurityCheck(Object* key);
  static void ApiIndexedSecurityCheck(uint32_t index);
  static void ApiNamedPropertyAccess(const char* tag,
                                     JSObject* holder,
                                     Object* name);
  static void ApiIndexedPropertyAccess(const char* tag,
                                       JSObject* holder,
                                       uint32_t index);
  static void ApiObjectAccess(const char* tag, JSObject* obj);
  static void ApiEntryCall(const char* name);


  // ==== Events logged by --log-code. ====
188
  // Emits a code event for a callback function.
189
  static void CallbackEvent(String* name, Address entry_point);
190 191
  static void GetterCallbackEvent(String* name, Address entry_point);
  static void SetterCallbackEvent(String* name, Address entry_point);
192
  // Emits a code create event.
193 194 195 196
  static void CodeCreateEvent(LogEventsAndTags tag,
                              Code* code, const char* source);
  static void CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name);
  static void CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name,
197
                              String* source, int line);
198
  static void CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count);
199 200
  // Emits a code create event for a RegExp.
  static void RegExpCodeCreateEvent(Code* code, String* source);
201 202 203 204
  // Emits a code move event.
  static void CodeMoveEvent(Address from, Address to);
  // Emits a code delete event.
  static void CodeDeleteEvent(Address from);
205 206 207 208 209 210
  // Emits a function object create event.
  static void FunctionCreateEvent(JSFunction* function);
  // Emits a function move event.
  static void FunctionMoveEvent(Address from, Address to);
  // Emits a function delete event.
  static void FunctionDeleteEvent(Address from);
211

212 213
  static void SnapshotPositionEvent(Address addr, int pos);

214 215 216 217 218
  // ==== Events logged by --log-gc. ====
  // Heap sampling events: start, end, and individual types.
  static void HeapSampleBeginEvent(const char* space, const char* kind);
  static void HeapSampleEndEvent(const char* space, const char* kind);
  static void HeapSampleItemEvent(const char* type, int number, int bytes);
219 220
  static void HeapSampleJSConstructorEvent(const char* constructor,
                                           int number, int bytes);
221 222
  static void HeapSampleJSRetainersEvent(const char* constructor,
                                         const char* event);
223 224
  static void HeapSampleJSProducerEvent(const char* constructor,
                                        Address* stack);
225 226
  static void HeapSampleStats(const char* space, const char* kind,
                              int capacity, int used);
227 228

  static void SharedLibraryEvent(const char* library_path,
229 230
                                 uintptr_t start,
                                 uintptr_t end);
231
  static void SharedLibraryEvent(const wchar_t* library_path,
232 233
                                 uintptr_t start,
                                 uintptr_t end);
234

235 236 237
  // ==== Events logged by --log-regexp ====
  // Regexp compilation and execution events.

238
  static void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache);
239

240 241
  // Log an event reported from generated code
  static void LogRuntime(Vector<const char> format, JSArray* args);
242

243
#ifdef ENABLE_LOGGING_AND_PROFILING
244
  static bool is_logging() {
245
    return logging_nesting_ > 0;
246
  }
247

248
  // Pause/Resume collection of profiling data.
249
  // When data collection is paused, CPU Tick events are discarded until
250
  // data collection is Resumed.
251 252
  static void PauseProfiler(int flags, int tag);
  static void ResumeProfiler(int flags, int tag);
253
  static int GetActiveProfilerModules();
254

255 256 257 258
  // If logging is performed into a memory buffer, allows to
  // retrieve previously written messages. See v8.h.
  static int GetLogLines(int from_pos, char* dest_buf, int max_size);

259 260
  // Logs all compiled functions found in the heap.
  static void LogCompiledFunctions();
261 262
  // Logs all compiled JSFunction objects found in the heap.
  static void LogFunctionObjects();
263 264
  // Logs all accessor callbacks found in the heap.
  static void LogAccessorCallbacks();
265
  // Used for logging stubs found in the snapshot.
266
  static void LogCodeObjects();
267

268 269 270
  // Converts tag to a corresponding NATIVE_... if the script is native.
  INLINE(static LogEventsAndTags ToNativeByScript(LogEventsAndTags, Script*));

271 272 273
  // Profiler's sampling interval (in milliseconds).
  static const int kSamplingIntervalMs = 1;

274 275
 private:

276 277 278
  // Size of window used for log records compression.
  static const int kCompressionWindowSize = 4;

279 280 281
  // Emits the profiler's first message.
  static void ProfilerBeginEvent();

282 283 284 285 286
  // Emits callback event messages.
  static void CallbackEventInternal(const char* prefix,
                                    const char* name,
                                    Address entry_point);

287 288 289 290 291 292 293 294 295
  // Internal configurable move event.
  static void MoveEventInternal(LogEventsAndTags event,
                                Address from,
                                Address to);

  // Internal configurable move event.
  static void DeleteEventInternal(LogEventsAndTags event,
                                  Address from);

296 297 298
  // Emits aliases for compressed messages.
  static void LogAliases();

299
  // Emits the source code of a regexp. Used by regexp events.
300
  static void LogRegExpSource(Handle<JSRegExp> regexp);
301

302 303 304
  // Used for logging stubs found in the snapshot.
  static void LogCodeObject(Object* code_object);

305 306 307 308 309
  // Emits a profiler tick event. Used by the profiler thread.
  static void TickEvent(TickSample* sample, bool overflow);

  static void ApiEvent(const char* name, ...);

310 311 312
  // Logs a StringEvent regardless of whether FLAG_log is true.
  static void UncheckedStringEvent(const char* name, const char* value);

313 314 315
  // Logs an IntEvent regardless of whether FLAG_log is true.
  static void UncheckedIntEvent(const char* name, int value);

316 317 318
  // Stops logging and profiling in case of insufficient resources.
  static void StopLoggingAndProfiling();

319 320 321
  // Returns whether profiler's sampler is active.
  static bool IsProfilerSamplerActive();

322 323 324 325 326 327 328 329 330 331 332 333
  // The sampler used by the profiler and the sliding state window.
  static Ticker* ticker_;

  // When the statistical profile is active, profiler_
  // points to a Profiler, that handles collection
  // of samples.
  static Profiler* profiler_;

  // SlidingStateWindow instance keeping a sliding window of the most
  // recent VM states.
  static SlidingStateWindow* sliding_state_window_;

334 335 336
  // An array of log events names.
  static const char** log_events_;

337 338
  // An instance of helper created if log compression is enabled.
  static CompressionHelper* compression_helper_;
339

340 341
  // Internal implementation classes with access to
  // private members.
342
  friend class CompressionHelper;
343 344 345 346
  friend class EventLog;
  friend class TimeLog;
  friend class Profiler;
  friend class SlidingStateWindow;
347
  friend class StackTracer;
348
  friend class VMState;
349 350

  friend class LoggerTestHelper;
351

352
  static int logging_nesting_;
353 354
  static int cpu_profiler_nesting_;
  static int heap_profiler_nesting_;
355 356

  friend class CpuProfiler;
357
#else
358
  static bool is_logging() { return false; }
359 360 361 362
#endif
};


363
// Class that extracts stack trace, used for profiling.
364
class StackTracer : public AllStatic {
365
 public:
366
  static void Trace(TickSample* sample);
367 368
};

369 370
} }  // namespace v8::internal

371

372
#endif  // V8_LOG_H_