00001 // Copyright 2006-2008 the V8 project authors. All rights reserved. 00002 // Redistribution and use in source and binary forms, with or without 00003 // modification, are permitted provided that the following conditions are 00004 // met: 00005 // 00006 // * Redistributions of source code must retain the above copyright 00007 // notice, this list of conditions and the following disclaimer. 00008 // * Redistributions in binary form must reproduce the above 00009 // copyright notice, this list of conditions and the following 00010 // disclaimer in the documentation and/or other materials provided 00011 // with the distribution. 00012 // * Neither the name of Google Inc. nor the names of its 00013 // contributors may be used to endorse or promote products derived 00014 // from this software without specific prior written permission. 00015 // 00016 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00017 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00018 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00019 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00020 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00021 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00022 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00026 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 00028 #ifndef V8_LOG_H_ 00029 #define V8_LOG_H_ 00030 00031 namespace v8 { namespace internal { 00032 00033 // Logger is used for collecting logging information from V8 during 00034 // execution. The result is dumped to a file. 00035 // 00036 // Available command line flags: 00037 // 00038 // --log 00039 // Minimal logging (no API, code, or GC sample events), default is off. 00040 // 00041 // --log-all 00042 // Log all events to the file, default is off. This is the same as combining 00043 // --log-api, --log-code, --log-gc, and --log-regexp. 00044 // 00045 // --log-api 00046 // Log API events to the logfile, default is off. --log-api implies --log. 00047 // 00048 // --log-code 00049 // Log code (create, move, and delete) events to the logfile, default is off. 00050 // --log-code implies --log. 00051 // 00052 // --log-gc 00053 // Log GC heap samples after each GC that can be processed by hp2ps, default 00054 // is off. --log-gc implies --log. 00055 // 00056 // --log-regexp 00057 // Log creation and use of regular expressions, Default is off. 00058 // --log-regexp implies --log. 00059 // 00060 // --logfile <filename> 00061 // Specify the name of the logfile, default is "v8.log". 00062 // 00063 // --prof 00064 // Collect statistical profiling information (ticks), default is off. The 00065 // tick profiler requires code events, so --prof implies --log-code. 00066 00067 // Forward declarations. 00068 class Ticker; 00069 class Profiler; 00070 class Semaphore; 00071 class SlidingStateWindow; 00072 00073 #undef LOG 00074 #ifdef ENABLE_LOGGING_AND_PROFILING 00075 #define LOG(Call) v8::internal::Logger::Call 00076 #else 00077 #define LOG(Call) ((void) 0) 00078 #endif 00079 00080 00081 class VMState { 00082 #ifdef ENABLE_LOGGING_AND_PROFILING 00083 public: 00084 explicit VMState(StateTag state); 00085 ~VMState(); 00086 00087 StateTag state() { return state_; } 00088 00089 private: 00090 StateTag state_; 00091 VMState* previous_; 00092 #else 00093 public: 00094 explicit VMState(StateTag state) {} 00095 #endif 00096 }; 00097 00098 00099 class Logger { 00100 public: 00101 // Opens the file for logging if the right flags are set. 00102 static bool Setup(); 00103 00104 // Closes file opened in Setup. 00105 static void TearDown(); 00106 00107 // Enable the computation of a sliding window of states. 00108 static void EnableSlidingStateWindow(); 00109 00110 // Write a raw string to the log to be used as a preamble. 00111 // No check is made that the 'preamble' is actually at the beginning 00112 // of the log. The preample is used to write code events saved in the 00113 // snapshot. 00114 static void Preamble(const char* content); 00115 00116 // ==== Events that are always logged. ==== 00117 // Emits an event with a string value -> (name, value). 00118 static void StringEvent(const char* name, const char* value); 00119 00120 // Emits an event with an int value -> (name, value). 00121 static void IntEvent(const char* name, int value); 00122 00123 // Emits an event with an handle value -> (name, location). 00124 static void HandleEvent(const char* name, Object** location); 00125 00126 // Emits memory management events for C allocated structures. 00127 static void NewEvent(const char* name, void* object, size_t size); 00128 static void DeleteEvent(const char* name, void* object); 00129 00130 // Emits an event with a tag, and some resource usage information. 00131 // -> (name, tag, <rusage information>). 00132 // Currently, the resource usage information is a process time stamp 00133 // and a real time timestamp. 00134 static void ResourceEvent(const char* name, const char* tag); 00135 00136 // Emits an event that an undefined property was read from an 00137 // object. 00138 static void SuspectReadEvent(String* name, String* obj); 00139 00140 // Emits an event when a message is put on or read from a debugging queue. 00141 // DebugTag lets us put a call-site specific label on the event. 00142 static void DebugTag(const char* call_site_tag); 00143 static void DebugEvent(const char* event_type, Vector<uint16_t> parameter); 00144 00145 00146 // ==== Events logged by --log-api. ==== 00147 static void ApiNamedSecurityCheck(Object* key); 00148 static void ApiIndexedSecurityCheck(uint32_t index); 00149 static void ApiNamedPropertyAccess(const char* tag, 00150 JSObject* holder, 00151 Object* name); 00152 static void ApiIndexedPropertyAccess(const char* tag, 00153 JSObject* holder, 00154 uint32_t index); 00155 static void ApiObjectAccess(const char* tag, JSObject* obj); 00156 static void ApiEntryCall(const char* name); 00157 00158 00159 // ==== Events logged by --log-code. ==== 00160 // Emits a code create event. 00161 static void CodeCreateEvent(const char* tag, Code* code, const char* source); 00162 static void CodeCreateEvent(const char* tag, Code* code, String* name); 00163 static void CodeCreateEvent(const char* tag, Code* code, int args_count); 00164 // Emits a code move event. 00165 static void CodeMoveEvent(Address from, Address to); 00166 // Emits a code delete event. 00167 static void CodeDeleteEvent(Address from); 00168 00169 // ==== Events logged by --log-gc. ==== 00170 // Heap sampling events: start, end, and individual types. 00171 static void HeapSampleBeginEvent(const char* space, const char* kind); 00172 static void HeapSampleEndEvent(const char* space, const char* kind); 00173 static void HeapSampleItemEvent(const char* type, int number, int bytes); 00174 00175 static void SharedLibraryEvent(const char* library_path, 00176 unsigned start, 00177 unsigned end); 00178 static void SharedLibraryEvent(const wchar_t* library_path, 00179 unsigned start, 00180 unsigned end); 00181 00182 // ==== Events logged by --log-regexp ==== 00183 // Regexp compilation and execution events. 00184 00185 static void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache); 00186 00187 static void RegExpExecEvent(Handle<JSRegExp> regexp, 00188 int start_index, 00189 Handle<String> input_string); 00190 00191 #ifdef ENABLE_LOGGING_AND_PROFILING 00192 static StateTag state() { 00193 return current_state_ ? current_state_->state() : OTHER; 00194 } 00195 #endif 00196 00197 #ifdef ENABLE_LOGGING_AND_PROFILING 00198 private: 00199 00200 // Emits the source code of a regexp. Used by regexp events. 00201 static void LogRegExpSource(Handle<JSRegExp> regexp); 00202 00203 static void LogString(Handle<String> str); 00204 00205 // Emits a profiler tick event. Used by the profiler thread. 00206 static void TickEvent(TickSample* sample, bool overflow); 00207 00208 static void ApiEvent(const char* name, ...); 00209 00210 // When logging is active, logfile_ refers the file 00211 // events are written to. 00212 static FILE* logfile_; 00213 00214 // The sampler used by the profiler and the sliding state window. 00215 static Ticker* ticker_; 00216 00217 // When the statistical profile is active, profiler_ 00218 // points to a Profiler, that handles collection 00219 // of samples. 00220 static Profiler* profiler_; 00221 00222 // mutex_ is a Mutex used for enforcing exclusive 00223 // access to the log file. 00224 static Mutex* mutex_; 00225 00226 // A stack of VM states. 00227 static VMState* current_state_; 00228 00229 // SlidingStateWindow instance keeping a sliding window of the most 00230 // recent VM states. 00231 static SlidingStateWindow* sliding_state_window_; 00232 00233 // Internal implementation classes with access to 00234 // private members. 00235 friend class EventLog; 00236 friend class TimeLog; 00237 friend class Profiler; 00238 friend class SlidingStateWindow; 00239 friend class VMState; 00240 #endif 00241 }; 00242 00243 00244 } } // namespace v8::internal 00245 00246 #endif // V8_LOG_H_