11cb0ef41Sopenharmony_ci// Copyright 2011 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#include "src/logging/log.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <atomic>
81cb0ef41Sopenharmony_ci#include <cstdarg>
91cb0ef41Sopenharmony_ci#include <memory>
101cb0ef41Sopenharmony_ci#include <sstream>
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include "include/v8-locker.h"
131cb0ef41Sopenharmony_ci#include "src/api/api-inl.h"
141cb0ef41Sopenharmony_ci#include "src/base/platform/mutex.h"
151cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h"
161cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
171cb0ef41Sopenharmony_ci#include "src/builtins/profile-data-reader.h"
181cb0ef41Sopenharmony_ci#include "src/codegen/bailout-reason.h"
191cb0ef41Sopenharmony_ci#include "src/codegen/macro-assembler.h"
201cb0ef41Sopenharmony_ci#include "src/codegen/source-position-table.h"
211cb0ef41Sopenharmony_ci#include "src/deoptimizer/deoptimizer.h"
221cb0ef41Sopenharmony_ci#include "src/diagnostics/perf-jit.h"
231cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
241cb0ef41Sopenharmony_ci#include "src/execution/v8threads.h"
251cb0ef41Sopenharmony_ci#include "src/execution/vm-state-inl.h"
261cb0ef41Sopenharmony_ci#include "src/handles/global-handles.h"
271cb0ef41Sopenharmony_ci#include "src/heap/combined-heap.h"
281cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
291cb0ef41Sopenharmony_ci#include "src/init/bootstrapper.h"
301cb0ef41Sopenharmony_ci#include "src/interpreter/bytecodes.h"
311cb0ef41Sopenharmony_ci#include "src/interpreter/interpreter.h"
321cb0ef41Sopenharmony_ci#include "src/libsampler/sampler.h"
331cb0ef41Sopenharmony_ci#include "src/logging/counters.h"
341cb0ef41Sopenharmony_ci#include "src/logging/log-inl.h"
351cb0ef41Sopenharmony_ci#include "src/logging/log-utils.h"
361cb0ef41Sopenharmony_ci#include "src/objects/api-callbacks.h"
371cb0ef41Sopenharmony_ci#include "src/objects/code-kind.h"
381cb0ef41Sopenharmony_ci#include "src/objects/code.h"
391cb0ef41Sopenharmony_ci#include "src/profiler/tick-sample.h"
401cb0ef41Sopenharmony_ci#include "src/snapshot/embedded/embedded-data.h"
411cb0ef41Sopenharmony_ci#include "src/strings/string-stream.h"
421cb0ef41Sopenharmony_ci#include "src/strings/unicode-inl.h"
431cb0ef41Sopenharmony_ci#include "src/tracing/tracing-category-observer.h"
441cb0ef41Sopenharmony_ci#include "src/utils/memcopy.h"
451cb0ef41Sopenharmony_ci#include "src/utils/version.h"
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci#ifdef ENABLE_GDB_JIT_INTERFACE
481cb0ef41Sopenharmony_ci#include "src/diagnostics/gdb-jit.h"
491cb0ef41Sopenharmony_ci#endif  // ENABLE_GDB_JIT_INTERFACE
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
521cb0ef41Sopenharmony_ci#include "src/wasm/wasm-code-manager.h"
531cb0ef41Sopenharmony_ci#include "src/wasm/wasm-engine.h"
541cb0ef41Sopenharmony_ci#include "src/wasm/wasm-objects-inl.h"
551cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci#if V8_OS_WIN
581cb0ef41Sopenharmony_ci#if defined(V8_ENABLE_SYSTEM_INSTRUMENTATION)
591cb0ef41Sopenharmony_ci#include "src/diagnostics/system-jit-win.h"
601cb0ef41Sopenharmony_ci#endif
611cb0ef41Sopenharmony_ci#endif  // V8_OS_WIN
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_cinamespace v8 {
641cb0ef41Sopenharmony_cinamespace internal {
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci#define DECLARE_EVENT(ignore1, name) #name,
671cb0ef41Sopenharmony_cistatic const char* kLogEventsNames[CodeEventListener::NUMBER_OF_LOG_EVENTS] = {
681cb0ef41Sopenharmony_ci    LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)};
691cb0ef41Sopenharmony_ci#undef DECLARE_EVENT
701cb0ef41Sopenharmony_ci
711cb0ef41Sopenharmony_cistatic v8::CodeEventType GetCodeEventTypeForTag(
721cb0ef41Sopenharmony_ci    CodeEventListener::LogEventsAndTags tag) {
731cb0ef41Sopenharmony_ci  switch (tag) {
741cb0ef41Sopenharmony_ci    case CodeEventListener::NUMBER_OF_LOG_EVENTS:
751cb0ef41Sopenharmony_ci#define V(Event, _) case CodeEventListener::Event:
761cb0ef41Sopenharmony_ci      LOG_EVENTS_LIST(V)
771cb0ef41Sopenharmony_ci#undef V
781cb0ef41Sopenharmony_ci      return v8::CodeEventType::kUnknownType;
791cb0ef41Sopenharmony_ci#define V(From, To)             \
801cb0ef41Sopenharmony_ci  case CodeEventListener::From: \
811cb0ef41Sopenharmony_ci    return v8::CodeEventType::k##To##Type;
821cb0ef41Sopenharmony_ci      TAGS_LIST(V)
831cb0ef41Sopenharmony_ci#undef V
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci  // The execution should never pass here
861cb0ef41Sopenharmony_ci  UNREACHABLE();
871cb0ef41Sopenharmony_ci}
881cb0ef41Sopenharmony_ci#define CALL_CODE_EVENT_HANDLER(Call) \
891cb0ef41Sopenharmony_ci  if (listener_) {                    \
901cb0ef41Sopenharmony_ci    listener_->Call;                  \
911cb0ef41Sopenharmony_ci  } else {                            \
921cb0ef41Sopenharmony_ci    PROFILE(isolate_, Call);          \
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_cistatic const char* ComputeMarker(SharedFunctionInfo shared, AbstractCode code) {
961cb0ef41Sopenharmony_ci  CodeKind kind = code.kind();
971cb0ef41Sopenharmony_ci  // We record interpreter trampoline builtin copies as having the
981cb0ef41Sopenharmony_ci  // "interpreted" marker.
991cb0ef41Sopenharmony_ci  if (FLAG_interpreted_frames_native_stack && kind == CodeKind::BUILTIN &&
1001cb0ef41Sopenharmony_ci      code.GetCode().is_interpreter_trampoline_builtin() &&
1011cb0ef41Sopenharmony_ci      ToCodeT(code.GetCode()) !=
1021cb0ef41Sopenharmony_ci          *BUILTIN_CODE(shared.GetIsolate(), InterpreterEntryTrampoline)) {
1031cb0ef41Sopenharmony_ci    kind = CodeKind::INTERPRETED_FUNCTION;
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci  if (shared.optimization_disabled() &&
1061cb0ef41Sopenharmony_ci      kind == CodeKind::INTERPRETED_FUNCTION) {
1071cb0ef41Sopenharmony_ci    return "";
1081cb0ef41Sopenharmony_ci  }
1091cb0ef41Sopenharmony_ci  return CodeKindToMarker(kind);
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1131cb0ef41Sopenharmony_cistatic const char* ComputeMarker(const wasm::WasmCode* code) {
1141cb0ef41Sopenharmony_ci  switch (code->kind()) {
1151cb0ef41Sopenharmony_ci    case wasm::WasmCode::kWasmFunction:
1161cb0ef41Sopenharmony_ci      return code->is_liftoff() ? "" : "*";
1171cb0ef41Sopenharmony_ci    default:
1181cb0ef41Sopenharmony_ci      return "";
1191cb0ef41Sopenharmony_ci  }
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ciclass CodeEventLogger::NameBuffer {
1241cb0ef41Sopenharmony_ci public:
1251cb0ef41Sopenharmony_ci  NameBuffer() { Reset(); }
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  void Reset() { utf8_pos_ = 0; }
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  void Init(LogEventsAndTags tag) {
1301cb0ef41Sopenharmony_ci    Reset();
1311cb0ef41Sopenharmony_ci    AppendBytes(kLogEventsNames[tag]);
1321cb0ef41Sopenharmony_ci    AppendByte(':');
1331cb0ef41Sopenharmony_ci  }
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  void AppendName(Name name) {
1361cb0ef41Sopenharmony_ci    if (name.IsString()) {
1371cb0ef41Sopenharmony_ci      AppendString(String::cast(name));
1381cb0ef41Sopenharmony_ci    } else {
1391cb0ef41Sopenharmony_ci      Symbol symbol = Symbol::cast(name);
1401cb0ef41Sopenharmony_ci      AppendBytes("symbol(");
1411cb0ef41Sopenharmony_ci      if (!symbol.description().IsUndefined()) {
1421cb0ef41Sopenharmony_ci        AppendBytes("\"");
1431cb0ef41Sopenharmony_ci        AppendString(String::cast(symbol.description()));
1441cb0ef41Sopenharmony_ci        AppendBytes("\" ");
1451cb0ef41Sopenharmony_ci      }
1461cb0ef41Sopenharmony_ci      AppendBytes("hash ");
1471cb0ef41Sopenharmony_ci      AppendHex(symbol.hash());
1481cb0ef41Sopenharmony_ci      AppendByte(')');
1491cb0ef41Sopenharmony_ci    }
1501cb0ef41Sopenharmony_ci  }
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  void AppendString(String str) {
1531cb0ef41Sopenharmony_ci    if (str.is_null()) return;
1541cb0ef41Sopenharmony_ci    int length = 0;
1551cb0ef41Sopenharmony_ci    std::unique_ptr<char[]> c_str =
1561cb0ef41Sopenharmony_ci        str.ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL, &length);
1571cb0ef41Sopenharmony_ci    AppendBytes(c_str.get(), length);
1581cb0ef41Sopenharmony_ci  }
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci  void AppendBytes(const char* bytes, int size) {
1611cb0ef41Sopenharmony_ci    size = std::min(size, kUtf8BufferSize - utf8_pos_);
1621cb0ef41Sopenharmony_ci    MemCopy(utf8_buffer_ + utf8_pos_, bytes, size);
1631cb0ef41Sopenharmony_ci    utf8_pos_ += size;
1641cb0ef41Sopenharmony_ci  }
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  void AppendBytes(const char* bytes) {
1671cb0ef41Sopenharmony_ci    size_t len = strlen(bytes);
1681cb0ef41Sopenharmony_ci    DCHECK_GE(kMaxInt, len);
1691cb0ef41Sopenharmony_ci    AppendBytes(bytes, static_cast<int>(len));
1701cb0ef41Sopenharmony_ci  }
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  void AppendByte(char c) {
1731cb0ef41Sopenharmony_ci    if (utf8_pos_ >= kUtf8BufferSize) return;
1741cb0ef41Sopenharmony_ci    utf8_buffer_[utf8_pos_++] = c;
1751cb0ef41Sopenharmony_ci  }
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci  void AppendInt(int n) {
1781cb0ef41Sopenharmony_ci    int space = kUtf8BufferSize - utf8_pos_;
1791cb0ef41Sopenharmony_ci    if (space <= 0) return;
1801cb0ef41Sopenharmony_ci    base::Vector<char> buffer(utf8_buffer_ + utf8_pos_, space);
1811cb0ef41Sopenharmony_ci    int size = SNPrintF(buffer, "%d", n);
1821cb0ef41Sopenharmony_ci    if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
1831cb0ef41Sopenharmony_ci      utf8_pos_ += size;
1841cb0ef41Sopenharmony_ci    }
1851cb0ef41Sopenharmony_ci  }
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_ci  void AppendHex(uint32_t n) {
1881cb0ef41Sopenharmony_ci    int space = kUtf8BufferSize - utf8_pos_;
1891cb0ef41Sopenharmony_ci    if (space <= 0) return;
1901cb0ef41Sopenharmony_ci    base::Vector<char> buffer(utf8_buffer_ + utf8_pos_, space);
1911cb0ef41Sopenharmony_ci    int size = SNPrintF(buffer, "%x", n);
1921cb0ef41Sopenharmony_ci    if (size > 0 && utf8_pos_ + size <= kUtf8BufferSize) {
1931cb0ef41Sopenharmony_ci      utf8_pos_ += size;
1941cb0ef41Sopenharmony_ci    }
1951cb0ef41Sopenharmony_ci  }
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci  const char* get() { return utf8_buffer_; }
1981cb0ef41Sopenharmony_ci  int size() const { return utf8_pos_; }
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci private:
2011cb0ef41Sopenharmony_ci  static const int kUtf8BufferSize = 512;
2021cb0ef41Sopenharmony_ci  static const int kUtf16BufferSize = kUtf8BufferSize;
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci  int utf8_pos_;
2051cb0ef41Sopenharmony_ci  char utf8_buffer_[kUtf8BufferSize];
2061cb0ef41Sopenharmony_ci};
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ciCodeEventLogger::CodeEventLogger(Isolate* isolate)
2091cb0ef41Sopenharmony_ci    : isolate_(isolate), name_buffer_(std::make_unique<NameBuffer>()) {}
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ciCodeEventLogger::~CodeEventLogger() = default;
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_civoid CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
2141cb0ef41Sopenharmony_ci                                      Handle<AbstractCode> code,
2151cb0ef41Sopenharmony_ci                                      const char* comment) {
2161cb0ef41Sopenharmony_ci  DCHECK(is_listening_to_code_events());
2171cb0ef41Sopenharmony_ci  name_buffer_->Init(tag);
2181cb0ef41Sopenharmony_ci  name_buffer_->AppendBytes(comment);
2191cb0ef41Sopenharmony_ci  LogRecordedBuffer(code, MaybeHandle<SharedFunctionInfo>(),
2201cb0ef41Sopenharmony_ci                    name_buffer_->get(), name_buffer_->size());
2211cb0ef41Sopenharmony_ci}
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_civoid CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
2241cb0ef41Sopenharmony_ci                                      Handle<AbstractCode> code,
2251cb0ef41Sopenharmony_ci                                      Handle<Name> name) {
2261cb0ef41Sopenharmony_ci  DCHECK(is_listening_to_code_events());
2271cb0ef41Sopenharmony_ci  name_buffer_->Init(tag);
2281cb0ef41Sopenharmony_ci  name_buffer_->AppendName(*name);
2291cb0ef41Sopenharmony_ci  LogRecordedBuffer(code, MaybeHandle<SharedFunctionInfo>(),
2301cb0ef41Sopenharmony_ci                    name_buffer_->get(), name_buffer_->size());
2311cb0ef41Sopenharmony_ci}
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_civoid CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
2341cb0ef41Sopenharmony_ci                                      Handle<AbstractCode> code,
2351cb0ef41Sopenharmony_ci                                      Handle<SharedFunctionInfo> shared,
2361cb0ef41Sopenharmony_ci                                      Handle<Name> script_name) {
2371cb0ef41Sopenharmony_ci  DCHECK(is_listening_to_code_events());
2381cb0ef41Sopenharmony_ci  name_buffer_->Init(tag);
2391cb0ef41Sopenharmony_ci  name_buffer_->AppendBytes(ComputeMarker(*shared, *code));
2401cb0ef41Sopenharmony_ci  name_buffer_->AppendByte(' ');
2411cb0ef41Sopenharmony_ci  name_buffer_->AppendName(*script_name);
2421cb0ef41Sopenharmony_ci  LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
2431cb0ef41Sopenharmony_ci}
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_civoid CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
2461cb0ef41Sopenharmony_ci                                      Handle<AbstractCode> code,
2471cb0ef41Sopenharmony_ci                                      Handle<SharedFunctionInfo> shared,
2481cb0ef41Sopenharmony_ci                                      Handle<Name> script_name, int line,
2491cb0ef41Sopenharmony_ci                                      int column) {
2501cb0ef41Sopenharmony_ci  DCHECK(is_listening_to_code_events());
2511cb0ef41Sopenharmony_ci  name_buffer_->Init(tag);
2521cb0ef41Sopenharmony_ci  name_buffer_->AppendBytes(ComputeMarker(*shared, *code));
2531cb0ef41Sopenharmony_ci  name_buffer_->AppendBytes(shared->DebugNameCStr().get());
2541cb0ef41Sopenharmony_ci  name_buffer_->AppendByte(' ');
2551cb0ef41Sopenharmony_ci  if (script_name->IsString()) {
2561cb0ef41Sopenharmony_ci    name_buffer_->AppendString(String::cast(*script_name));
2571cb0ef41Sopenharmony_ci  } else {
2581cb0ef41Sopenharmony_ci    name_buffer_->AppendBytes("symbol(hash ");
2591cb0ef41Sopenharmony_ci    name_buffer_->AppendHex(Name::cast(*script_name).hash());
2601cb0ef41Sopenharmony_ci    name_buffer_->AppendByte(')');
2611cb0ef41Sopenharmony_ci  }
2621cb0ef41Sopenharmony_ci  name_buffer_->AppendByte(':');
2631cb0ef41Sopenharmony_ci  name_buffer_->AppendInt(line);
2641cb0ef41Sopenharmony_ci  LogRecordedBuffer(code, shared, name_buffer_->get(), name_buffer_->size());
2651cb0ef41Sopenharmony_ci}
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2681cb0ef41Sopenharmony_civoid CodeEventLogger::CodeCreateEvent(LogEventsAndTags tag,
2691cb0ef41Sopenharmony_ci                                      const wasm::WasmCode* code,
2701cb0ef41Sopenharmony_ci                                      wasm::WasmName name,
2711cb0ef41Sopenharmony_ci                                      const char* source_url,
2721cb0ef41Sopenharmony_ci                                      int /*code_offset*/, int /*script_id*/) {
2731cb0ef41Sopenharmony_ci  DCHECK(is_listening_to_code_events());
2741cb0ef41Sopenharmony_ci  name_buffer_->Init(tag);
2751cb0ef41Sopenharmony_ci  DCHECK(!name.empty());
2761cb0ef41Sopenharmony_ci  name_buffer_->AppendBytes(name.begin(), name.length());
2771cb0ef41Sopenharmony_ci  name_buffer_->AppendByte('-');
2781cb0ef41Sopenharmony_ci  if (code->IsAnonymous()) {
2791cb0ef41Sopenharmony_ci    name_buffer_->AppendBytes("<anonymous>");
2801cb0ef41Sopenharmony_ci  } else {
2811cb0ef41Sopenharmony_ci    name_buffer_->AppendInt(code->index());
2821cb0ef41Sopenharmony_ci  }
2831cb0ef41Sopenharmony_ci  name_buffer_->AppendByte('-');
2841cb0ef41Sopenharmony_ci  name_buffer_->AppendBytes(ExecutionTierToString(code->tier()));
2851cb0ef41Sopenharmony_ci  LogRecordedBuffer(code, name_buffer_->get(), name_buffer_->size());
2861cb0ef41Sopenharmony_ci}
2871cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_civoid CodeEventLogger::RegExpCodeCreateEvent(Handle<AbstractCode> code,
2901cb0ef41Sopenharmony_ci                                            Handle<String> source) {
2911cb0ef41Sopenharmony_ci  DCHECK(is_listening_to_code_events());
2921cb0ef41Sopenharmony_ci  name_buffer_->Init(CodeEventListener::REG_EXP_TAG);
2931cb0ef41Sopenharmony_ci  name_buffer_->AppendString(*source);
2941cb0ef41Sopenharmony_ci  LogRecordedBuffer(code, MaybeHandle<SharedFunctionInfo>(),
2951cb0ef41Sopenharmony_ci                    name_buffer_->get(), name_buffer_->size());
2961cb0ef41Sopenharmony_ci}
2971cb0ef41Sopenharmony_ci
2981cb0ef41Sopenharmony_ci// Linux perf tool logging support.
2991cb0ef41Sopenharmony_ci#if V8_OS_LINUX
3001cb0ef41Sopenharmony_ciclass PerfBasicLogger : public CodeEventLogger {
3011cb0ef41Sopenharmony_ci public:
3021cb0ef41Sopenharmony_ci  explicit PerfBasicLogger(Isolate* isolate);
3031cb0ef41Sopenharmony_ci  ~PerfBasicLogger() override;
3041cb0ef41Sopenharmony_ci
3051cb0ef41Sopenharmony_ci  void CodeMoveEvent(AbstractCode from, AbstractCode to) override {}
3061cb0ef41Sopenharmony_ci  void CodeDisableOptEvent(Handle<AbstractCode> code,
3071cb0ef41Sopenharmony_ci                           Handle<SharedFunctionInfo> shared) override {}
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci private:
3101cb0ef41Sopenharmony_ci  void LogRecordedBuffer(Handle<AbstractCode> code,
3111cb0ef41Sopenharmony_ci                         MaybeHandle<SharedFunctionInfo> maybe_shared,
3121cb0ef41Sopenharmony_ci                         const char* name, int length) override;
3131cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
3141cb0ef41Sopenharmony_ci  void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
3151cb0ef41Sopenharmony_ci                         int length) override;
3161cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
3171cb0ef41Sopenharmony_ci  void WriteLogRecordedBuffer(uintptr_t address, int size, const char* name,
3181cb0ef41Sopenharmony_ci                              int name_length);
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci  // Extension added to V8 log file name to get the low-level log name.
3211cb0ef41Sopenharmony_ci  static const char kFilenameFormatString[];
3221cb0ef41Sopenharmony_ci  static const int kFilenameBufferPadding;
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci  FILE* perf_output_handle_;
3251cb0ef41Sopenharmony_ci};
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_ciconst char PerfBasicLogger::kFilenameFormatString[] = "/tmp/perf-%d.map";
3281cb0ef41Sopenharmony_ci// Extra space for the PID in the filename
3291cb0ef41Sopenharmony_ciconst int PerfBasicLogger::kFilenameBufferPadding = 16;
3301cb0ef41Sopenharmony_ci
3311cb0ef41Sopenharmony_ciPerfBasicLogger::PerfBasicLogger(Isolate* isolate)
3321cb0ef41Sopenharmony_ci    : CodeEventLogger(isolate), perf_output_handle_(nullptr) {
3331cb0ef41Sopenharmony_ci  // Open the perf JIT dump file.
3341cb0ef41Sopenharmony_ci  int bufferSize = sizeof(kFilenameFormatString) + kFilenameBufferPadding;
3351cb0ef41Sopenharmony_ci  base::ScopedVector<char> perf_dump_name(bufferSize);
3361cb0ef41Sopenharmony_ci  int size = SNPrintF(perf_dump_name, kFilenameFormatString,
3371cb0ef41Sopenharmony_ci                      base::OS::GetCurrentProcessId());
3381cb0ef41Sopenharmony_ci  CHECK_NE(size, -1);
3391cb0ef41Sopenharmony_ci  perf_output_handle_ =
3401cb0ef41Sopenharmony_ci      base::OS::FOpen(perf_dump_name.begin(), base::OS::LogFileOpenMode);
3411cb0ef41Sopenharmony_ci  CHECK_NOT_NULL(perf_output_handle_);
3421cb0ef41Sopenharmony_ci  setvbuf(perf_output_handle_, nullptr, _IOLBF, 0);
3431cb0ef41Sopenharmony_ci}
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ciPerfBasicLogger::~PerfBasicLogger() {
3461cb0ef41Sopenharmony_ci  base::Fclose(perf_output_handle_);
3471cb0ef41Sopenharmony_ci  perf_output_handle_ = nullptr;
3481cb0ef41Sopenharmony_ci}
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_civoid PerfBasicLogger::WriteLogRecordedBuffer(uintptr_t address, int size,
3511cb0ef41Sopenharmony_ci                                             const char* name,
3521cb0ef41Sopenharmony_ci                                             int name_length) {
3531cb0ef41Sopenharmony_ci  // Linux perf expects hex literals without a leading 0x, while some
3541cb0ef41Sopenharmony_ci  // implementations of printf might prepend one when using the %p format
3551cb0ef41Sopenharmony_ci  // for pointers, leading to wrongly formatted JIT symbols maps.
3561cb0ef41Sopenharmony_ci  //
3571cb0ef41Sopenharmony_ci  // Instead, we use V8PRIxPTR format string and cast pointer to uintpr_t,
3581cb0ef41Sopenharmony_ci  // so that we have control over the exact output format.
3591cb0ef41Sopenharmony_ci  base::OS::FPrint(perf_output_handle_, "%" V8PRIxPTR " %x %.*s\n", address,
3601cb0ef41Sopenharmony_ci                   size, name_length, name);
3611cb0ef41Sopenharmony_ci}
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_civoid PerfBasicLogger::LogRecordedBuffer(Handle<AbstractCode> code,
3641cb0ef41Sopenharmony_ci                                        MaybeHandle<SharedFunctionInfo>,
3651cb0ef41Sopenharmony_ci                                        const char* name, int length) {
3661cb0ef41Sopenharmony_ci  if (FLAG_perf_basic_prof_only_functions &&
3671cb0ef41Sopenharmony_ci      !CodeKindIsBuiltinOrJSFunction(code->kind())) {
3681cb0ef41Sopenharmony_ci    return;
3691cb0ef41Sopenharmony_ci  }
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci  WriteLogRecordedBuffer(static_cast<uintptr_t>(code->InstructionStart()),
3721cb0ef41Sopenharmony_ci                         code->InstructionSize(), name, length);
3731cb0ef41Sopenharmony_ci}
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
3761cb0ef41Sopenharmony_civoid PerfBasicLogger::LogRecordedBuffer(const wasm::WasmCode* code,
3771cb0ef41Sopenharmony_ci                                        const char* name, int length) {
3781cb0ef41Sopenharmony_ci  WriteLogRecordedBuffer(static_cast<uintptr_t>(code->instruction_start()),
3791cb0ef41Sopenharmony_ci                         code->instructions().length(), name, length);
3801cb0ef41Sopenharmony_ci}
3811cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
3821cb0ef41Sopenharmony_ci#endif  // V8_OS_LINUX
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ci// External CodeEventListener
3851cb0ef41Sopenharmony_ciExternalCodeEventListener::ExternalCodeEventListener(Isolate* isolate)
3861cb0ef41Sopenharmony_ci    : is_listening_(false), isolate_(isolate), code_event_handler_(nullptr) {}
3871cb0ef41Sopenharmony_ci
3881cb0ef41Sopenharmony_ciExternalCodeEventListener::~ExternalCodeEventListener() {
3891cb0ef41Sopenharmony_ci  if (is_listening_) {
3901cb0ef41Sopenharmony_ci    StopListening();
3911cb0ef41Sopenharmony_ci  }
3921cb0ef41Sopenharmony_ci}
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_civoid ExternalCodeEventListener::LogExistingCode() {
3951cb0ef41Sopenharmony_ci  HandleScope scope(isolate_);
3961cb0ef41Sopenharmony_ci  ExistingCodeLogger logger(isolate_, this);
3971cb0ef41Sopenharmony_ci  logger.LogCodeObjects();
3981cb0ef41Sopenharmony_ci  logger.LogCompiledFunctions();
3991cb0ef41Sopenharmony_ci}
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_civoid ExternalCodeEventListener::StartListening(
4021cb0ef41Sopenharmony_ci    CodeEventHandler* code_event_handler) {
4031cb0ef41Sopenharmony_ci  if (is_listening_ || code_event_handler == nullptr) {
4041cb0ef41Sopenharmony_ci    return;
4051cb0ef41Sopenharmony_ci  }
4061cb0ef41Sopenharmony_ci  code_event_handler_ = code_event_handler;
4071cb0ef41Sopenharmony_ci  is_listening_ = isolate_->code_event_dispatcher()->AddListener(this);
4081cb0ef41Sopenharmony_ci  if (is_listening_) {
4091cb0ef41Sopenharmony_ci    LogExistingCode();
4101cb0ef41Sopenharmony_ci  }
4111cb0ef41Sopenharmony_ci}
4121cb0ef41Sopenharmony_ci
4131cb0ef41Sopenharmony_civoid ExternalCodeEventListener::StopListening() {
4141cb0ef41Sopenharmony_ci  if (!is_listening_) {
4151cb0ef41Sopenharmony_ci    return;
4161cb0ef41Sopenharmony_ci  }
4171cb0ef41Sopenharmony_ci
4181cb0ef41Sopenharmony_ci  isolate_->code_event_dispatcher()->RemoveListener(this);
4191cb0ef41Sopenharmony_ci  is_listening_ = false;
4201cb0ef41Sopenharmony_ci}
4211cb0ef41Sopenharmony_ci
4221cb0ef41Sopenharmony_civoid ExternalCodeEventListener::CodeCreateEvent(LogEventsAndTags tag,
4231cb0ef41Sopenharmony_ci                                                Handle<AbstractCode> code,
4241cb0ef41Sopenharmony_ci                                                const char* comment) {
4251cb0ef41Sopenharmony_ci  CodeEvent code_event;
4261cb0ef41Sopenharmony_ci  code_event.code_start_address =
4271cb0ef41Sopenharmony_ci      static_cast<uintptr_t>(code->InstructionStart());
4281cb0ef41Sopenharmony_ci  code_event.code_size = static_cast<size_t>(code->InstructionSize());
4291cb0ef41Sopenharmony_ci  code_event.function_name = isolate_->factory()->empty_string();
4301cb0ef41Sopenharmony_ci  code_event.script_name = isolate_->factory()->empty_string();
4311cb0ef41Sopenharmony_ci  code_event.script_line = 0;
4321cb0ef41Sopenharmony_ci  code_event.script_column = 0;
4331cb0ef41Sopenharmony_ci  code_event.code_type = GetCodeEventTypeForTag(tag);
4341cb0ef41Sopenharmony_ci  code_event.comment = comment;
4351cb0ef41Sopenharmony_ci
4361cb0ef41Sopenharmony_ci  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
4371cb0ef41Sopenharmony_ci}
4381cb0ef41Sopenharmony_ci
4391cb0ef41Sopenharmony_civoid ExternalCodeEventListener::CodeCreateEvent(LogEventsAndTags tag,
4401cb0ef41Sopenharmony_ci                                                Handle<AbstractCode> code,
4411cb0ef41Sopenharmony_ci                                                Handle<Name> name) {
4421cb0ef41Sopenharmony_ci  Handle<String> name_string =
4431cb0ef41Sopenharmony_ci      Name::ToFunctionName(isolate_, name).ToHandleChecked();
4441cb0ef41Sopenharmony_ci
4451cb0ef41Sopenharmony_ci  CodeEvent code_event;
4461cb0ef41Sopenharmony_ci  code_event.code_start_address =
4471cb0ef41Sopenharmony_ci      static_cast<uintptr_t>(code->InstructionStart());
4481cb0ef41Sopenharmony_ci  code_event.code_size = static_cast<size_t>(code->InstructionSize());
4491cb0ef41Sopenharmony_ci  code_event.function_name = name_string;
4501cb0ef41Sopenharmony_ci  code_event.script_name = isolate_->factory()->empty_string();
4511cb0ef41Sopenharmony_ci  code_event.script_line = 0;
4521cb0ef41Sopenharmony_ci  code_event.script_column = 0;
4531cb0ef41Sopenharmony_ci  code_event.code_type = GetCodeEventTypeForTag(tag);
4541cb0ef41Sopenharmony_ci  code_event.comment = "";
4551cb0ef41Sopenharmony_ci
4561cb0ef41Sopenharmony_ci  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
4571cb0ef41Sopenharmony_ci}
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_civoid ExternalCodeEventListener::CodeCreateEvent(
4601cb0ef41Sopenharmony_ci    LogEventsAndTags tag, Handle<AbstractCode> code,
4611cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared, Handle<Name> name) {
4621cb0ef41Sopenharmony_ci  Handle<String> name_string =
4631cb0ef41Sopenharmony_ci      Name::ToFunctionName(isolate_, name).ToHandleChecked();
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_ci  CodeEvent code_event;
4661cb0ef41Sopenharmony_ci  code_event.code_start_address =
4671cb0ef41Sopenharmony_ci      static_cast<uintptr_t>(code->InstructionStart());
4681cb0ef41Sopenharmony_ci  code_event.code_size = static_cast<size_t>(code->InstructionSize());
4691cb0ef41Sopenharmony_ci  code_event.function_name = name_string;
4701cb0ef41Sopenharmony_ci  code_event.script_name = isolate_->factory()->empty_string();
4711cb0ef41Sopenharmony_ci  code_event.script_line = 0;
4721cb0ef41Sopenharmony_ci  code_event.script_column = 0;
4731cb0ef41Sopenharmony_ci  code_event.code_type = GetCodeEventTypeForTag(tag);
4741cb0ef41Sopenharmony_ci  code_event.comment = "";
4751cb0ef41Sopenharmony_ci
4761cb0ef41Sopenharmony_ci  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
4771cb0ef41Sopenharmony_ci}
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_civoid ExternalCodeEventListener::CodeCreateEvent(
4801cb0ef41Sopenharmony_ci    LogEventsAndTags tag, Handle<AbstractCode> code,
4811cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared, Handle<Name> source, int line,
4821cb0ef41Sopenharmony_ci    int column) {
4831cb0ef41Sopenharmony_ci  Handle<String> name_string =
4841cb0ef41Sopenharmony_ci      Name::ToFunctionName(isolate_, handle(shared->Name(), isolate_))
4851cb0ef41Sopenharmony_ci          .ToHandleChecked();
4861cb0ef41Sopenharmony_ci  Handle<String> source_string =
4871cb0ef41Sopenharmony_ci      Name::ToFunctionName(isolate_, source).ToHandleChecked();
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  CodeEvent code_event;
4901cb0ef41Sopenharmony_ci  code_event.code_start_address =
4911cb0ef41Sopenharmony_ci      static_cast<uintptr_t>(code->InstructionStart());
4921cb0ef41Sopenharmony_ci  code_event.code_size = static_cast<size_t>(code->InstructionSize());
4931cb0ef41Sopenharmony_ci  code_event.function_name = name_string;
4941cb0ef41Sopenharmony_ci  code_event.script_name = source_string;
4951cb0ef41Sopenharmony_ci  code_event.script_line = line;
4961cb0ef41Sopenharmony_ci  code_event.script_column = column;
4971cb0ef41Sopenharmony_ci  code_event.code_type = GetCodeEventTypeForTag(tag);
4981cb0ef41Sopenharmony_ci  code_event.comment = "";
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
5011cb0ef41Sopenharmony_ci}
5021cb0ef41Sopenharmony_ci
5031cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
5041cb0ef41Sopenharmony_civoid ExternalCodeEventListener::CodeCreateEvent(
5051cb0ef41Sopenharmony_ci    LogEventsAndTags tag, const wasm::WasmCode* code, wasm::WasmName name,
5061cb0ef41Sopenharmony_ci    const char* source_url, int code_offset, int script_id) {
5071cb0ef41Sopenharmony_ci  // TODO(mmarchini): handle later
5081cb0ef41Sopenharmony_ci}
5091cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
5101cb0ef41Sopenharmony_ci
5111cb0ef41Sopenharmony_civoid ExternalCodeEventListener::RegExpCodeCreateEvent(Handle<AbstractCode> code,
5121cb0ef41Sopenharmony_ci                                                      Handle<String> source) {
5131cb0ef41Sopenharmony_ci  CodeEvent code_event;
5141cb0ef41Sopenharmony_ci  code_event.code_start_address =
5151cb0ef41Sopenharmony_ci      static_cast<uintptr_t>(code->InstructionStart());
5161cb0ef41Sopenharmony_ci  code_event.code_size = static_cast<size_t>(code->InstructionSize());
5171cb0ef41Sopenharmony_ci  code_event.function_name = source;
5181cb0ef41Sopenharmony_ci  code_event.script_name = isolate_->factory()->empty_string();
5191cb0ef41Sopenharmony_ci  code_event.script_line = 0;
5201cb0ef41Sopenharmony_ci  code_event.script_column = 0;
5211cb0ef41Sopenharmony_ci  code_event.code_type = GetCodeEventTypeForTag(CodeEventListener::REG_EXP_TAG);
5221cb0ef41Sopenharmony_ci  code_event.comment = "";
5231cb0ef41Sopenharmony_ci
5241cb0ef41Sopenharmony_ci  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
5251cb0ef41Sopenharmony_ci}
5261cb0ef41Sopenharmony_ci
5271cb0ef41Sopenharmony_civoid ExternalCodeEventListener::CodeMoveEvent(AbstractCode from,
5281cb0ef41Sopenharmony_ci                                              AbstractCode to) {
5291cb0ef41Sopenharmony_ci  CodeEvent code_event;
5301cb0ef41Sopenharmony_ci  code_event.previous_code_start_address =
5311cb0ef41Sopenharmony_ci      static_cast<uintptr_t>(from.InstructionStart());
5321cb0ef41Sopenharmony_ci  code_event.code_start_address = static_cast<uintptr_t>(to.InstructionStart());
5331cb0ef41Sopenharmony_ci  code_event.code_size = static_cast<size_t>(to.InstructionSize());
5341cb0ef41Sopenharmony_ci  code_event.function_name = isolate_->factory()->empty_string();
5351cb0ef41Sopenharmony_ci  code_event.script_name = isolate_->factory()->empty_string();
5361cb0ef41Sopenharmony_ci  code_event.script_line = 0;
5371cb0ef41Sopenharmony_ci  code_event.script_column = 0;
5381cb0ef41Sopenharmony_ci  code_event.code_type = v8::CodeEventType::kRelocationType;
5391cb0ef41Sopenharmony_ci  code_event.comment = "";
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci  code_event_handler_->Handle(reinterpret_cast<v8::CodeEvent*>(&code_event));
5421cb0ef41Sopenharmony_ci}
5431cb0ef41Sopenharmony_ci
5441cb0ef41Sopenharmony_ci// Low-level logging support.
5451cb0ef41Sopenharmony_ciclass LowLevelLogger : public CodeEventLogger {
5461cb0ef41Sopenharmony_ci public:
5471cb0ef41Sopenharmony_ci  LowLevelLogger(Isolate* isolate, const char* file_name);
5481cb0ef41Sopenharmony_ci  ~LowLevelLogger() override;
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci  void CodeMoveEvent(AbstractCode from, AbstractCode to) override;
5511cb0ef41Sopenharmony_ci  void CodeDisableOptEvent(Handle<AbstractCode> code,
5521cb0ef41Sopenharmony_ci                           Handle<SharedFunctionInfo> shared) override {}
5531cb0ef41Sopenharmony_ci  void SnapshotPositionEvent(HeapObject obj, int pos);
5541cb0ef41Sopenharmony_ci  void CodeMovingGCEvent() override;
5551cb0ef41Sopenharmony_ci
5561cb0ef41Sopenharmony_ci private:
5571cb0ef41Sopenharmony_ci  void LogRecordedBuffer(Handle<AbstractCode> code,
5581cb0ef41Sopenharmony_ci                         MaybeHandle<SharedFunctionInfo> maybe_shared,
5591cb0ef41Sopenharmony_ci                         const char* name, int length) override;
5601cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
5611cb0ef41Sopenharmony_ci  void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
5621cb0ef41Sopenharmony_ci                         int length) override;
5631cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ci  // Low-level profiling event structures.
5661cb0ef41Sopenharmony_ci  struct CodeCreateStruct {
5671cb0ef41Sopenharmony_ci    static const char kTag = 'C';
5681cb0ef41Sopenharmony_ci
5691cb0ef41Sopenharmony_ci    int32_t name_size;
5701cb0ef41Sopenharmony_ci    Address code_address;
5711cb0ef41Sopenharmony_ci    int32_t code_size;
5721cb0ef41Sopenharmony_ci  };
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci  struct CodeMoveStruct {
5751cb0ef41Sopenharmony_ci    static const char kTag = 'M';
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci    Address from_address;
5781cb0ef41Sopenharmony_ci    Address to_address;
5791cb0ef41Sopenharmony_ci  };
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ci  static const char kCodeMovingGCTag = 'G';
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ci  // Extension added to V8 log file name to get the low-level log name.
5841cb0ef41Sopenharmony_ci  static const char kLogExt[];
5851cb0ef41Sopenharmony_ci
5861cb0ef41Sopenharmony_ci  void LogCodeInfo();
5871cb0ef41Sopenharmony_ci  void LogWriteBytes(const char* bytes, int size);
5881cb0ef41Sopenharmony_ci
5891cb0ef41Sopenharmony_ci  template <typename T>
5901cb0ef41Sopenharmony_ci  void LogWriteStruct(const T& s) {
5911cb0ef41Sopenharmony_ci    char tag = T::kTag;
5921cb0ef41Sopenharmony_ci    LogWriteBytes(reinterpret_cast<const char*>(&tag), sizeof(tag));
5931cb0ef41Sopenharmony_ci    LogWriteBytes(reinterpret_cast<const char*>(&s), sizeof(s));
5941cb0ef41Sopenharmony_ci  }
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci  FILE* ll_output_handle_;
5971cb0ef41Sopenharmony_ci};
5981cb0ef41Sopenharmony_ci
5991cb0ef41Sopenharmony_ciconst char LowLevelLogger::kLogExt[] = ".ll";
6001cb0ef41Sopenharmony_ci
6011cb0ef41Sopenharmony_ciLowLevelLogger::LowLevelLogger(Isolate* isolate, const char* name)
6021cb0ef41Sopenharmony_ci    : CodeEventLogger(isolate), ll_output_handle_(nullptr) {
6031cb0ef41Sopenharmony_ci  // Open the low-level log file.
6041cb0ef41Sopenharmony_ci  size_t len = strlen(name);
6051cb0ef41Sopenharmony_ci  base::ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLogExt)));
6061cb0ef41Sopenharmony_ci  MemCopy(ll_name.begin(), name, len);
6071cb0ef41Sopenharmony_ci  MemCopy(ll_name.begin() + len, kLogExt, sizeof(kLogExt));
6081cb0ef41Sopenharmony_ci  ll_output_handle_ =
6091cb0ef41Sopenharmony_ci      base::OS::FOpen(ll_name.begin(), base::OS::LogFileOpenMode);
6101cb0ef41Sopenharmony_ci  setvbuf(ll_output_handle_, nullptr, _IOLBF, 0);
6111cb0ef41Sopenharmony_ci
6121cb0ef41Sopenharmony_ci  LogCodeInfo();
6131cb0ef41Sopenharmony_ci}
6141cb0ef41Sopenharmony_ci
6151cb0ef41Sopenharmony_ciLowLevelLogger::~LowLevelLogger() {
6161cb0ef41Sopenharmony_ci  base::Fclose(ll_output_handle_);
6171cb0ef41Sopenharmony_ci  ll_output_handle_ = nullptr;
6181cb0ef41Sopenharmony_ci}
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_civoid LowLevelLogger::LogCodeInfo() {
6211cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_IA32
6221cb0ef41Sopenharmony_ci  const char arch[] = "ia32";
6231cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_64_BIT
6241cb0ef41Sopenharmony_ci  const char arch[] = "x64";
6251cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_ARM
6261cb0ef41Sopenharmony_ci  const char arch[] = "arm";
6271cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_PPC
6281cb0ef41Sopenharmony_ci  const char arch[] = "ppc";
6291cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_PPC64
6301cb0ef41Sopenharmony_ci  const char arch[] = "ppc64";
6311cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_MIPS
6321cb0ef41Sopenharmony_ci  const char arch[] = "mips";
6331cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_LOONG64
6341cb0ef41Sopenharmony_ci  const char arch[] = "loong64";
6351cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_ARM64
6361cb0ef41Sopenharmony_ci  const char arch[] = "arm64";
6371cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_S390
6381cb0ef41Sopenharmony_ci  const char arch[] = "s390";
6391cb0ef41Sopenharmony_ci#elif V8_TARGET_ARCH_RISCV64
6401cb0ef41Sopenharmony_ci  const char arch[] = "riscv64";
6411cb0ef41Sopenharmony_ci#else
6421cb0ef41Sopenharmony_ci  const char arch[] = "unknown";
6431cb0ef41Sopenharmony_ci#endif
6441cb0ef41Sopenharmony_ci  LogWriteBytes(arch, sizeof(arch));
6451cb0ef41Sopenharmony_ci}
6461cb0ef41Sopenharmony_ci
6471cb0ef41Sopenharmony_civoid LowLevelLogger::LogRecordedBuffer(Handle<AbstractCode> code,
6481cb0ef41Sopenharmony_ci                                       MaybeHandle<SharedFunctionInfo>,
6491cb0ef41Sopenharmony_ci                                       const char* name, int length) {
6501cb0ef41Sopenharmony_ci  CodeCreateStruct event;
6511cb0ef41Sopenharmony_ci  event.name_size = length;
6521cb0ef41Sopenharmony_ci  event.code_address = code->InstructionStart();
6531cb0ef41Sopenharmony_ci  event.code_size = code->InstructionSize();
6541cb0ef41Sopenharmony_ci  LogWriteStruct(event);
6551cb0ef41Sopenharmony_ci  LogWriteBytes(name, length);
6561cb0ef41Sopenharmony_ci  LogWriteBytes(reinterpret_cast<const char*>(code->InstructionStart()),
6571cb0ef41Sopenharmony_ci                code->InstructionSize());
6581cb0ef41Sopenharmony_ci}
6591cb0ef41Sopenharmony_ci
6601cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
6611cb0ef41Sopenharmony_civoid LowLevelLogger::LogRecordedBuffer(const wasm::WasmCode* code,
6621cb0ef41Sopenharmony_ci                                       const char* name, int length) {
6631cb0ef41Sopenharmony_ci  CodeCreateStruct event;
6641cb0ef41Sopenharmony_ci  event.name_size = length;
6651cb0ef41Sopenharmony_ci  event.code_address = code->instruction_start();
6661cb0ef41Sopenharmony_ci  event.code_size = code->instructions().length();
6671cb0ef41Sopenharmony_ci  LogWriteStruct(event);
6681cb0ef41Sopenharmony_ci  LogWriteBytes(name, length);
6691cb0ef41Sopenharmony_ci  LogWriteBytes(reinterpret_cast<const char*>(code->instruction_start()),
6701cb0ef41Sopenharmony_ci                code->instructions().length());
6711cb0ef41Sopenharmony_ci}
6721cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
6731cb0ef41Sopenharmony_ci
6741cb0ef41Sopenharmony_civoid LowLevelLogger::CodeMoveEvent(AbstractCode from, AbstractCode to) {
6751cb0ef41Sopenharmony_ci  CodeMoveStruct event;
6761cb0ef41Sopenharmony_ci  event.from_address = from.InstructionStart();
6771cb0ef41Sopenharmony_ci  event.to_address = to.InstructionStart();
6781cb0ef41Sopenharmony_ci  LogWriteStruct(event);
6791cb0ef41Sopenharmony_ci}
6801cb0ef41Sopenharmony_ci
6811cb0ef41Sopenharmony_civoid LowLevelLogger::LogWriteBytes(const char* bytes, int size) {
6821cb0ef41Sopenharmony_ci  size_t rv = fwrite(bytes, 1, size, ll_output_handle_);
6831cb0ef41Sopenharmony_ci  DCHECK(static_cast<size_t>(size) == rv);
6841cb0ef41Sopenharmony_ci  USE(rv);
6851cb0ef41Sopenharmony_ci}
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_civoid LowLevelLogger::CodeMovingGCEvent() {
6881cb0ef41Sopenharmony_ci  const char tag = kCodeMovingGCTag;
6891cb0ef41Sopenharmony_ci
6901cb0ef41Sopenharmony_ci  LogWriteBytes(&tag, sizeof(tag));
6911cb0ef41Sopenharmony_ci}
6921cb0ef41Sopenharmony_ci
6931cb0ef41Sopenharmony_ciclass JitLogger : public CodeEventLogger {
6941cb0ef41Sopenharmony_ci public:
6951cb0ef41Sopenharmony_ci  JitLogger(Isolate* isolate, JitCodeEventHandler code_event_handler);
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_ci  void CodeMoveEvent(AbstractCode from, AbstractCode to) override;
6981cb0ef41Sopenharmony_ci  void CodeDisableOptEvent(Handle<AbstractCode> code,
6991cb0ef41Sopenharmony_ci                           Handle<SharedFunctionInfo> shared) override {}
7001cb0ef41Sopenharmony_ci  void AddCodeLinePosInfoEvent(void* jit_handler_data, int pc_offset,
7011cb0ef41Sopenharmony_ci                               int position,
7021cb0ef41Sopenharmony_ci                               JitCodeEvent::PositionType position_type,
7031cb0ef41Sopenharmony_ci                               JitCodeEvent::CodeType code_type);
7041cb0ef41Sopenharmony_ci
7051cb0ef41Sopenharmony_ci  void* StartCodePosInfoEvent(JitCodeEvent::CodeType code_type);
7061cb0ef41Sopenharmony_ci  void EndCodePosInfoEvent(Address start_address, void* jit_handler_data,
7071cb0ef41Sopenharmony_ci                           JitCodeEvent::CodeType code_type);
7081cb0ef41Sopenharmony_ci
7091cb0ef41Sopenharmony_ci private:
7101cb0ef41Sopenharmony_ci  void LogRecordedBuffer(Handle<AbstractCode> code,
7111cb0ef41Sopenharmony_ci                         MaybeHandle<SharedFunctionInfo> maybe_shared,
7121cb0ef41Sopenharmony_ci                         const char* name, int length) override;
7131cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
7141cb0ef41Sopenharmony_ci  void LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
7151cb0ef41Sopenharmony_ci                         int length) override;
7161cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
7171cb0ef41Sopenharmony_ci
7181cb0ef41Sopenharmony_ci  JitCodeEventHandler code_event_handler_;
7191cb0ef41Sopenharmony_ci  base::Mutex logger_mutex_;
7201cb0ef41Sopenharmony_ci};
7211cb0ef41Sopenharmony_ci
7221cb0ef41Sopenharmony_ciJitLogger::JitLogger(Isolate* isolate, JitCodeEventHandler code_event_handler)
7231cb0ef41Sopenharmony_ci    : CodeEventLogger(isolate), code_event_handler_(code_event_handler) {}
7241cb0ef41Sopenharmony_ci
7251cb0ef41Sopenharmony_civoid JitLogger::LogRecordedBuffer(Handle<AbstractCode> code,
7261cb0ef41Sopenharmony_ci                                  MaybeHandle<SharedFunctionInfo> maybe_shared,
7271cb0ef41Sopenharmony_ci                                  const char* name, int length) {
7281cb0ef41Sopenharmony_ci  JitCodeEvent event = {};
7291cb0ef41Sopenharmony_ci  event.type = JitCodeEvent::CODE_ADDED;
7301cb0ef41Sopenharmony_ci  event.code_start = reinterpret_cast<void*>(code->InstructionStart());
7311cb0ef41Sopenharmony_ci  event.code_type =
7321cb0ef41Sopenharmony_ci      code->IsCode() ? JitCodeEvent::JIT_CODE : JitCodeEvent::BYTE_CODE;
7331cb0ef41Sopenharmony_ci  event.code_len = code->InstructionSize();
7341cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared;
7351cb0ef41Sopenharmony_ci  if (maybe_shared.ToHandle(&shared) && shared->script().IsScript()) {
7361cb0ef41Sopenharmony_ci    event.script = ToApiHandle<v8::UnboundScript>(shared);
7371cb0ef41Sopenharmony_ci  } else {
7381cb0ef41Sopenharmony_ci    event.script = Local<v8::UnboundScript>();
7391cb0ef41Sopenharmony_ci  }
7401cb0ef41Sopenharmony_ci  event.name.str = name;
7411cb0ef41Sopenharmony_ci  event.name.len = length;
7421cb0ef41Sopenharmony_ci  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
7431cb0ef41Sopenharmony_ci  code_event_handler_(&event);
7441cb0ef41Sopenharmony_ci}
7451cb0ef41Sopenharmony_ci
7461cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
7471cb0ef41Sopenharmony_civoid JitLogger::LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
7481cb0ef41Sopenharmony_ci                                  int length) {
7491cb0ef41Sopenharmony_ci  JitCodeEvent event = {};
7501cb0ef41Sopenharmony_ci  event.type = JitCodeEvent::CODE_ADDED;
7511cb0ef41Sopenharmony_ci  event.code_type = JitCodeEvent::WASM_CODE;
7521cb0ef41Sopenharmony_ci  event.code_start = code->instructions().begin();
7531cb0ef41Sopenharmony_ci  event.code_len = code->instructions().length();
7541cb0ef41Sopenharmony_ci  event.name.str = name;
7551cb0ef41Sopenharmony_ci  event.name.len = length;
7561cb0ef41Sopenharmony_ci  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
7571cb0ef41Sopenharmony_ci
7581cb0ef41Sopenharmony_ci  wasm::WasmModuleSourceMap* source_map =
7591cb0ef41Sopenharmony_ci      code->native_module()->GetWasmSourceMap();
7601cb0ef41Sopenharmony_ci  wasm::WireBytesRef code_ref =
7611cb0ef41Sopenharmony_ci      code->native_module()->module()->functions[code->index()].code;
7621cb0ef41Sopenharmony_ci  uint32_t code_offset = code_ref.offset();
7631cb0ef41Sopenharmony_ci  uint32_t code_end_offset = code_ref.end_offset();
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci  std::vector<v8::JitCodeEvent::line_info_t> mapping_info;
7661cb0ef41Sopenharmony_ci  std::string filename;
7671cb0ef41Sopenharmony_ci  std::unique_ptr<JitCodeEvent::wasm_source_info_t> wasm_source_info;
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_ci  if (source_map && source_map->IsValid() &&
7701cb0ef41Sopenharmony_ci      source_map->HasSource(code_offset, code_end_offset)) {
7711cb0ef41Sopenharmony_ci    size_t last_line_number = 0;
7721cb0ef41Sopenharmony_ci
7731cb0ef41Sopenharmony_ci    for (SourcePositionTableIterator iterator(code->source_positions());
7741cb0ef41Sopenharmony_ci         !iterator.done(); iterator.Advance()) {
7751cb0ef41Sopenharmony_ci      uint32_t offset = iterator.source_position().ScriptOffset() + code_offset;
7761cb0ef41Sopenharmony_ci      if (!source_map->HasValidEntry(code_offset, offset)) continue;
7771cb0ef41Sopenharmony_ci      if (filename.empty()) {
7781cb0ef41Sopenharmony_ci        filename = source_map->GetFilename(offset);
7791cb0ef41Sopenharmony_ci      }
7801cb0ef41Sopenharmony_ci      mapping_info.push_back({static_cast<size_t>(iterator.code_offset()),
7811cb0ef41Sopenharmony_ci                              last_line_number, JitCodeEvent::POSITION});
7821cb0ef41Sopenharmony_ci      last_line_number = source_map->GetSourceLine(offset) + 1;
7831cb0ef41Sopenharmony_ci    }
7841cb0ef41Sopenharmony_ci
7851cb0ef41Sopenharmony_ci    wasm_source_info = std::make_unique<JitCodeEvent::wasm_source_info_t>();
7861cb0ef41Sopenharmony_ci    wasm_source_info->filename = filename.c_str();
7871cb0ef41Sopenharmony_ci    wasm_source_info->filename_size = filename.size();
7881cb0ef41Sopenharmony_ci    wasm_source_info->line_number_table_size = mapping_info.size();
7891cb0ef41Sopenharmony_ci    wasm_source_info->line_number_table = mapping_info.data();
7901cb0ef41Sopenharmony_ci
7911cb0ef41Sopenharmony_ci    event.wasm_source_info = wasm_source_info.get();
7921cb0ef41Sopenharmony_ci  }
7931cb0ef41Sopenharmony_ci  code_event_handler_(&event);
7941cb0ef41Sopenharmony_ci}
7951cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_civoid JitLogger::CodeMoveEvent(AbstractCode from, AbstractCode to) {
7981cb0ef41Sopenharmony_ci  base::MutexGuard guard(&logger_mutex_);
7991cb0ef41Sopenharmony_ci
8001cb0ef41Sopenharmony_ci  JitCodeEvent event;
8011cb0ef41Sopenharmony_ci  event.type = JitCodeEvent::CODE_MOVED;
8021cb0ef41Sopenharmony_ci  event.code_type =
8031cb0ef41Sopenharmony_ci      from.IsCode() ? JitCodeEvent::JIT_CODE : JitCodeEvent::BYTE_CODE;
8041cb0ef41Sopenharmony_ci  event.code_start = reinterpret_cast<void*>(from.InstructionStart());
8051cb0ef41Sopenharmony_ci  event.code_len = from.InstructionSize();
8061cb0ef41Sopenharmony_ci  event.new_code_start = reinterpret_cast<void*>(to.InstructionStart());
8071cb0ef41Sopenharmony_ci  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
8081cb0ef41Sopenharmony_ci
8091cb0ef41Sopenharmony_ci  code_event_handler_(&event);
8101cb0ef41Sopenharmony_ci}
8111cb0ef41Sopenharmony_ci
8121cb0ef41Sopenharmony_civoid JitLogger::AddCodeLinePosInfoEvent(
8131cb0ef41Sopenharmony_ci    void* jit_handler_data, int pc_offset, int position,
8141cb0ef41Sopenharmony_ci    JitCodeEvent::PositionType position_type,
8151cb0ef41Sopenharmony_ci    JitCodeEvent::CodeType code_type) {
8161cb0ef41Sopenharmony_ci  JitCodeEvent event = {};
8171cb0ef41Sopenharmony_ci  event.type = JitCodeEvent::CODE_ADD_LINE_POS_INFO;
8181cb0ef41Sopenharmony_ci  event.code_type = code_type;
8191cb0ef41Sopenharmony_ci  event.user_data = jit_handler_data;
8201cb0ef41Sopenharmony_ci  event.line_info.offset = pc_offset;
8211cb0ef41Sopenharmony_ci  event.line_info.pos = position;
8221cb0ef41Sopenharmony_ci  event.line_info.position_type = position_type;
8231cb0ef41Sopenharmony_ci  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ci  code_event_handler_(&event);
8261cb0ef41Sopenharmony_ci}
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_civoid* JitLogger::StartCodePosInfoEvent(JitCodeEvent::CodeType code_type) {
8291cb0ef41Sopenharmony_ci  JitCodeEvent event = {};
8301cb0ef41Sopenharmony_ci  event.type = JitCodeEvent::CODE_START_LINE_INFO_RECORDING;
8311cb0ef41Sopenharmony_ci  event.code_type = code_type;
8321cb0ef41Sopenharmony_ci  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci  code_event_handler_(&event);
8351cb0ef41Sopenharmony_ci  return event.user_data;
8361cb0ef41Sopenharmony_ci}
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_civoid JitLogger::EndCodePosInfoEvent(Address start_address,
8391cb0ef41Sopenharmony_ci                                    void* jit_handler_data,
8401cb0ef41Sopenharmony_ci                                    JitCodeEvent::CodeType code_type) {
8411cb0ef41Sopenharmony_ci  JitCodeEvent event = {};
8421cb0ef41Sopenharmony_ci  event.type = JitCodeEvent::CODE_END_LINE_INFO_RECORDING;
8431cb0ef41Sopenharmony_ci  event.code_type = code_type;
8441cb0ef41Sopenharmony_ci  event.code_start = reinterpret_cast<void*>(start_address);
8451cb0ef41Sopenharmony_ci  event.user_data = jit_handler_data;
8461cb0ef41Sopenharmony_ci  event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
8471cb0ef41Sopenharmony_ci
8481cb0ef41Sopenharmony_ci  code_event_handler_(&event);
8491cb0ef41Sopenharmony_ci}
8501cb0ef41Sopenharmony_ci
8511cb0ef41Sopenharmony_ci// TODO(lpy): Keeping sampling thread inside V8 is a workaround currently,
8521cb0ef41Sopenharmony_ci// the reason is to reduce code duplication during migration to sampler library,
8531cb0ef41Sopenharmony_ci// sampling thread, as well as the sampler, will be moved to D8 eventually.
8541cb0ef41Sopenharmony_ciclass SamplingThread : public base::Thread {
8551cb0ef41Sopenharmony_ci public:
8561cb0ef41Sopenharmony_ci  static const int kSamplingThreadStackSize = 64 * KB;
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci  SamplingThread(sampler::Sampler* sampler, int interval_microseconds)
8591cb0ef41Sopenharmony_ci      : base::Thread(
8601cb0ef41Sopenharmony_ci            base::Thread::Options("SamplingThread", kSamplingThreadStackSize)),
8611cb0ef41Sopenharmony_ci        sampler_(sampler),
8621cb0ef41Sopenharmony_ci        interval_microseconds_(interval_microseconds) {}
8631cb0ef41Sopenharmony_ci  void Run() override {
8641cb0ef41Sopenharmony_ci    while (sampler_->IsActive()) {
8651cb0ef41Sopenharmony_ci      sampler_->DoSample();
8661cb0ef41Sopenharmony_ci      base::OS::Sleep(
8671cb0ef41Sopenharmony_ci          base::TimeDelta::FromMicroseconds(interval_microseconds_));
8681cb0ef41Sopenharmony_ci    }
8691cb0ef41Sopenharmony_ci  }
8701cb0ef41Sopenharmony_ci
8711cb0ef41Sopenharmony_ci private:
8721cb0ef41Sopenharmony_ci  sampler::Sampler* sampler_;
8731cb0ef41Sopenharmony_ci  const int interval_microseconds_;
8741cb0ef41Sopenharmony_ci};
8751cb0ef41Sopenharmony_ci
8761cb0ef41Sopenharmony_ci// The Profiler samples pc and sp values for the main thread.
8771cb0ef41Sopenharmony_ci// Each sample is appended to a circular buffer.
8781cb0ef41Sopenharmony_ci// An independent thread removes data and writes it to the log.
8791cb0ef41Sopenharmony_ci// This design minimizes the time spent in the sampler.
8801cb0ef41Sopenharmony_ci//
8811cb0ef41Sopenharmony_ciclass Profiler : public base::Thread {
8821cb0ef41Sopenharmony_ci public:
8831cb0ef41Sopenharmony_ci  explicit Profiler(Isolate* isolate);
8841cb0ef41Sopenharmony_ci  void Engage();
8851cb0ef41Sopenharmony_ci  void Disengage();
8861cb0ef41Sopenharmony_ci
8871cb0ef41Sopenharmony_ci  // Inserts collected profiling data into buffer.
8881cb0ef41Sopenharmony_ci  void Insert(TickSample* sample) {
8891cb0ef41Sopenharmony_ci    if (Succ(head_) == static_cast<int>(base::Relaxed_Load(&tail_))) {
8901cb0ef41Sopenharmony_ci      overflow_ = true;
8911cb0ef41Sopenharmony_ci    } else {
8921cb0ef41Sopenharmony_ci      buffer_[head_] = *sample;
8931cb0ef41Sopenharmony_ci      head_ = Succ(head_);
8941cb0ef41Sopenharmony_ci      buffer_semaphore_.Signal();  // Tell we have an element.
8951cb0ef41Sopenharmony_ci    }
8961cb0ef41Sopenharmony_ci  }
8971cb0ef41Sopenharmony_ci
8981cb0ef41Sopenharmony_ci  void Run() override;
8991cb0ef41Sopenharmony_ci
9001cb0ef41Sopenharmony_ci private:
9011cb0ef41Sopenharmony_ci  // Waits for a signal and removes profiling data.
9021cb0ef41Sopenharmony_ci  bool Remove(TickSample* sample) {
9031cb0ef41Sopenharmony_ci    buffer_semaphore_.Wait();  // Wait for an element.
9041cb0ef41Sopenharmony_ci    *sample = buffer_[base::Relaxed_Load(&tail_)];
9051cb0ef41Sopenharmony_ci    bool result = overflow_;
9061cb0ef41Sopenharmony_ci    base::Relaxed_Store(
9071cb0ef41Sopenharmony_ci        &tail_, static_cast<base::Atomic32>(Succ(base::Relaxed_Load(&tail_))));
9081cb0ef41Sopenharmony_ci    overflow_ = false;
9091cb0ef41Sopenharmony_ci    return result;
9101cb0ef41Sopenharmony_ci  }
9111cb0ef41Sopenharmony_ci
9121cb0ef41Sopenharmony_ci  // Returns the next index in the cyclic buffer.
9131cb0ef41Sopenharmony_ci  int Succ(int index) { return (index + 1) % kBufferSize; }
9141cb0ef41Sopenharmony_ci
9151cb0ef41Sopenharmony_ci  Isolate* isolate_;
9161cb0ef41Sopenharmony_ci  // Cyclic buffer for communicating profiling samples
9171cb0ef41Sopenharmony_ci  // between the signal handler and the worker thread.
9181cb0ef41Sopenharmony_ci  static const int kBufferSize = 128;
9191cb0ef41Sopenharmony_ci  TickSample buffer_[kBufferSize];  // Buffer storage.
9201cb0ef41Sopenharmony_ci  int head_;                        // Index to the buffer head.
9211cb0ef41Sopenharmony_ci  base::Atomic32 tail_;             // Index to the buffer tail.
9221cb0ef41Sopenharmony_ci  bool overflow_;  // Tell whether a buffer overflow has occurred.
9231cb0ef41Sopenharmony_ci  // Semaphore used for buffer synchronization.
9241cb0ef41Sopenharmony_ci  base::Semaphore buffer_semaphore_;
9251cb0ef41Sopenharmony_ci
9261cb0ef41Sopenharmony_ci  // Tells whether worker thread should continue running.
9271cb0ef41Sopenharmony_ci  base::Atomic32 running_;
9281cb0ef41Sopenharmony_ci};
9291cb0ef41Sopenharmony_ci
9301cb0ef41Sopenharmony_ci//
9311cb0ef41Sopenharmony_ci// Ticker used to provide ticks to the profiler and the sliding state
9321cb0ef41Sopenharmony_ci// window.
9331cb0ef41Sopenharmony_ci//
9341cb0ef41Sopenharmony_ciclass Ticker : public sampler::Sampler {
9351cb0ef41Sopenharmony_ci public:
9361cb0ef41Sopenharmony_ci  Ticker(Isolate* isolate, int interval_microseconds)
9371cb0ef41Sopenharmony_ci      : sampler::Sampler(reinterpret_cast<v8::Isolate*>(isolate)),
9381cb0ef41Sopenharmony_ci        sampling_thread_(
9391cb0ef41Sopenharmony_ci            std::make_unique<SamplingThread>(this, interval_microseconds)),
9401cb0ef41Sopenharmony_ci        perThreadData_(isolate->FindPerThreadDataForThisThread()) {}
9411cb0ef41Sopenharmony_ci
9421cb0ef41Sopenharmony_ci  ~Ticker() override {
9431cb0ef41Sopenharmony_ci    if (IsActive()) Stop();
9441cb0ef41Sopenharmony_ci  }
9451cb0ef41Sopenharmony_ci
9461cb0ef41Sopenharmony_ci  void SetProfiler(Profiler* profiler) {
9471cb0ef41Sopenharmony_ci    DCHECK_NULL(profiler_);
9481cb0ef41Sopenharmony_ci    profiler_ = profiler;
9491cb0ef41Sopenharmony_ci    if (!IsActive()) Start();
9501cb0ef41Sopenharmony_ci    sampling_thread_->StartSynchronously();
9511cb0ef41Sopenharmony_ci  }
9521cb0ef41Sopenharmony_ci
9531cb0ef41Sopenharmony_ci  void ClearProfiler() {
9541cb0ef41Sopenharmony_ci    profiler_ = nullptr;
9551cb0ef41Sopenharmony_ci    if (IsActive()) Stop();
9561cb0ef41Sopenharmony_ci    sampling_thread_->Join();
9571cb0ef41Sopenharmony_ci  }
9581cb0ef41Sopenharmony_ci
9591cb0ef41Sopenharmony_ci  void SampleStack(const v8::RegisterState& state) override {
9601cb0ef41Sopenharmony_ci    if (!profiler_) return;
9611cb0ef41Sopenharmony_ci    Isolate* isolate = reinterpret_cast<Isolate*>(this->isolate());
9621cb0ef41Sopenharmony_ci    if (isolate->was_locker_ever_used() &&
9631cb0ef41Sopenharmony_ci        (!isolate->thread_manager()->IsLockedByThread(
9641cb0ef41Sopenharmony_ci             perThreadData_->thread_id()) ||
9651cb0ef41Sopenharmony_ci         perThreadData_->thread_state() != nullptr))
9661cb0ef41Sopenharmony_ci      return;
9671cb0ef41Sopenharmony_ci    TickSample sample;
9681cb0ef41Sopenharmony_ci    sample.Init(isolate, state, TickSample::kIncludeCEntryFrame, true);
9691cb0ef41Sopenharmony_ci    profiler_->Insert(&sample);
9701cb0ef41Sopenharmony_ci  }
9711cb0ef41Sopenharmony_ci
9721cb0ef41Sopenharmony_ci private:
9731cb0ef41Sopenharmony_ci  Profiler* profiler_ = nullptr;
9741cb0ef41Sopenharmony_ci  std::unique_ptr<SamplingThread> sampling_thread_;
9751cb0ef41Sopenharmony_ci  Isolate::PerIsolateThreadData* perThreadData_;
9761cb0ef41Sopenharmony_ci};
9771cb0ef41Sopenharmony_ci
9781cb0ef41Sopenharmony_ci//
9791cb0ef41Sopenharmony_ci// Profiler implementation when invoking with --prof.
9801cb0ef41Sopenharmony_ci//
9811cb0ef41Sopenharmony_ciProfiler::Profiler(Isolate* isolate)
9821cb0ef41Sopenharmony_ci    : base::Thread(Options("v8:Profiler")),
9831cb0ef41Sopenharmony_ci      isolate_(isolate),
9841cb0ef41Sopenharmony_ci      head_(0),
9851cb0ef41Sopenharmony_ci      overflow_(false),
9861cb0ef41Sopenharmony_ci      buffer_semaphore_(0) {
9871cb0ef41Sopenharmony_ci  base::Relaxed_Store(&tail_, 0);
9881cb0ef41Sopenharmony_ci  base::Relaxed_Store(&running_, 0);
9891cb0ef41Sopenharmony_ci}
9901cb0ef41Sopenharmony_ci
9911cb0ef41Sopenharmony_civoid Profiler::Engage() {
9921cb0ef41Sopenharmony_ci  std::vector<base::OS::SharedLibraryAddress> addresses =
9931cb0ef41Sopenharmony_ci      base::OS::GetSharedLibraryAddresses();
9941cb0ef41Sopenharmony_ci  for (const auto& address : addresses) {
9951cb0ef41Sopenharmony_ci    LOG(isolate_, SharedLibraryEvent(address.library_path, address.start,
9961cb0ef41Sopenharmony_ci                                     address.end, address.aslr_slide));
9971cb0ef41Sopenharmony_ci  }
9981cb0ef41Sopenharmony_ci  LOG(isolate_, SharedLibraryEnd());
9991cb0ef41Sopenharmony_ci
10001cb0ef41Sopenharmony_ci  // Start thread processing the profiler buffer.
10011cb0ef41Sopenharmony_ci  base::Relaxed_Store(&running_, 1);
10021cb0ef41Sopenharmony_ci  CHECK(Start());
10031cb0ef41Sopenharmony_ci
10041cb0ef41Sopenharmony_ci  // Register to get ticks.
10051cb0ef41Sopenharmony_ci  Logger* logger = isolate_->logger();
10061cb0ef41Sopenharmony_ci  logger->ticker_->SetProfiler(this);
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ci  LOG(isolate_, ProfilerBeginEvent());
10091cb0ef41Sopenharmony_ci}
10101cb0ef41Sopenharmony_ci
10111cb0ef41Sopenharmony_civoid Profiler::Disengage() {
10121cb0ef41Sopenharmony_ci  // Stop receiving ticks.
10131cb0ef41Sopenharmony_ci  isolate_->logger()->ticker_->ClearProfiler();
10141cb0ef41Sopenharmony_ci
10151cb0ef41Sopenharmony_ci  // Terminate the worker thread by setting running_ to false,
10161cb0ef41Sopenharmony_ci  // inserting a fake element in the queue and then wait for
10171cb0ef41Sopenharmony_ci  // the thread to terminate.
10181cb0ef41Sopenharmony_ci  base::Relaxed_Store(&running_, 0);
10191cb0ef41Sopenharmony_ci  TickSample sample;
10201cb0ef41Sopenharmony_ci  Insert(&sample);
10211cb0ef41Sopenharmony_ci  Join();
10221cb0ef41Sopenharmony_ci
10231cb0ef41Sopenharmony_ci  LOG(isolate_, UncheckedStringEvent("profiler", "end"));
10241cb0ef41Sopenharmony_ci}
10251cb0ef41Sopenharmony_ci
10261cb0ef41Sopenharmony_civoid Profiler::Run() {
10271cb0ef41Sopenharmony_ci  TickSample sample;
10281cb0ef41Sopenharmony_ci  bool overflow = Remove(&sample);
10291cb0ef41Sopenharmony_ci  while (base::Relaxed_Load(&running_)) {
10301cb0ef41Sopenharmony_ci    LOG(isolate_, TickEvent(&sample, overflow));
10311cb0ef41Sopenharmony_ci    overflow = Remove(&sample);
10321cb0ef41Sopenharmony_ci  }
10331cb0ef41Sopenharmony_ci}
10341cb0ef41Sopenharmony_ci
10351cb0ef41Sopenharmony_ci//
10361cb0ef41Sopenharmony_ci// Logger class implementation.
10371cb0ef41Sopenharmony_ci//
10381cb0ef41Sopenharmony_ci#define MSG_BUILDER()                                                       \
10391cb0ef41Sopenharmony_ci  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); \
10401cb0ef41Sopenharmony_ci  if (!msg_ptr) return;                                                     \
10411cb0ef41Sopenharmony_ci  Log::MessageBuilder& msg = *msg_ptr.get();
10421cb0ef41Sopenharmony_ci
10431cb0ef41Sopenharmony_ciLogger::Logger(Isolate* isolate)
10441cb0ef41Sopenharmony_ci    : isolate_(isolate),
10451cb0ef41Sopenharmony_ci      is_logging_(false),
10461cb0ef41Sopenharmony_ci      is_initialized_(false),
10471cb0ef41Sopenharmony_ci      existing_code_logger_(isolate) {}
10481cb0ef41Sopenharmony_ci
10491cb0ef41Sopenharmony_ciLogger::~Logger() = default;
10501cb0ef41Sopenharmony_ci
10511cb0ef41Sopenharmony_ciconst LogSeparator Logger::kNext = LogSeparator::kSeparator;
10521cb0ef41Sopenharmony_ci
10531cb0ef41Sopenharmony_ciint64_t Logger::Time() {
10541cb0ef41Sopenharmony_ci  if (FLAG_verify_predictable) {
10551cb0ef41Sopenharmony_ci    return isolate_->heap()->MonotonicallyIncreasingTimeInMs() * 1000;
10561cb0ef41Sopenharmony_ci  }
10571cb0ef41Sopenharmony_ci  return timer_.Elapsed().InMicroseconds();
10581cb0ef41Sopenharmony_ci}
10591cb0ef41Sopenharmony_ci
10601cb0ef41Sopenharmony_civoid Logger::AddCodeEventListener(CodeEventListener* listener) {
10611cb0ef41Sopenharmony_ci  bool result = isolate_->code_event_dispatcher()->AddListener(listener);
10621cb0ef41Sopenharmony_ci  CHECK(result);
10631cb0ef41Sopenharmony_ci}
10641cb0ef41Sopenharmony_ci
10651cb0ef41Sopenharmony_civoid Logger::RemoveCodeEventListener(CodeEventListener* listener) {
10661cb0ef41Sopenharmony_ci  isolate_->code_event_dispatcher()->RemoveListener(listener);
10671cb0ef41Sopenharmony_ci}
10681cb0ef41Sopenharmony_ci
10691cb0ef41Sopenharmony_civoid Logger::ProfilerBeginEvent() {
10701cb0ef41Sopenharmony_ci  MSG_BUILDER();
10711cb0ef41Sopenharmony_ci  msg << "profiler" << kNext << "begin" << kNext << FLAG_prof_sampling_interval;
10721cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
10731cb0ef41Sopenharmony_ci}
10741cb0ef41Sopenharmony_ci
10751cb0ef41Sopenharmony_civoid Logger::StringEvent(const char* name, const char* value) {
10761cb0ef41Sopenharmony_ci  if (FLAG_log) UncheckedStringEvent(name, value);
10771cb0ef41Sopenharmony_ci}
10781cb0ef41Sopenharmony_ci
10791cb0ef41Sopenharmony_civoid Logger::UncheckedStringEvent(const char* name, const char* value) {
10801cb0ef41Sopenharmony_ci  MSG_BUILDER();
10811cb0ef41Sopenharmony_ci  msg << name << kNext << value;
10821cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
10831cb0ef41Sopenharmony_ci}
10841cb0ef41Sopenharmony_ci
10851cb0ef41Sopenharmony_civoid Logger::IntPtrTEvent(const char* name, intptr_t value) {
10861cb0ef41Sopenharmony_ci  if (!FLAG_log) return;
10871cb0ef41Sopenharmony_ci  MSG_BUILDER();
10881cb0ef41Sopenharmony_ci  msg << name << kNext;
10891cb0ef41Sopenharmony_ci  msg.AppendFormatString("%" V8PRIdPTR, value);
10901cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
10911cb0ef41Sopenharmony_ci}
10921cb0ef41Sopenharmony_ci
10931cb0ef41Sopenharmony_civoid Logger::SharedLibraryEvent(const std::string& library_path,
10941cb0ef41Sopenharmony_ci                                uintptr_t start, uintptr_t end,
10951cb0ef41Sopenharmony_ci                                intptr_t aslr_slide) {
10961cb0ef41Sopenharmony_ci  if (!FLAG_prof_cpp) return;
10971cb0ef41Sopenharmony_ci  MSG_BUILDER();
10981cb0ef41Sopenharmony_ci  msg << "shared-library" << kNext << library_path.c_str() << kNext
10991cb0ef41Sopenharmony_ci      << reinterpret_cast<void*>(start) << kNext << reinterpret_cast<void*>(end)
11001cb0ef41Sopenharmony_ci      << kNext << aslr_slide;
11011cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
11021cb0ef41Sopenharmony_ci}
11031cb0ef41Sopenharmony_ci
11041cb0ef41Sopenharmony_civoid Logger::SharedLibraryEnd() {
11051cb0ef41Sopenharmony_ci  if (!FLAG_prof_cpp) return;
11061cb0ef41Sopenharmony_ci  MSG_BUILDER();
11071cb0ef41Sopenharmony_ci  msg << "shared-library-end";
11081cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
11091cb0ef41Sopenharmony_ci}
11101cb0ef41Sopenharmony_ci
11111cb0ef41Sopenharmony_civoid Logger::CurrentTimeEvent() {
11121cb0ef41Sopenharmony_ci  DCHECK(FLAG_log_internal_timer_events);
11131cb0ef41Sopenharmony_ci  MSG_BUILDER();
11141cb0ef41Sopenharmony_ci  msg << "current-time" << kNext << Time();
11151cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
11161cb0ef41Sopenharmony_ci}
11171cb0ef41Sopenharmony_ci
11181cb0ef41Sopenharmony_civoid Logger::TimerEvent(v8::LogEventStatus se, const char* name) {
11191cb0ef41Sopenharmony_ci  MSG_BUILDER();
11201cb0ef41Sopenharmony_ci  switch (se) {
11211cb0ef41Sopenharmony_ci    case kStart:
11221cb0ef41Sopenharmony_ci      msg << "timer-event-start";
11231cb0ef41Sopenharmony_ci      break;
11241cb0ef41Sopenharmony_ci    case kEnd:
11251cb0ef41Sopenharmony_ci      msg << "timer-event-end";
11261cb0ef41Sopenharmony_ci      break;
11271cb0ef41Sopenharmony_ci    case kStamp:
11281cb0ef41Sopenharmony_ci      msg << "timer-event";
11291cb0ef41Sopenharmony_ci  }
11301cb0ef41Sopenharmony_ci  msg << kNext << name << kNext << Time();
11311cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
11321cb0ef41Sopenharmony_ci}
11331cb0ef41Sopenharmony_ci
11341cb0ef41Sopenharmony_civoid Logger::BasicBlockCounterEvent(const char* name, int block_id,
11351cb0ef41Sopenharmony_ci                                    uint32_t count) {
11361cb0ef41Sopenharmony_ci  if (!FLAG_turbo_profiling_log_builtins) return;
11371cb0ef41Sopenharmony_ci  MSG_BUILDER();
11381cb0ef41Sopenharmony_ci  msg << ProfileDataFromFileConstants::kBlockCounterMarker << kNext << name
11391cb0ef41Sopenharmony_ci      << kNext << block_id << kNext << count;
11401cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
11411cb0ef41Sopenharmony_ci}
11421cb0ef41Sopenharmony_ci
11431cb0ef41Sopenharmony_civoid Logger::BuiltinHashEvent(const char* name, int hash) {
11441cb0ef41Sopenharmony_ci  if (!FLAG_turbo_profiling_log_builtins) return;
11451cb0ef41Sopenharmony_ci  MSG_BUILDER();
11461cb0ef41Sopenharmony_ci  msg << ProfileDataFromFileConstants::kBuiltinHashMarker << kNext << name
11471cb0ef41Sopenharmony_ci      << kNext << hash;
11481cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
11491cb0ef41Sopenharmony_ci}
11501cb0ef41Sopenharmony_ci
11511cb0ef41Sopenharmony_cibool Logger::is_logging() {
11521cb0ef41Sopenharmony_ci  // Disable logging while the CPU profiler is running.
11531cb0ef41Sopenharmony_ci  if (isolate_->is_profiling()) return false;
11541cb0ef41Sopenharmony_ci  return is_logging_.load(std::memory_order_relaxed);
11551cb0ef41Sopenharmony_ci}
11561cb0ef41Sopenharmony_ci
11571cb0ef41Sopenharmony_ci// Instantiate template methods.
11581cb0ef41Sopenharmony_ci#define V(TimerName, expose)                                           \
11591cb0ef41Sopenharmony_ci  template void TimerEventScope<TimerEvent##TimerName>::LogTimerEvent( \
11601cb0ef41Sopenharmony_ci      v8::LogEventStatus se);
11611cb0ef41Sopenharmony_ciTIMER_EVENTS_LIST(V)
11621cb0ef41Sopenharmony_ci#undef V
11631cb0ef41Sopenharmony_ci
11641cb0ef41Sopenharmony_civoid Logger::NewEvent(const char* name, void* object, size_t size) {
11651cb0ef41Sopenharmony_ci  if (!FLAG_log) return;
11661cb0ef41Sopenharmony_ci  MSG_BUILDER();
11671cb0ef41Sopenharmony_ci  msg << "new" << kNext << name << kNext << object << kNext
11681cb0ef41Sopenharmony_ci      << static_cast<unsigned int>(size);
11691cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
11701cb0ef41Sopenharmony_ci}
11711cb0ef41Sopenharmony_ci
11721cb0ef41Sopenharmony_civoid Logger::DeleteEvent(const char* name, void* object) {
11731cb0ef41Sopenharmony_ci  if (!FLAG_log) return;
11741cb0ef41Sopenharmony_ci  MSG_BUILDER();
11751cb0ef41Sopenharmony_ci  msg << "delete" << kNext << name << kNext << object;
11761cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
11771cb0ef41Sopenharmony_ci}
11781cb0ef41Sopenharmony_ci
11791cb0ef41Sopenharmony_cinamespace {
11801cb0ef41Sopenharmony_ci
11811cb0ef41Sopenharmony_civoid AppendCodeCreateHeader(Log::MessageBuilder& msg,
11821cb0ef41Sopenharmony_ci                            CodeEventListener::LogEventsAndTags tag,
11831cb0ef41Sopenharmony_ci                            CodeKind kind, uint8_t* address, int size,
11841cb0ef41Sopenharmony_ci                            uint64_t time) {
11851cb0ef41Sopenharmony_ci  msg << kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT]
11861cb0ef41Sopenharmony_ci      << Logger::kNext << kLogEventsNames[tag] << Logger::kNext
11871cb0ef41Sopenharmony_ci      << static_cast<int>(kind) << Logger::kNext << time << Logger::kNext
11881cb0ef41Sopenharmony_ci      << reinterpret_cast<void*>(address) << Logger::kNext << size
11891cb0ef41Sopenharmony_ci      << Logger::kNext;
11901cb0ef41Sopenharmony_ci}
11911cb0ef41Sopenharmony_ci
11921cb0ef41Sopenharmony_civoid AppendCodeCreateHeader(Log::MessageBuilder& msg,
11931cb0ef41Sopenharmony_ci                            CodeEventListener::LogEventsAndTags tag,
11941cb0ef41Sopenharmony_ci                            AbstractCode code, uint64_t time) {
11951cb0ef41Sopenharmony_ci  AppendCodeCreateHeader(msg, tag, code.kind(),
11961cb0ef41Sopenharmony_ci                         reinterpret_cast<uint8_t*>(code.InstructionStart()),
11971cb0ef41Sopenharmony_ci                         code.InstructionSize(), time);
11981cb0ef41Sopenharmony_ci}
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_ci}  // namespace
12011cb0ef41Sopenharmony_ci// We log source code information in the form:
12021cb0ef41Sopenharmony_ci//
12031cb0ef41Sopenharmony_ci// code-source-info <addr>,<script>,<start>,<end>,<pos>,<inline-pos>,<fns>
12041cb0ef41Sopenharmony_ci//
12051cb0ef41Sopenharmony_ci// where
12061cb0ef41Sopenharmony_ci//   <addr> is code object address
12071cb0ef41Sopenharmony_ci//   <script> is script id
12081cb0ef41Sopenharmony_ci//   <start> is the starting position inside the script
12091cb0ef41Sopenharmony_ci//   <end> is the end position inside the script
12101cb0ef41Sopenharmony_ci//   <pos> is source position table encoded in the string,
12111cb0ef41Sopenharmony_ci//      it is a sequence of C<code-offset>O<script-offset>[I<inlining-id>]
12121cb0ef41Sopenharmony_ci//      where
12131cb0ef41Sopenharmony_ci//        <code-offset> is the offset within the code object
12141cb0ef41Sopenharmony_ci//        <script-offset> is the position within the script
12151cb0ef41Sopenharmony_ci//        <inlining-id> is the offset in the <inlining> table
12161cb0ef41Sopenharmony_ci//   <inlining> table is a sequence of strings of the form
12171cb0ef41Sopenharmony_ci//      F<function-id>O<script-offset>[I<inlining-id>]
12181cb0ef41Sopenharmony_ci//      where
12191cb0ef41Sopenharmony_ci//         <function-id> is an index into the <fns> function table
12201cb0ef41Sopenharmony_ci//   <fns> is the function table encoded as a sequence of strings
12211cb0ef41Sopenharmony_ci//      S<shared-function-info-address>
12221cb0ef41Sopenharmony_ci
12231cb0ef41Sopenharmony_civoid Logger::LogSourceCodeInformation(Handle<AbstractCode> code,
12241cb0ef41Sopenharmony_ci                                      Handle<SharedFunctionInfo> shared) {
12251cb0ef41Sopenharmony_ci  Object script_object = shared->script();
12261cb0ef41Sopenharmony_ci  if (!script_object.IsScript()) return;
12271cb0ef41Sopenharmony_ci  Script script = Script::cast(script_object);
12281cb0ef41Sopenharmony_ci  EnsureLogScriptSource(script);
12291cb0ef41Sopenharmony_ci
12301cb0ef41Sopenharmony_ci  MSG_BUILDER();
12311cb0ef41Sopenharmony_ci  msg << "code-source-info" << Logger::kNext
12321cb0ef41Sopenharmony_ci      << reinterpret_cast<void*>(code->InstructionStart()) << Logger::kNext
12331cb0ef41Sopenharmony_ci      << script.id() << Logger::kNext << shared->StartPosition()
12341cb0ef41Sopenharmony_ci      << Logger::kNext << shared->EndPosition() << Logger::kNext;
12351cb0ef41Sopenharmony_ci  // TODO(v8:11429): Clean-up baseline-replated code in source position
12361cb0ef41Sopenharmony_ci  // iteration.
12371cb0ef41Sopenharmony_ci  bool hasInlined = false;
12381cb0ef41Sopenharmony_ci  if (code->kind() != CodeKind::BASELINE) {
12391cb0ef41Sopenharmony_ci    SourcePositionTableIterator iterator(code->SourcePositionTable(*shared));
12401cb0ef41Sopenharmony_ci    for (; !iterator.done(); iterator.Advance()) {
12411cb0ef41Sopenharmony_ci      SourcePosition pos = iterator.source_position();
12421cb0ef41Sopenharmony_ci      msg << "C" << iterator.code_offset() << "O" << pos.ScriptOffset();
12431cb0ef41Sopenharmony_ci      if (pos.isInlined()) {
12441cb0ef41Sopenharmony_ci        msg << "I" << pos.InliningId();
12451cb0ef41Sopenharmony_ci        hasInlined = true;
12461cb0ef41Sopenharmony_ci      }
12471cb0ef41Sopenharmony_ci    }
12481cb0ef41Sopenharmony_ci  }
12491cb0ef41Sopenharmony_ci  msg << Logger::kNext;
12501cb0ef41Sopenharmony_ci  int maxInlinedId = -1;
12511cb0ef41Sopenharmony_ci  if (hasInlined) {
12521cb0ef41Sopenharmony_ci    PodArray<InliningPosition> inlining_positions =
12531cb0ef41Sopenharmony_ci        DeoptimizationData::cast(
12541cb0ef41Sopenharmony_ci            Handle<Code>::cast(code)->deoptimization_data())
12551cb0ef41Sopenharmony_ci            .InliningPositions();
12561cb0ef41Sopenharmony_ci    for (int i = 0; i < inlining_positions.length(); i++) {
12571cb0ef41Sopenharmony_ci      InliningPosition inlining_pos = inlining_positions.get(i);
12581cb0ef41Sopenharmony_ci      msg << "F";
12591cb0ef41Sopenharmony_ci      if (inlining_pos.inlined_function_id != -1) {
12601cb0ef41Sopenharmony_ci        msg << inlining_pos.inlined_function_id;
12611cb0ef41Sopenharmony_ci        if (inlining_pos.inlined_function_id > maxInlinedId) {
12621cb0ef41Sopenharmony_ci          maxInlinedId = inlining_pos.inlined_function_id;
12631cb0ef41Sopenharmony_ci        }
12641cb0ef41Sopenharmony_ci      }
12651cb0ef41Sopenharmony_ci      SourcePosition pos = inlining_pos.position;
12661cb0ef41Sopenharmony_ci      msg << "O" << pos.ScriptOffset();
12671cb0ef41Sopenharmony_ci      if (pos.isInlined()) {
12681cb0ef41Sopenharmony_ci        msg << "I" << pos.InliningId();
12691cb0ef41Sopenharmony_ci      }
12701cb0ef41Sopenharmony_ci    }
12711cb0ef41Sopenharmony_ci  }
12721cb0ef41Sopenharmony_ci  msg << Logger::kNext;
12731cb0ef41Sopenharmony_ci  if (hasInlined) {
12741cb0ef41Sopenharmony_ci    DeoptimizationData deopt_data = DeoptimizationData::cast(
12751cb0ef41Sopenharmony_ci        Handle<Code>::cast(code)->deoptimization_data());
12761cb0ef41Sopenharmony_ci    msg << std::hex;
12771cb0ef41Sopenharmony_ci    for (int i = 0; i <= maxInlinedId; i++) {
12781cb0ef41Sopenharmony_ci      msg << "S"
12791cb0ef41Sopenharmony_ci          << reinterpret_cast<void*>(
12801cb0ef41Sopenharmony_ci                 deopt_data.GetInlinedFunction(i).address());
12811cb0ef41Sopenharmony_ci    }
12821cb0ef41Sopenharmony_ci    msg << std::dec;
12831cb0ef41Sopenharmony_ci  }
12841cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
12851cb0ef41Sopenharmony_ci}
12861cb0ef41Sopenharmony_ci
12871cb0ef41Sopenharmony_civoid Logger::LogCodeDisassemble(Handle<AbstractCode> code) {
12881cb0ef41Sopenharmony_ci  if (!FLAG_log_code_disassemble) return;
12891cb0ef41Sopenharmony_ci  MSG_BUILDER();
12901cb0ef41Sopenharmony_ci  msg << "code-disassemble" << Logger::kNext
12911cb0ef41Sopenharmony_ci      << reinterpret_cast<void*>(code->InstructionStart()) << Logger::kNext
12921cb0ef41Sopenharmony_ci      << CodeKindToString(code->kind()) << Logger::kNext;
12931cb0ef41Sopenharmony_ci  {
12941cb0ef41Sopenharmony_ci    std::ostringstream stream;
12951cb0ef41Sopenharmony_ci    if (code->IsCode()) {
12961cb0ef41Sopenharmony_ci#ifdef ENABLE_DISASSEMBLER
12971cb0ef41Sopenharmony_ci      Code::cast(*code).Disassemble(nullptr, stream, isolate_);
12981cb0ef41Sopenharmony_ci#endif
12991cb0ef41Sopenharmony_ci    } else {
13001cb0ef41Sopenharmony_ci      BytecodeArray::cast(*code).Disassemble(stream);
13011cb0ef41Sopenharmony_ci    }
13021cb0ef41Sopenharmony_ci    std::string string = stream.str();
13031cb0ef41Sopenharmony_ci    msg.AppendString(string.c_str(), string.length());
13041cb0ef41Sopenharmony_ci  }
13051cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
13061cb0ef41Sopenharmony_ci}
13071cb0ef41Sopenharmony_ci
13081cb0ef41Sopenharmony_ci// Builtins and Bytecode handlers
13091cb0ef41Sopenharmony_civoid Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
13101cb0ef41Sopenharmony_ci                             const char* name) {
13111cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
13121cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
13131cb0ef41Sopenharmony_ci  {
13141cb0ef41Sopenharmony_ci    MSG_BUILDER();
13151cb0ef41Sopenharmony_ci    AppendCodeCreateHeader(msg, tag, *code, Time());
13161cb0ef41Sopenharmony_ci    msg << name;
13171cb0ef41Sopenharmony_ci    msg.WriteToLogFile();
13181cb0ef41Sopenharmony_ci  }
13191cb0ef41Sopenharmony_ci  LogCodeDisassemble(code);
13201cb0ef41Sopenharmony_ci}
13211cb0ef41Sopenharmony_ci
13221cb0ef41Sopenharmony_civoid Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
13231cb0ef41Sopenharmony_ci                             Handle<Name> name) {
13241cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
13251cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
13261cb0ef41Sopenharmony_ci  {
13271cb0ef41Sopenharmony_ci    MSG_BUILDER();
13281cb0ef41Sopenharmony_ci    AppendCodeCreateHeader(msg, tag, *code, Time());
13291cb0ef41Sopenharmony_ci    msg << *name;
13301cb0ef41Sopenharmony_ci    msg.WriteToLogFile();
13311cb0ef41Sopenharmony_ci  }
13321cb0ef41Sopenharmony_ci  LogCodeDisassemble(code);
13331cb0ef41Sopenharmony_ci}
13341cb0ef41Sopenharmony_ci
13351cb0ef41Sopenharmony_ci// Scripts
13361cb0ef41Sopenharmony_civoid Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
13371cb0ef41Sopenharmony_ci                             Handle<SharedFunctionInfo> shared,
13381cb0ef41Sopenharmony_ci                             Handle<Name> script_name) {
13391cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
13401cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
13411cb0ef41Sopenharmony_ci  if (*code ==
13421cb0ef41Sopenharmony_ci      AbstractCode::cast(isolate_->builtins()->code(Builtin::kCompileLazy))) {
13431cb0ef41Sopenharmony_ci    return;
13441cb0ef41Sopenharmony_ci  }
13451cb0ef41Sopenharmony_ci  {
13461cb0ef41Sopenharmony_ci    MSG_BUILDER();
13471cb0ef41Sopenharmony_ci    AppendCodeCreateHeader(msg, tag, *code, Time());
13481cb0ef41Sopenharmony_ci    msg << *script_name << kNext << reinterpret_cast<void*>(shared->address())
13491cb0ef41Sopenharmony_ci        << kNext << ComputeMarker(*shared, *code);
13501cb0ef41Sopenharmony_ci    msg.WriteToLogFile();
13511cb0ef41Sopenharmony_ci  }
13521cb0ef41Sopenharmony_ci  LogSourceCodeInformation(code, shared);
13531cb0ef41Sopenharmony_ci  LogCodeDisassemble(code);
13541cb0ef41Sopenharmony_ci}
13551cb0ef41Sopenharmony_ci
13561cb0ef41Sopenharmony_civoid Logger::FeedbackVectorEvent(FeedbackVector vector, AbstractCode code) {
13571cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
13581cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
13591cb0ef41Sopenharmony_ci  MSG_BUILDER();
13601cb0ef41Sopenharmony_ci  msg << "feedback-vector" << kNext << Time();
13611cb0ef41Sopenharmony_ci  msg << kNext << reinterpret_cast<void*>(vector.address()) << kNext
13621cb0ef41Sopenharmony_ci      << vector.length();
13631cb0ef41Sopenharmony_ci  msg << kNext << reinterpret_cast<void*>(code.InstructionStart());
13641cb0ef41Sopenharmony_ci  msg << kNext << vector.tiering_state();
13651cb0ef41Sopenharmony_ci  msg << kNext << vector.maybe_has_optimized_code();
13661cb0ef41Sopenharmony_ci  msg << kNext << vector.invocation_count();
13671cb0ef41Sopenharmony_ci  msg << kNext << vector.profiler_ticks() << kNext;
13681cb0ef41Sopenharmony_ci
13691cb0ef41Sopenharmony_ci#ifdef OBJECT_PRINT
13701cb0ef41Sopenharmony_ci  std::ostringstream buffer;
13711cb0ef41Sopenharmony_ci  vector.FeedbackVectorPrint(buffer);
13721cb0ef41Sopenharmony_ci  std::string contents = buffer.str();
13731cb0ef41Sopenharmony_ci  msg.AppendString(contents.c_str(), contents.length());
13741cb0ef41Sopenharmony_ci#else
13751cb0ef41Sopenharmony_ci  msg << "object-printing-disabled";
13761cb0ef41Sopenharmony_ci#endif
13771cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
13781cb0ef41Sopenharmony_ci}
13791cb0ef41Sopenharmony_ci
13801cb0ef41Sopenharmony_ci// Functions
13811cb0ef41Sopenharmony_ci// Although, it is possible to extract source and line from
13821cb0ef41Sopenharmony_ci// the SharedFunctionInfo object, we left it to caller
13831cb0ef41Sopenharmony_ci// to leave logging functions free from heap allocations.
13841cb0ef41Sopenharmony_civoid Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
13851cb0ef41Sopenharmony_ci                             Handle<SharedFunctionInfo> shared,
13861cb0ef41Sopenharmony_ci                             Handle<Name> script_name, int line, int column) {
13871cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
13881cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
13891cb0ef41Sopenharmony_ci  {
13901cb0ef41Sopenharmony_ci    MSG_BUILDER();
13911cb0ef41Sopenharmony_ci    AppendCodeCreateHeader(msg, tag, *code, Time());
13921cb0ef41Sopenharmony_ci    msg << shared->DebugNameCStr().get() << " " << *script_name << ":" << line
13931cb0ef41Sopenharmony_ci        << ":" << column << kNext << reinterpret_cast<void*>(shared->address())
13941cb0ef41Sopenharmony_ci        << kNext << ComputeMarker(*shared, *code);
13951cb0ef41Sopenharmony_ci
13961cb0ef41Sopenharmony_ci    msg.WriteToLogFile();
13971cb0ef41Sopenharmony_ci  }
13981cb0ef41Sopenharmony_ci  LogSourceCodeInformation(code, shared);
13991cb0ef41Sopenharmony_ci  LogCodeDisassemble(code);
14001cb0ef41Sopenharmony_ci}
14011cb0ef41Sopenharmony_ci
14021cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
14031cb0ef41Sopenharmony_civoid Logger::CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
14041cb0ef41Sopenharmony_ci                             wasm::WasmName name, const char* /*source_url*/,
14051cb0ef41Sopenharmony_ci                             int /*code_offset*/, int /*script_id*/) {
14061cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
14071cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
14081cb0ef41Sopenharmony_ci  MSG_BUILDER();
14091cb0ef41Sopenharmony_ci  AppendCodeCreateHeader(msg, tag, CodeKind::WASM_FUNCTION,
14101cb0ef41Sopenharmony_ci                         code->instructions().begin(),
14111cb0ef41Sopenharmony_ci                         code->instructions().length(), Time());
14121cb0ef41Sopenharmony_ci  DCHECK(!name.empty());
14131cb0ef41Sopenharmony_ci  msg.AppendString(name);
14141cb0ef41Sopenharmony_ci
14151cb0ef41Sopenharmony_ci  // We have to add two extra fields that allow the tick processor to group
14161cb0ef41Sopenharmony_ci  // events for the same wasm function, even if it gets compiled again. For
14171cb0ef41Sopenharmony_ci  // normal JS functions, we use the shared function info. For wasm, the pointer
14181cb0ef41Sopenharmony_ci  // to the native module + function index works well enough.
14191cb0ef41Sopenharmony_ci  // TODO(herhut) Clean up the tick processor code instead.
14201cb0ef41Sopenharmony_ci  void* tag_ptr =
14211cb0ef41Sopenharmony_ci      reinterpret_cast<byte*>(code->native_module()) + code->index();
14221cb0ef41Sopenharmony_ci  msg << kNext << tag_ptr << kNext << ComputeMarker(code);
14231cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
14241cb0ef41Sopenharmony_ci}
14251cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
14261cb0ef41Sopenharmony_ci
14271cb0ef41Sopenharmony_civoid Logger::CallbackEventInternal(const char* prefix, Handle<Name> name,
14281cb0ef41Sopenharmony_ci                                   Address entry_point) {
14291cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
14301cb0ef41Sopenharmony_ci  MSG_BUILDER();
14311cb0ef41Sopenharmony_ci  msg << kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT] << kNext
14321cb0ef41Sopenharmony_ci      << kLogEventsNames[CodeEventListener::CALLBACK_TAG] << kNext << -2
14331cb0ef41Sopenharmony_ci      << kNext << Time() << kNext << reinterpret_cast<void*>(entry_point)
14341cb0ef41Sopenharmony_ci      << kNext << 1 << kNext << prefix << *name;
14351cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
14361cb0ef41Sopenharmony_ci}
14371cb0ef41Sopenharmony_ci
14381cb0ef41Sopenharmony_civoid Logger::CallbackEvent(Handle<Name> name, Address entry_point) {
14391cb0ef41Sopenharmony_ci  CallbackEventInternal("", name, entry_point);
14401cb0ef41Sopenharmony_ci}
14411cb0ef41Sopenharmony_ci
14421cb0ef41Sopenharmony_civoid Logger::GetterCallbackEvent(Handle<Name> name, Address entry_point) {
14431cb0ef41Sopenharmony_ci  CallbackEventInternal("get ", name, entry_point);
14441cb0ef41Sopenharmony_ci}
14451cb0ef41Sopenharmony_ci
14461cb0ef41Sopenharmony_civoid Logger::SetterCallbackEvent(Handle<Name> name, Address entry_point) {
14471cb0ef41Sopenharmony_ci  CallbackEventInternal("set ", name, entry_point);
14481cb0ef41Sopenharmony_ci}
14491cb0ef41Sopenharmony_ci
14501cb0ef41Sopenharmony_civoid Logger::RegExpCodeCreateEvent(Handle<AbstractCode> code,
14511cb0ef41Sopenharmony_ci                                   Handle<String> source) {
14521cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
14531cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
14541cb0ef41Sopenharmony_ci  MSG_BUILDER();
14551cb0ef41Sopenharmony_ci  AppendCodeCreateHeader(msg, CodeEventListener::REG_EXP_TAG, *code, Time());
14561cb0ef41Sopenharmony_ci  msg << *source;
14571cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
14581cb0ef41Sopenharmony_ci}
14591cb0ef41Sopenharmony_ci
14601cb0ef41Sopenharmony_civoid Logger::CodeMoveEvent(AbstractCode from, AbstractCode to) {
14611cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
14621cb0ef41Sopenharmony_ci  MoveEventInternal(CodeEventListener::CODE_MOVE_EVENT, from.InstructionStart(),
14631cb0ef41Sopenharmony_ci                    to.InstructionStart());
14641cb0ef41Sopenharmony_ci}
14651cb0ef41Sopenharmony_ci
14661cb0ef41Sopenharmony_civoid Logger::SharedFunctionInfoMoveEvent(Address from, Address to) {
14671cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
14681cb0ef41Sopenharmony_ci  MoveEventInternal(CodeEventListener::SHARED_FUNC_MOVE_EVENT, from, to);
14691cb0ef41Sopenharmony_ci}
14701cb0ef41Sopenharmony_ci
14711cb0ef41Sopenharmony_civoid Logger::CodeMovingGCEvent() {
14721cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
14731cb0ef41Sopenharmony_ci  if (!FLAG_ll_prof) return;
14741cb0ef41Sopenharmony_ci  base::OS::SignalCodeMovingGC();
14751cb0ef41Sopenharmony_ci}
14761cb0ef41Sopenharmony_ci
14771cb0ef41Sopenharmony_civoid Logger::CodeDisableOptEvent(Handle<AbstractCode> code,
14781cb0ef41Sopenharmony_ci                                 Handle<SharedFunctionInfo> shared) {
14791cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
14801cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
14811cb0ef41Sopenharmony_ci  MSG_BUILDER();
14821cb0ef41Sopenharmony_ci  msg << kLogEventsNames[CodeEventListener::CODE_DISABLE_OPT_EVENT] << kNext
14831cb0ef41Sopenharmony_ci      << shared->DebugNameCStr().get() << kNext
14841cb0ef41Sopenharmony_ci      << GetBailoutReason(shared->disabled_optimization_reason());
14851cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
14861cb0ef41Sopenharmony_ci}
14871cb0ef41Sopenharmony_ci
14881cb0ef41Sopenharmony_civoid Logger::ProcessDeoptEvent(Handle<Code> code, SourcePosition position,
14891cb0ef41Sopenharmony_ci                               const char* kind, const char* reason) {
14901cb0ef41Sopenharmony_ci  MSG_BUILDER();
14911cb0ef41Sopenharmony_ci  msg << "code-deopt" << kNext << Time() << kNext << code->CodeSize() << kNext
14921cb0ef41Sopenharmony_ci      << reinterpret_cast<void*>(code->InstructionStart());
14931cb0ef41Sopenharmony_ci
14941cb0ef41Sopenharmony_ci  std::ostringstream deopt_location;
14951cb0ef41Sopenharmony_ci  int inlining_id = -1;
14961cb0ef41Sopenharmony_ci  int script_offset = -1;
14971cb0ef41Sopenharmony_ci  if (position.IsKnown()) {
14981cb0ef41Sopenharmony_ci    position.Print(deopt_location, *code);
14991cb0ef41Sopenharmony_ci    inlining_id = position.InliningId();
15001cb0ef41Sopenharmony_ci    script_offset = position.ScriptOffset();
15011cb0ef41Sopenharmony_ci  } else {
15021cb0ef41Sopenharmony_ci    deopt_location << "<unknown>";
15031cb0ef41Sopenharmony_ci  }
15041cb0ef41Sopenharmony_ci  msg << kNext << inlining_id << kNext << script_offset << kNext;
15051cb0ef41Sopenharmony_ci  msg << kind << kNext;
15061cb0ef41Sopenharmony_ci  msg << deopt_location.str().c_str() << kNext << reason;
15071cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
15081cb0ef41Sopenharmony_ci}
15091cb0ef41Sopenharmony_ci
15101cb0ef41Sopenharmony_civoid Logger::CodeDeoptEvent(Handle<Code> code, DeoptimizeKind kind, Address pc,
15111cb0ef41Sopenharmony_ci                            int fp_to_sp_delta) {
15121cb0ef41Sopenharmony_ci  if (!is_logging() || !FLAG_log_deopt) return;
15131cb0ef41Sopenharmony_ci  Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(*code, pc);
15141cb0ef41Sopenharmony_ci  ProcessDeoptEvent(code, info.position, Deoptimizer::MessageFor(kind),
15151cb0ef41Sopenharmony_ci                    DeoptimizeReasonToString(info.deopt_reason));
15161cb0ef41Sopenharmony_ci}
15171cb0ef41Sopenharmony_ci
15181cb0ef41Sopenharmony_civoid Logger::CodeDependencyChangeEvent(Handle<Code> code,
15191cb0ef41Sopenharmony_ci                                       Handle<SharedFunctionInfo> sfi,
15201cb0ef41Sopenharmony_ci                                       const char* reason) {
15211cb0ef41Sopenharmony_ci  if (!is_logging() || !FLAG_log_deopt) return;
15221cb0ef41Sopenharmony_ci  SourcePosition position(sfi->StartPosition(), -1);
15231cb0ef41Sopenharmony_ci  ProcessDeoptEvent(code, position, "dependency-change", reason);
15241cb0ef41Sopenharmony_ci}
15251cb0ef41Sopenharmony_ci
15261cb0ef41Sopenharmony_cinamespace {
15271cb0ef41Sopenharmony_ci
15281cb0ef41Sopenharmony_civoid CodeLinePosEvent(JitLogger& jit_logger, Address code_start,
15291cb0ef41Sopenharmony_ci                      SourcePositionTableIterator& iter,
15301cb0ef41Sopenharmony_ci                      JitCodeEvent::CodeType code_type) {
15311cb0ef41Sopenharmony_ci  void* jit_handler_data = jit_logger.StartCodePosInfoEvent(code_type);
15321cb0ef41Sopenharmony_ci  for (; !iter.done(); iter.Advance()) {
15331cb0ef41Sopenharmony_ci    if (iter.is_statement()) {
15341cb0ef41Sopenharmony_ci      jit_logger.AddCodeLinePosInfoEvent(jit_handler_data, iter.code_offset(),
15351cb0ef41Sopenharmony_ci                                         iter.source_position().ScriptOffset(),
15361cb0ef41Sopenharmony_ci                                         JitCodeEvent::STATEMENT_POSITION,
15371cb0ef41Sopenharmony_ci                                         code_type);
15381cb0ef41Sopenharmony_ci    }
15391cb0ef41Sopenharmony_ci    jit_logger.AddCodeLinePosInfoEvent(jit_handler_data, iter.code_offset(),
15401cb0ef41Sopenharmony_ci                                       iter.source_position().ScriptOffset(),
15411cb0ef41Sopenharmony_ci                                       JitCodeEvent::POSITION, code_type);
15421cb0ef41Sopenharmony_ci  }
15431cb0ef41Sopenharmony_ci  jit_logger.EndCodePosInfoEvent(code_start, jit_handler_data, code_type);
15441cb0ef41Sopenharmony_ci}
15451cb0ef41Sopenharmony_ci
15461cb0ef41Sopenharmony_ci}  // namespace
15471cb0ef41Sopenharmony_ci
15481cb0ef41Sopenharmony_civoid Logger::CodeLinePosInfoRecordEvent(Address code_start,
15491cb0ef41Sopenharmony_ci                                        ByteArray source_position_table,
15501cb0ef41Sopenharmony_ci                                        JitCodeEvent::CodeType code_type) {
15511cb0ef41Sopenharmony_ci  if (!jit_logger_) return;
15521cb0ef41Sopenharmony_ci  SourcePositionTableIterator iter(source_position_table);
15531cb0ef41Sopenharmony_ci  CodeLinePosEvent(*jit_logger_, code_start, iter, code_type);
15541cb0ef41Sopenharmony_ci}
15551cb0ef41Sopenharmony_ci
15561cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
15571cb0ef41Sopenharmony_civoid Logger::WasmCodeLinePosInfoRecordEvent(
15581cb0ef41Sopenharmony_ci    Address code_start, base::Vector<const byte> source_position_table) {
15591cb0ef41Sopenharmony_ci  if (!jit_logger_) return;
15601cb0ef41Sopenharmony_ci  SourcePositionTableIterator iter(source_position_table);
15611cb0ef41Sopenharmony_ci  CodeLinePosEvent(*jit_logger_, code_start, iter, JitCodeEvent::WASM_CODE);
15621cb0ef41Sopenharmony_ci}
15631cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
15641cb0ef41Sopenharmony_ci
15651cb0ef41Sopenharmony_civoid Logger::CodeNameEvent(Address addr, int pos, const char* code_name) {
15661cb0ef41Sopenharmony_ci  if (code_name == nullptr) return;  // Not a code object.
15671cb0ef41Sopenharmony_ci  if (!is_listening_to_code_events()) return;
15681cb0ef41Sopenharmony_ci  MSG_BUILDER();
15691cb0ef41Sopenharmony_ci  msg << kLogEventsNames[CodeEventListener::SNAPSHOT_CODE_NAME_EVENT] << kNext
15701cb0ef41Sopenharmony_ci      << pos << kNext << code_name;
15711cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
15721cb0ef41Sopenharmony_ci}
15731cb0ef41Sopenharmony_ci
15741cb0ef41Sopenharmony_civoid Logger::MoveEventInternal(LogEventsAndTags event, Address from,
15751cb0ef41Sopenharmony_ci                               Address to) {
15761cb0ef41Sopenharmony_ci  if (!FLAG_log_code) return;
15771cb0ef41Sopenharmony_ci  MSG_BUILDER();
15781cb0ef41Sopenharmony_ci  msg << kLogEventsNames[event] << kNext << reinterpret_cast<void*>(from)
15791cb0ef41Sopenharmony_ci      << kNext << reinterpret_cast<void*>(to);
15801cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
15811cb0ef41Sopenharmony_ci}
15821cb0ef41Sopenharmony_ci
15831cb0ef41Sopenharmony_cinamespace {
15841cb0ef41Sopenharmony_civoid AppendFunctionMessage(Log::MessageBuilder& msg, const char* reason,
15851cb0ef41Sopenharmony_ci                           int script_id, double time_delta, int start_position,
15861cb0ef41Sopenharmony_ci                           int end_position, uint64_t time) {
15871cb0ef41Sopenharmony_ci  msg << "function" << Logger::kNext << reason << Logger::kNext << script_id
15881cb0ef41Sopenharmony_ci      << Logger::kNext << start_position << Logger::kNext << end_position
15891cb0ef41Sopenharmony_ci      << Logger::kNext;
15901cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(FLAG_predictable)) {
15911cb0ef41Sopenharmony_ci    msg << 0.1;
15921cb0ef41Sopenharmony_ci  } else {
15931cb0ef41Sopenharmony_ci    msg << time_delta;
15941cb0ef41Sopenharmony_ci  }
15951cb0ef41Sopenharmony_ci  msg << Logger::kNext << time << Logger::kNext;
15961cb0ef41Sopenharmony_ci}
15971cb0ef41Sopenharmony_ci}  // namespace
15981cb0ef41Sopenharmony_ci
15991cb0ef41Sopenharmony_civoid Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
16001cb0ef41Sopenharmony_ci                           int start_position, int end_position,
16011cb0ef41Sopenharmony_ci                           String function_name) {
16021cb0ef41Sopenharmony_ci  if (!FLAG_log_function_events) return;
16031cb0ef41Sopenharmony_ci  MSG_BUILDER();
16041cb0ef41Sopenharmony_ci  AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
16051cb0ef41Sopenharmony_ci                        end_position, Time());
16061cb0ef41Sopenharmony_ci  if (!function_name.is_null()) msg << function_name;
16071cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
16081cb0ef41Sopenharmony_ci}
16091cb0ef41Sopenharmony_ci
16101cb0ef41Sopenharmony_civoid Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
16111cb0ef41Sopenharmony_ci                           int start_position, int end_position,
16121cb0ef41Sopenharmony_ci                           const char* function_name,
16131cb0ef41Sopenharmony_ci                           size_t function_name_length, bool is_one_byte) {
16141cb0ef41Sopenharmony_ci  if (!FLAG_log_function_events) return;
16151cb0ef41Sopenharmony_ci  MSG_BUILDER();
16161cb0ef41Sopenharmony_ci  AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
16171cb0ef41Sopenharmony_ci                        end_position, Time());
16181cb0ef41Sopenharmony_ci  if (function_name_length > 0) {
16191cb0ef41Sopenharmony_ci    msg.AppendString(function_name, function_name_length, is_one_byte);
16201cb0ef41Sopenharmony_ci  }
16211cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
16221cb0ef41Sopenharmony_ci}
16231cb0ef41Sopenharmony_ci
16241cb0ef41Sopenharmony_civoid Logger::CompilationCacheEvent(const char* action, const char* cache_type,
16251cb0ef41Sopenharmony_ci                                   SharedFunctionInfo sfi) {
16261cb0ef41Sopenharmony_ci  if (!FLAG_log_function_events) return;
16271cb0ef41Sopenharmony_ci  MSG_BUILDER();
16281cb0ef41Sopenharmony_ci  int script_id = -1;
16291cb0ef41Sopenharmony_ci  if (sfi.script().IsScript()) {
16301cb0ef41Sopenharmony_ci    script_id = Script::cast(sfi.script()).id();
16311cb0ef41Sopenharmony_ci  }
16321cb0ef41Sopenharmony_ci  msg << "compilation-cache" << Logger::kNext << action << Logger::kNext
16331cb0ef41Sopenharmony_ci      << cache_type << Logger::kNext << script_id << Logger::kNext
16341cb0ef41Sopenharmony_ci      << sfi.StartPosition() << Logger::kNext << sfi.EndPosition()
16351cb0ef41Sopenharmony_ci      << Logger::kNext << Time();
16361cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
16371cb0ef41Sopenharmony_ci}
16381cb0ef41Sopenharmony_ci
16391cb0ef41Sopenharmony_civoid Logger::ScriptEvent(ScriptEventType type, int script_id) {
16401cb0ef41Sopenharmony_ci  if (!FLAG_log_function_events) return;
16411cb0ef41Sopenharmony_ci  MSG_BUILDER();
16421cb0ef41Sopenharmony_ci  msg << "script" << Logger::kNext;
16431cb0ef41Sopenharmony_ci  switch (type) {
16441cb0ef41Sopenharmony_ci    case ScriptEventType::kReserveId:
16451cb0ef41Sopenharmony_ci      msg << "reserve-id";
16461cb0ef41Sopenharmony_ci      break;
16471cb0ef41Sopenharmony_ci    case ScriptEventType::kCreate:
16481cb0ef41Sopenharmony_ci      msg << "create";
16491cb0ef41Sopenharmony_ci      break;
16501cb0ef41Sopenharmony_ci    case ScriptEventType::kDeserialize:
16511cb0ef41Sopenharmony_ci      msg << "deserialize";
16521cb0ef41Sopenharmony_ci      break;
16531cb0ef41Sopenharmony_ci    case ScriptEventType::kBackgroundCompile:
16541cb0ef41Sopenharmony_ci      msg << "background-compile";
16551cb0ef41Sopenharmony_ci      break;
16561cb0ef41Sopenharmony_ci    case ScriptEventType::kStreamingCompile:
16571cb0ef41Sopenharmony_ci      msg << "streaming-compile";
16581cb0ef41Sopenharmony_ci      break;
16591cb0ef41Sopenharmony_ci  }
16601cb0ef41Sopenharmony_ci  msg << Logger::kNext << script_id << Logger::kNext << Time();
16611cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
16621cb0ef41Sopenharmony_ci}
16631cb0ef41Sopenharmony_ci
16641cb0ef41Sopenharmony_civoid Logger::ScriptDetails(Script script) {
16651cb0ef41Sopenharmony_ci  if (!FLAG_log_function_events) return;
16661cb0ef41Sopenharmony_ci  {
16671cb0ef41Sopenharmony_ci    MSG_BUILDER();
16681cb0ef41Sopenharmony_ci    msg << "script-details" << Logger::kNext << script.id() << Logger::kNext;
16691cb0ef41Sopenharmony_ci    if (script.name().IsString()) {
16701cb0ef41Sopenharmony_ci      msg << String::cast(script.name());
16711cb0ef41Sopenharmony_ci    }
16721cb0ef41Sopenharmony_ci    msg << Logger::kNext << script.line_offset() << Logger::kNext
16731cb0ef41Sopenharmony_ci        << script.column_offset() << Logger::kNext;
16741cb0ef41Sopenharmony_ci    if (script.source_mapping_url().IsString()) {
16751cb0ef41Sopenharmony_ci      msg << String::cast(script.source_mapping_url());
16761cb0ef41Sopenharmony_ci    }
16771cb0ef41Sopenharmony_ci    msg.WriteToLogFile();
16781cb0ef41Sopenharmony_ci  }
16791cb0ef41Sopenharmony_ci  EnsureLogScriptSource(script);
16801cb0ef41Sopenharmony_ci}
16811cb0ef41Sopenharmony_ci
16821cb0ef41Sopenharmony_cibool Logger::EnsureLogScriptSource(Script script) {
16831cb0ef41Sopenharmony_ci  // Make sure the script is written to the log file.
16841cb0ef41Sopenharmony_ci  int script_id = script.id();
16851cb0ef41Sopenharmony_ci  if (logged_source_code_.find(script_id) != logged_source_code_.end()) {
16861cb0ef41Sopenharmony_ci    return true;
16871cb0ef41Sopenharmony_ci  }
16881cb0ef41Sopenharmony_ci  // This script has not been logged yet.
16891cb0ef41Sopenharmony_ci  logged_source_code_.insert(script_id);
16901cb0ef41Sopenharmony_ci  Object source_object = script.source();
16911cb0ef41Sopenharmony_ci  if (!source_object.IsString()) return false;
16921cb0ef41Sopenharmony_ci
16931cb0ef41Sopenharmony_ci  std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
16941cb0ef41Sopenharmony_ci  if (!msg_ptr) return false;
16951cb0ef41Sopenharmony_ci  Log::MessageBuilder& msg = *msg_ptr.get();
16961cb0ef41Sopenharmony_ci
16971cb0ef41Sopenharmony_ci  String source_code = String::cast(source_object);
16981cb0ef41Sopenharmony_ci  msg << "script-source" << kNext << script_id << kNext;
16991cb0ef41Sopenharmony_ci
17001cb0ef41Sopenharmony_ci  // Log the script name.
17011cb0ef41Sopenharmony_ci  if (script.name().IsString()) {
17021cb0ef41Sopenharmony_ci    msg << String::cast(script.name()) << kNext;
17031cb0ef41Sopenharmony_ci  } else {
17041cb0ef41Sopenharmony_ci    msg << "<unknown>" << kNext;
17051cb0ef41Sopenharmony_ci  }
17061cb0ef41Sopenharmony_ci
17071cb0ef41Sopenharmony_ci  // Log the source code.
17081cb0ef41Sopenharmony_ci  msg << source_code;
17091cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
17101cb0ef41Sopenharmony_ci  return true;
17111cb0ef41Sopenharmony_ci}
17121cb0ef41Sopenharmony_ci
17131cb0ef41Sopenharmony_civoid Logger::RuntimeCallTimerEvent() {
17141cb0ef41Sopenharmony_ci#ifdef V8_RUNTIME_CALL_STATS
17151cb0ef41Sopenharmony_ci  RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats();
17161cb0ef41Sopenharmony_ci  RuntimeCallCounter* counter = stats->current_counter();
17171cb0ef41Sopenharmony_ci  if (counter == nullptr) return;
17181cb0ef41Sopenharmony_ci  MSG_BUILDER();
17191cb0ef41Sopenharmony_ci  msg << "active-runtime-timer" << kNext << counter->name();
17201cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
17211cb0ef41Sopenharmony_ci#endif  // V8_RUNTIME_CALL_STATS
17221cb0ef41Sopenharmony_ci}
17231cb0ef41Sopenharmony_ci
17241cb0ef41Sopenharmony_civoid Logger::TickEvent(TickSample* sample, bool overflow) {
17251cb0ef41Sopenharmony_ci  if (!FLAG_prof_cpp) return;
17261cb0ef41Sopenharmony_ci  if (V8_UNLIKELY(TracingFlags::runtime_stats.load(std::memory_order_relaxed) ==
17271cb0ef41Sopenharmony_ci                  v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE)) {
17281cb0ef41Sopenharmony_ci    RuntimeCallTimerEvent();
17291cb0ef41Sopenharmony_ci  }
17301cb0ef41Sopenharmony_ci  MSG_BUILDER();
17311cb0ef41Sopenharmony_ci  msg << kLogEventsNames[CodeEventListener::TICK_EVENT] << kNext
17321cb0ef41Sopenharmony_ci      << reinterpret_cast<void*>(sample->pc) << kNext << Time();
17331cb0ef41Sopenharmony_ci  if (sample->has_external_callback) {
17341cb0ef41Sopenharmony_ci    msg << kNext << 1 << kNext
17351cb0ef41Sopenharmony_ci        << reinterpret_cast<void*>(sample->external_callback_entry);
17361cb0ef41Sopenharmony_ci  } else {
17371cb0ef41Sopenharmony_ci    msg << kNext << 0 << kNext << reinterpret_cast<void*>(sample->tos);
17381cb0ef41Sopenharmony_ci  }
17391cb0ef41Sopenharmony_ci  msg << kNext << static_cast<int>(sample->state);
17401cb0ef41Sopenharmony_ci  if (overflow) msg << kNext << "overflow";
17411cb0ef41Sopenharmony_ci  for (unsigned i = 0; i < sample->frames_count; ++i) {
17421cb0ef41Sopenharmony_ci    msg << kNext << reinterpret_cast<void*>(sample->stack[i]);
17431cb0ef41Sopenharmony_ci  }
17441cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
17451cb0ef41Sopenharmony_ci}
17461cb0ef41Sopenharmony_ci
17471cb0ef41Sopenharmony_civoid Logger::ICEvent(const char* type, bool keyed, Handle<Map> map,
17481cb0ef41Sopenharmony_ci                     Handle<Object> key, char old_state, char new_state,
17491cb0ef41Sopenharmony_ci                     const char* modifier, const char* slow_stub_reason) {
17501cb0ef41Sopenharmony_ci  if (!FLAG_log_ic) return;
17511cb0ef41Sopenharmony_ci  int line;
17521cb0ef41Sopenharmony_ci  int column;
17531cb0ef41Sopenharmony_ci  // GetAbstractPC must come before MSG_BUILDER(), as it can GC, which might
17541cb0ef41Sopenharmony_ci  // attempt to get the log lock again and result in a deadlock.
17551cb0ef41Sopenharmony_ci  Address pc = isolate_->GetAbstractPC(&line, &column);
17561cb0ef41Sopenharmony_ci  MSG_BUILDER();
17571cb0ef41Sopenharmony_ci  if (keyed) msg << "Keyed";
17581cb0ef41Sopenharmony_ci  msg << type << kNext << reinterpret_cast<void*>(pc) << kNext << Time()
17591cb0ef41Sopenharmony_ci      << kNext << line << kNext << column << kNext << old_state << kNext
17601cb0ef41Sopenharmony_ci      << new_state << kNext
17611cb0ef41Sopenharmony_ci      << AsHex::Address(map.is_null() ? kNullAddress : map->ptr()) << kNext;
17621cb0ef41Sopenharmony_ci  if (key->IsSmi()) {
17631cb0ef41Sopenharmony_ci    msg << Smi::ToInt(*key);
17641cb0ef41Sopenharmony_ci  } else if (key->IsNumber()) {
17651cb0ef41Sopenharmony_ci    msg << key->Number();
17661cb0ef41Sopenharmony_ci  } else if (key->IsName()) {
17671cb0ef41Sopenharmony_ci    msg << Name::cast(*key);
17681cb0ef41Sopenharmony_ci  }
17691cb0ef41Sopenharmony_ci  msg << kNext << modifier << kNext;
17701cb0ef41Sopenharmony_ci  if (slow_stub_reason != nullptr) {
17711cb0ef41Sopenharmony_ci    msg << slow_stub_reason;
17721cb0ef41Sopenharmony_ci  }
17731cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
17741cb0ef41Sopenharmony_ci}
17751cb0ef41Sopenharmony_ci
17761cb0ef41Sopenharmony_civoid Logger::MapEvent(const char* type, Handle<Map> from, Handle<Map> to,
17771cb0ef41Sopenharmony_ci                      const char* reason, Handle<HeapObject> name_or_sfi) {
17781cb0ef41Sopenharmony_ci  if (!FLAG_log_maps) return;
17791cb0ef41Sopenharmony_ci  if (!to.is_null()) MapDetails(*to);
17801cb0ef41Sopenharmony_ci  int line = -1;
17811cb0ef41Sopenharmony_ci  int column = -1;
17821cb0ef41Sopenharmony_ci  Address pc = 0;
17831cb0ef41Sopenharmony_ci
17841cb0ef41Sopenharmony_ci  if (!isolate_->bootstrapper()->IsActive()) {
17851cb0ef41Sopenharmony_ci    pc = isolate_->GetAbstractPC(&line, &column);
17861cb0ef41Sopenharmony_ci  }
17871cb0ef41Sopenharmony_ci  MSG_BUILDER();
17881cb0ef41Sopenharmony_ci  msg << "map" << kNext << type << kNext << Time() << kNext
17891cb0ef41Sopenharmony_ci      << AsHex::Address(from.is_null() ? kNullAddress : from->ptr()) << kNext
17901cb0ef41Sopenharmony_ci      << AsHex::Address(to.is_null() ? kNullAddress : to->ptr()) << kNext
17911cb0ef41Sopenharmony_ci      << AsHex::Address(pc) << kNext << line << kNext << column << kNext
17921cb0ef41Sopenharmony_ci      << reason << kNext;
17931cb0ef41Sopenharmony_ci
17941cb0ef41Sopenharmony_ci  if (!name_or_sfi.is_null()) {
17951cb0ef41Sopenharmony_ci    if (name_or_sfi->IsName()) {
17961cb0ef41Sopenharmony_ci      msg << Name::cast(*name_or_sfi);
17971cb0ef41Sopenharmony_ci    } else if (name_or_sfi->IsSharedFunctionInfo()) {
17981cb0ef41Sopenharmony_ci      SharedFunctionInfo sfi = SharedFunctionInfo::cast(*name_or_sfi);
17991cb0ef41Sopenharmony_ci      msg << sfi.DebugNameCStr().get();
18001cb0ef41Sopenharmony_ci#if V8_SFI_HAS_UNIQUE_ID
18011cb0ef41Sopenharmony_ci      msg << " " << sfi.unique_id();
18021cb0ef41Sopenharmony_ci#endif  // V8_SFI_HAS_UNIQUE_ID
18031cb0ef41Sopenharmony_ci    }
18041cb0ef41Sopenharmony_ci  }
18051cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
18061cb0ef41Sopenharmony_ci}
18071cb0ef41Sopenharmony_ci
18081cb0ef41Sopenharmony_civoid Logger::MapCreate(Map map) {
18091cb0ef41Sopenharmony_ci  if (!FLAG_log_maps) return;
18101cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
18111cb0ef41Sopenharmony_ci  MSG_BUILDER();
18121cb0ef41Sopenharmony_ci  msg << "map-create" << kNext << Time() << kNext << AsHex::Address(map.ptr());
18131cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
18141cb0ef41Sopenharmony_ci}
18151cb0ef41Sopenharmony_ci
18161cb0ef41Sopenharmony_civoid Logger::MapDetails(Map map) {
18171cb0ef41Sopenharmony_ci  if (!FLAG_log_maps) return;
18181cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
18191cb0ef41Sopenharmony_ci  MSG_BUILDER();
18201cb0ef41Sopenharmony_ci  msg << "map-details" << kNext << Time() << kNext << AsHex::Address(map.ptr())
18211cb0ef41Sopenharmony_ci      << kNext;
18221cb0ef41Sopenharmony_ci  if (FLAG_log_maps_details) {
18231cb0ef41Sopenharmony_ci    std::ostringstream buffer;
18241cb0ef41Sopenharmony_ci    map.PrintMapDetails(buffer);
18251cb0ef41Sopenharmony_ci    msg << buffer.str().c_str();
18261cb0ef41Sopenharmony_ci  }
18271cb0ef41Sopenharmony_ci  msg.WriteToLogFile();
18281cb0ef41Sopenharmony_ci}
18291cb0ef41Sopenharmony_ci
18301cb0ef41Sopenharmony_cistatic std::vector<std::pair<Handle<SharedFunctionInfo>, Handle<AbstractCode>>>
18311cb0ef41Sopenharmony_ciEnumerateCompiledFunctions(Heap* heap) {
18321cb0ef41Sopenharmony_ci  HeapObjectIterator iterator(heap);
18331cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
18341cb0ef41Sopenharmony_ci  std::vector<std::pair<Handle<SharedFunctionInfo>, Handle<AbstractCode>>>
18351cb0ef41Sopenharmony_ci      compiled_funcs;
18361cb0ef41Sopenharmony_ci  Isolate* isolate = heap->isolate();
18371cb0ef41Sopenharmony_ci
18381cb0ef41Sopenharmony_ci  // Iterate the heap to find JSFunctions and record their optimized code.
18391cb0ef41Sopenharmony_ci  for (HeapObject obj = iterator.Next(); !obj.is_null();
18401cb0ef41Sopenharmony_ci       obj = iterator.Next()) {
18411cb0ef41Sopenharmony_ci    if (obj.IsSharedFunctionInfo()) {
18421cb0ef41Sopenharmony_ci      SharedFunctionInfo sfi = SharedFunctionInfo::cast(obj);
18431cb0ef41Sopenharmony_ci      if (sfi.is_compiled() && !sfi.HasBytecodeArray()) {
18441cb0ef41Sopenharmony_ci        compiled_funcs.emplace_back(
18451cb0ef41Sopenharmony_ci            handle(sfi, isolate),
18461cb0ef41Sopenharmony_ci            handle(AbstractCode::cast(sfi.abstract_code(isolate)), isolate));
18471cb0ef41Sopenharmony_ci      }
18481cb0ef41Sopenharmony_ci    } else if (obj.IsJSFunction()) {
18491cb0ef41Sopenharmony_ci      // Given that we no longer iterate over all optimized JSFunctions, we need
18501cb0ef41Sopenharmony_ci      // to take care of this here.
18511cb0ef41Sopenharmony_ci      JSFunction function = JSFunction::cast(obj);
18521cb0ef41Sopenharmony_ci      // TODO(jarin) This leaves out deoptimized code that might still be on the
18531cb0ef41Sopenharmony_ci      // stack. Also note that we will not log optimized code objects that are
18541cb0ef41Sopenharmony_ci      // only on a type feedback vector. We should make this mroe precise.
18551cb0ef41Sopenharmony_ci      if (function.HasAttachedOptimizedCode() &&
18561cb0ef41Sopenharmony_ci          Script::cast(function.shared().script()).HasValidSource()) {
18571cb0ef41Sopenharmony_ci        compiled_funcs.emplace_back(
18581cb0ef41Sopenharmony_ci            handle(function.shared(), isolate),
18591cb0ef41Sopenharmony_ci            handle(AbstractCode::cast(FromCodeT(function.code())), isolate));
18601cb0ef41Sopenharmony_ci      }
18611cb0ef41Sopenharmony_ci    }
18621cb0ef41Sopenharmony_ci  }
18631cb0ef41Sopenharmony_ci
18641cb0ef41Sopenharmony_ci  Script::Iterator script_iterator(heap->isolate());
18651cb0ef41Sopenharmony_ci  for (Script script = script_iterator.Next(); !script.is_null();
18661cb0ef41Sopenharmony_ci       script = script_iterator.Next()) {
18671cb0ef41Sopenharmony_ci    if (!script.HasValidSource()) continue;
18681cb0ef41Sopenharmony_ci
18691cb0ef41Sopenharmony_ci    SharedFunctionInfo::ScriptIterator sfi_iterator(heap->isolate(), script);
18701cb0ef41Sopenharmony_ci    for (SharedFunctionInfo sfi = sfi_iterator.Next(); !sfi.is_null();
18711cb0ef41Sopenharmony_ci         sfi = sfi_iterator.Next()) {
18721cb0ef41Sopenharmony_ci      if (sfi.is_compiled()) {
18731cb0ef41Sopenharmony_ci        compiled_funcs.emplace_back(
18741cb0ef41Sopenharmony_ci            handle(sfi, isolate),
18751cb0ef41Sopenharmony_ci            handle(AbstractCode::cast(sfi.abstract_code(isolate)), isolate));
18761cb0ef41Sopenharmony_ci      }
18771cb0ef41Sopenharmony_ci    }
18781cb0ef41Sopenharmony_ci  }
18791cb0ef41Sopenharmony_ci
18801cb0ef41Sopenharmony_ci  return compiled_funcs;
18811cb0ef41Sopenharmony_ci}
18821cb0ef41Sopenharmony_ci
18831cb0ef41Sopenharmony_civoid Logger::LogCodeObjects() { existing_code_logger_.LogCodeObjects(); }
18841cb0ef41Sopenharmony_ci
18851cb0ef41Sopenharmony_civoid Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
18861cb0ef41Sopenharmony_ci                                 Handle<AbstractCode> code) {
18871cb0ef41Sopenharmony_ci  existing_code_logger_.LogExistingFunction(shared, code);
18881cb0ef41Sopenharmony_ci}
18891cb0ef41Sopenharmony_ci
18901cb0ef41Sopenharmony_civoid Logger::LogCompiledFunctions() {
18911cb0ef41Sopenharmony_ci  existing_code_logger_.LogCompiledFunctions();
18921cb0ef41Sopenharmony_ci}
18931cb0ef41Sopenharmony_ci
18941cb0ef41Sopenharmony_civoid Logger::LogBuiltins() { existing_code_logger_.LogBuiltins(); }
18951cb0ef41Sopenharmony_ci
18961cb0ef41Sopenharmony_civoid Logger::LogAccessorCallbacks() {
18971cb0ef41Sopenharmony_ci  Heap* heap = isolate_->heap();
18981cb0ef41Sopenharmony_ci  HeapObjectIterator iterator(heap);
18991cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
19001cb0ef41Sopenharmony_ci  for (HeapObject obj = iterator.Next(); !obj.is_null();
19011cb0ef41Sopenharmony_ci       obj = iterator.Next()) {
19021cb0ef41Sopenharmony_ci    if (!obj.IsAccessorInfo()) continue;
19031cb0ef41Sopenharmony_ci    AccessorInfo ai = AccessorInfo::cast(obj);
19041cb0ef41Sopenharmony_ci    if (!ai.name().IsName()) continue;
19051cb0ef41Sopenharmony_ci    Address getter_entry = v8::ToCData<Address>(ai.getter());
19061cb0ef41Sopenharmony_ci    HandleScope scope(isolate_);
19071cb0ef41Sopenharmony_ci    Handle<Name> name(Name::cast(ai.name()), isolate_);
19081cb0ef41Sopenharmony_ci    if (getter_entry != 0) {
19091cb0ef41Sopenharmony_ci#if USES_FUNCTION_DESCRIPTORS
19101cb0ef41Sopenharmony_ci      getter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(getter_entry);
19111cb0ef41Sopenharmony_ci#endif
19121cb0ef41Sopenharmony_ci      PROFILE(isolate_, GetterCallbackEvent(name, getter_entry));
19131cb0ef41Sopenharmony_ci    }
19141cb0ef41Sopenharmony_ci    Address setter_entry = v8::ToCData<Address>(ai.setter());
19151cb0ef41Sopenharmony_ci    if (setter_entry != 0) {
19161cb0ef41Sopenharmony_ci#if USES_FUNCTION_DESCRIPTORS
19171cb0ef41Sopenharmony_ci      setter_entry = *FUNCTION_ENTRYPOINT_ADDRESS(setter_entry);
19181cb0ef41Sopenharmony_ci#endif
19191cb0ef41Sopenharmony_ci      PROFILE(isolate_, SetterCallbackEvent(name, setter_entry));
19201cb0ef41Sopenharmony_ci    }
19211cb0ef41Sopenharmony_ci  }
19221cb0ef41Sopenharmony_ci}
19231cb0ef41Sopenharmony_ci
19241cb0ef41Sopenharmony_civoid Logger::LogAllMaps() {
19251cb0ef41Sopenharmony_ci  Heap* heap = isolate_->heap();
19261cb0ef41Sopenharmony_ci  CombinedHeapObjectIterator iterator(heap);
19271cb0ef41Sopenharmony_ci  for (HeapObject obj = iterator.Next(); !obj.is_null();
19281cb0ef41Sopenharmony_ci       obj = iterator.Next()) {
19291cb0ef41Sopenharmony_ci    if (!obj.IsMap()) continue;
19301cb0ef41Sopenharmony_ci    Map map = Map::cast(obj);
19311cb0ef41Sopenharmony_ci    MapCreate(map);
19321cb0ef41Sopenharmony_ci    MapDetails(map);
19331cb0ef41Sopenharmony_ci  }
19341cb0ef41Sopenharmony_ci}
19351cb0ef41Sopenharmony_ci
19361cb0ef41Sopenharmony_cistatic void AddIsolateIdIfNeeded(std::ostream& os, Isolate* isolate) {
19371cb0ef41Sopenharmony_ci  if (!FLAG_logfile_per_isolate) return;
19381cb0ef41Sopenharmony_ci  os << "isolate-" << isolate << "-" << base::OS::GetCurrentProcessId() << "-";
19391cb0ef41Sopenharmony_ci}
19401cb0ef41Sopenharmony_ci
19411cb0ef41Sopenharmony_cistatic void PrepareLogFileName(std::ostream& os, Isolate* isolate,
19421cb0ef41Sopenharmony_ci                               const char* file_name) {
19431cb0ef41Sopenharmony_ci  int dir_separator_count = 0;
19441cb0ef41Sopenharmony_ci  for (const char* p = file_name; *p; p++) {
19451cb0ef41Sopenharmony_ci    if (base::OS::isDirectorySeparator(*p)) dir_separator_count++;
19461cb0ef41Sopenharmony_ci  }
19471cb0ef41Sopenharmony_ci
19481cb0ef41Sopenharmony_ci  for (const char* p = file_name; *p; p++) {
19491cb0ef41Sopenharmony_ci    if (dir_separator_count == 0) {
19501cb0ef41Sopenharmony_ci      AddIsolateIdIfNeeded(os, isolate);
19511cb0ef41Sopenharmony_ci      dir_separator_count--;
19521cb0ef41Sopenharmony_ci    }
19531cb0ef41Sopenharmony_ci    if (*p == '%') {
19541cb0ef41Sopenharmony_ci      p++;
19551cb0ef41Sopenharmony_ci      switch (*p) {
19561cb0ef41Sopenharmony_ci        case '\0':
19571cb0ef41Sopenharmony_ci          // If there's a % at the end of the string we back up
19581cb0ef41Sopenharmony_ci          // one character so we can escape the loop properly.
19591cb0ef41Sopenharmony_ci          p--;
19601cb0ef41Sopenharmony_ci          break;
19611cb0ef41Sopenharmony_ci        case 'p':
19621cb0ef41Sopenharmony_ci          os << base::OS::GetCurrentProcessId();
19631cb0ef41Sopenharmony_ci          break;
19641cb0ef41Sopenharmony_ci        case 't':
19651cb0ef41Sopenharmony_ci          // %t expands to the current time in milliseconds.
19661cb0ef41Sopenharmony_ci          os << static_cast<int64_t>(
19671cb0ef41Sopenharmony_ci              V8::GetCurrentPlatform()->CurrentClockTimeMillis());
19681cb0ef41Sopenharmony_ci          break;
19691cb0ef41Sopenharmony_ci        case '%':
19701cb0ef41Sopenharmony_ci          // %% expands (contracts really) to %.
19711cb0ef41Sopenharmony_ci          os << '%';
19721cb0ef41Sopenharmony_ci          break;
19731cb0ef41Sopenharmony_ci        default:
19741cb0ef41Sopenharmony_ci          // All other %'s expand to themselves.
19751cb0ef41Sopenharmony_ci          os << '%' << *p;
19761cb0ef41Sopenharmony_ci          break;
19771cb0ef41Sopenharmony_ci      }
19781cb0ef41Sopenharmony_ci    } else {
19791cb0ef41Sopenharmony_ci      if (base::OS::isDirectorySeparator(*p)) dir_separator_count--;
19801cb0ef41Sopenharmony_ci      os << *p;
19811cb0ef41Sopenharmony_ci    }
19821cb0ef41Sopenharmony_ci  }
19831cb0ef41Sopenharmony_ci}
19841cb0ef41Sopenharmony_ci
19851cb0ef41Sopenharmony_cibool Logger::SetUp(Isolate* isolate) {
19861cb0ef41Sopenharmony_ci  // Tests and EnsureInitialize() can call this twice in a row. It's harmless.
19871cb0ef41Sopenharmony_ci  if (is_initialized_) return true;
19881cb0ef41Sopenharmony_ci  is_initialized_ = true;
19891cb0ef41Sopenharmony_ci
19901cb0ef41Sopenharmony_ci  std::ostringstream log_file_name;
19911cb0ef41Sopenharmony_ci  PrepareLogFileName(log_file_name, isolate, FLAG_logfile);
19921cb0ef41Sopenharmony_ci  log_ = std::make_unique<Log>(this, log_file_name.str());
19931cb0ef41Sopenharmony_ci
19941cb0ef41Sopenharmony_ci#if V8_OS_LINUX
19951cb0ef41Sopenharmony_ci  if (FLAG_perf_basic_prof) {
19961cb0ef41Sopenharmony_ci    perf_basic_logger_ = std::make_unique<PerfBasicLogger>(isolate);
19971cb0ef41Sopenharmony_ci    AddCodeEventListener(perf_basic_logger_.get());
19981cb0ef41Sopenharmony_ci  }
19991cb0ef41Sopenharmony_ci
20001cb0ef41Sopenharmony_ci  if (FLAG_perf_prof) {
20011cb0ef41Sopenharmony_ci    perf_jit_logger_ = std::make_unique<PerfJitLogger>(isolate);
20021cb0ef41Sopenharmony_ci    AddCodeEventListener(perf_jit_logger_.get());
20031cb0ef41Sopenharmony_ci  }
20041cb0ef41Sopenharmony_ci#else
20051cb0ef41Sopenharmony_ci  static_assert(
20061cb0ef41Sopenharmony_ci      !FLAG_perf_prof,
20071cb0ef41Sopenharmony_ci      "--perf-prof should be statically disabled on non-Linux platforms");
20081cb0ef41Sopenharmony_ci  static_assert(
20091cb0ef41Sopenharmony_ci      !FLAG_perf_basic_prof,
20101cb0ef41Sopenharmony_ci      "--perf-basic-prof should be statically disabled on non-Linux platforms");
20111cb0ef41Sopenharmony_ci#endif
20121cb0ef41Sopenharmony_ci
20131cb0ef41Sopenharmony_ci#ifdef ENABLE_GDB_JIT_INTERFACE
20141cb0ef41Sopenharmony_ci  if (i::FLAG_gdbjit) {
20151cb0ef41Sopenharmony_ci    auto code_event_handler = i::GDBJITInterface::EventHandler;
20161cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(code_event_handler);
20171cb0ef41Sopenharmony_ci    gdb_jit_logger_ = std::make_unique<JitLogger>(isolate, code_event_handler);
20181cb0ef41Sopenharmony_ci    AddCodeEventListener(gdb_jit_logger_.get());
20191cb0ef41Sopenharmony_ci    CHECK(isolate->code_event_dispatcher()->IsListeningToCodeEvents());
20201cb0ef41Sopenharmony_ci  }
20211cb0ef41Sopenharmony_ci#endif  // ENABLE_GDB_JIT_INTERFACE
20221cb0ef41Sopenharmony_ci
20231cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN) && defined(V8_ENABLE_SYSTEM_INSTRUMENTATION)
20241cb0ef41Sopenharmony_ci  if (i::FLAG_enable_system_instrumentation) {
20251cb0ef41Sopenharmony_ci    auto code_event_handler = i::ETWJITInterface::EventHandler;
20261cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(code_event_handler);
20271cb0ef41Sopenharmony_ci    etw_jit_logger_ = std::make_unique<JitLogger>(isolate, code_event_handler);
20281cb0ef41Sopenharmony_ci    AddCodeEventListener(etw_jit_logger_.get());
20291cb0ef41Sopenharmony_ci    CHECK(isolate->code_event_dispatcher()->IsListeningToCodeEvents());
20301cb0ef41Sopenharmony_ci  }
20311cb0ef41Sopenharmony_ci#endif  // defined(V8_OS_WIN)
20321cb0ef41Sopenharmony_ci
20331cb0ef41Sopenharmony_ci  if (FLAG_ll_prof) {
20341cb0ef41Sopenharmony_ci    ll_logger_ =
20351cb0ef41Sopenharmony_ci        std::make_unique<LowLevelLogger>(isolate, log_file_name.str().c_str());
20361cb0ef41Sopenharmony_ci    AddCodeEventListener(ll_logger_.get());
20371cb0ef41Sopenharmony_ci  }
20381cb0ef41Sopenharmony_ci  ticker_ = std::make_unique<Ticker>(isolate, FLAG_prof_sampling_interval);
20391cb0ef41Sopenharmony_ci  if (FLAG_log) UpdateIsLogging(true);
20401cb0ef41Sopenharmony_ci  timer_.Start();
20411cb0ef41Sopenharmony_ci  if (FLAG_prof_cpp) {
20421cb0ef41Sopenharmony_ci    CHECK(FLAG_log);
20431cb0ef41Sopenharmony_ci    CHECK(is_logging());
20441cb0ef41Sopenharmony_ci    profiler_ = std::make_unique<Profiler>(isolate);
20451cb0ef41Sopenharmony_ci    profiler_->Engage();
20461cb0ef41Sopenharmony_ci  }
20471cb0ef41Sopenharmony_ci  if (is_logging_) AddCodeEventListener(this);
20481cb0ef41Sopenharmony_ci  return true;
20491cb0ef41Sopenharmony_ci}
20501cb0ef41Sopenharmony_ci
20511cb0ef41Sopenharmony_civoid Logger::LateSetup(Isolate* isolate) {
20521cb0ef41Sopenharmony_ci  if (!isolate->code_event_dispatcher()->IsListeningToCodeEvents()) return;
20531cb0ef41Sopenharmony_ci  Builtins::EmitCodeCreateEvents(isolate);
20541cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
20551cb0ef41Sopenharmony_ci  wasm::GetWasmEngine()->EnableCodeLogging(isolate);
20561cb0ef41Sopenharmony_ci#endif
20571cb0ef41Sopenharmony_ci}
20581cb0ef41Sopenharmony_ci
20591cb0ef41Sopenharmony_civoid Logger::SetCodeEventHandler(uint32_t options,
20601cb0ef41Sopenharmony_ci                                 JitCodeEventHandler event_handler) {
20611cb0ef41Sopenharmony_ci  if (jit_logger_) {
20621cb0ef41Sopenharmony_ci    RemoveCodeEventListener(jit_logger_.get());
20631cb0ef41Sopenharmony_ci    jit_logger_.reset();
20641cb0ef41Sopenharmony_ci  }
20651cb0ef41Sopenharmony_ci
20661cb0ef41Sopenharmony_ci  if (event_handler) {
20671cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
20681cb0ef41Sopenharmony_ci    wasm::GetWasmEngine()->EnableCodeLogging(isolate_);
20691cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
20701cb0ef41Sopenharmony_ci    jit_logger_ = std::make_unique<JitLogger>(isolate_, event_handler);
20711cb0ef41Sopenharmony_ci    AddCodeEventListener(jit_logger_.get());
20721cb0ef41Sopenharmony_ci    if (options & kJitCodeEventEnumExisting) {
20731cb0ef41Sopenharmony_ci      HandleScope scope(isolate_);
20741cb0ef41Sopenharmony_ci      LogCodeObjects();
20751cb0ef41Sopenharmony_ci      LogBuiltins();
20761cb0ef41Sopenharmony_ci      LogCompiledFunctions();
20771cb0ef41Sopenharmony_ci    }
20781cb0ef41Sopenharmony_ci  }
20791cb0ef41Sopenharmony_ci}
20801cb0ef41Sopenharmony_ci
20811cb0ef41Sopenharmony_cisampler::Sampler* Logger::sampler() { return ticker_.get(); }
20821cb0ef41Sopenharmony_cistd::string Logger::file_name() const { return log_.get()->file_name(); }
20831cb0ef41Sopenharmony_ci
20841cb0ef41Sopenharmony_civoid Logger::StopProfilerThread() {
20851cb0ef41Sopenharmony_ci  if (profiler_ != nullptr) {
20861cb0ef41Sopenharmony_ci    profiler_->Disengage();
20871cb0ef41Sopenharmony_ci    profiler_.reset();
20881cb0ef41Sopenharmony_ci  }
20891cb0ef41Sopenharmony_ci}
20901cb0ef41Sopenharmony_ci
20911cb0ef41Sopenharmony_ciFILE* Logger::TearDownAndGetLogFile() {
20921cb0ef41Sopenharmony_ci  if (!is_initialized_) return nullptr;
20931cb0ef41Sopenharmony_ci  is_initialized_ = false;
20941cb0ef41Sopenharmony_ci  UpdateIsLogging(false);
20951cb0ef41Sopenharmony_ci
20961cb0ef41Sopenharmony_ci  // Stop the profiler thread before closing the file.
20971cb0ef41Sopenharmony_ci  StopProfilerThread();
20981cb0ef41Sopenharmony_ci
20991cb0ef41Sopenharmony_ci  ticker_.reset();
21001cb0ef41Sopenharmony_ci  timer_.Stop();
21011cb0ef41Sopenharmony_ci
21021cb0ef41Sopenharmony_ci#if V8_OS_LINUX
21031cb0ef41Sopenharmony_ci  if (perf_basic_logger_) {
21041cb0ef41Sopenharmony_ci    RemoveCodeEventListener(perf_basic_logger_.get());
21051cb0ef41Sopenharmony_ci    perf_basic_logger_.reset();
21061cb0ef41Sopenharmony_ci  }
21071cb0ef41Sopenharmony_ci
21081cb0ef41Sopenharmony_ci  if (perf_jit_logger_) {
21091cb0ef41Sopenharmony_ci    RemoveCodeEventListener(perf_jit_logger_.get());
21101cb0ef41Sopenharmony_ci    perf_jit_logger_.reset();
21111cb0ef41Sopenharmony_ci  }
21121cb0ef41Sopenharmony_ci#endif
21131cb0ef41Sopenharmony_ci
21141cb0ef41Sopenharmony_ci  if (ll_logger_) {
21151cb0ef41Sopenharmony_ci    RemoveCodeEventListener(ll_logger_.get());
21161cb0ef41Sopenharmony_ci    ll_logger_.reset();
21171cb0ef41Sopenharmony_ci  }
21181cb0ef41Sopenharmony_ci
21191cb0ef41Sopenharmony_ci  if (jit_logger_) {
21201cb0ef41Sopenharmony_ci    RemoveCodeEventListener(jit_logger_.get());
21211cb0ef41Sopenharmony_ci    jit_logger_.reset();
21221cb0ef41Sopenharmony_ci  }
21231cb0ef41Sopenharmony_ci
21241cb0ef41Sopenharmony_ci  return log_->Close();
21251cb0ef41Sopenharmony_ci}
21261cb0ef41Sopenharmony_ci
21271cb0ef41Sopenharmony_civoid Logger::UpdateIsLogging(bool value) {
21281cb0ef41Sopenharmony_ci  base::MutexGuard guard(log_->mutex());
21291cb0ef41Sopenharmony_ci  if (value) {
21301cb0ef41Sopenharmony_ci    isolate_->CollectSourcePositionsForAllBytecodeArrays();
21311cb0ef41Sopenharmony_ci  }
21321cb0ef41Sopenharmony_ci  // Relaxed atomic to avoid locking the mutex for the most common case: when
21331cb0ef41Sopenharmony_ci  // logging is disabled.
21341cb0ef41Sopenharmony_ci  is_logging_.store(value, std::memory_order_relaxed);
21351cb0ef41Sopenharmony_ci}
21361cb0ef41Sopenharmony_ci
21371cb0ef41Sopenharmony_civoid ExistingCodeLogger::LogCodeObject(Object object) {
21381cb0ef41Sopenharmony_ci  HandleScope scope(isolate_);
21391cb0ef41Sopenharmony_ci  Handle<AbstractCode> abstract_code(AbstractCode::cast(object), isolate_);
21401cb0ef41Sopenharmony_ci  CodeEventListener::LogEventsAndTags tag = CodeEventListener::STUB_TAG;
21411cb0ef41Sopenharmony_ci  const char* description = "Unknown code from before profiling";
21421cb0ef41Sopenharmony_ci  switch (abstract_code->kind()) {
21431cb0ef41Sopenharmony_ci    case CodeKind::INTERPRETED_FUNCTION:
21441cb0ef41Sopenharmony_ci    case CodeKind::TURBOFAN:
21451cb0ef41Sopenharmony_ci    case CodeKind::BASELINE:
21461cb0ef41Sopenharmony_ci    case CodeKind::MAGLEV:
21471cb0ef41Sopenharmony_ci      return;  // We log this later using LogCompiledFunctions.
21481cb0ef41Sopenharmony_ci    case CodeKind::FOR_TESTING:
21491cb0ef41Sopenharmony_ci      description = "STUB code";
21501cb0ef41Sopenharmony_ci      tag = CodeEventListener::STUB_TAG;
21511cb0ef41Sopenharmony_ci      break;
21521cb0ef41Sopenharmony_ci    case CodeKind::REGEXP:
21531cb0ef41Sopenharmony_ci      description = "Regular expression code";
21541cb0ef41Sopenharmony_ci      tag = CodeEventListener::REG_EXP_TAG;
21551cb0ef41Sopenharmony_ci      break;
21561cb0ef41Sopenharmony_ci    case CodeKind::BYTECODE_HANDLER:
21571cb0ef41Sopenharmony_ci      description =
21581cb0ef41Sopenharmony_ci          isolate_->builtins()->name(abstract_code->GetCode().builtin_id());
21591cb0ef41Sopenharmony_ci      tag = CodeEventListener::BYTECODE_HANDLER_TAG;
21601cb0ef41Sopenharmony_ci      break;
21611cb0ef41Sopenharmony_ci    case CodeKind::BUILTIN:
21621cb0ef41Sopenharmony_ci      if (Code::cast(object).is_interpreter_trampoline_builtin() &&
21631cb0ef41Sopenharmony_ci          ToCodeT(Code::cast(object)) !=
21641cb0ef41Sopenharmony_ci              *BUILTIN_CODE(isolate_, InterpreterEntryTrampoline)) {
21651cb0ef41Sopenharmony_ci        return;
21661cb0ef41Sopenharmony_ci      }
21671cb0ef41Sopenharmony_ci      description =
21681cb0ef41Sopenharmony_ci          isolate_->builtins()->name(abstract_code->GetCode().builtin_id());
21691cb0ef41Sopenharmony_ci      tag = CodeEventListener::BUILTIN_TAG;
21701cb0ef41Sopenharmony_ci      break;
21711cb0ef41Sopenharmony_ci    case CodeKind::WASM_FUNCTION:
21721cb0ef41Sopenharmony_ci      description = "A Wasm function";
21731cb0ef41Sopenharmony_ci      tag = CodeEventListener::FUNCTION_TAG;
21741cb0ef41Sopenharmony_ci      break;
21751cb0ef41Sopenharmony_ci    case CodeKind::JS_TO_WASM_FUNCTION:
21761cb0ef41Sopenharmony_ci      description = "A JavaScript to Wasm adapter";
21771cb0ef41Sopenharmony_ci      tag = CodeEventListener::STUB_TAG;
21781cb0ef41Sopenharmony_ci      break;
21791cb0ef41Sopenharmony_ci    case CodeKind::JS_TO_JS_FUNCTION:
21801cb0ef41Sopenharmony_ci      description = "A WebAssembly.Function adapter";
21811cb0ef41Sopenharmony_ci      tag = CodeEventListener::STUB_TAG;
21821cb0ef41Sopenharmony_ci      break;
21831cb0ef41Sopenharmony_ci    case CodeKind::WASM_TO_CAPI_FUNCTION:
21841cb0ef41Sopenharmony_ci      description = "A Wasm to C-API adapter";
21851cb0ef41Sopenharmony_ci      tag = CodeEventListener::STUB_TAG;
21861cb0ef41Sopenharmony_ci      break;
21871cb0ef41Sopenharmony_ci    case CodeKind::WASM_TO_JS_FUNCTION:
21881cb0ef41Sopenharmony_ci      description = "A Wasm to JavaScript adapter";
21891cb0ef41Sopenharmony_ci      tag = CodeEventListener::STUB_TAG;
21901cb0ef41Sopenharmony_ci      break;
21911cb0ef41Sopenharmony_ci    case CodeKind::C_WASM_ENTRY:
21921cb0ef41Sopenharmony_ci      description = "A C to Wasm entry stub";
21931cb0ef41Sopenharmony_ci      tag = CodeEventListener::STUB_TAG;
21941cb0ef41Sopenharmony_ci      break;
21951cb0ef41Sopenharmony_ci  }
21961cb0ef41Sopenharmony_ci  CALL_CODE_EVENT_HANDLER(CodeCreateEvent(tag, abstract_code, description))
21971cb0ef41Sopenharmony_ci}
21981cb0ef41Sopenharmony_ci
21991cb0ef41Sopenharmony_civoid ExistingCodeLogger::LogCodeObjects() {
22001cb0ef41Sopenharmony_ci  Heap* heap = isolate_->heap();
22011cb0ef41Sopenharmony_ci  HeapObjectIterator iterator(heap);
22021cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
22031cb0ef41Sopenharmony_ci  for (HeapObject obj = iterator.Next(); !obj.is_null();
22041cb0ef41Sopenharmony_ci       obj = iterator.Next()) {
22051cb0ef41Sopenharmony_ci    if (obj.IsCode()) LogCodeObject(obj);
22061cb0ef41Sopenharmony_ci    if (obj.IsBytecodeArray()) LogCodeObject(obj);
22071cb0ef41Sopenharmony_ci  }
22081cb0ef41Sopenharmony_ci}
22091cb0ef41Sopenharmony_ci
22101cb0ef41Sopenharmony_civoid ExistingCodeLogger::LogBuiltins() {
22111cb0ef41Sopenharmony_ci  Builtins* builtins = isolate_->builtins();
22121cb0ef41Sopenharmony_ci  DCHECK(builtins->is_initialized());
22131cb0ef41Sopenharmony_ci  for (Builtin builtin = Builtins::kFirst; builtin <= Builtins::kLast;
22141cb0ef41Sopenharmony_ci       ++builtin) {
22151cb0ef41Sopenharmony_ci    Code code = FromCodeT(builtins->code(builtin));
22161cb0ef41Sopenharmony_ci    LogCodeObject(code);
22171cb0ef41Sopenharmony_ci  }
22181cb0ef41Sopenharmony_ci}
22191cb0ef41Sopenharmony_ci
22201cb0ef41Sopenharmony_civoid ExistingCodeLogger::LogCompiledFunctions() {
22211cb0ef41Sopenharmony_ci  Heap* heap = isolate_->heap();
22221cb0ef41Sopenharmony_ci  HandleScope scope(isolate_);
22231cb0ef41Sopenharmony_ci  std::vector<std::pair<Handle<SharedFunctionInfo>, Handle<AbstractCode>>>
22241cb0ef41Sopenharmony_ci      compiled_funcs = EnumerateCompiledFunctions(heap);
22251cb0ef41Sopenharmony_ci
22261cb0ef41Sopenharmony_ci  // During iteration, there can be heap allocation due to
22271cb0ef41Sopenharmony_ci  // GetScriptLineNumber call.
22281cb0ef41Sopenharmony_ci  for (auto& pair : compiled_funcs) {
22291cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared = pair.first;
22301cb0ef41Sopenharmony_ci    SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate_, shared);
22311cb0ef41Sopenharmony_ci    if (shared->HasInterpreterData()) {
22321cb0ef41Sopenharmony_ci      LogExistingFunction(
22331cb0ef41Sopenharmony_ci          shared,
22341cb0ef41Sopenharmony_ci          Handle<AbstractCode>(
22351cb0ef41Sopenharmony_ci              AbstractCode::cast(FromCodeT(shared->InterpreterTrampoline())),
22361cb0ef41Sopenharmony_ci              isolate_));
22371cb0ef41Sopenharmony_ci    }
22381cb0ef41Sopenharmony_ci    if (shared->HasBaselineCode()) {
22391cb0ef41Sopenharmony_ci      LogExistingFunction(shared, Handle<AbstractCode>(
22401cb0ef41Sopenharmony_ci                                      AbstractCode::cast(FromCodeT(
22411cb0ef41Sopenharmony_ci                                          shared->baseline_code(kAcquireLoad))),
22421cb0ef41Sopenharmony_ci                                      isolate_));
22431cb0ef41Sopenharmony_ci    }
22441cb0ef41Sopenharmony_ci    if (pair.second.is_identical_to(BUILTIN_CODE(isolate_, CompileLazy)))
22451cb0ef41Sopenharmony_ci      continue;
22461cb0ef41Sopenharmony_ci    LogExistingFunction(pair.first, pair.second);
22471cb0ef41Sopenharmony_ci  }
22481cb0ef41Sopenharmony_ci
22491cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
22501cb0ef41Sopenharmony_ci  HeapObjectIterator iterator(heap);
22511cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
22521cb0ef41Sopenharmony_ci
22531cb0ef41Sopenharmony_ci  for (HeapObject obj = iterator.Next(); !obj.is_null();
22541cb0ef41Sopenharmony_ci       obj = iterator.Next()) {
22551cb0ef41Sopenharmony_ci    if (!obj.IsWasmModuleObject()) continue;
22561cb0ef41Sopenharmony_ci    auto module_object = WasmModuleObject::cast(obj);
22571cb0ef41Sopenharmony_ci    module_object.native_module()->LogWasmCodes(isolate_,
22581cb0ef41Sopenharmony_ci                                                module_object.script());
22591cb0ef41Sopenharmony_ci  }
22601cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
22611cb0ef41Sopenharmony_ci}
22621cb0ef41Sopenharmony_ci
22631cb0ef41Sopenharmony_civoid ExistingCodeLogger::LogExistingFunction(
22641cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> shared, Handle<AbstractCode> code,
22651cb0ef41Sopenharmony_ci    CodeEventListener::LogEventsAndTags tag) {
22661cb0ef41Sopenharmony_ci  if (shared->script().IsScript()) {
22671cb0ef41Sopenharmony_ci    Handle<Script> script(Script::cast(shared->script()), isolate_);
22681cb0ef41Sopenharmony_ci    int line_num = Script::GetLineNumber(script, shared->StartPosition()) + 1;
22691cb0ef41Sopenharmony_ci    int column_num =
22701cb0ef41Sopenharmony_ci        Script::GetColumnNumber(script, shared->StartPosition()) + 1;
22711cb0ef41Sopenharmony_ci    if (script->name().IsString()) {
22721cb0ef41Sopenharmony_ci      Handle<String> script_name(String::cast(script->name()), isolate_);
22731cb0ef41Sopenharmony_ci      if (!shared->is_toplevel()) {
22741cb0ef41Sopenharmony_ci        CALL_CODE_EVENT_HANDLER(
22751cb0ef41Sopenharmony_ci            CodeCreateEvent(Logger::ToNativeByScript(tag, *script), code,
22761cb0ef41Sopenharmony_ci                            shared, script_name, line_num, column_num))
22771cb0ef41Sopenharmony_ci      } else {
22781cb0ef41Sopenharmony_ci        // Can't distinguish eval and script here, so always use Script.
22791cb0ef41Sopenharmony_ci        CALL_CODE_EVENT_HANDLER(CodeCreateEvent(
22801cb0ef41Sopenharmony_ci            Logger::ToNativeByScript(CodeEventListener::SCRIPT_TAG, *script),
22811cb0ef41Sopenharmony_ci            code, shared, script_name))
22821cb0ef41Sopenharmony_ci      }
22831cb0ef41Sopenharmony_ci    } else {
22841cb0ef41Sopenharmony_ci      CALL_CODE_EVENT_HANDLER(CodeCreateEvent(
22851cb0ef41Sopenharmony_ci          Logger::ToNativeByScript(tag, *script), code, shared,
22861cb0ef41Sopenharmony_ci          ReadOnlyRoots(isolate_).empty_string_handle(), line_num, column_num))
22871cb0ef41Sopenharmony_ci    }
22881cb0ef41Sopenharmony_ci  } else if (shared->IsApiFunction()) {
22891cb0ef41Sopenharmony_ci    // API function.
22901cb0ef41Sopenharmony_ci    Handle<FunctionTemplateInfo> fun_data =
22911cb0ef41Sopenharmony_ci        handle(shared->get_api_func_data(), isolate_);
22921cb0ef41Sopenharmony_ci    Object raw_call_data = fun_data->call_code(kAcquireLoad);
22931cb0ef41Sopenharmony_ci    if (!raw_call_data.IsUndefined(isolate_)) {
22941cb0ef41Sopenharmony_ci      CallHandlerInfo call_data = CallHandlerInfo::cast(raw_call_data);
22951cb0ef41Sopenharmony_ci      Object callback_obj = call_data.callback();
22961cb0ef41Sopenharmony_ci      Address entry_point = v8::ToCData<Address>(callback_obj);
22971cb0ef41Sopenharmony_ci#if USES_FUNCTION_DESCRIPTORS
22981cb0ef41Sopenharmony_ci      entry_point = *FUNCTION_ENTRYPOINT_ADDRESS(entry_point);
22991cb0ef41Sopenharmony_ci#endif
23001cb0ef41Sopenharmony_ci      Handle<String> fun_name = SharedFunctionInfo::DebugName(shared);
23011cb0ef41Sopenharmony_ci      CALL_CODE_EVENT_HANDLER(CallbackEvent(fun_name, entry_point))
23021cb0ef41Sopenharmony_ci
23031cb0ef41Sopenharmony_ci      // Fast API function.
23041cb0ef41Sopenharmony_ci      int c_functions_count = fun_data->GetCFunctionsCount();
23051cb0ef41Sopenharmony_ci      for (int i = 0; i < c_functions_count; i++) {
23061cb0ef41Sopenharmony_ci        CALL_CODE_EVENT_HANDLER(
23071cb0ef41Sopenharmony_ci            CallbackEvent(fun_name, fun_data->GetCFunction(i)))
23081cb0ef41Sopenharmony_ci      }
23091cb0ef41Sopenharmony_ci    }
23101cb0ef41Sopenharmony_ci  }
23111cb0ef41Sopenharmony_ci}
23121cb0ef41Sopenharmony_ci
23131cb0ef41Sopenharmony_ci#undef CALL_CODE_EVENT_HANDLER
23141cb0ef41Sopenharmony_ci#undef MSG_BUILDER
23151cb0ef41Sopenharmony_ci
23161cb0ef41Sopenharmony_ci}  // namespace internal
23171cb0ef41Sopenharmony_ci}  // namespace v8
2318