11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_LOGGING_LOG_H_
61cb0ef41Sopenharmony_ci#define V8_LOGGING_LOG_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <atomic>
91cb0ef41Sopenharmony_ci#include <memory>
101cb0ef41Sopenharmony_ci#include <set>
111cb0ef41Sopenharmony_ci#include <string>
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci#include "include/v8-callbacks.h"
141cb0ef41Sopenharmony_ci#include "include/v8-profiler.h"
151cb0ef41Sopenharmony_ci#include "src/base/platform/elapsed-timer.h"
161cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
171cb0ef41Sopenharmony_ci#include "src/logging/code-events.h"
181cb0ef41Sopenharmony_ci#include "src/objects/objects.h"
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_cinamespace v8 {
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_cinamespace sampler {
231cb0ef41Sopenharmony_ciclass Sampler;
241cb0ef41Sopenharmony_ci}  // namespace sampler
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_cinamespace internal {
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_cistruct TickSample;
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci// Logger is used for collecting logging information from V8 during
311cb0ef41Sopenharmony_ci// execution. The result is dumped to a file.
321cb0ef41Sopenharmony_ci//
331cb0ef41Sopenharmony_ci// Available command line flags:
341cb0ef41Sopenharmony_ci//
351cb0ef41Sopenharmony_ci//  --log
361cb0ef41Sopenharmony_ci// Minimal logging (no API, code, or GC sample events), default is off.
371cb0ef41Sopenharmony_ci//
381cb0ef41Sopenharmony_ci// --log-all
391cb0ef41Sopenharmony_ci// Log all events to the file, default is off.  This is the same as combining
401cb0ef41Sopenharmony_ci// --log-api and --log-code.
411cb0ef41Sopenharmony_ci//
421cb0ef41Sopenharmony_ci// --log-api
431cb0ef41Sopenharmony_ci// Log API events to the logfile, default is off.  --log-api implies --log.
441cb0ef41Sopenharmony_ci//
451cb0ef41Sopenharmony_ci// --log-code
461cb0ef41Sopenharmony_ci// Log code (create, move, and delete) events to the logfile, default is off.
471cb0ef41Sopenharmony_ci// --log-code implies --log.
481cb0ef41Sopenharmony_ci//
491cb0ef41Sopenharmony_ci// --logfile <filename>
501cb0ef41Sopenharmony_ci// Specify the name of the logfile, default is "v8.log".
511cb0ef41Sopenharmony_ci//
521cb0ef41Sopenharmony_ci// --prof
531cb0ef41Sopenharmony_ci// Collect statistical profiling information (ticks), default is off.  The
541cb0ef41Sopenharmony_ci// tick profiler requires code events, so --prof implies --log-code.
551cb0ef41Sopenharmony_ci//
561cb0ef41Sopenharmony_ci// --prof-sampling-interval <microseconds>
571cb0ef41Sopenharmony_ci// The interval between --prof samples, default is 1000 microseconds (5000 on
581cb0ef41Sopenharmony_ci// Android).
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci// Forward declarations.
611cb0ef41Sopenharmony_ciclass CodeEventListener;
621cb0ef41Sopenharmony_ciclass Isolate;
631cb0ef41Sopenharmony_ciclass JitLogger;
641cb0ef41Sopenharmony_ciclass Log;
651cb0ef41Sopenharmony_ciclass LowLevelLogger;
661cb0ef41Sopenharmony_ciclass PerfBasicLogger;
671cb0ef41Sopenharmony_ciclass PerfJitLogger;
681cb0ef41Sopenharmony_ciclass Profiler;
691cb0ef41Sopenharmony_ciclass SourcePosition;
701cb0ef41Sopenharmony_ciclass Ticker;
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci#undef LOG
731cb0ef41Sopenharmony_ci#define LOG(isolate, Call)                                 \
741cb0ef41Sopenharmony_ci  do {                                                     \
751cb0ef41Sopenharmony_ci    if (v8::internal::FLAG_log) (isolate)->logger()->Call; \
761cb0ef41Sopenharmony_ci  } while (false)
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci#define LOG_CODE_EVENT(isolate, Call)                        \
791cb0ef41Sopenharmony_ci  do {                                                       \
801cb0ef41Sopenharmony_ci    auto&& logger = (isolate)->logger();                     \
811cb0ef41Sopenharmony_ci    if (logger->is_listening_to_code_events()) logger->Call; \
821cb0ef41Sopenharmony_ci  } while (false)
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciclass ExistingCodeLogger {
851cb0ef41Sopenharmony_ci public:
861cb0ef41Sopenharmony_ci  explicit ExistingCodeLogger(Isolate* isolate,
871cb0ef41Sopenharmony_ci                              CodeEventListener* listener = nullptr)
881cb0ef41Sopenharmony_ci      : isolate_(isolate), listener_(listener) {}
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  void LogCodeObjects();
911cb0ef41Sopenharmony_ci  void LogBuiltins();
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  void LogCompiledFunctions();
941cb0ef41Sopenharmony_ci  void LogExistingFunction(Handle<SharedFunctionInfo> shared,
951cb0ef41Sopenharmony_ci                           Handle<AbstractCode> code,
961cb0ef41Sopenharmony_ci                           CodeEventListener::LogEventsAndTags tag =
971cb0ef41Sopenharmony_ci                               CodeEventListener::FUNCTION_TAG);
981cb0ef41Sopenharmony_ci  void LogCodeObject(Object object);
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci private:
1011cb0ef41Sopenharmony_ci  Isolate* isolate_;
1021cb0ef41Sopenharmony_ci  CodeEventListener* listener_;
1031cb0ef41Sopenharmony_ci};
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_cienum class LogSeparator;
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ciclass Logger : public CodeEventListener {
1081cb0ef41Sopenharmony_ci public:
1091cb0ef41Sopenharmony_ci  enum class ScriptEventType {
1101cb0ef41Sopenharmony_ci    kReserveId,
1111cb0ef41Sopenharmony_ci    kCreate,
1121cb0ef41Sopenharmony_ci    kDeserialize,
1131cb0ef41Sopenharmony_ci    kBackgroundCompile,
1141cb0ef41Sopenharmony_ci    kStreamingCompile
1151cb0ef41Sopenharmony_ci  };
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  explicit Logger(Isolate* isolate);
1181cb0ef41Sopenharmony_ci  ~Logger() override;
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  // The separator is used to write an unescaped "," into the log.
1211cb0ef41Sopenharmony_ci  static const LogSeparator kNext;
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci  // Acquires resources for logging if the right flags are set.
1241cb0ef41Sopenharmony_ci  bool SetUp(Isolate* isolate);
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci  // Additional steps taken after the logger has been set up.
1271cb0ef41Sopenharmony_ci  void LateSetup(Isolate* isolate);
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  // Frees resources acquired in SetUp.
1301cb0ef41Sopenharmony_ci  // When a temporary file is used for the log, returns its stream descriptor,
1311cb0ef41Sopenharmony_ci  // leaving the file open.
1321cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE FILE* TearDownAndGetLogFile();
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  // Sets the current code event handler.
1351cb0ef41Sopenharmony_ci  void SetCodeEventHandler(uint32_t options, JitCodeEventHandler event_handler);
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  sampler::Sampler* sampler();
1381cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE std::string file_name() const;
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void StopProfilerThread();
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ci  // Emits an event with a string value -> (name, value).
1431cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void StringEvent(const char* name, const char* value);
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  // Emits an event with an int value -> (name, value).
1461cb0ef41Sopenharmony_ci  void IntPtrTEvent(const char* name, intptr_t value);
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ci  // Emits memory management events for C allocated structures.
1491cb0ef41Sopenharmony_ci  void NewEvent(const char* name, void* object, size_t size);
1501cb0ef41Sopenharmony_ci  void DeleteEvent(const char* name, void* object);
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  // ==== Events logged by --log-function-events ====
1531cb0ef41Sopenharmony_ci  void FunctionEvent(const char* reason, int script_id, double time_delta_ms,
1541cb0ef41Sopenharmony_ci                     int start_position, int end_position,
1551cb0ef41Sopenharmony_ci                     String function_name);
1561cb0ef41Sopenharmony_ci  void FunctionEvent(const char* reason, int script_id, double time_delta_ms,
1571cb0ef41Sopenharmony_ci                     int start_position, int end_position,
1581cb0ef41Sopenharmony_ci                     const char* function_name = nullptr,
1591cb0ef41Sopenharmony_ci                     size_t function_name_length = 0, bool is_one_byte = true);
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci  void CompilationCacheEvent(const char* action, const char* cache_type,
1621cb0ef41Sopenharmony_ci                             SharedFunctionInfo sfi);
1631cb0ef41Sopenharmony_ci  void ScriptEvent(ScriptEventType type, int script_id);
1641cb0ef41Sopenharmony_ci  void ScriptDetails(Script script);
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  // ==== Events logged by --log-code. ====
1671cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void AddCodeEventListener(CodeEventListener* listener);
1681cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void RemoveCodeEventListener(CodeEventListener* listener);
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  // CodeEventListener implementation.
1711cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
1721cb0ef41Sopenharmony_ci                       const char* name) override;
1731cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
1741cb0ef41Sopenharmony_ci                       Handle<Name> name) override;
1751cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
1761cb0ef41Sopenharmony_ci                       Handle<SharedFunctionInfo> shared,
1771cb0ef41Sopenharmony_ci                       Handle<Name> script_name) override;
1781cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
1791cb0ef41Sopenharmony_ci                       Handle<SharedFunctionInfo> shared,
1801cb0ef41Sopenharmony_ci                       Handle<Name> script_name, int line, int column) override;
1811cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1821cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
1831cb0ef41Sopenharmony_ci                       wasm::WasmName name, const char* source_url,
1841cb0ef41Sopenharmony_ci                       int code_offset, int script_id) override;
1851cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci  void CallbackEvent(Handle<Name> name, Address entry_point) override;
1881cb0ef41Sopenharmony_ci  void GetterCallbackEvent(Handle<Name> name, Address entry_point) override;
1891cb0ef41Sopenharmony_ci  void SetterCallbackEvent(Handle<Name> name, Address entry_point) override;
1901cb0ef41Sopenharmony_ci  void RegExpCodeCreateEvent(Handle<AbstractCode> code,
1911cb0ef41Sopenharmony_ci                             Handle<String> source) override;
1921cb0ef41Sopenharmony_ci  void CodeMoveEvent(AbstractCode from, AbstractCode to) override;
1931cb0ef41Sopenharmony_ci  void SharedFunctionInfoMoveEvent(Address from, Address to) override;
1941cb0ef41Sopenharmony_ci  void NativeContextMoveEvent(Address from, Address to) override {}
1951cb0ef41Sopenharmony_ci  void CodeMovingGCEvent() override;
1961cb0ef41Sopenharmony_ci  void CodeDisableOptEvent(Handle<AbstractCode> code,
1971cb0ef41Sopenharmony_ci                           Handle<SharedFunctionInfo> shared) override;
1981cb0ef41Sopenharmony_ci  void CodeDeoptEvent(Handle<Code> code, DeoptimizeKind kind, Address pc,
1991cb0ef41Sopenharmony_ci                      int fp_to_sp_delta) override;
2001cb0ef41Sopenharmony_ci  void CodeDependencyChangeEvent(Handle<Code> code,
2011cb0ef41Sopenharmony_ci                                 Handle<SharedFunctionInfo> sfi,
2021cb0ef41Sopenharmony_ci                                 const char* reason) override;
2031cb0ef41Sopenharmony_ci  void FeedbackVectorEvent(FeedbackVector vector, AbstractCode code);
2041cb0ef41Sopenharmony_ci  void WeakCodeClearEvent() override {}
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci  void ProcessDeoptEvent(Handle<Code> code, SourcePosition position,
2071cb0ef41Sopenharmony_ci                         const char* kind, const char* reason);
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci  // Emits a code line info record event.
2101cb0ef41Sopenharmony_ci  void CodeLinePosInfoRecordEvent(Address code_start,
2111cb0ef41Sopenharmony_ci                                  ByteArray source_position_table,
2121cb0ef41Sopenharmony_ci                                  JitCodeEvent::CodeType code_type);
2131cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2141cb0ef41Sopenharmony_ci  void WasmCodeLinePosInfoRecordEvent(
2151cb0ef41Sopenharmony_ci      Address code_start, base::Vector<const byte> source_position_table);
2161cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci  void CodeNameEvent(Address addr, int pos, const char* code_name);
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci  void ICEvent(const char* type, bool keyed, Handle<Map> map,
2211cb0ef41Sopenharmony_ci               Handle<Object> key, char old_state, char new_state,
2221cb0ef41Sopenharmony_ci               const char* modifier, const char* slow_stub_reason);
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ci  void MapEvent(const char* type, Handle<Map> from, Handle<Map> to,
2251cb0ef41Sopenharmony_ci                const char* reason = nullptr,
2261cb0ef41Sopenharmony_ci                Handle<HeapObject> name_or_sfi = Handle<HeapObject>());
2271cb0ef41Sopenharmony_ci  void MapCreate(Map map);
2281cb0ef41Sopenharmony_ci  void MapDetails(Map map);
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci  void SharedLibraryEvent(const std::string& library_path, uintptr_t start,
2311cb0ef41Sopenharmony_ci                          uintptr_t end, intptr_t aslr_slide);
2321cb0ef41Sopenharmony_ci  void SharedLibraryEnd();
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci  void CurrentTimeEvent();
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void TimerEvent(v8::LogEventStatus se, const char* name);
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ci  void BasicBlockCounterEvent(const char* name, int block_id, uint32_t count);
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci  void BuiltinHashEvent(const char* name, int hash);
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci  static void EnterExternal(Isolate* isolate);
2431cb0ef41Sopenharmony_ci  static void LeaveExternal(Isolate* isolate);
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  static void DefaultEventLoggerSentinel(const char* name, int event) {}
2461cb0ef41Sopenharmony_ci
2471cb0ef41Sopenharmony_ci  V8_INLINE static void CallEventLoggerInternal(Isolate* isolate,
2481cb0ef41Sopenharmony_ci                                                const char* name,
2491cb0ef41Sopenharmony_ci                                                v8::LogEventStatus se,
2501cb0ef41Sopenharmony_ci                                                bool expose_to_api) {
2511cb0ef41Sopenharmony_ci    if (isolate->event_logger() == DefaultEventLoggerSentinel) {
2521cb0ef41Sopenharmony_ci      LOG(isolate, TimerEvent(se, name));
2531cb0ef41Sopenharmony_ci    } else if (expose_to_api) {
2541cb0ef41Sopenharmony_ci      isolate->event_logger()(name, static_cast<v8::LogEventStatus>(se));
2551cb0ef41Sopenharmony_ci    }
2561cb0ef41Sopenharmony_ci  }
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  V8_INLINE static void CallEventLogger(Isolate* isolate, const char* name,
2591cb0ef41Sopenharmony_ci                                        v8::LogEventStatus se,
2601cb0ef41Sopenharmony_ci                                        bool expose_to_api) {
2611cb0ef41Sopenharmony_ci    if (!isolate->event_logger()) return;
2621cb0ef41Sopenharmony_ci    CallEventLoggerInternal(isolate, name, se, expose_to_api);
2631cb0ef41Sopenharmony_ci  }
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE bool is_logging();
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  bool is_listening_to_code_events() override {
2681cb0ef41Sopenharmony_ci    return is_logging() || jit_logger_ != nullptr;
2691cb0ef41Sopenharmony_ci  }
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci  void LogExistingFunction(Handle<SharedFunctionInfo> shared,
2721cb0ef41Sopenharmony_ci                           Handle<AbstractCode> code);
2731cb0ef41Sopenharmony_ci  // Logs all compiled functions found in the heap.
2741cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void LogCompiledFunctions();
2751cb0ef41Sopenharmony_ci  // Logs all accessor callbacks found in the heap.
2761cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void LogAccessorCallbacks();
2771cb0ef41Sopenharmony_ci  // Used for logging stubs found in the snapshot.
2781cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void LogCodeObjects();
2791cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void LogBuiltins();
2801cb0ef41Sopenharmony_ci  // Logs all Maps found on the heap.
2811cb0ef41Sopenharmony_ci  void LogAllMaps();
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci  // Converts tag to a corresponding NATIVE_... if the script is native.
2841cb0ef41Sopenharmony_ci  V8_INLINE static CodeEventListener::LogEventsAndTags ToNativeByScript(
2851cb0ef41Sopenharmony_ci      CodeEventListener::LogEventsAndTags, Script);
2861cb0ef41Sopenharmony_ci
2871cb0ef41Sopenharmony_ci private:
2881cb0ef41Sopenharmony_ci  void UpdateIsLogging(bool value);
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_ci  // Emits the profiler's first message.
2911cb0ef41Sopenharmony_ci  void ProfilerBeginEvent();
2921cb0ef41Sopenharmony_ci
2931cb0ef41Sopenharmony_ci  // Emits callback event messages.
2941cb0ef41Sopenharmony_ci  void CallbackEventInternal(const char* prefix, Handle<Name> name,
2951cb0ef41Sopenharmony_ci                             Address entry_point);
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci  // Internal configurable move event.
2981cb0ef41Sopenharmony_ci  void MoveEventInternal(CodeEventListener::LogEventsAndTags event,
2991cb0ef41Sopenharmony_ci                         Address from, Address to);
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci  // Helper method. It resets name_buffer_ and add tag name into it.
3021cb0ef41Sopenharmony_ci  void InitNameBuffer(CodeEventListener::LogEventsAndTags tag);
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  // Emits a profiler tick event. Used by the profiler thread.
3051cb0ef41Sopenharmony_ci  void TickEvent(TickSample* sample, bool overflow);
3061cb0ef41Sopenharmony_ci  void RuntimeCallTimerEvent();
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci  // Logs a StringEvent regardless of whether FLAG_log is true.
3091cb0ef41Sopenharmony_ci  void UncheckedStringEvent(const char* name, const char* value);
3101cb0ef41Sopenharmony_ci
3111cb0ef41Sopenharmony_ci  // Logs a scripts sources. Keeps track of all logged scripts to ensure that
3121cb0ef41Sopenharmony_ci  // each script is logged only once.
3131cb0ef41Sopenharmony_ci  bool EnsureLogScriptSource(Script script);
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ci  void LogSourceCodeInformation(Handle<AbstractCode> code,
3161cb0ef41Sopenharmony_ci                                Handle<SharedFunctionInfo> shared);
3171cb0ef41Sopenharmony_ci  void LogCodeDisassemble(Handle<AbstractCode> code);
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ci  void WriteApiSecurityCheck();
3201cb0ef41Sopenharmony_ci  void WriteApiNamedPropertyAccess(const char* tag, JSObject holder,
3211cb0ef41Sopenharmony_ci                                   Object name);
3221cb0ef41Sopenharmony_ci  void WriteApiIndexedPropertyAccess(const char* tag, JSObject holder,
3231cb0ef41Sopenharmony_ci                                     uint32_t index);
3241cb0ef41Sopenharmony_ci  void WriteApiObjectAccess(const char* tag, JSReceiver obj);
3251cb0ef41Sopenharmony_ci  void WriteApiEntryCall(const char* name);
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_ci  int64_t Time();
3281cb0ef41Sopenharmony_ci
3291cb0ef41Sopenharmony_ci  Isolate* isolate_;
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ci  // The sampler used by the profiler and the sliding state window.
3321cb0ef41Sopenharmony_ci  std::unique_ptr<Ticker> ticker_;
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ci  // When the statistical profile is active, profiler_
3351cb0ef41Sopenharmony_ci  // points to a Profiler, that handles collection
3361cb0ef41Sopenharmony_ci  // of samples.
3371cb0ef41Sopenharmony_ci  std::unique_ptr<Profiler> profiler_;
3381cb0ef41Sopenharmony_ci
3391cb0ef41Sopenharmony_ci  // Internal implementation classes with access to private members.
3401cb0ef41Sopenharmony_ci  friend class Profiler;
3411cb0ef41Sopenharmony_ci
3421cb0ef41Sopenharmony_ci  std::atomic<bool> is_logging_;
3431cb0ef41Sopenharmony_ci  std::unique_ptr<Log> log_;
3441cb0ef41Sopenharmony_ci#if V8_OS_LINUX
3451cb0ef41Sopenharmony_ci  std::unique_ptr<PerfBasicLogger> perf_basic_logger_;
3461cb0ef41Sopenharmony_ci  std::unique_ptr<PerfJitLogger> perf_jit_logger_;
3471cb0ef41Sopenharmony_ci#endif
3481cb0ef41Sopenharmony_ci  std::unique_ptr<LowLevelLogger> ll_logger_;
3491cb0ef41Sopenharmony_ci  std::unique_ptr<JitLogger> jit_logger_;
3501cb0ef41Sopenharmony_ci#ifdef ENABLE_GDB_JIT_INTERFACE
3511cb0ef41Sopenharmony_ci  std::unique_ptr<JitLogger> gdb_jit_logger_;
3521cb0ef41Sopenharmony_ci#endif
3531cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN) && defined(V8_ENABLE_SYSTEM_INSTRUMENTATION)
3541cb0ef41Sopenharmony_ci  std::unique_ptr<JitLogger> etw_jit_logger_;
3551cb0ef41Sopenharmony_ci#endif
3561cb0ef41Sopenharmony_ci  std::set<int> logged_source_code_;
3571cb0ef41Sopenharmony_ci  uint32_t next_source_info_id_ = 0;
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_ci  // Guards against multiple calls to TearDown() that can happen in some tests.
3601cb0ef41Sopenharmony_ci  // 'true' between SetUp() and TearDown().
3611cb0ef41Sopenharmony_ci  bool is_initialized_;
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ci  ExistingCodeLogger existing_code_logger_;
3641cb0ef41Sopenharmony_ci
3651cb0ef41Sopenharmony_ci  base::ElapsedTimer timer_;
3661cb0ef41Sopenharmony_ci};
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci#define TIMER_EVENTS_LIST(V)     \
3691cb0ef41Sopenharmony_ci  V(RecompileSynchronous, true)  \
3701cb0ef41Sopenharmony_ci  V(RecompileConcurrent, true)   \
3711cb0ef41Sopenharmony_ci  V(CompileIgnition, true)       \
3721cb0ef41Sopenharmony_ci  V(CompileFullCode, true)       \
3731cb0ef41Sopenharmony_ci  V(OptimizeCode, true)          \
3741cb0ef41Sopenharmony_ci  V(CompileCode, true)           \
3751cb0ef41Sopenharmony_ci  V(CompileCodeBackground, true) \
3761cb0ef41Sopenharmony_ci  V(DeoptimizeCode, true)        \
3771cb0ef41Sopenharmony_ci  V(Execute, true)
3781cb0ef41Sopenharmony_ci
3791cb0ef41Sopenharmony_ci#define V(TimerName, expose)                          \
3801cb0ef41Sopenharmony_ci  class TimerEvent##TimerName : public AllStatic {    \
3811cb0ef41Sopenharmony_ci   public:                                            \
3821cb0ef41Sopenharmony_ci    static const char* name(void* unused = nullptr) { \
3831cb0ef41Sopenharmony_ci      return "V8." #TimerName;                        \
3841cb0ef41Sopenharmony_ci    }                                                 \
3851cb0ef41Sopenharmony_ci    static bool expose_to_api() { return expose; }    \
3861cb0ef41Sopenharmony_ci  };
3871cb0ef41Sopenharmony_ciTIMER_EVENTS_LIST(V)
3881cb0ef41Sopenharmony_ci#undef V
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_citemplate <class TimerEvent>
3911cb0ef41Sopenharmony_ciclass V8_NODISCARD TimerEventScope {
3921cb0ef41Sopenharmony_ci public:
3931cb0ef41Sopenharmony_ci  explicit TimerEventScope(Isolate* isolate) : isolate_(isolate) {
3941cb0ef41Sopenharmony_ci    LogTimerEvent(v8::LogEventStatus::kStart);
3951cb0ef41Sopenharmony_ci  }
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ci  ~TimerEventScope() { LogTimerEvent(v8::LogEventStatus::kEnd); }
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci private:
4001cb0ef41Sopenharmony_ci  void LogTimerEvent(v8::LogEventStatus se);
4011cb0ef41Sopenharmony_ci  Isolate* isolate_;
4021cb0ef41Sopenharmony_ci};
4031cb0ef41Sopenharmony_ci
4041cb0ef41Sopenharmony_ci// Abstract
4051cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE CodeEventLogger : public CodeEventListener {
4061cb0ef41Sopenharmony_ci public:
4071cb0ef41Sopenharmony_ci  explicit CodeEventLogger(Isolate* isolate);
4081cb0ef41Sopenharmony_ci  ~CodeEventLogger() override;
4091cb0ef41Sopenharmony_ci
4101cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
4111cb0ef41Sopenharmony_ci                       const char* name) override;
4121cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
4131cb0ef41Sopenharmony_ci                       Handle<Name> name) override;
4141cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
4151cb0ef41Sopenharmony_ci                       Handle<SharedFunctionInfo> shared,
4161cb0ef41Sopenharmony_ci                       Handle<Name> script_name) override;
4171cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
4181cb0ef41Sopenharmony_ci                       Handle<SharedFunctionInfo> shared,
4191cb0ef41Sopenharmony_ci                       Handle<Name> script_name, int line, int column) override;
4201cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
4211cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
4221cb0ef41Sopenharmony_ci                       wasm::WasmName name, const char* source_url,
4231cb0ef41Sopenharmony_ci                       int code_offset, int script_id) override;
4241cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_ci  void RegExpCodeCreateEvent(Handle<AbstractCode> code,
4271cb0ef41Sopenharmony_ci                             Handle<String> source) override;
4281cb0ef41Sopenharmony_ci  void CallbackEvent(Handle<Name> name, Address entry_point) override {}
4291cb0ef41Sopenharmony_ci  void GetterCallbackEvent(Handle<Name> name, Address entry_point) override {}
4301cb0ef41Sopenharmony_ci  void SetterCallbackEvent(Handle<Name> name, Address entry_point) override {}
4311cb0ef41Sopenharmony_ci  void SharedFunctionInfoMoveEvent(Address from, Address to) override {}
4321cb0ef41Sopenharmony_ci  void NativeContextMoveEvent(Address from, Address to) override {}
4331cb0ef41Sopenharmony_ci  void CodeMovingGCEvent() override {}
4341cb0ef41Sopenharmony_ci  void CodeDeoptEvent(Handle<Code> code, DeoptimizeKind kind, Address pc,
4351cb0ef41Sopenharmony_ci                      int fp_to_sp_delta) override {}
4361cb0ef41Sopenharmony_ci  void CodeDependencyChangeEvent(Handle<Code> code,
4371cb0ef41Sopenharmony_ci                                 Handle<SharedFunctionInfo> sfi,
4381cb0ef41Sopenharmony_ci                                 const char* reason) override {}
4391cb0ef41Sopenharmony_ci  void WeakCodeClearEvent() override {}
4401cb0ef41Sopenharmony_ci
4411cb0ef41Sopenharmony_ci  bool is_listening_to_code_events() override { return true; }
4421cb0ef41Sopenharmony_ci
4431cb0ef41Sopenharmony_ci protected:
4441cb0ef41Sopenharmony_ci  Isolate* isolate_;
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci private:
4471cb0ef41Sopenharmony_ci  class NameBuffer;
4481cb0ef41Sopenharmony_ci
4491cb0ef41Sopenharmony_ci  virtual void LogRecordedBuffer(Handle<AbstractCode> code,
4501cb0ef41Sopenharmony_ci                                 MaybeHandle<SharedFunctionInfo> maybe_shared,
4511cb0ef41Sopenharmony_ci                                 const char* name, int length) = 0;
4521cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
4531cb0ef41Sopenharmony_ci  virtual void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
4541cb0ef41Sopenharmony_ci                                 int length) = 0;
4551cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci  std::unique_ptr<NameBuffer> name_buffer_;
4581cb0ef41Sopenharmony_ci};
4591cb0ef41Sopenharmony_ci
4601cb0ef41Sopenharmony_cistruct CodeEvent {
4611cb0ef41Sopenharmony_ci  Isolate* isolate_;
4621cb0ef41Sopenharmony_ci  uintptr_t code_start_address;
4631cb0ef41Sopenharmony_ci  size_t code_size;
4641cb0ef41Sopenharmony_ci  Handle<String> function_name;
4651cb0ef41Sopenharmony_ci  Handle<String> script_name;
4661cb0ef41Sopenharmony_ci  int script_line;
4671cb0ef41Sopenharmony_ci  int script_column;
4681cb0ef41Sopenharmony_ci  CodeEventType code_type;
4691cb0ef41Sopenharmony_ci  const char* comment;
4701cb0ef41Sopenharmony_ci  uintptr_t previous_code_start_address;
4711cb0ef41Sopenharmony_ci};
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ciclass ExternalCodeEventListener : public CodeEventListener {
4741cb0ef41Sopenharmony_ci public:
4751cb0ef41Sopenharmony_ci  explicit ExternalCodeEventListener(Isolate* isolate);
4761cb0ef41Sopenharmony_ci  ~ExternalCodeEventListener() override;
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
4791cb0ef41Sopenharmony_ci                       const char* comment) override;
4801cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
4811cb0ef41Sopenharmony_ci                       Handle<Name> name) override;
4821cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
4831cb0ef41Sopenharmony_ci                       Handle<SharedFunctionInfo> shared,
4841cb0ef41Sopenharmony_ci                       Handle<Name> name) override;
4851cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
4861cb0ef41Sopenharmony_ci                       Handle<SharedFunctionInfo> shared, Handle<Name> source,
4871cb0ef41Sopenharmony_ci                       int line, int column) override;
4881cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
4891cb0ef41Sopenharmony_ci  void CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
4901cb0ef41Sopenharmony_ci                       wasm::WasmName name, const char* source_url,
4911cb0ef41Sopenharmony_ci                       int code_offset, int script_id) override;
4921cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
4931cb0ef41Sopenharmony_ci
4941cb0ef41Sopenharmony_ci  void RegExpCodeCreateEvent(Handle<AbstractCode> code,
4951cb0ef41Sopenharmony_ci                             Handle<String> source) override;
4961cb0ef41Sopenharmony_ci  void CallbackEvent(Handle<Name> name, Address entry_point) override {}
4971cb0ef41Sopenharmony_ci  void GetterCallbackEvent(Handle<Name> name, Address entry_point) override {}
4981cb0ef41Sopenharmony_ci  void SetterCallbackEvent(Handle<Name> name, Address entry_point) override {}
4991cb0ef41Sopenharmony_ci  void SharedFunctionInfoMoveEvent(Address from, Address to) override {}
5001cb0ef41Sopenharmony_ci  void NativeContextMoveEvent(Address from, Address to) override {}
5011cb0ef41Sopenharmony_ci  void CodeMoveEvent(AbstractCode from, AbstractCode to) override;
5021cb0ef41Sopenharmony_ci  void CodeDisableOptEvent(Handle<AbstractCode> code,
5031cb0ef41Sopenharmony_ci                           Handle<SharedFunctionInfo> shared) override {}
5041cb0ef41Sopenharmony_ci  void CodeMovingGCEvent() override {}
5051cb0ef41Sopenharmony_ci  void CodeDeoptEvent(Handle<Code> code, DeoptimizeKind kind, Address pc,
5061cb0ef41Sopenharmony_ci                      int fp_to_sp_delta) override {}
5071cb0ef41Sopenharmony_ci  void CodeDependencyChangeEvent(Handle<Code> code,
5081cb0ef41Sopenharmony_ci                                 Handle<SharedFunctionInfo> sfi,
5091cb0ef41Sopenharmony_ci                                 const char* reason) override {}
5101cb0ef41Sopenharmony_ci  void WeakCodeClearEvent() override {}
5111cb0ef41Sopenharmony_ci
5121cb0ef41Sopenharmony_ci  void StartListening(v8::CodeEventHandler* code_event_handler);
5131cb0ef41Sopenharmony_ci  void StopListening();
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci  bool is_listening_to_code_events() override { return true; }
5161cb0ef41Sopenharmony_ci
5171cb0ef41Sopenharmony_ci private:
5181cb0ef41Sopenharmony_ci  void LogExistingCode();
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci  bool is_listening_;
5211cb0ef41Sopenharmony_ci  Isolate* isolate_;
5221cb0ef41Sopenharmony_ci  v8::CodeEventHandler* code_event_handler_;
5231cb0ef41Sopenharmony_ci};
5241cb0ef41Sopenharmony_ci
5251cb0ef41Sopenharmony_ci}  // namespace internal
5261cb0ef41Sopenharmony_ci}  // namespace v8
5271cb0ef41Sopenharmony_ci
5281cb0ef41Sopenharmony_ci#endif  // V8_LOGGING_LOG_H_
529