log.h 15.1 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 78 79

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

mikhail.naganov@gmail.com's avatar
mikhail.naganov@gmail.com committed
89
#define LOG_EVENTS_AND_TAGS_LIST(V) \
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
  V(CODE_CREATION_EVENT,            "code-creation")            \
  V(CODE_MOVE_EVENT,                "code-move")                \
  V(CODE_DELETE_EVENT,              "code-delete")              \
  V(CODE_MOVING_GC,                 "code-moving-gc")           \
  V(FUNCTION_CREATION_EVENT,        "function-creation")        \
  V(FUNCTION_MOVE_EVENT,            "function-move")            \
  V(FUNCTION_DELETE_EVENT,          "function-delete")          \
  V(SNAPSHOT_POSITION_EVENT,        "snapshot-pos")             \
  V(TICK_EVENT,                     "tick")                     \
  V(REPEAT_META_EVENT,              "repeat")                   \
  V(BUILTIN_TAG,                    "Builtin")                  \
  V(CALL_DEBUG_BREAK_TAG,           "CallDebugBreak")           \
  V(CALL_DEBUG_PREPARE_STEP_IN_TAG, "CallDebugPrepareStepIn")   \
  V(CALL_IC_TAG,                    "CallIC")                   \
  V(CALL_INITIALIZE_TAG,            "CallInitialize")           \
  V(CALL_MEGAMORPHIC_TAG,           "CallMegamorphic")          \
  V(CALL_MISS_TAG,                  "CallMiss")                 \
  V(CALL_NORMAL_TAG,                "CallNormal")               \
  V(CALL_PRE_MONOMORPHIC_TAG,       "CallPreMonomorphic")       \
  V(KEYED_CALL_DEBUG_BREAK_TAG,     "KeyedCallDebugBreak")      \
  V(KEYED_CALL_DEBUG_PREPARE_STEP_IN_TAG,                       \
    "KeyedCallDebugPrepareStepIn")                              \
  V(KEYED_CALL_IC_TAG,              "KeyedCallIC")              \
  V(KEYED_CALL_INITIALIZE_TAG,      "KeyedCallInitialize")      \
  V(KEYED_CALL_MEGAMORPHIC_TAG,     "KeyedCallMegamorphic")     \
  V(KEYED_CALL_MISS_TAG,            "KeyedCallMiss")            \
  V(KEYED_CALL_NORMAL_TAG,          "KeyedCallNormal")          \
  V(KEYED_CALL_PRE_MONOMORPHIC_TAG, "KeyedCallPreMonomorphic")  \
  V(CALLBACK_TAG,                   "Callback")                 \
  V(EVAL_TAG,                       "Eval")                     \
  V(FUNCTION_TAG,                   "Function")                 \
  V(KEYED_LOAD_IC_TAG,              "KeyedLoadIC")              \
  V(KEYED_STORE_IC_TAG,             "KeyedStoreIC")             \
  V(LAZY_COMPILE_TAG,               "LazyCompile")              \
  V(LOAD_IC_TAG,                    "LoadIC")                   \
  V(REG_EXP_TAG,                    "RegExp")                   \
  V(SCRIPT_TAG,                     "Script")                   \
  V(STORE_IC_TAG,                   "StoreIC")                  \
  V(STUB_TAG,                       "Stub")                     \
  V(NATIVE_FUNCTION_TAG,            "Function")                 \
  V(NATIVE_LAZY_COMPILE_TAG,        "LazyCompile")              \
  V(NATIVE_SCRIPT_TAG,              "Script")
mikhail.naganov@gmail.com's avatar
mikhail.naganov@gmail.com committed
132 133 134
// Note that 'NATIVE_' cases for functions and scripts are mapped onto
// original tags when writing to the log.

135

136 137
class Logger {
 public:
138
#define DECLARE_ENUM(enum_item, ignore) enum_item,
139 140 141 142 143 144
  enum LogEventsAndTags {
    LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM)
    NUMBER_OF_LOG_EVENTS
  };
#undef DECLARE_ENUM

145
  // Acquires resources for logging if the right flags are set.
146 147
  static bool Setup();

148 149 150
  static void EnsureTickerStarted();
  static void EnsureTickerStopped();

151
  // Frees resources acquired in Setup.
152 153 154 155 156 157 158 159 160 161
  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);
162
  static void IntPtrTEvent(const char* name, intptr_t value);
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178

  // 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.
