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