// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_LOGGING_LOG_H_ #define V8_LOGGING_LOG_H_ #include #include #include #include #include "include/v8-callbacks.h" #include "include/v8-profiler.h" #include "src/base/platform/elapsed-timer.h" #include "src/execution/isolate.h" #include "src/logging/code-events.h" #include "src/objects/objects.h" namespace v8 { namespace sampler { class Sampler; } // namespace sampler namespace internal { struct TickSample; // V8FileLogger 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 // --log-api and --log-code. // // --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. // // --logfile // 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. // // --prof-sampling-interval // The interval between --prof samples, default is 1000 microseconds (5000 on // Android). // Forward declarations. class LogEventListener; class Isolate; class JitLogger; class LogFile; class LowLevelLogger; class LinuxPerfBasicLogger; class LinuxPerfJitLogger; class Profiler; class SourcePosition; class Ticker; #if defined(V8_OS_WIN) && defined(V8_ENABLE_ETW_STACK_WALKING) class ETWJitLogger; #endif #undef LOG #define LOG(isolate, Call) \ do { \ if (v8::internal::v8_flags.log) (isolate)->v8_file_logger()->Call; \ } while (false) #define LOG_CODE_EVENT(isolate, Call) \ do { \ auto&& logger = (isolate)->v8_file_logger(); \ if (logger->is_listening_to_code_events()) logger->Call; \ } while (false) class ExistingCodeLogger { public: using CodeTag = LogEventListener::CodeTag; explicit ExistingCodeLogger(Isolate* isolate, LogEventListener* listener = nullptr) : isolate_(isolate), listener_(listener) {} void LogCodeObjects(); void LogBuiltins(); void LogCompiledFunctions(bool ensure_source_positions_available = true); void LogExistingFunction( Handle shared, Handle code, LogEventListener::CodeTag tag = LogEventListener::CodeTag::kFunction); void LogCodeObject(Tagged object); #if defined(V8_OS_WIN) && defined(V8_ENABLE_ETW_STACK_WALKING) void LogInterpretedFunctions(); #endif // V8_OS_WIN && V8_ENABLE_ETW_STACK_WALKING private: Isolate* isolate_; LogEventListener* listener_; }; enum class LogSeparator; class V8FileLogger : public LogEventListener { public: explicit V8FileLogger(Isolate* isolate); ~V8FileLogger() override; // The separator is used to write an unescaped "," into the log. static const LogSeparator kNext; // Acquires resources for logging if the right flags are set. bool SetUp(Isolate* isolate); // Additional steps taken after the logger has been set up. void LateSetup(Isolate* isolate); // Frees resources acquired in SetUp. // When a temporary file is used for the log, returns its stream descriptor, // leaving the file open. V8_EXPORT_PRIVATE FILE* TearDownAndGetLogFile(); // Sets the current code event handler. void SetCodeEventHandler(uint32_t options, JitCodeEventHandler event_handler); #if defined(V8_OS_WIN) && defined(V8_ENABLE_ETW_STACK_WALKING) void SetEtwCodeEventHandler(uint32_t options); void ResetEtwCodeEventHandler(); #endif sampler::Sampler* sampler(); V8_EXPORT_PRIVATE std::string file_name() const; V8_EXPORT_PRIVATE void StopProfilerThread(); // Emits an event with a string value -> (name, value). V8_EXPORT_PRIVATE void StringEvent(const char* name, const char* value); // Emits an event with an int value -> (name, value). void IntPtrTEvent(const char* name, intptr_t value); // Emits memory management events for C allocated structures. void NewEvent(const char* name, void* object, size_t size); void DeleteEvent(const char* name, void* object); // ==== Events logged by --log-function-events ==== void FunctionEvent(const char* reason, int script_id, double time_delta_ms, int start_position, int end_position, Tagged function_name); void FunctionEvent(const char* reason, int script_id, double time_delta_ms, int start_position, int end_position, const char* function_name = nullptr, size_t function_name_length = 0, bool is_one_byte = true); void CompilationCacheEvent(const char* action, const char* cache_type, Tagged sfi); void ScriptEvent(ScriptEventType type, int script_id); void ScriptDetails(Tagged