log.h 14.9 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 90
#else
#define LOG(Call) ((void) 0)
#endif


91
class VMState BASE_EMBEDDED {
92 93
#ifdef ENABLE_LOGGING_AND_PROFILING
 public:
94
  inline VMState(StateTag state);
95
  inline ~VMState();
96 97

  StateTag state() { return state_; }
98 99 100 101
  Address external_callback() { return external_callback_; }
  void set_external_callback(Address external_callback) {
    external_callback_ = external_callback;
  }
102 103

 private:
104
  bool disabled_;
105 106
  StateTag state_;
  VMState* previous_;
107
  Address external_callback_;
108 109 110 111 112 113 114
#else
 public:
  explicit VMState(StateTag state) {}
#endif
};


115 116 117 118
#define LOG_EVENTS_AND_TAGS_LIST(V) \
  V(CODE_CREATION_EVENT,            "code-creation",          "cc")       \
  V(CODE_MOVE_EVENT,                "code-move",              "cm")       \
  V(CODE_DELETE_EVENT,              "code-delete",            "cd")       \
119 120 121
  V(FUNCTION_CREATION_EVENT,        "function-creation",      "fc")       \
  V(FUNCTION_MOVE_EVENT,            "function-move",          "fm")       \
  V(FUNCTION_DELETE_EVENT,          "function-delete",        "fd")       \
122
  V(SNAPSHOT_POSITION_EVENT,        "snapshot-pos",           "sp")       \
123
  V(TICK_EVENT,                     "tick",                   "t")        \
124
  V(REPEAT_META_EVENT,              "repeat",                 "r")        \
125 126 127 128 129 130 131 132 133
  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")      \
134
  V(CALLBACK_TAG,                   "Callback",               "cb")       \
135 136 137 138 139 140 141 142 143 144 145
  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")      \
  V(STUB_TAG,                       "Stub",                   "s")

146 147
class Logger {
 public:
148 149 150 151 152 153 154
#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

155
  // Acquires resources for logging if the right flags are set.
156 157
  static bool Setup();

158
  // Frees resources acquired in Setup.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
  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.
185
  static void SuspectReadEvent(String* name, Object* obj);
186

187 188 189 190 191
  // 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);

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206

  // ==== 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. ====
207
  // Emits a code event for a callback function.
208
  static void CallbackEvent(String* name, Address entry_point);
209 210
  static void GetterCallbackEvent(String* name, Address entry_point);
  static void SetterCallbackEvent(String* name, Address entry_point);
211
  // Emits a code create event.
212 213 214 215
  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,
216
                              String* source, int line);
217
  static void CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count);
218 219
  // Emits a code create event for a RegExp.
  static void RegExpCodeCreateEvent(Code* code, String* source);
220 221 222 223
  // Emits a code move event.
  static void CodeMoveEvent(Address from, Address to);
  // Emits a code delete event.
  static void CodeDeleteEvent(Address from);
224 225 226 227 228 229
  // 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);
230

231 232
  static void SnapshotPositionEvent(Address addr, int pos);

233 234 235 236 237
  // ==== 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);
238 239
  static void HeapSampleJSConstructorEvent(const char* constructor,
                                           int number, int bytes);
240 241
  static void HeapSampleJSRetainersEvent(const char* constructor,
                                         const char* event);
242 243
  static void HeapSampleJSProducerEvent(const char* constructor,
                                        Address* stack);
244 245
  static void HeapSampleStats(const char* space, const char* kind,
                              int capacity, int used);
246 247

  static void SharedLibraryEvent(const char* library_path,
248 249
                                 uintptr_t start,
                                 uintptr_t end);
250
  static void SharedLibraryEvent(const wchar_t* library_path,
251 252
                                 uintptr_t start,
                                 uintptr_t end);
253

254 255 256
  // ==== Events logged by --log-regexp ====
  // Regexp compilation and execution events.

257
  static void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache);
258

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

262 263 264 265 266
#ifdef ENABLE_LOGGING_AND_PROFILING
  static StateTag state() {
    return current_state_ ? current_state_->state() : OTHER;
  }

267
  static bool is_logging() {
268
    return logging_nesting_ > 0;
269
  }
270

271
  // Pause/Resume collection of profiling data.
272
  // When data collection is paused, CPU Tick events are discarded until
273
  // data collection is Resumed.
274 275
  static void PauseProfiler(int flags, int tag);
  static void ResumeProfiler(int flags, int tag);
276
  static int GetActiveProfilerModules();
277

278 279 280 281
  // 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);

282 283
  // Logs all compiled functions found in the heap.
  static void LogCompiledFunctions();
284 285
  // Logs all compiled JSFunction objects found in the heap.
  static void LogFunctionObjects();
286 287
  // Logs all accessor callbacks found in the heap.
  static void LogAccessorCallbacks();
288
  // Used for logging stubs found in the snapshot.
289
  static void LogCodeObjects();
290

291
 private:
292

293 294 295
  // Profiler's sampling interval (in milliseconds).
  static const int kSamplingIntervalMs = 1;

296 297 298
  // Size of window used for log records compression.
  static const int kCompressionWindowSize = 4;

299 300 301
  // Emits the profiler's first message.
  static void ProfilerBeginEvent();

302 303 304 305 306
  // Emits callback event messages.
  static void CallbackEventInternal(const char* prefix,
                                    const char* name,
                                    Address entry_point);

307 308 309 310 311 312 313 314 315
  // Internal configurable move event.
  static void MoveEventInternal(LogEventsAndTags event,
                                Address from,
                                Address to);

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

316 317 318
  // Emits aliases for compressed messages.
  static void LogAliases();

319
  // Emits the source code of a regexp. Used by regexp events.
320
  static void LogRegExpSource(Handle<JSRegExp> regexp);
321

322 323 324
  // Used for logging stubs found in the snapshot.
  static void LogCodeObject(Object* code_object);

325 326 327 328 329
  // Emits a profiler tick event. Used by the profiler thread.
  static void TickEvent(TickSample* sample, bool overflow);

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

330 331 332
  // Logs a StringEvent regardless of whether FLAG_log is true.
  static void UncheckedStringEvent(const char* name, const char* value);

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

336 337 338
  // Stops logging and profiling in case of insufficient resources.
  static void StopLoggingAndProfiling();

339 340 341
  // Returns whether profiler's sampler is active.
  static bool IsProfilerSamplerActive();

342 343 344 345 346 347 348 349 350 351 352
  // 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_;

  // A stack of VM states.
  static VMState* current_state_;

353 354 355
  // Singleton bottom or default vm state.
  static VMState bottom_state_;

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

360 361 362
  // An array of log events names.
  static const char** log_events_;

363 364
  // An instance of helper created if log compression is enabled.
  static CompressionHelper* compression_helper_;
365

366 367
  // Internal implementation classes with access to
  // private members.
368
  friend class CompressionHelper;
369 370 371 372
  friend class EventLog;
  friend class TimeLog;
  friend class Profiler;
  friend class SlidingStateWindow;
373
  friend class StackTracer;
374
  friend class VMState;
375 376

  friend class LoggerTestHelper;
377

378
  static int logging_nesting_;
379 380
  static int cpu_profiler_nesting_;
  static int heap_profiler_nesting_;
381
#else
382
  static bool is_logging() { return false; }
383 384 385 386
#endif
};


387
// Class that extracts stack trace, used for profiling.
388
class StackTracer : public AllStatic {
389
 public:
390
  static void Trace(TickSample* sample);
391 392 393
};


394 395 396
} }  // namespace v8::internal

#endif  // V8_LOG_H_