LCOV - code coverage report
Current view: top level - src - log.h (source / functions) Hit Total Coverage
Test: app.info Lines: 6 16 37.5 %
Date: 2017-04-26 Functions: 3 13 23.1 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_LOG_H_
       6             : #define V8_LOG_H_
       7             : 
       8             : #include <string>
       9             : 
      10             : #include "src/allocation.h"
      11             : #include "src/base/compiler-specific.h"
      12             : #include "src/base/platform/elapsed-timer.h"
      13             : #include "src/base/platform/platform.h"
      14             : #include "src/code-events.h"
      15             : #include "src/isolate.h"
      16             : #include "src/objects.h"
      17             : 
      18             : namespace v8 {
      19             : 
      20             : struct TickSample;
      21             : 
      22             : namespace sampler {
      23             : class Sampler;
      24             : }
      25             : 
      26             : namespace internal {
      27             : 
      28             : // Logger is used for collecting logging information from V8 during
      29             : // execution. The result is dumped to a file.
      30             : //
      31             : // Available command line flags:
      32             : //
      33             : //  --log
      34             : // Minimal logging (no API, code, or GC sample events), default is off.
      35             : //
      36             : // --log-all
      37             : // Log all events to the file, default is off.  This is the same as combining
      38             : // --log-api, --log-code, --log-gc, and --log-regexp.
      39             : //
      40             : // --log-api
      41             : // Log API events to the logfile, default is off.  --log-api implies --log.
      42             : //
      43             : // --log-code
      44             : // Log code (create, move, and delete) events to the logfile, default is off.
      45             : // --log-code implies --log.
      46             : //
      47             : // --log-gc
      48             : // Log GC heap samples after each GC that can be processed by hp2ps, default
      49             : // is off.  --log-gc implies --log.
      50             : //
      51             : // --log-regexp
      52             : // Log creation and use of regular expressions, Default is off.
      53             : // --log-regexp implies --log.
      54             : //
      55             : // --logfile <filename>
      56             : // Specify the name of the logfile, default is "v8.log".
      57             : //
      58             : // --prof
      59             : // Collect statistical profiling information (ticks), default is off.  The
      60             : // tick profiler requires code events, so --prof implies --log-code.
      61             : //
      62             : // --prof-sampling-interval <microseconds>
      63             : // The interval between --prof samples, default is 1000 microseconds (5000 on
      64             : // Android).
      65             : 
      66             : // Forward declarations.
      67             : class CodeEventListener;
      68             : class CpuProfiler;
      69             : class Isolate;
      70             : class JitLogger;
      71             : class Log;
      72             : class LowLevelLogger;
      73             : class PerfBasicLogger;
      74             : class PerfJitLogger;
      75             : class Profiler;
      76             : class ProfilerListener;
      77             : class RuntimeCallTimer;
      78             : class Ticker;
      79             : 
      80             : #undef LOG
      81             : #define LOG(isolate, Call)                              \
      82             :   do {                                                  \
      83             :     v8::internal::Logger* logger = (isolate)->logger(); \
      84             :     if (logger->is_logging()) logger->Call;             \
      85             :   } while (false)
      86             : 
      87             : #define LOG_CODE_EVENT(isolate, Call)                   \
      88             :   do {                                                  \
      89             :     v8::internal::Logger* logger = (isolate)->logger(); \
      90             :     if (logger->is_logging_code_events()) logger->Call; \
      91             :   } while (false)
      92             : 
      93             : class Logger : public CodeEventListener {
      94             :  public:
      95             :   enum StartEnd { START = 0, END = 1 };
      96             : 
      97             :   // Acquires resources for logging if the right flags are set.
      98             :   bool SetUp(Isolate* isolate);
      99             : 
     100             :   // Sets the current code event handler.
     101             :   void SetCodeEventHandler(uint32_t options,
     102             :                            JitCodeEventHandler event_handler);
     103             : 
     104             :   // Sets up ProfilerListener.
     105             :   void SetUpProfilerListener();
     106             : 
     107             :   // Tear down ProfilerListener if it has no observers.
     108             :   void TearDownProfilerListener();
     109             : 
     110             :   sampler::Sampler* sampler();
     111             : 
     112             :   ProfilerListener* profiler_listener() { return profiler_listener_.get(); }
     113             : 
     114             :   // Frees resources acquired in SetUp.
     115             :   // When a temporary file is used for the log, returns its stream descriptor,
     116             :   // leaving the file open.
     117             :   FILE* TearDown();
     118             : 
     119             :   // Emits an event with a string value -> (name, value).
     120             :   void StringEvent(const char* name, const char* value);
     121             : 
     122             :   // Emits an event with an int value -> (name, value).
     123             :   void IntEvent(const char* name, int value);
     124             :   void IntPtrTEvent(const char* name, intptr_t value);
     125             : 
     126             :   // Emits an event with an handle value -> (name, location).
     127             :   void HandleEvent(const char* name, Object** location);
     128             : 
     129             :   // Emits memory management events for C allocated structures.
     130             :   void NewEvent(const char* name, void* object, size_t size);
     131             :   void DeleteEvent(const char* name, void* object);
     132             : 
     133             :   // Emits an event with a tag, and some resource usage information.
     134             :   // -> (name, tag, <rusage information>).
     135             :   // Currently, the resource usage information is a process time stamp
     136             :   // and a real time timestamp.
     137             :   void ResourceEvent(const char* name, const char* tag);
     138             : 
     139             :   // Emits an event that an undefined property was read from an
     140             :   // object.
     141             :   void SuspectReadEvent(Name* name, Object* obj);
     142             : 
     143             :   // ==== Events logged by --log-api. ====
     144             :   void ApiSecurityCheck();
     145             :   void ApiNamedPropertyAccess(const char* tag, JSObject* holder, Object* name);
     146             :   void ApiIndexedPropertyAccess(const char* tag,
     147             :                                 JSObject* holder,
     148             :                                 uint32_t index);
     149             :   void ApiObjectAccess(const char* tag, JSObject* obj);
     150             :   void ApiEntryCall(const char* name);
     151             : 
     152             :   // ==== Events logged by --log-code. ====
     153             :   void addCodeEventListener(CodeEventListener* listener);
     154             :   void removeCodeEventListener(CodeEventListener* listener);
     155             : 
     156             :   // Emits a code event for a callback function.
     157             :   void CallbackEvent(Name* name, Address entry_point);
     158             :   void GetterCallbackEvent(Name* name, Address entry_point);
     159             :   void SetterCallbackEvent(Name* name, Address entry_point);
     160             :   // Emits a code create event.
     161             :   void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
     162             :                        AbstractCode* code, const char* source);
     163             :   void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
     164             :                        AbstractCode* code, Name* name);
     165             :   void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
     166             :                        AbstractCode* code, SharedFunctionInfo* shared,
     167             :                        Name* name);
     168             :   void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
     169             :                        AbstractCode* code, SharedFunctionInfo* shared,
     170             :                        Name* source, int line, int column);
     171             :   void CodeCreateEvent(CodeEventListener::LogEventsAndTags tag,
     172             :                        AbstractCode* code, int args_count);
     173             :   // Emits a code deoptimization event.
     174             :   void CodeDisableOptEvent(AbstractCode* code, SharedFunctionInfo* shared);
     175             :   void CodeMovingGCEvent();
     176             :   // Emits a code create event for a RegExp.
     177             :   void RegExpCodeCreateEvent(AbstractCode* code, String* source);
     178             :   // Emits a code move event.
     179             :   void CodeMoveEvent(AbstractCode* from, Address to);
     180             :   // Emits a code line info record event.
     181             :   void CodeLinePosInfoRecordEvent(AbstractCode* code,
     182             :                                   ByteArray* source_position_table);
     183             : 
     184             :   void SharedFunctionInfoMoveEvent(Address from, Address to);
     185             : 
     186             :   void CodeNameEvent(Address addr, int pos, const char* code_name);
     187             : 
     188             :   void CodeDeoptEvent(Code* code, DeoptKind kind, Address pc,
     189             :                       int fp_to_sp_delta);
     190             : 
     191             :   void ICEvent(const char* type, bool keyed, const Address pc, int line,
     192             :                int column, Map* map, Object* key, char old_state,
     193             :                char new_state, const char* modifier,
     194             :                const char* slow_stub_reason);
     195             :   void CompareIC(const Address pc, int line, int column, Code* stub,
     196             :                  const char* op, const char* old_left, const char* old_right,
     197             :                  const char* old_state, const char* new_left,
     198             :                  const char* new_right, const char* new_state);
     199             :   void BinaryOpIC(const Address pc, int line, int column, Code* stub,
     200             :                   const char* old_state, const char* new_state,
     201             :                   AllocationSite* allocation_site);
     202             :   void ToBooleanIC(const Address pc, int line, int column, Code* stub,
     203             :                    const char* old_state, const char* new_state);
     204             :   void PatchIC(const Address pc, const Address test, int delta);
     205             : 
     206             :   // ==== Events logged by --log-gc. ====
     207             :   // Heap sampling events: start, end, and individual types.
     208             :   void HeapSampleBeginEvent(const char* space, const char* kind);
     209             :   void HeapSampleEndEvent(const char* space, const char* kind);
     210             :   void HeapSampleItemEvent(const char* type, int number, int bytes);
     211             :   void HeapSampleJSConstructorEvent(const char* constructor,
     212             :                                     int number, int bytes);
     213             :   void HeapSampleJSRetainersEvent(const char* constructor,
     214             :                                          const char* event);
     215             :   void HeapSampleJSProducerEvent(const char* constructor,
     216             :                                  Address* stack);
     217             :   void HeapSampleStats(const char* space, const char* kind,
     218             :                        intptr_t capacity, intptr_t used);
     219             : 
     220             :   void SharedLibraryEvent(const std::string& library_path, uintptr_t start,
     221             :                           uintptr_t end, intptr_t aslr_slide);
     222             : 
     223             :   void CurrentTimeEvent();
     224             : 
     225             :   void TimerEvent(StartEnd se, const char* name);
     226             : 
     227             :   static void EnterExternal(Isolate* isolate);
     228             :   static void LeaveExternal(Isolate* isolate);
     229             : 
     230           0 :   static void DefaultEventLoggerSentinel(const char* name, int event) {}
     231             : 
     232             :   INLINE(static void CallEventLogger(Isolate* isolate, const char* name,
     233             :                                      StartEnd se, bool expose_to_api));
     234             : 
     235           0 :   bool is_logging() {
     236           0 :     return is_logging_;
     237             :   }
     238             : 
     239     8416998 :   bool is_logging_code_events() {
     240     8416998 :     return is_logging() || jit_logger_ != NULL;
     241             :   }
     242             : 
     243             :   // Stop collection of profiling data.
     244             :   // When data collection is paused, CPU Tick events are discarded.
     245             :   void StopProfiler();
     246             : 
     247             :   void LogExistingFunction(Handle<SharedFunctionInfo> shared,
     248             :                            Handle<AbstractCode> code);
     249             :   // Logs all compiled functions found in the heap.
     250             :   void LogCompiledFunctions();
     251             :   // Logs all accessor callbacks found in the heap.
     252             :   void LogAccessorCallbacks();
     253             :   // Used for logging stubs found in the snapshot.
     254             :   void LogCodeObjects();
     255             :   // Used for logging bytecode handlers found in the snapshot.
     256             :   void LogBytecodeHandlers();
     257             : 
     258             :   // Converts tag to a corresponding NATIVE_... if the script is native.
     259             :   INLINE(static CodeEventListener::LogEventsAndTags ToNativeByScript(
     260             :       CodeEventListener::LogEventsAndTags, Script*));
     261             : 
     262             :   // Callback from Log, stops profiling in case of insufficient resources.
     263             :   void LogFailure();
     264             : 
     265             :  private:
     266             :   explicit Logger(Isolate* isolate);
     267             :   ~Logger();
     268             : 
     269             :   // Emits the profiler's first message.
     270             :   void ProfilerBeginEvent();
     271             : 
     272             :   // Emits callback event messages.
     273             :   void CallbackEventInternal(const char* prefix,
     274             :                              Name* name,
     275             :                              Address entry_point);
     276             : 
     277             :   // Internal configurable move event.
     278             :   void MoveEventInternal(CodeEventListener::LogEventsAndTags event,
     279             :                          Address from, Address to);
     280             : 
     281             :   // Used for logging stubs found in the snapshot.
     282             :   void LogCodeObject(Object* code_object);
     283             : 
     284             :   // Helper method. It resets name_buffer_ and add tag name into it.
     285             :   void InitNameBuffer(CodeEventListener::LogEventsAndTags tag);
     286             : 
     287             :   // Emits a profiler tick event. Used by the profiler thread.
     288             :   void TickEvent(TickSample* sample, bool overflow);
     289             :   void RuntimeCallTimerEvent();
     290             : 
     291             :   PRINTF_FORMAT(2, 3) void ApiEvent(const char* format, ...);
     292             : 
     293             :   // Logs a StringEvent regardless of whether FLAG_log is true.
     294             :   void UncheckedStringEvent(const char* name, const char* value);
     295             : 
     296             :   // Logs an IntEvent regardless of whether FLAG_log is true.
     297             :   void UncheckedIntEvent(const char* name, int value);
     298             :   void UncheckedIntPtrTEvent(const char* name, intptr_t value);
     299             : 
     300             :   Isolate* isolate_;
     301             : 
     302             :   // The sampler used by the profiler and the sliding state window.
     303             :   Ticker* ticker_;
     304             : 
     305             :   // When the statistical profile is active, profiler_
     306             :   // points to a Profiler, that handles collection
     307             :   // of samples.
     308             :   Profiler* profiler_;
     309             : 
     310             :   // An array of log events names.
     311             :   const char* const* log_events_;
     312             : 
     313             :   // Internal implementation classes with access to
     314             :   // private members.
     315             :   friend class EventLog;
     316             :   friend class Isolate;
     317             :   friend class TimeLog;
     318             :   friend class Profiler;
     319             :   template <StateTag Tag> friend class VMState;
     320             :   friend class LoggerTestHelper;
     321             : 
     322             :   bool is_logging_;
     323             :   Log* log_;
     324             :   PerfBasicLogger* perf_basic_logger_;
     325             :   PerfJitLogger* perf_jit_logger_;
     326             :   LowLevelLogger* ll_logger_;
     327             :   JitLogger* jit_logger_;
     328             :   std::unique_ptr<ProfilerListener> profiler_listener_;
     329             :   List<CodeEventListener*> listeners_;
     330             : 
     331             :   // Guards against multiple calls to TearDown() that can happen in some tests.
     332             :   // 'true' between SetUp() and TearDown().
     333             :   bool is_initialized_;
     334             : 
     335             :   base::ElapsedTimer timer_;
     336             : 
     337             :   friend class CpuProfiler;
     338             : };
     339             : 
     340             : #define TIMER_EVENTS_LIST(V)    \
     341             :   V(RecompileSynchronous, true) \
     342             :   V(RecompileConcurrent, true)  \
     343             :   V(CompileIgnition, true)      \
     344             :   V(CompileFullCode, true)      \
     345             :   V(OptimizeCode, true)         \
     346             :   V(CompileCode, true)          \
     347             :   V(DeoptimizeCode, true)       \
     348             :   V(Execute, true)              \
     349             :   V(External, true)
     350             : 
     351             : #define V(TimerName, expose)                                                  \
     352             :   class TimerEvent##TimerName : public AllStatic {                            \
     353             :    public:                                                                    \
     354             :     static const char* name(void* unused = NULL) { return "V8." #TimerName; } \
     355             :     static bool expose_to_api() { return expose; }                            \
     356             :   };
     357             : TIMER_EVENTS_LIST(V)
     358             : #undef V
     359             : 
     360             : 
     361             : template <class TimerEvent>
     362             : class TimerEventScope {
     363             :  public:
     364    35464186 :   explicit TimerEventScope(Isolate* isolate) : isolate_(isolate) {
     365    35464186 :     LogTimerEvent(Logger::START);
     366      124580 :   }
     367             : 
     368    35464194 :   ~TimerEventScope() { LogTimerEvent(Logger::END); }
     369             : 
     370             :  private:
     371             :   void LogTimerEvent(Logger::StartEnd se);
     372             :   Isolate* isolate_;
     373             : };
     374             : 
     375             : class CodeEventLogger : public CodeEventListener {
     376             :  public:
     377             :   CodeEventLogger();
     378             :   ~CodeEventLogger() override;
     379             : 
     380             :   void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
     381             :                        const char* comment) override;
     382             :   void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
     383             :                        Name* name) override;
     384             :   void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
     385             :                        int args_count) override;
     386             :   void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
     387             :                        SharedFunctionInfo* shared, Name* name) override;
     388             :   void CodeCreateEvent(LogEventsAndTags tag, AbstractCode* code,
     389             :                        SharedFunctionInfo* shared, Name* source, int line,
     390             :                        int column) override;
     391             :   void RegExpCodeCreateEvent(AbstractCode* code, String* source) override;
     392             : 
     393           0 :   void CallbackEvent(Name* name, Address entry_point) override {}
     394           0 :   void GetterCallbackEvent(Name* name, Address entry_point) override {}
     395           0 :   void SetterCallbackEvent(Name* name, Address entry_point) override {}
     396           0 :   void SharedFunctionInfoMoveEvent(Address from, Address to) override {}
     397           0 :   void CodeMovingGCEvent() override {}
     398           0 :   void CodeDeoptEvent(Code* code, DeoptKind kind, Address pc,
     399           0 :                       int fp_to_sp_delta) override {}
     400             : 
     401             :  private:
     402             :   class NameBuffer;
     403             : 
     404             :   virtual void LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo* shared,
     405             :                                  const char* name, int length) = 0;
     406             : 
     407             :   NameBuffer* name_buffer_;
     408             : };
     409             : 
     410             : 
     411             : }  // namespace internal
     412             : }  // namespace v8
     413             : 
     414             : 
     415             : #endif  // V8_LOG_H_

Generated by: LCOV version 1.10