179
  static void SuspectReadEvent(String* name, Object* obj);
180

181 182 183 184 185
  // 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);

186 187 188 189 190 191 192 193 194 195 196 197 198 199 200

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

227 228
  static void SnapshotPositionEvent(Address addr, int pos);

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

  static void SharedLibraryEvent(const char* library_path,
244 245
                                 uintptr_t start,
                                 uintptr_t end);
246
  static void SharedLibraryEvent(const wchar_t* library_path,
247 248
                                 uintptr_t start,
                                 uintptr_t end);
249

250 251 252
  // ==== Events logged by --log-regexp ====
  // Regexp compilation and execution events.

253
  static void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache);
254

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

258
#ifdef ENABLE_LOGGING_AND_PROFILING
259
  static bool is_logging() {
260
    return logging_nesting_ > 0;
261
  }
262

263
  // Pause/Resume collection of profiling data.
264
  // When data collection is paused, CPU Tick events are discarded until
265
  // data collection is Resumed.
266 267
  static void PauseProfiler(int flags, int tag);
  static void ResumeProfiler(int flags, int tag);
268
  static int GetActiveProfilerModules();
269

270 271 272 273
  // 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);

274 275
  // Logs all compiled functions found in the heap.
  static void LogCompiledFunctions();
276 277
  // Logs all compiled JSFunction objects found in the heap.
  static void LogFunctionObjects();
278 279
  // Logs all accessor callbacks found in the heap.
  static void LogAccessorCallbacks();
280
  // Used for logging stubs found in the snapshot.
281
  static void LogCodeObjects();
282

283 284 285
  // Converts tag to a corresponding NATIVE_... if the script is native.
  INLINE(static LogEventsAndTags ToNativeByScript(LogEventsAndTags, Script*));

286 287 288
  // Profiler's sampling interval (in milliseconds).
  static const int kSamplingIntervalMs = 1;

289 290
 private:

291 292 293
  // Emits the profiler's first message.
  static void ProfilerBeginEvent();

294 295 296 297 298
  // Emits callback event messages.
  static void CallbackEventInternal(const char* prefix,
                                    const char* name,
                                    Address entry_point);

299 300 301 302 303 304 305 306 307
  // Internal configurable move event.
  static void MoveEventInternal(LogEventsAndTags event,
                                Address from,
                                Address to);

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

308
  // Emits the source code of a regexp. Used by regexp events.
309
  static void LogRegExpSource(Handle<JSRegExp> regexp);
310

311 312 313
  // Used for logging stubs found in the snapshot.
  static void LogCodeObject(Object* code_object);

314 315 316 317 318 319
  // Emits general information about generated code.
  static void LogCodeInfo();

  // Handles code creation when low-level profiling is active.
  static void LowLevelCodeCreateEvent(Code* code, LogMessageBuilder* msg);

320 321 322 323 324
  // Emits a profiler tick event. Used by the profiler thread.
  static void TickEvent(TickSample* sample, bool overflow);

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

325 326 327
  // Logs a StringEvent regardless of whether FLAG_log is true.
  static void UncheckedStringEvent(const char* name, const char* value);

328 329
  // Logs an IntEvent regardless of whether FLAG_log is true.
  static void UncheckedIntEvent(const char* name, int value);
330
  static void UncheckedIntPtrTEvent(const char* name, intptr_t value);
331

332 333 334
  // Stops logging and profiling in case of insufficient resources.
  static void StopLoggingAndProfiling();

335 336 337
  // Returns whether profiler's sampler is active.
  static bool IsProfilerSamplerActive();

338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
  // 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_;

  // Internal implementation classes with access to
  // private members.
  friend class EventLog;
  friend class TimeLog;
  friend class Profiler;
  friend class SlidingStateWindow;
356
  friend class StackTracer;
357
  friend class VMState;
358 359

  friend class LoggerTestHelper;
360

361
  static int logging_nesting_;
362 363
  static int cpu_profiler_nesting_;
  static int heap_profiler_nesting_;
364 365

  friend class CpuProfiler;
366
#else
367
  static bool is_logging() { return false; }
368 369 370 371
#endif
};


372
// Class that extracts stack trace, used for profiling.
373
class StackTracer : public AllStatic {
374
 public:
375
  static void Trace(TickSample* sample);
376 377
};

378 379
} }  // namespace v8::internal

380

381
#endif  // V8_LOG_H_