1 // Copyright 2006-2008 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 "platform.h" 32 #include "log-utils.h" 33 34 namespace v8 { 35 namespace internal { 36 37 // Logger is used for collecting logging information from V8 during 38 // execution. The result is dumped to a file. 39 // 40 // Available command line flags: 41 // 42 // --log 43 // Minimal logging (no API, code, or GC sample events), default is off. 44 // 45 // --log-all 46 // 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 // --log-api 50 // Log API events to the logfile, default is off. --log-api implies --log. 51 // 52 // --log-code 53 // Log code (create, move, and delete) events to the logfile, default is off. 54 // --log-code implies --log. 55 // 56 // --log-gc 57 // Log GC heap samples after each GC that can be processed by hp2ps, default 58 // is off. --log-gc implies --log. 59 // 60 // --log-regexp 61 // Log creation and use of regular expressions, Default is off. 62 // --log-regexp implies --log. 63 // 64 // --logfile <filename> 65 // Specify the name of the logfile, default is "v8.log". 66 // 67 // --prof 68 // Collect statistical profiling information (ticks), default is off. The 69 // tick profiler requires code events, so --prof implies --log-code. 70 71 // Forward declarations. 72 class Ticker; 73 class Profiler; 74 class Semaphore; 75 class SlidingStateWindow; 76 class LogMessageBuilder; 77 class CompressionHelper; 78 79 #undef LOG 80 #ifdef ENABLE_LOGGING_AND_PROFILING 81 #define LOG(Call) \ 82 do { \ 83 if (v8::internal::Logger::is_logging()) \ 84 v8::internal::Logger::Call; \ 85 } while (false) 86 #else 87 #define LOG(Call) ((void) 0) 88 #endif 89 90 91 class VMState BASE_EMBEDDED { 92 #ifdef ENABLE_LOGGING_AND_PROFILING 93 public: 94 inline explicit VMState(StateTag state); 95 inline ~VMState(); 96 state()97 StateTag state() { return state_; } 98 99 private: 100 bool disabled_; 101 StateTag state_; 102 VMState* previous_; 103 #else 104 public: 105 explicit VMState(StateTag state) {} 106 #endif 107 }; 108 109 110 #define LOG_EVENTS_AND_TAGS_LIST(V) \ 111 V(CODE_CREATION_EVENT, "code-creation", "cc") \ 112 V(CODE_MOVE_EVENT, "code-move", "cm") \ 113 V(CODE_DELETE_EVENT, "code-delete", "cd") \ 114 V(TICK_EVENT, "tick", "t") \ 115 V(REPEAT_META_EVENT, "repeat", "r") \ 116 V(BUILTIN_TAG, "Builtin", "bi") \ 117 V(CALL_DEBUG_BREAK_TAG, "CallDebugBreak", "cdb") \ 118 V(CALL_DEBUG_PREPARE_STEP_IN_TAG, "CallDebugPrepareStepIn", "cdbsi") \ 119 V(CALL_IC_TAG, "CallIC", "cic") \ 120 V(CALL_INITIALIZE_TAG, "CallInitialize", "ci") \ 121 V(CALL_MEGAMORPHIC_TAG, "CallMegamorphic", "cmm") \ 122 V(CALL_MISS_TAG, "CallMiss", "cm") \ 123 V(CALL_NORMAL_TAG, "CallNormal", "cn") \ 124 V(CALL_PRE_MONOMORPHIC_TAG, "CallPreMonomorphic", "cpm") \ 125 V(EVAL_TAG, "Eval", "e") \ 126 V(FUNCTION_TAG, "Function", "f") \ 127 V(KEYED_LOAD_IC_TAG, "KeyedLoadIC", "klic") \ 128 V(KEYED_STORE_IC_TAG, "KeyedStoreIC", "ksic") \ 129 V(LAZY_COMPILE_TAG, "LazyCompile", "lc") \ 130 V(LOAD_IC_TAG, "LoadIC", "lic") \ 131 V(REG_EXP_TAG, "RegExp", "re") \ 132 V(SCRIPT_TAG, "Script", "sc") \ 133 V(STORE_IC_TAG, "StoreIC", "sic") \ 134 V(STUB_TAG, "Stub", "s") 135 136 class Logger { 137 public: 138 #define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item, 139 enum LogEventsAndTags { 140 LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM) 141 NUMBER_OF_LOG_EVENTS 142 }; 143 #undef DECLARE_ENUM 144 145 // Acquires resources for logging if the right flags are set. 146 static bool Setup(); 147 148 // Frees resources acquired in Setup. 149 static void TearDown(); 150 151 // Enable the computation of a sliding window of states. 152 static void EnableSlidingStateWindow(); 153 154 // Write a raw string to the log to be used as a preamble. 155 // No check is made that the 'preamble' is actually at the beginning 156 // of the log. The preample is used to write code events saved in the 157 // snapshot. 158 static void Preamble(const char* content); 159 160 // Emits an event with a string value -> (name, value). 161 static void StringEvent(const char* name, const char* value); 162 163 // Emits an event with an int value -> (name, value). 164 static void IntEvent(const char* name, int value); 165 166 // Emits an event with an handle value -> (name, location). 167 static void HandleEvent(const char* name, Object** location); 168 169 // Emits memory management events for C allocated structures. 170 static void NewEvent(const char* name, void* object, size_t size); 171 static void DeleteEvent(const char* name, void* object); 172 173 // Emits an event with a tag, and some resource usage information. 174 // -> (name, tag, <rusage information>). 175 // Currently, the resource usage information is a process time stamp 176 // and a real time timestamp. 177 static void ResourceEvent(const char* name, const char* tag); 178 179 // Emits an event that an undefined property was read from an 180 // object. 181 static void SuspectReadEvent(String* name, Object* obj); 182 183 // Emits an event when a message is put on or read from a debugging queue. 184 // DebugTag lets us put a call-site specific label on the event. 185 static void DebugTag(const char* call_site_tag); 186 static void DebugEvent(const char* event_type, Vector<uint16_t> parameter); 187 188 189 // ==== Events logged by --log-api. ==== 190 static void ApiNamedSecurityCheck(Object* key); 191 static void ApiIndexedSecurityCheck(uint32_t index); 192 static void ApiNamedPropertyAccess(const char* tag, 193 JSObject* holder, 194 Object* name); 195 static void ApiIndexedPropertyAccess(const char* tag, 196 JSObject* holder, 197 uint32_t index); 198 static void ApiObjectAccess(const char* tag, JSObject* obj); 199 static void ApiEntryCall(const char* name); 200 201 202 // ==== Events logged by --log-code. ==== 203 // Emits a code create event. 204 static void CodeCreateEvent(LogEventsAndTags tag, 205 Code* code, const char* source); 206 static void CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name); 207 static void CodeCreateEvent(LogEventsAndTags tag, Code* code, String* name, 208 String* source, int line); 209 static void CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count); 210 // Emits a code create event for a RegExp. 211 static void RegExpCodeCreateEvent(Code* code, String* source); 212 // Emits a code move event. 213 static void CodeMoveEvent(Address from, Address to); 214 // Emits a code delete event. 215 static void CodeDeleteEvent(Address from); 216 217 // ==== Events logged by --log-gc. ==== 218 // Heap sampling events: start, end, and individual types. 219 static void HeapSampleBeginEvent(const char* space, const char* kind); 220 static void HeapSampleEndEvent(const char* space, const char* kind); 221 static void HeapSampleItemEvent(const char* type, int number, int bytes); 222 static void HeapSampleJSConstructorEvent(const char* constructor, 223 int number, int bytes); 224 static void HeapSampleStats(const char* space, const char* kind, 225 int capacity, int used); 226 227 static void SharedLibraryEvent(const char* library_path, 228 uintptr_t start, 229 uintptr_t end); 230 static void SharedLibraryEvent(const wchar_t* library_path, 231 uintptr_t start, 232 uintptr_t end); 233 234 // ==== Events logged by --log-regexp ==== 235 // Regexp compilation and execution events. 236 237 static void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache); 238 239 // Log an event reported from generated code 240 static void LogRuntime(Vector<const char> format, JSArray* args); 241 242 #ifdef ENABLE_LOGGING_AND_PROFILING state()243 static StateTag state() { 244 return current_state_ ? current_state_->state() : OTHER; 245 } 246 is_logging()247 static bool is_logging() { 248 return is_logging_; 249 } 250 251 // Pause/Resume collection of profiling data. 252 // When data collection is paused, CPU Tick events are discarded until 253 // data collection is Resumed. 254 static void PauseProfiler(int flags); 255 static void ResumeProfiler(int flags); 256 static int GetActiveProfilerModules(); 257 258 // If logging is performed into a memory buffer, allows to 259 // retrieve previously written messages. See v8.h. 260 static int GetLogLines(int from_pos, char* dest_buf, int max_size); 261 262 // Logs all compiled functions found in the heap. 263 static void LogCompiledFunctions(); 264 265 private: 266 267 // Profiler's sampling interval (in milliseconds). 268 static const int kSamplingIntervalMs = 1; 269 270 // Size of window used for log records compression. 271 static const int kCompressionWindowSize = 4; 272 273 // Emits the profiler's first message. 274 static void ProfilerBeginEvent(); 275 276 // Emits aliases for compressed messages. 277 static void LogAliases(); 278 279 // Emits the source code of a regexp. Used by regexp events. 280 static void LogRegExpSource(Handle<JSRegExp> regexp); 281 282 // Emits a profiler tick event. Used by the profiler thread. 283 static void TickEvent(TickSample* sample, bool overflow); 284 285 static void ApiEvent(const char* name, ...); 286 287 // Logs a StringEvent regardless of whether FLAG_log is true. 288 static void UncheckedStringEvent(const char* name, const char* value); 289 290 // Stops logging and profiling in case of insufficient resources. 291 static void StopLoggingAndProfiling(); 292 293 // Returns whether profiler's sampler is active. 294 static bool IsProfilerSamplerActive(); 295 296 // The sampler used by the profiler and the sliding state window. 297 static Ticker* ticker_; 298 299 // When the statistical profile is active, profiler_ 300 // points to a Profiler, that handles collection 301 // of samples. 302 static Profiler* profiler_; 303 304 // A stack of VM states. 305 static VMState* current_state_; 306 307 // Singleton bottom or default vm state. 308 static VMState bottom_state_; 309 310 // SlidingStateWindow instance keeping a sliding window of the most 311 // recent VM states. 312 static SlidingStateWindow* sliding_state_window_; 313 314 // An array of log events names. 315 static const char** log_events_; 316 317 // An instance of helper created if log compression is enabled. 318 static CompressionHelper* compression_helper_; 319 320 // Internal implementation classes with access to 321 // private members. 322 friend class CompressionHelper; 323 friend class EventLog; 324 friend class TimeLog; 325 friend class Profiler; 326 friend class SlidingStateWindow; 327 friend class VMState; 328 329 friend class LoggerTestHelper; 330 331 static bool is_logging_; 332 #else is_logging()333 static bool is_logging() { return false; } 334 #endif 335 }; 336 337 338 // Class that extracts stack trace, used for profiling. 339 class StackTracer : public AllStatic { 340 public: 341 static void Trace(TickSample* sample); 342 }; 343 344 345 } } // namespace v8::internal 346 347 #endif // V8_LOG_H_ 348