From 762089e4aab680cd7f6841d9b596ab9a2ffad3fc Mon Sep 17 00:00:00 2001 From: Matheus Marchini Date: Mon, 18 Jun 2018 09:47:52 -0700 Subject: [PATCH 01/23] deps: cherry-pick 5dd3395 from upstream V8 Original commit message: [log] improve --perf-basic-prof-only-functions Change --perf-basic-prof-only-functions to also log builtin code creation events, otherwise InterpretedFunctions generated by --interpreted-frames-native-stack will be filtered out. R=yangguo@google.com Change-Id: Ib0623fca88e25c514473a43de56ebbbdcb146f97 Reviewed-on: https://chromium-review.googlesource.com/1100014 Reviewed-by: Yang Guo Commit-Queue: Yang Guo Cr-Commit-Position: refs/heads/master@{#53760} Refs: https://github.com/v8/v8/commit/5dd33955d5cb1d84dd2509363e11d3c2a Backport-PR-URL: https://github.com/nodejs/node/pull/21668 PR-URL: https://github.com/nodejs/node/pull/21386 Reviewed-By: Yang Guo Reviewed-By: Gus Caplan Reviewed-By: James M Snell --- src/log.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/log.cc b/src/log.cc index 953216aef7..f5e1fe6baf 100644 --- a/src/log.cc +++ b/src/log.cc @@ -305,6 +305,7 @@ void PerfBasicLogger::LogRecordedBuffer(AbstractCode* code, SharedFunctionInfo*, const char* name, int length) { if (FLAG_perf_basic_prof_only_functions && (code->kind() != AbstractCode::INTERPRETED_FUNCTION && + code->kind() != AbstractCode::BUILTIN && code->kind() != AbstractCode::OPTIMIZED_FUNCTION)) { return; } -- 2.17.0 From bf391a14d065dcaeef410a09d300c5e91a06bf8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Thu, 5 Jul 2018 08:38:02 +0200 Subject: [PATCH 02/23] deps: cherry-pick aa6ce3e from upstream V8 Original commit message: [log][api] introduce public CodeEventListener API Introduce a new public API called CodeEventListener to allow embedders to better support external profilers and other diagnostic tools without relying on unsupported methods like --perf-basic-prof. Bug: v8:7694 Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Change-Id: I063cc965394d59401358757634c9ea84c11517e9 Co-authored-by: Daniel Beckert Reviewed-on: https://chromium-review.googlesource.com/1028770 Commit-Queue: Yang Guo Reviewed-by: Hannes Payer Reviewed-by: Yang Guo Reviewed-by: Andreas Haas Cr-Commit-Position: refs/heads/master@{#53382} Refs: https://github.com/v8/v8/commit/aa6ce3ee617b2f324bea3a5d8e3263aee4cde6d7 Backport-PR-URL: https://github.com/nodejs/node/pull/21668 PR-URL: https://github.com/nodejs/node/pull/21079 Reviewed-By: James M Snell Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig Reviewed-By: Yang Guo --- include/v8-profiler.h | 70 +++++ src/api.cc | 64 ++++ src/code-events.h | 62 ++-- src/compiler.cc | 5 +- src/compiler/wasm-compiler.cc | 3 +- src/heap/mark-compact.cc | 2 +- src/isolate.cc | 2 +- src/isolate.h | 1 + src/log.cc | 510 ++++++++++++++++++++++---------- src/log.h | 86 +++++- src/runtime/runtime-function.cc | 3 +- src/snapshot/code-serializer.cc | 3 +- src/snapshot/snapshot-common.cc | 6 +- src/wasm/wasm-code-manager.cc | 2 +- test/cctest/test-log.cc | 75 +++++ 15 files changed, 694 insertions(+), 200 deletions(-) diff --git a/include/v8-profiler.h b/include/v8-profiler.h index 34ad2b9cea..76490afe3c 100644 --- a/include/v8-profiler.h +++ b/include/v8-profiler.h @@ -992,6 +992,76 @@ struct HeapStatsUpdate { uint32_t size; // New value of size field for the interval with this index. }; +#define CODE_EVENTS_LIST(V) \ + V(Builtin) \ + V(Callback) \ + V(Eval) \ + V(Function) \ + V(InterpretedFunction) \ + V(Handler) \ + V(BytecodeHandler) \ + V(LazyCompile) \ + V(RegExp) \ + V(Script) \ + V(Stub) + +/** + * Note that this enum may be extended in the future. Please include a default + * case if this enum is used in a switch statement. + */ +enum CodeEventType { + kUnknownType = 0 +#define V(Name) , k##Name##Type + CODE_EVENTS_LIST(V) +#undef V +}; + +/** + * Representation of a code creation event + */ +class V8_EXPORT CodeEvent { + public: + uintptr_t GetCodeStartAddress(); + size_t GetCodeSize(); + Local GetFunctionName(); + Local GetScriptName(); + int GetScriptLine(); + int GetScriptColumn(); + /** + * NOTE (mmarchini): We can't allocate objects in the heap when we collect + * existing code, and both the code type and the comment are not stored in the + * heap, so we return those as const char*. + */ + CodeEventType GetCodeType(); + const char* GetComment(); + + static const char* GetCodeEventTypeName(CodeEventType code_event_type); +}; + +/** + * Interface to listen to code creation events. + */ +class V8_EXPORT CodeEventHandler { + public: + /** + * Creates a new listener for the |isolate|. The isolate must be initialized. + * The listener object must be disposed after use by calling |Dispose| method. + * Multiple listeners can be created for the same isolate. + */ + explicit CodeEventHandler(Isolate* isolate); + virtual ~CodeEventHandler(); + + virtual void Handle(CodeEvent* code_event) = 0; + + void Enable(); + void Disable(); + + private: + CodeEventHandler(); + CodeEventHandler(const CodeEventHandler&); + CodeEventHandler& operator=(const CodeEventHandler&); + void* internal_listener_; +}; } // namespace v8 diff --git a/src/api.cc b/src/api.cc index 89bcb2e4fa..f51576ed2a 100644 --- a/src/api.cc +++ b/src/api.cc @@ -10104,6 +10104,70 @@ void CpuProfiler::SetIdle(bool is_idle) { isolate->SetIdle(is_idle); } +uintptr_t CodeEvent::GetCodeStartAddress() { + return reinterpret_cast(this)->code_start_address; +} + +size_t CodeEvent::GetCodeSize() { + return reinterpret_cast(this)->code_size; +} + +Local CodeEvent::GetFunctionName() { + return ToApiHandle( + reinterpret_cast(this)->function_name); +} + +Local CodeEvent::GetScriptName() { + return ToApiHandle( + reinterpret_cast(this)->script_name); +} + +int CodeEvent::GetScriptLine() { + return reinterpret_cast(this)->script_line; +} + +int CodeEvent::GetScriptColumn() { + return reinterpret_cast(this)->script_column; +} + +CodeEventType CodeEvent::GetCodeType() { + return reinterpret_cast(this)->code_type; +} + +const char* CodeEvent::GetComment() { + return reinterpret_cast(this)->comment; +} + +const char* CodeEvent::GetCodeEventTypeName(CodeEventType code_event_type) { + switch (code_event_type) { + case kUnknownType: + return "Unknown"; +#define V(Name) \ + case k##Name##Type: \ + return #Name; + CODE_EVENTS_LIST(V) +#undef V + } +} + +CodeEventHandler::CodeEventHandler(Isolate* isolate) { + internal_listener_ = + new i::ExternalCodeEventListener(reinterpret_cast(isolate)); +} + +CodeEventHandler::~CodeEventHandler() { + delete reinterpret_cast(internal_listener_); +} + +void CodeEventHandler::Enable() { + reinterpret_cast(internal_listener_) + ->StartListening(this); +} + +void CodeEventHandler::Disable() { + reinterpret_cast(internal_listener_) + ->StopListening(); +} static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) { return const_cast( diff --git a/src/code-events.h b/src/code-events.h index 439cb54dca..caed5160f4 100644 --- a/src/code-events.h +++ b/src/code-events.h @@ -24,32 +24,38 @@ class WasmCode; using WasmName = Vector; } // namespace wasm -#define LOG_EVENTS_AND_TAGS_LIST(V) \ - V(CODE_CREATION_EVENT, "code-creation") \ - V(CODE_DISABLE_OPT_EVENT, "code-disable-optimization") \ - V(CODE_MOVE_EVENT, "code-move") \ - V(CODE_DELETE_EVENT, "code-delete") \ - V(CODE_MOVING_GC, "code-moving-gc") \ - V(SHARED_FUNC_MOVE_EVENT, "sfi-move") \ - V(SNAPSHOT_CODE_NAME_EVENT, "snapshot-code-name") \ - V(TICK_EVENT, "tick") \ - V(BUILTIN_TAG, "Builtin") \ - V(CALLBACK_TAG, "Callback") \ - V(EVAL_TAG, "Eval") \ - V(FUNCTION_TAG, "Function") \ - V(INTERPRETED_FUNCTION_TAG, "InterpretedFunction") \ - V(HANDLER_TAG, "Handler") \ - V(BYTECODE_HANDLER_TAG, "BytecodeHandler") \ - V(LAZY_COMPILE_TAG, "LazyCompile") \ - V(REG_EXP_TAG, "RegExp") \ - V(SCRIPT_TAG, "Script") \ - V(STUB_TAG, "Stub") \ - V(NATIVE_FUNCTION_TAG, "Function") \ - V(NATIVE_LAZY_COMPILE_TAG, "LazyCompile") \ - V(NATIVE_SCRIPT_TAG, "Script") +#define LOG_EVENTS_LIST(V) \ + V(CODE_CREATION_EVENT, code-creation) \ + V(CODE_DISABLE_OPT_EVENT, code-disable-optimization) \ + V(CODE_MOVE_EVENT, code-move) \ + V(CODE_DELETE_EVENT, code-delete) \ + V(CODE_MOVING_GC, code-moving-gc) \ + V(SHARED_FUNC_MOVE_EVENT, sfi-move) \ + V(SNAPSHOT_CODE_NAME_EVENT, snapshot-code-name) \ + V(TICK_EVENT, tick) + +#define TAGS_LIST(V) \ + V(BUILTIN_TAG, Builtin) \ + V(CALLBACK_TAG, Callback) \ + V(EVAL_TAG, Eval) \ + V(FUNCTION_TAG, Function) \ + V(INTERPRETED_FUNCTION_TAG, InterpretedFunction) \ + V(HANDLER_TAG, Handler) \ + V(BYTECODE_HANDLER_TAG, BytecodeHandler) \ + V(LAZY_COMPILE_TAG, LazyCompile) \ + V(REG_EXP_TAG, RegExp) \ + V(SCRIPT_TAG, Script) \ + V(STUB_TAG, Stub) \ + V(NATIVE_FUNCTION_TAG, Function) \ + V(NATIVE_LAZY_COMPILE_TAG, LazyCompile) \ + V(NATIVE_SCRIPT_TAG, Script) // Note that 'NATIVE_' cases for functions and scripts are mapped onto // original tags when writing to the log. +#define LOG_EVENTS_AND_TAGS_LIST(V) \ + LOG_EVENTS_LIST(V) \ + TAGS_LIST(V) + #define PROFILE(the_isolate, Call) (the_isolate)->code_event_dispatcher()->Call; class CodeEventListener { @@ -85,6 +91,8 @@ class CodeEventListener { enum DeoptKind { kSoft, kLazy, kEager }; virtual void CodeDeoptEvent(Code* code, DeoptKind kind, Address pc, int fp_to_sp_delta) = 0; + + virtual bool is_listening_to_code_events() { return false; } }; class CodeEventDispatcher { @@ -101,6 +109,14 @@ class CodeEventDispatcher { base::LockGuard guard(&mutex_); listeners_.erase(listener); } + bool IsListeningToCodeEvents() { + for (auto it : listeners_) { + if (it->is_listening_to_code_events()) { + return true; + } + } + return false; + } #define CODE_EVENT_DISPATCH(code) \ base::LockGuard guard(&mutex_); \ diff --git a/src/compiler.cc b/src/compiler.cc index ae6bc9c4fa..a01750b23a 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -84,8 +84,9 @@ void LogFunctionCompilation(CodeEventListener::LogEventsAndTags tag, // Log the code generation. If source information is available include // script name and line number. Check explicitly whether logging is // enabled as finding the line number is not free. - if (!isolate->logger()->is_logging_code_events() && - !isolate->is_profiling() && !FLAG_log_function_events) { + if (!isolate->logger()->is_listening_to_code_events() && + !isolate->is_profiling() && !FLAG_log_function_events && + !isolate->code_event_dispatcher()->IsListeningToCodeEvents()) { return; } diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index daceffd331..61c3a350f7 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -3952,7 +3952,8 @@ Node* WasmGraphBuilder::AtomicOp(wasm::WasmOpcode opcode, Node* const* inputs, namespace { bool must_record_function_compilation(Isolate* isolate) { - return isolate->logger()->is_logging_code_events() || isolate->is_profiling(); + return isolate->logger()->is_listening_to_code_events() || + isolate->is_profiling(); } PRINTF_FORMAT(4, 5) diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc index 50be29c29a..66575f8250 100644 --- a/src/heap/mark-compact.cc +++ b/src/heap/mark-compact.cc @@ -2414,7 +2414,7 @@ void MarkCompactCollectorBase::CreateAndExecuteEvacuationTasks( const bool profiling = heap()->isolate()->is_profiling() || - heap()->isolate()->logger()->is_logging_code_events() || + heap()->isolate()->logger()->is_listening_to_code_events() || heap()->isolate()->heap_profiler()->is_tracking_object_moves() || heap()->has_heap_object_allocation_tracker(); ProfilingMigrationObserver profiling_observer(heap()); diff --git a/src/isolate.cc b/src/isolate.cc index abd74ee40d..dd66479f73 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -2892,7 +2892,7 @@ void CreateOffHeapTrampolines(Isolate* isolate) { // thus collected by the GC. builtins->set_builtin(i, *trampoline); - if (isolate->logger()->is_logging_code_events() || + if (isolate->logger()->is_listening_to_code_events() || isolate->is_profiling()) { isolate->logger()->LogCodeObject(*trampoline); } diff --git a/src/isolate.h b/src/isolate.h index 929403e134..69ec1f1853 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -57,6 +57,7 @@ class BuiltinsConstantsTableBuilder; class CallInterfaceDescriptorData; class CancelableTaskManager; class CodeEventDispatcher; +class ExternalCodeEventListener; class CodeGenerator; class CodeRange; class CodeStubDescriptor; diff --git a/src/log.cc b/src/log.cc index f5e1fe6baf..20e5f2c964 100644 --- a/src/log.cc +++ b/src/log.cc @@ -40,11 +40,33 @@ namespace v8 { namespace internal { -#define DECLARE_EVENT(ignore1, name) name, +#define DECLARE_EVENT(ignore1, name) #name, static const char* kLogEventsNames[CodeEventListener::NUMBER_OF_LOG_EVENTS] = { LOG_EVENTS_AND_TAGS_LIST(DECLARE_EVENT)}; #undef DECLARE_EVENT +static v8::CodeEventType GetCodeEventTypeForTag( + CodeEventListener::LogEventsAndTags tag) { + switch (tag) { + case CodeEventListener::NUMBER_OF_LOG_EVENTS: +#define V(Event, _) case CodeEventListener::Event: + LOG_EVENTS_LIST(V) +#undef V + return v8::CodeEventType::kUnknownType; +#define V(From, To) \ + case CodeEventListener::From: \ + return v8::CodeEventType::k##To##Type; + TAGS_LIST(V) +#undef V + } +} +#define CALL_CODE_EVENT_HANDLER(Call) \ + if (listener_) { \ + listener_->Call; \ + } else { \ + PROFILE(isolate_, Call); \ + } + static const char* ComputeMarker(SharedFunctionInfo* shared, AbstractCode* code) { switch (code->kind()) { @@ -320,9 +342,147 @@ void PerfBasicLogger::LogRecordedBuffer(const wasm::WasmCode* code, code->instructions().length(), name, length); } -// Low-level logging support. -#define LL_LOG(Call) if (ll_logger_) ll_logger_->Call; +// External CodeEventListener +ExternalCodeEventListener::ExternalCodeEventListener(Isolate* isolate) + : is_listening_(false), isolate_(isolate), code_event_handler_(nullptr) {} + +ExternalCodeEventListener::~ExternalCodeEventListener() { + if (is_listening_) { + StopListening(); + } +} + +void ExternalCodeEventListener::LogExistingCode() { + HandleScope scope(isolate_); + ExistingCodeLogger logger(isolate_, this); + logger.LogCodeObjects(); + logger.LogBytecodeHandlers(); + logger.LogCompiledFunctions(); +} + +void ExternalCodeEventListener::StartListening( + CodeEventHandler* code_event_handler) { + if (is_listening_ || code_event_handler == nullptr) { + return; + } + code_event_handler_ = code_event_handler; + is_listening_ = isolate_->code_event_dispatcher()->AddListener(this); + if (is_listening_) { + LogExistingCode(); + } +} +void ExternalCodeEventListener::StopListening() { + if (!is_listening_) { + return; + } + + isolate_->code_event_dispatcher()->RemoveListener(this); + is_listening_ = false; +} + +void ExternalCodeEventListener::CodeCreateEvent( + CodeEventListener::LogEventsAndTags tag, AbstractCode* code, + const char* comment) { + CodeEvent code_event; + code_event.code_start_address = + static_cast(code->InstructionStart()); + code_event.code_size = static_cast(code->InstructionSize()); + code_event.function_name = isolate_->factory()->empty_string(); + code_event.script_name = isolate_->factory()->empty_string(); + code_event.script_line = 0; + code_event.script_column = 0; + code_event.code_type = GetCodeEventTypeForTag(tag); + code_event.comment = comment; + + code_event_handler_->Handle(reinterpret_cast(&code_event)); +} + +void ExternalCodeEventListener::CodeCreateEvent( + CodeEventListener::LogEventsAndTags tag, AbstractCode* code, Name* name) { + Handle name_string = + Name::ToFunctionName(Handle(name, isolate_)).ToHandleChecked(); + + CodeEvent code_event; + code_event.code_start_address = + static_cast(code->InstructionStart()); + code_event.code_size = static_cast(code->InstructionSize()); + code_event.function_name = name_string; + code_event.script_name = isolate_->factory()->empty_string(); + code_event.script_line = 0; + code_event.script_column = 0; + code_event.code_type = GetCodeEventTypeForTag(tag); + code_event.comment = ""; + + code_event_handler_->Handle(reinterpret_cast(&code_event)); +} + +void ExternalCodeEventListener::CodeCreateEvent( + CodeEventListener::LogEventsAndTags tag, AbstractCode* code, + SharedFunctionInfo* shared, Name* name) { + Handle name_string = + Name::ToFunctionName(Handle(name, isolate_)).ToHandleChecked(); + + CodeEvent code_event; + code_event.code_start_address = + static_cast(code->InstructionStart()); + code_event.code_size = static_cast(code->InstructionSize()); + code_event.function_name = name_string; + code_event.script_name = isolate_->factory()->empty_string(); + code_event.script_line = 0; + code_event.script_column = 0; + code_event.code_type = GetCodeEventTypeForTag(tag); + code_event.comment = ""; + + code_event_handler_->Handle(reinterpret_cast(&code_event)); +} + +void ExternalCodeEventListener::CodeCreateEvent( + CodeEventListener::LogEventsAndTags tag, AbstractCode* code, + SharedFunctionInfo* shared, Name* source, int line, int column) { + Handle name_string = + Name::ToFunctionName(Handle(shared->Name(), isolate_)) + .ToHandleChecked(); + Handle source_string = + Name::ToFunctionName(Handle(source, isolate_)).ToHandleChecked(); + + CodeEvent code_event; + code_event.code_start_address = + static_cast(code->InstructionStart()); + code_event.code_size = static_cast(code->InstructionSize()); + code_event.function_name = name_string; + code_event.script_name = source_string; + code_event.script_line = line; + code_event.script_column = column; + code_event.code_type = GetCodeEventTypeForTag(tag); + code_event.comment = ""; + + code_event_handler_->Handle(reinterpret_cast(&code_event)); +} + +void ExternalCodeEventListener::CodeCreateEvent(LogEventsAndTags tag, + const wasm::WasmCode* code, + wasm::WasmName name) { + // TODO(mmarchini): handle later +} + +void ExternalCodeEventListener::RegExpCodeCreateEvent(AbstractCode* code, + String* source) { + CodeEvent code_event; + code_event.code_start_address = + static_cast(code->InstructionStart()); + code_event.code_size = static_cast(code->InstructionSize()); + code_event.function_name = Handle(source, isolate_); + code_event.script_name = isolate_->factory()->empty_string(); + code_event.script_line = 0; + code_event.script_column = 0; + code_event.code_type = GetCodeEventTypeForTag(CodeEventListener::REG_EXP_TAG); + code_event.comment = ""; + + code_event_handler_->Handle(reinterpret_cast(&code_event)); +} + +// Low-level logging support. class LowLevelLogger : public CodeEventLogger { public: explicit LowLevelLogger(const char* file_name); @@ -809,7 +969,8 @@ Logger::Logger(Isolate* isolate) perf_jit_logger_(nullptr), ll_logger_(nullptr), jit_logger_(nullptr), - is_initialized_(false) {} + is_initialized_(false), + existing_code_logger_(isolate) {} Logger::~Logger() { delete log_; @@ -1078,7 +1239,7 @@ void AppendCodeCreateHeader(Log::MessageBuilder& msg, void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode* code, const char* comment) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; Log::MessageBuilder msg(log_); AppendCodeCreateHeader(msg, tag, code, &timer_); @@ -1088,7 +1249,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode* code, Name* name) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; Log::MessageBuilder msg(log_); AppendCodeCreateHeader(msg, tag, code, &timer_); @@ -1099,7 +1260,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode* code, SharedFunctionInfo* shared, Name* name) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; if (code == AbstractCode::cast( isolate_->builtins()->builtin(Builtins::kCompileLazy))) { @@ -1115,7 +1276,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, const wasm::WasmCode* code, wasm::WasmName name) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; Log::MessageBuilder msg(log_); AppendCodeCreateHeader(msg, tag, AbstractCode::Kind::WASM_FUNCTION, @@ -1143,7 +1304,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, AbstractCode* code, SharedFunctionInfo* shared, Name* source, int line, int column) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; Log::MessageBuilder msg(log_); @@ -1260,7 +1421,7 @@ void Logger::CodeCreateEvent(CodeEventListener::LogEventsAndTags tag, void Logger::CodeDisableOptEvent(AbstractCode* code, SharedFunctionInfo* shared) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; Log::MessageBuilder msg(log_); msg << kLogEventsNames[CodeEventListener::CODE_DISABLE_OPT_EVENT] << kNext @@ -1271,13 +1432,13 @@ void Logger::CodeDisableOptEvent(AbstractCode* code, void Logger::CodeMovingGCEvent() { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; if (!log_->IsEnabled() || !FLAG_ll_prof) return; base::OS::SignalCodeMovingGC(); } void Logger::RegExpCodeCreateEvent(AbstractCode* code, String* source) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; if (!FLAG_log_code || !log_->IsEnabled()) return; Log::MessageBuilder msg(log_); AppendCodeCreateHeader(msg, CodeEventListener::REG_EXP_TAG, code, &timer_); @@ -1286,7 +1447,7 @@ void Logger::RegExpCodeCreateEvent(AbstractCode* code, String* source) { } void Logger::CodeMoveEvent(AbstractCode* from, Address to) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; MoveEventInternal(CodeEventListener::CODE_MOVE_EVENT, from->address(), to); } @@ -1335,7 +1496,7 @@ void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { void Logger::SharedFunctionInfoMoveEvent(Address from, Address to) { - if (!is_logging_code_events()) return; + if (!is_listening_to_code_events()) return; MoveEventInternal(CodeEventListener::SHARED_FUNC_MOVE_EVENT, from, to); } @@ -1625,170 +1786,28 @@ static int EnumerateWasmModules(Heap* heap, } void Logger::LogCodeObject(Object* object) { - AbstractCode* code_object = AbstractCode::cast(object); - CodeEventListener::LogEventsAndTags tag = CodeEventListener::STUB_TAG; - const char* description = "Unknown code from the snapshot"; - switch (code_object->kind()) { - case AbstractCode::INTERPRETED_FUNCTION: - case AbstractCode::OPTIMIZED_FUNCTION: - return; // We log this later using LogCompiledFunctions. - case AbstractCode::BYTECODE_HANDLER: - return; // We log it later by walking the dispatch table. - case AbstractCode::STUB: - description = - CodeStub::MajorName(CodeStub::GetMajorKey(code_object->GetCode())); - if (description == nullptr) description = "A stub from the snapshot"; - tag = CodeEventListener::STUB_TAG; - break; - case AbstractCode::REGEXP: - description = "Regular expression code"; - tag = CodeEventListener::REG_EXP_TAG; - break; - case AbstractCode::BUILTIN: - description = - isolate_->builtins()->name(code_object->GetCode()->builtin_index()); - tag = CodeEventListener::BUILTIN_TAG; - break; - case AbstractCode::WASM_FUNCTION: - description = "A Wasm function"; - tag = CodeEventListener::FUNCTION_TAG; - break; - case AbstractCode::JS_TO_WASM_FUNCTION: - description = "A JavaScript to Wasm adapter"; - tag = CodeEventListener::STUB_TAG; - break; - case AbstractCode::WASM_TO_JS_FUNCTION: - description = "A Wasm to JavaScript adapter"; - tag = CodeEventListener::STUB_TAG; - break; - case AbstractCode::WASM_INTERPRETER_ENTRY: - description = "A Wasm to Interpreter adapter"; - tag = CodeEventListener::STUB_TAG; - break; - case AbstractCode::C_WASM_ENTRY: - description = "A C to Wasm entry stub"; - tag = CodeEventListener::STUB_TAG; - break; - case AbstractCode::NUMBER_OF_KINDS: - UNIMPLEMENTED(); - } - PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); + existing_code_logger_.LogCodeObject(object); } -void Logger::LogCodeObjects() { - Heap* heap = isolate_->heap(); - HeapIterator iterator(heap); - DisallowHeapAllocation no_gc; - for (HeapObject* obj = iterator.next(); obj != nullptr; - obj = iterator.next()) { - if (obj->IsCode()) LogCodeObject(obj); - if (obj->IsBytecodeArray()) LogCodeObject(obj); - } -} +void Logger::LogCodeObjects() { existing_code_logger_.LogCodeObjects(); } void Logger::LogBytecodeHandler(interpreter::Bytecode bytecode, interpreter::OperandScale operand_scale, Code* code) { - std::string bytecode_name = - interpreter::Bytecodes::ToString(bytecode, operand_scale); - PROFILE(isolate_, - CodeCreateEvent(CodeEventListener::BYTECODE_HANDLER_TAG, - AbstractCode::cast(code), bytecode_name.c_str())); + existing_code_logger_.LogBytecodeHandler(bytecode, operand_scale, code); } void Logger::LogBytecodeHandlers() { - const interpreter::OperandScale kOperandScales[] = { -#define VALUE(Name, _) interpreter::OperandScale::k##Name, - OPERAND_SCALE_LIST(VALUE) -#undef VALUE - }; - - const int last_index = static_cast(interpreter::Bytecode::kLast); - interpreter::Interpreter* interpreter = isolate_->interpreter(); - for (auto operand_scale : kOperandScales) { - for (int index = 0; index <= last_index; ++index) { - interpreter::Bytecode bytecode = interpreter::Bytecodes::FromByte(index); - if (interpreter::Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) { - Code* code = interpreter->GetBytecodeHandler(bytecode, operand_scale); - if (isolate_->heap()->IsDeserializeLazyHandler(code)) continue; - LogBytecodeHandler(bytecode, operand_scale, code); - } - } - } + existing_code_logger_.LogBytecodeHandlers(); } void Logger::LogExistingFunction(Handle shared, Handle code) { - if (shared->script()->IsScript()) { - Handle