/*
 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Autogenerated file -- DO NOT EDIT!

#ifndef PANDA_EVENTS_GEN_H
#define PANDA_EVENTS_GEN_H

#include "libarkbase/macros.h"
#include "libarkbase/os/mutex.h"
#include "libarkbase/utils/list.h"
#include "runtime/include/mem/panda_string.h"
#include <fstream>
#include <variant>
#include <vector>

namespace ark {

namespace events {

enum class OsrEntryKind {
    AFTER_CFRAME, AFTER_IFRAME, TOP_FRAME
};
enum class OsrEntryResult {
    SUCCESS, ERROR
};
enum class InlineKind {
    STATIC, VIRTUAL, VIRTUAL_CHA, VIRTUAL_MONOMORPHIC, VIRTUAL_POLYMORPHIC, DYNAMIC_MONOMORPHIC, DYNAMIC_POLYMORPHIC
};
enum class InlineResult {
    SUCCESS, FAIL, FAIL_RESOLVE, FAIL_MEGAMORPHIC, UNSUITABLE, NOINLINE, LOST_SINGLE_IMPL, LIMIT, IGNORE_LIMIT, DEVIRTUALIZED, INF_LOOP, SKIP_EXTERNAL
};
enum class DeoptimizationAfter {
    CFRAME, IFRAME, TOP
};
enum class ExceptionType {
    NULL_CHECK, BOUND_CHECK, NEGATIVE_SIZE, NATIVE, THROW, ABSTRACT_METHOD, ARITHMETIC, INSTANTIATION_ERROR, CAST_CHECK, STACK_OVERFLOW, ICCE_METHOD_CONFLICT
};
enum class CompilationStatus {
    COMPILED, FAILED, DROPPED, FAILED_SINGLE_IMPL
};
enum class IntrinsicCompilationResult {
    INLINED, INLINE_FAILED
};
enum class InterpProfilingAction {
    START, STOP
};
enum class MethodEnterKind {
    INTERP, COMPILED, INLINED
};
enum class MethodExitKind {
    INTERP, COMPILED, INLINED
};
enum class AotManagerAction {
    ADDED, OPEN_FAILED, VERIFIED, CHA_VERIFY_FAILED, FILE_VERIFY_FAILED
};
enum class CodegenSimplificationInst {
    CHECKCAST, ISINSTANCE
};
enum class CodegenSimplificationReason {
    FINAL_CLASS, SKIP_NULLCHECK
};

class EventsBase {
public:
    EventsBase() = default;
    virtual ~EventsBase() = default;
    NO_COPY_SEMANTIC(EventsBase);
    NO_MOVE_SEMANTIC(EventsBase);

    virtual void OsrEntry(const std::string&, size_t, OsrEntryKind, OsrEntryResult) {}  // NOLINT
    virtual void Inline(const std::string&, const std::string&, int, InlineKind, InlineResult) {}  // NOLINT
    virtual void Deoptimization(const std::string&, uintptr_t, DeoptimizationAfter) {}  // NOLINT
    virtual void DeoptimizationReason(const std::string&, const std::string&) {}  // NOLINT
    virtual void Exception(const std::string&, size_t, size_t, ExceptionType) {}  // NOLINT
    virtual void Compilation(const std::string&, bool, size_t, uintptr_t, size_t, size_t, CompilationStatus) {}  // NOLINT
    virtual void Paoc(const std::string&) {}  // NOLINT
    virtual void IntrinsicCompilation(const std::string&, IntrinsicCompilationResult) {}  // NOLINT
    virtual void ChaInvalidate(const std::string&, const std::string&) {}  // NOLINT
    virtual void ChaDeoptimize(const std::string&, size_t) {}  // NOLINT
    virtual void InterpProfiling(InterpProfilingAction, PandaString, size_t) {}  // NOLINT
    virtual void MethodEnter(PandaString, MethodEnterKind, int) {}  // NOLINT
    virtual void MethodExit(PandaString, MethodExitKind, int) {}  // NOLINT
    virtual void TlabAlloc(size_t, size_t, size_t, int) {}  // NOLINT
    virtual void SbBufferRealloc(size_t, void*, size_t, size_t, size_t) {}  // NOLINT
    virtual void SlowpathAlloc(size_t) {}  // NOLINT
    virtual void AotResolveString(PandaString) {}  // NOLINT
    virtual void AotLoadedForClass(PandaString, PandaString) {}  // NOLINT
    virtual void AotEntrypointFound(PandaString) {}  // NOLINT
    virtual void JitUseResolvedString(const std::string&, int) {}  // NOLINT
    virtual void ImplicitNullcheck(uintptr_t) {}  // NOLINT
    virtual void AotManager(const std::string&, AotManagerAction) {}  // NOLINT
    virtual void CodegenSimplification(CodegenSimplificationInst, CodegenSimplificationReason) {}  // NOLINT
    virtual void VolatileField(PandaString, const std::string&, const std::string&) {}  // NOLINT
    virtual void EtsCache(const std::string&) {}  // NOLINT
    virtual void Codegen(const std::string&) {}  // NOLINT

    auto& GetLock() {
        return lock_;
    }
private:
    os::memory::Mutex lock_;
};

inline std::ostream& operator<<(std::ostream& os, OsrEntryKind field) {
    switch (field) {
        case OsrEntryKind::AFTER_CFRAME: os << "AFTER_CFRAME"; break;
        case OsrEntryKind::AFTER_IFRAME: os << "AFTER_IFRAME"; break;
        case OsrEntryKind::TOP_FRAME: os << "TOP_FRAME"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, OsrEntryResult field) {
    switch (field) {
        case OsrEntryResult::SUCCESS: os << "SUCCESS"; break;
        case OsrEntryResult::ERROR: os << "ERROR"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, InlineKind field) {
    switch (field) {
        case InlineKind::STATIC: os << "STATIC"; break;
        case InlineKind::VIRTUAL: os << "VIRTUAL"; break;
        case InlineKind::VIRTUAL_CHA: os << "VIRTUAL_CHA"; break;
        case InlineKind::VIRTUAL_MONOMORPHIC: os << "VIRTUAL_MONOMORPHIC"; break;
        case InlineKind::VIRTUAL_POLYMORPHIC: os << "VIRTUAL_POLYMORPHIC"; break;
        case InlineKind::DYNAMIC_MONOMORPHIC: os << "DYNAMIC_MONOMORPHIC"; break;
        case InlineKind::DYNAMIC_POLYMORPHIC: os << "DYNAMIC_POLYMORPHIC"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, InlineResult field) {
    switch (field) {
        case InlineResult::SUCCESS: os << "SUCCESS"; break;
        case InlineResult::FAIL: os << "FAIL"; break;
        case InlineResult::FAIL_RESOLVE: os << "FAIL_RESOLVE"; break;
        case InlineResult::FAIL_MEGAMORPHIC: os << "FAIL_MEGAMORPHIC"; break;
        case InlineResult::UNSUITABLE: os << "UNSUITABLE"; break;
        case InlineResult::NOINLINE: os << "NOINLINE"; break;
        case InlineResult::LOST_SINGLE_IMPL: os << "LOST_SINGLE_IMPL"; break;
        case InlineResult::LIMIT: os << "LIMIT"; break;
        case InlineResult::IGNORE_LIMIT: os << "IGNORE_LIMIT"; break;
        case InlineResult::DEVIRTUALIZED: os << "DEVIRTUALIZED"; break;
        case InlineResult::INF_LOOP: os << "INF_LOOP"; break;
        case InlineResult::SKIP_EXTERNAL: os << "SKIP_EXTERNAL"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, DeoptimizationAfter field) {
    switch (field) {
        case DeoptimizationAfter::CFRAME: os << "CFRAME"; break;
        case DeoptimizationAfter::IFRAME: os << "IFRAME"; break;
        case DeoptimizationAfter::TOP: os << "TOP"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, ExceptionType field) {
    switch (field) {
        case ExceptionType::NULL_CHECK: os << "NULL_CHECK"; break;
        case ExceptionType::BOUND_CHECK: os << "BOUND_CHECK"; break;
        case ExceptionType::NEGATIVE_SIZE: os << "NEGATIVE_SIZE"; break;
        case ExceptionType::NATIVE: os << "NATIVE"; break;
        case ExceptionType::THROW: os << "THROW"; break;
        case ExceptionType::ABSTRACT_METHOD: os << "ABSTRACT_METHOD"; break;
        case ExceptionType::ARITHMETIC: os << "ARITHMETIC"; break;
        case ExceptionType::INSTANTIATION_ERROR: os << "INSTANTIATION_ERROR"; break;
        case ExceptionType::CAST_CHECK: os << "CAST_CHECK"; break;
        case ExceptionType::STACK_OVERFLOW: os << "STACK_OVERFLOW"; break;
        case ExceptionType::ICCE_METHOD_CONFLICT: os << "ICCE_METHOD_CONFLICT"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, CompilationStatus field) {
    switch (field) {
        case CompilationStatus::COMPILED: os << "COMPILED"; break;
        case CompilationStatus::FAILED: os << "FAILED"; break;
        case CompilationStatus::DROPPED: os << "DROPPED"; break;
        case CompilationStatus::FAILED_SINGLE_IMPL: os << "FAILED_SINGLE_IMPL"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, IntrinsicCompilationResult field) {
    switch (field) {
        case IntrinsicCompilationResult::INLINED: os << "INLINED"; break;
        case IntrinsicCompilationResult::INLINE_FAILED: os << "INLINE_FAILED"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, InterpProfilingAction field) {
    switch (field) {
        case InterpProfilingAction::START: os << "START"; break;
        case InterpProfilingAction::STOP: os << "STOP"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, MethodEnterKind field) {
    switch (field) {
        case MethodEnterKind::INTERP: os << "INTERP"; break;
        case MethodEnterKind::COMPILED: os << "COMPILED"; break;
        case MethodEnterKind::INLINED: os << "INLINED"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, MethodExitKind field) {
    switch (field) {
        case MethodExitKind::INTERP: os << "INTERP"; break;
        case MethodExitKind::COMPILED: os << "COMPILED"; break;
        case MethodExitKind::INLINED: os << "INLINED"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, AotManagerAction field) {
    switch (field) {
        case AotManagerAction::ADDED: os << "ADDED"; break;
        case AotManagerAction::OPEN_FAILED: os << "OPEN_FAILED"; break;
        case AotManagerAction::VERIFIED: os << "VERIFIED"; break;
        case AotManagerAction::CHA_VERIFY_FAILED: os << "CHA_VERIFY_FAILED"; break;
        case AotManagerAction::FILE_VERIFY_FAILED: os << "FILE_VERIFY_FAILED"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, CodegenSimplificationInst field) {
    switch (field) {
        case CodegenSimplificationInst::CHECKCAST: os << "CHECKCAST"; break;
        case CodegenSimplificationInst::ISINSTANCE: os << "ISINSTANCE"; break;
    }
    return os;
}
inline std::ostream& operator<<(std::ostream& os, CodegenSimplificationReason field) {
    switch (field) {
        case CodegenSimplificationReason::FINAL_CLASS: os << "FINAL_CLASS"; break;
        case CodegenSimplificationReason::SKIP_NULLCHECK: os << "SKIP_NULLCHECK"; break;
    }
    return os;
}

class EventsMemory : public events::EventsBase {

public:
    struct OsrEntryEvent{
        std::string methodName;
        size_t bcOffset;
        OsrEntryKind kind;
        OsrEntryResult result;
    };
    struct InlineEvent{
        std::string caller;
        std::string callee;
        int callInstId;
        InlineKind kind;
        InlineResult result;
    };
    struct DeoptimizationEvent{
        std::string methodName;
        uintptr_t pc;
        DeoptimizationAfter after;
    };
    struct DeoptimizationReasonEvent{
        std::string methodName;
        std::string reason;
    };
    struct ExceptionEvent{
        std::string methodName;
        size_t pc;
        size_t npc;
        ExceptionType type;
    };
    struct CompilationEvent{
        std::string methodName;
        bool isOsr;
        size_t bcSize;
        uintptr_t address;
        size_t codeSize;
        size_t infoSize;
        CompilationStatus status;
    };
    struct PaocEvent{
        std::string description;
    };
    struct IntrinsicCompilationEvent{
        std::string name;
        IntrinsicCompilationResult result;
    };
    struct ChaInvalidateEvent{
        std::string method;
        std::string loadedClass;
    };
    struct ChaDeoptimizeEvent{
        std::string method;
        size_t inStackCount;
    };
    struct InterpProfilingEvent{
        InterpProfilingAction action;
        PandaString method;
        size_t vcallsNum;
    };
    struct MethodEnterEvent{
        PandaString method;
        MethodEnterKind kind;
        int depth;
    };
    struct MethodExitEvent{
        PandaString method;
        MethodExitKind kind;
        int depth;
    };
    struct TlabAllocEvent{
        size_t threadId;
        size_t tlab;
        size_t allocateMemory;
        int size;
    };
    struct SbBufferReallocEvent{
        size_t threadId;
        void* buffer;
        size_t length;
        size_t elemSize;
        size_t objSize;
    };
    struct SlowpathAllocEvent{
        size_t threadId;
    };
    struct AotResolveStringEvent{
        PandaString value;
    };
    struct AotLoadedForClassEvent{
        PandaString filename;
        PandaString classname;
    };
    struct AotEntrypointFoundEvent{
        PandaString methodname;
    };
    struct JitUseResolvedStringEvent{
        std::string methodName;
        int stringId;
    };
    struct ImplicitNullcheckEvent{
        uintptr_t pc;
    };
    struct AotManagerEvent{
        std::string aotFile;
        AotManagerAction action;
    };
    struct CodegenSimplificationEvent{
        CodegenSimplificationInst inst;
        CodegenSimplificationReason reason;
    };
    struct VolatileFieldEvent{
        PandaString methodName;
        std::string className;
        std::string fieldName;
    };
    struct EtsCacheEvent{
        std::string message;
    };
    struct CodegenEvent{
        std::string message;
    };

    // NOLINTNEXTLINE(fuchsia-multiple-inheritance)
    struct EventRecord : public ListNode, public std::variant<OsrEntryEvent, InlineEvent, DeoptimizationEvent, DeoptimizationReasonEvent, ExceptionEvent, CompilationEvent, PaocEvent, IntrinsicCompilationEvent, ChaInvalidateEvent, ChaDeoptimizeEvent, InterpProfilingEvent, MethodEnterEvent, MethodExitEvent, TlabAllocEvent, SbBufferReallocEvent, SlowpathAllocEvent, AotResolveStringEvent, AotLoadedForClassEvent, AotEntrypointFoundEvent, JitUseResolvedStringEvent, ImplicitNullcheckEvent, AotManagerEvent, CodegenSimplificationEvent, VolatileFieldEvent, EtsCacheEvent, CodegenEvent> {
        using VariantBase = std::variant<OsrEntryEvent, InlineEvent, DeoptimizationEvent, DeoptimizationReasonEvent, ExceptionEvent, CompilationEvent, PaocEvent, IntrinsicCompilationEvent, ChaInvalidateEvent, ChaDeoptimizeEvent, InterpProfilingEvent, MethodEnterEvent, MethodExitEvent, TlabAllocEvent, SbBufferReallocEvent, SlowpathAllocEvent, AotResolveStringEvent, AotLoadedForClassEvent, AotEntrypointFoundEvent, JitUseResolvedStringEvent, ImplicitNullcheckEvent, AotManagerEvent, CodegenSimplificationEvent, VolatileFieldEvent, EtsCacheEvent, CodegenEvent>;
        explicit EventRecord(OsrEntryEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(InlineEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(DeoptimizationEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(DeoptimizationReasonEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(ExceptionEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(CompilationEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(PaocEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(IntrinsicCompilationEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(ChaInvalidateEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(ChaDeoptimizeEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(InterpProfilingEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(MethodEnterEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(MethodExitEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(TlabAllocEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(SbBufferReallocEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(SlowpathAllocEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(AotResolveStringEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(AotLoadedForClassEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(AotEntrypointFoundEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(JitUseResolvedStringEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(ImplicitNullcheckEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(AotManagerEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(CodegenSimplificationEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(VolatileFieldEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(EtsCacheEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
        explicit EventRecord(CodegenEvent v) : VariantBase(v) {} // NOLINT(bugprone-throw-keyword-missing)
    };

public:
    EventsMemory() = default;
    ~EventsMemory() override {
        os::memory::LockHolder lock(GetLock());
        for (auto it = eventList_.begin(); it != eventList_.end(); ) {
            delete &*(it++);
        }
    }
    NO_COPY_SEMANTIC(EventsMemory);
    NO_MOVE_SEMANTIC(EventsMemory);

    void OsrEntry(const std::string& methodName, size_t bcOffset, OsrEntryKind kind, OsrEntryResult result) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(OsrEntryEvent{methodName, bcOffset, kind, result});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void Inline(const std::string& caller, const std::string& callee, int callInstId, InlineKind kind, InlineResult result) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(InlineEvent{caller, callee, callInstId, kind, result});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void Deoptimization(const std::string& methodName, uintptr_t pc, DeoptimizationAfter after) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(DeoptimizationEvent{methodName, pc, after});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void DeoptimizationReason(const std::string& methodName, const std::string& reason) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(DeoptimizationReasonEvent{methodName, reason});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void Exception(const std::string& methodName, size_t pc, size_t npc, ExceptionType type) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(ExceptionEvent{methodName, pc, npc, type});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void Compilation(const std::string& methodName, bool isOsr, size_t bcSize, uintptr_t address, size_t codeSize, size_t infoSize, CompilationStatus status) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(CompilationEvent{methodName, isOsr, bcSize, address, codeSize, infoSize, status});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void Paoc(const std::string& description) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(PaocEvent{description});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void IntrinsicCompilation(const std::string& name, IntrinsicCompilationResult result) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(IntrinsicCompilationEvent{name, result});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void ChaInvalidate(const std::string& method, const std::string& loadedClass) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(ChaInvalidateEvent{method, loadedClass});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void ChaDeoptimize(const std::string& method, size_t inStackCount) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(ChaDeoptimizeEvent{method, inStackCount});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void InterpProfiling(InterpProfilingAction action, PandaString method, size_t vcallsNum) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(InterpProfilingEvent{action, method, vcallsNum});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void MethodEnter(PandaString method, MethodEnterKind kind, int depth) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(MethodEnterEvent{method, kind, depth});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void MethodExit(PandaString method, MethodExitKind kind, int depth) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(MethodExitEvent{method, kind, depth});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void TlabAlloc(size_t threadId, size_t tlab, size_t allocateMemory, int size) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(TlabAllocEvent{threadId, tlab, allocateMemory, size});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void SbBufferRealloc(size_t threadId, void* buffer, size_t length, size_t elemSize, size_t objSize) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(SbBufferReallocEvent{threadId, buffer, length, elemSize, objSize});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void SlowpathAlloc(size_t threadId) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(SlowpathAllocEvent{threadId});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void AotResolveString(PandaString value) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(AotResolveStringEvent{value});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void AotLoadedForClass(PandaString filename, PandaString classname) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(AotLoadedForClassEvent{filename, classname});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void AotEntrypointFound(PandaString methodname) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(AotEntrypointFoundEvent{methodname});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void JitUseResolvedString(const std::string& methodName, int stringId) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(JitUseResolvedStringEvent{methodName, stringId});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void ImplicitNullcheck(uintptr_t pc) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(ImplicitNullcheckEvent{pc});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void AotManager(const std::string& aotFile, AotManagerAction action) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(AotManagerEvent{aotFile, action});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void CodegenSimplification(CodegenSimplificationInst inst, CodegenSimplificationReason reason) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(CodegenSimplificationEvent{inst, reason});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void VolatileField(PandaString methodName, const std::string& className, const std::string& fieldName) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(VolatileFieldEvent{methodName, className, fieldName});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void EtsCache(const std::string& message) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(EtsCacheEvent{message});
        last_ = eventList_.InsertAfter(last_, *event);
    }
    void Codegen(const std::string& message) override {
        os::memory::LockHolder lock(GetLock());
        auto event = new EventRecord(CodegenEvent{message});
        last_ = eventList_.InsertAfter(last_, *event);
    }

    template<typename EventT, typename Func>
    void EnumerateEvents(Func func) {
        os::memory::LockHolder lock(GetLock());
        for (const auto& event : eventList_) {
            if(auto p = std::get_if<EventT>(&event)) {
                func(static_cast<const EventT&>(*p));
            }
        }
    }

    template<typename EventT, typename Comp>
    bool Find(Comp cmp) {
        bool found = false;
        EnumerateEvents<EventT>([&found, &cmp](const auto& event) {
          if (cmp(event)) {
              found = true;
              return false;
          }
          return true;
        });
        return found;
    }

    template<typename EventT, typename F = bool>
    std::vector<const EventT*> Select([[maybe_unused]] F pred = false) {
        std::vector<const EventT*> res;
        if constexpr (std::is_same_v<F, bool>) {
            EnumerateEvents<EventT>([&res](const auto& event) { res.push_back(&event); });
        } else {
            EnumerateEvents<EventT>([&pred, &res](const auto& event) {
              if (pred(&event)) {
                  res.push_back(&event);
              }
            });
        }
        return res;
    }

private:
    List<EventRecord> eventList_ GUARDED_BY(GetLock());
    List<EventRecord>::Iterator last_{eventList_.before_begin()};
};

class EventsCsv : public events::EventsBase {
public:
    EventsCsv() {
        file_.open("events.csv");
    }
    explicit EventsCsv(std::string_view path) {
        file_.open(path.data());
    }
    ~EventsCsv() override {
        os::memory::LockHolder lock(GetLock());
        file_.close();
    }
    NO_COPY_SEMANTIC(EventsCsv);
    NO_MOVE_SEMANTIC(EventsCsv);

    void OsrEntry(const std::string& methodName, size_t bcOffset, OsrEntryKind kind, OsrEntryResult result) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "OsrEntry," << methodName << ',' << bcOffset << ',' << kind << ',' << result << std::endl;
    }
    void Inline(const std::string& caller, const std::string& callee, int callInstId, InlineKind kind, InlineResult result) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "Inline," << caller << ',' << callee << ',' << callInstId << ',' << kind << ',' << result << std::endl;
    }
    void Deoptimization(const std::string& methodName, uintptr_t pc, DeoptimizationAfter after) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "Deoptimization," << methodName << ',' << pc << ',' << after << std::endl;
    }
    void DeoptimizationReason(const std::string& methodName, const std::string& reason) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "DeoptimizationReason," << methodName << ',' << reason << std::endl;
    }
    void Exception(const std::string& methodName, size_t pc, size_t npc, ExceptionType type) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "Exception," << methodName << ',' << pc << ',' << npc << ',' << type << std::endl;
    }
    void Compilation(const std::string& methodName, bool isOsr, size_t bcSize, uintptr_t address, size_t codeSize, size_t infoSize, CompilationStatus status) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "Compilation," << methodName << ',' << isOsr << ',' << bcSize << ',' << address << ',' << codeSize << ',' << infoSize << ',' << status << std::endl;
    }
    void Paoc(const std::string& description) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "Paoc," << description << std::endl;
    }
    void IntrinsicCompilation(const std::string& name, IntrinsicCompilationResult result) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "IntrinsicCompilation," << name << ',' << result << std::endl;
    }
    void ChaInvalidate(const std::string& method, const std::string& loadedClass) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "ChaInvalidate," << method << ',' << loadedClass << std::endl;
    }
    void ChaDeoptimize(const std::string& method, size_t inStackCount) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "ChaDeoptimize," << method << ',' << inStackCount << std::endl;
    }
    void InterpProfiling(InterpProfilingAction action, PandaString method, size_t vcallsNum) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "InterpProfiling," << action << ',' << method << ',' << vcallsNum << std::endl;
    }
    void MethodEnter(PandaString method, MethodEnterKind kind, int depth) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "MethodEnter," << method << ',' << kind << ',' << depth << std::endl;
    }
    void MethodExit(PandaString method, MethodExitKind kind, int depth) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "MethodExit," << method << ',' << kind << ',' << depth << std::endl;
    }
    void TlabAlloc(size_t threadId, size_t tlab, size_t allocateMemory, int size) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "TlabAlloc," << threadId << ',' << tlab << ',' << allocateMemory << ',' << size << std::endl;
    }
    void SbBufferRealloc(size_t threadId, void* buffer, size_t length, size_t elemSize, size_t objSize) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "SbBufferRealloc," << threadId << ',' << buffer << ',' << length << ',' << elemSize << ',' << objSize << std::endl;
    }
    void SlowpathAlloc(size_t threadId) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "SlowpathAlloc," << threadId << std::endl;
    }
    void AotResolveString(PandaString value) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "AotResolveString," << value << std::endl;
    }
    void AotLoadedForClass(PandaString filename, PandaString classname) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "AotLoadedForClass," << filename << ',' << classname << std::endl;
    }
    void AotEntrypointFound(PandaString methodname) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "AotEntrypointFound," << methodname << std::endl;
    }
    void JitUseResolvedString(const std::string& methodName, int stringId) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "JitUseResolvedString," << methodName << ',' << stringId << std::endl;
    }
    void ImplicitNullcheck(uintptr_t pc) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "ImplicitNullcheck," << pc << std::endl;
    }
    void AotManager(const std::string& aotFile, AotManagerAction action) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "AotManager," << aotFile << ',' << action << std::endl;
    }
    void CodegenSimplification(CodegenSimplificationInst inst, CodegenSimplificationReason reason) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "CodegenSimplification," << inst << ',' << reason << std::endl;
    }
    void VolatileField(PandaString methodName, const std::string& className, const std::string& fieldName) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "VolatileField," << methodName << ',' << className << ',' << fieldName << std::endl;
    }
    void EtsCache(const std::string& message) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "EtsCache," << message << std::endl;
    }
    void Codegen(const std::string& message) override {
        os::memory::LockHolder lock(GetLock());
        file_ << "Codegen," << message << std::endl;
    }

private:
    std::ofstream file_ GUARDED_BY(GetLock());
};

class EventsLog : public events::EventsBase {
public:
    EventsLog() {
        Logger::EnableComponent(Logger::EVENTS);
    }
    ~EventsLog() override {
        Logger::DisableComponent(Logger::EVENTS);
    }
    NO_COPY_SEMANTIC(EventsLog);
    NO_MOVE_SEMANTIC(EventsLog);

    void OsrEntry(const std::string& methodName, size_t bcOffset, OsrEntryKind kind, OsrEntryResult result) override {
        LOG(INFO, EVENTS) << "OsrEntry," << methodName << ',' << bcOffset << ',' << kind << ',' << result;
    }
    void Inline(const std::string& caller, const std::string& callee, int callInstId, InlineKind kind, InlineResult result) override {
        LOG(INFO, EVENTS) << "Inline," << caller << ',' << callee << ',' << callInstId << ',' << kind << ',' << result;
    }
    void Deoptimization(const std::string& methodName, uintptr_t pc, DeoptimizationAfter after) override {
        LOG(INFO, EVENTS) << "Deoptimization," << methodName << ',' << pc << ',' << after;
    }
    void DeoptimizationReason(const std::string& methodName, const std::string& reason) override {
        LOG(INFO, EVENTS) << "DeoptimizationReason," << methodName << ',' << reason;
    }
    void Exception(const std::string& methodName, size_t pc, size_t npc, ExceptionType type) override {
        LOG(INFO, EVENTS) << "Exception," << methodName << ',' << pc << ',' << npc << ',' << type;
    }
    void Compilation(const std::string& methodName, bool isOsr, size_t bcSize, uintptr_t address, size_t codeSize, size_t infoSize, CompilationStatus status) override {
        LOG(INFO, EVENTS) << "Compilation," << methodName << ',' << isOsr << ',' << bcSize << ',' << address << ',' << codeSize << ',' << infoSize << ',' << status;
    }
    void Paoc(const std::string& description) override {
        LOG(INFO, EVENTS) << "Paoc," << description;
    }
    void IntrinsicCompilation(const std::string& name, IntrinsicCompilationResult result) override {
        LOG(INFO, EVENTS) << "IntrinsicCompilation," << name << ',' << result;
    }
    void ChaInvalidate(const std::string& method, const std::string& loadedClass) override {
        LOG(INFO, EVENTS) << "ChaInvalidate," << method << ',' << loadedClass;
    }
    void ChaDeoptimize(const std::string& method, size_t inStackCount) override {
        LOG(INFO, EVENTS) << "ChaDeoptimize," << method << ',' << inStackCount;
    }
    void InterpProfiling(InterpProfilingAction action, PandaString method, size_t vcallsNum) override {
        LOG(INFO, EVENTS) << "InterpProfiling," << action << ',' << method << ',' << vcallsNum;
    }
    void MethodEnter(PandaString method, MethodEnterKind kind, int depth) override {
        LOG(INFO, EVENTS) << "MethodEnter," << method << ',' << kind << ',' << depth;
    }
    void MethodExit(PandaString method, MethodExitKind kind, int depth) override {
        LOG(INFO, EVENTS) << "MethodExit," << method << ',' << kind << ',' << depth;
    }
    void TlabAlloc(size_t threadId, size_t tlab, size_t allocateMemory, int size) override {
        LOG(INFO, EVENTS) << "TlabAlloc," << threadId << ',' << tlab << ',' << allocateMemory << ',' << size;
    }
    void SbBufferRealloc(size_t threadId, void* buffer, size_t length, size_t elemSize, size_t objSize) override {
        LOG(INFO, EVENTS) << "SbBufferRealloc," << threadId << ',' << buffer << ',' << length << ',' << elemSize << ',' << objSize;
    }
    void SlowpathAlloc(size_t threadId) override {
        LOG(INFO, EVENTS) << "SlowpathAlloc," << threadId;
    }
    void AotResolveString(PandaString value) override {
        LOG(INFO, EVENTS) << "AotResolveString," << value;
    }
    void AotLoadedForClass(PandaString filename, PandaString classname) override {
        LOG(INFO, EVENTS) << "AotLoadedForClass," << filename << ',' << classname;
    }
    void AotEntrypointFound(PandaString methodname) override {
        LOG(INFO, EVENTS) << "AotEntrypointFound," << methodname;
    }
    void JitUseResolvedString(const std::string& methodName, int stringId) override {
        LOG(INFO, EVENTS) << "JitUseResolvedString," << methodName << ',' << stringId;
    }
    void ImplicitNullcheck(uintptr_t pc) override {
        LOG(INFO, EVENTS) << "ImplicitNullcheck," << pc;
    }
    void AotManager(const std::string& aotFile, AotManagerAction action) override {
        LOG(INFO, EVENTS) << "AotManager," << aotFile << ',' << action;
    }
    void CodegenSimplification(CodegenSimplificationInst inst, CodegenSimplificationReason reason) override {
        LOG(INFO, EVENTS) << "CodegenSimplification," << inst << ',' << reason;
    }
    void VolatileField(PandaString methodName, const std::string& className, const std::string& fieldName) override {
        LOG(INFO, EVENTS) << "VolatileField," << methodName << ',' << className << ',' << fieldName;
    }
    void EtsCache(const std::string& message) override {
        LOG(INFO, EVENTS) << "EtsCache," << message;
    }
    void Codegen(const std::string& message) override {
        LOG(INFO, EVENTS) << "Codegen," << message;
    }
};

}  // namespace events

class PANDA_PUBLIC_API Events {
public:
    enum StreamKind { CSV, MEMORY, LOG };

    template<StreamKind KIND, typename... Args>
    static void Create(Args&&... args) {
        if constexpr (KIND == StreamKind::CSV) {  // NOLINT
            pevents_ = new events::EventsCsv(std::forward<Args>(args)...);
        } else if constexpr (KIND == StreamKind::MEMORY) {  // NOLINT
            pevents_ = new events::EventsMemory;
        } else if constexpr (KIND == StreamKind::LOG) {  // NOLINT
            pevents_ = new events::EventsLog;
        } else {  // NOLINT
            UNREACHABLE();
        }
    }

    template<typename... Args>
    static void Create(std::string_view output, Args&&... args) {
        if (output == "csv") {
            pevents_ = new events::EventsCsv(std::forward<Args>(args)...);
        } else if (output == "memory") {
            pevents_ = new events::EventsMemory;
        } else if (output == "log") {
            pevents_ = new events::EventsLog;
        } else {  // NOLINT
            UNREACHABLE();
        }
    }

    static void Destroy() {
        delete pevents_;
        pevents_ = nullptr;
    }

    template<StreamKind KIND>
    static auto CastTo() {
        if constexpr (KIND == StreamKind::CSV) {  // NOLINT
            return static_cast<events::EventsCsv*>(pevents_);
        } else if constexpr (KIND == StreamKind::MEMORY) {  // NOLINT
            return static_cast<events::EventsMemory*>(pevents_);
        } else {  // NOLINT
            UNREACHABLE();
        }
    }

    static bool IsEnabled() {
        return pevents_ != nullptr;
    }

    static events::EventsBase* GetEvents() {
        return pevents_;
    }

private:
    static inline events::EventsBase* pevents_{nullptr};
};

#ifndef NDEBUG

#define PANDA_EVENTS_ENABLED

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_OSR_ENTRY_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_OSR_ENTRY(method_name, bc_offset, kind, result)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->OsrEntry(method_name, bc_offset, kind, result); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INLINE_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INLINE(caller, callee, call_inst_id, kind, result)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->Inline(caller, callee, call_inst_id, kind, result); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_DEOPTIMIZATION_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_DEOPTIMIZATION(method_name, pc, after)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->Deoptimization(method_name, pc, after); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_DEOPTIMIZATION_REASON_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_DEOPTIMIZATION_REASON(method_name, reason)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->DeoptimizationReason(method_name, reason); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_EXCEPTION_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_EXCEPTION(method_name, pc, npc, type)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->Exception(method_name, pc, npc, type); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_COMPILATION_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_COMPILATION(method_name, is_osr, bc_size, address, code_size, info_size, status)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->Compilation(method_name, is_osr, bc_size, address, code_size, info_size, status); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_PAOC_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_PAOC(description)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->Paoc(description); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INTRINSIC_COMPILATION_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INTRINSIC_COMPILATION(name, result)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->IntrinsicCompilation(name, result); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CHA_INVALIDATE_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CHA_INVALIDATE(method, loaded_class)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->ChaInvalidate(method, loaded_class); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CHA_DEOPTIMIZE_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CHA_DEOPTIMIZE(method, in_stack_count)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->ChaDeoptimize(method, in_stack_count); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INTERP_PROFILING_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INTERP_PROFILING(action, method, vcalls_num)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->InterpProfiling(action, method, vcalls_num); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_METHOD_ENTER_ENABLED 0
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_METHOD_ENTER(method, kind, depth)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_METHOD_EXIT_ENABLED 0
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_METHOD_EXIT(method, kind, depth)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_TLAB_ALLOC_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_TLAB_ALLOC(thread_id, tlab, allocate_memory, size)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->TlabAlloc(thread_id, tlab, allocate_memory, size); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_SB_BUFFER_REALLOC_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_SB_BUFFER_REALLOC(thread_id, buffer, length, elem_size, obj_size)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->SbBufferRealloc(thread_id, buffer, length, elem_size, obj_size); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_SLOWPATH_ALLOC_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_SLOWPATH_ALLOC(thread_id)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->SlowpathAlloc(thread_id); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_RESOLVE_STRING_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_RESOLVE_STRING(value)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->AotResolveString(value); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_LOADED_FOR_CLASS_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_LOADED_FOR_CLASS(filename, classname)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->AotLoadedForClass(filename, classname); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_ENTRYPOINT_FOUND_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_ENTRYPOINT_FOUND(methodname)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->AotEntrypointFound(methodname); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_JIT_USE_RESOLVED_STRING_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_JIT_USE_RESOLVED_STRING(method_name, string_id)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->JitUseResolvedString(method_name, string_id); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_IMPLICIT_NULLCHECK_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_IMPLICIT_NULLCHECK(pc)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->ImplicitNullcheck(pc); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_MANAGER_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_MANAGER(aot_file, action)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->AotManager(aot_file, action); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CODEGEN_SIMPLIFICATION_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CODEGEN_SIMPLIFICATION(inst, reason)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->CodegenSimplification(inst, reason); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_VOLATILE_FIELD_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_VOLATILE_FIELD(method_name, class_name, field_name)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->VolatileField(method_name, class_name, field_name); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_ETS_CACHE_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_ETS_CACHE(message)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->EtsCache(message); \
    }
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CODEGEN_ENABLED 1
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CODEGEN(message)      \
    if (Events::IsEnabled()) {                                                          \
        Events::GetEvents()->Codegen(message); \
    }
#else
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_OSR_ENTRY(method_name, bc_offset, kind, result)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INLINE(caller, callee, call_inst_id, kind, result)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_DEOPTIMIZATION(method_name, pc, after)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_DEOPTIMIZATION_REASON(method_name, reason)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_EXCEPTION(method_name, pc, npc, type)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_COMPILATION(method_name, is_osr, bc_size, address, code_size, info_size, status)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_PAOC(description)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INTRINSIC_COMPILATION(name, result)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CHA_INVALIDATE(method, loaded_class)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CHA_DEOPTIMIZE(method, in_stack_count)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_INTERP_PROFILING(action, method, vcalls_num)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_METHOD_ENTER(method, kind, depth)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_METHOD_EXIT(method, kind, depth)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_TLAB_ALLOC(thread_id, tlab, allocate_memory, size)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_SB_BUFFER_REALLOC(thread_id, buffer, length, elem_size, obj_size)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_SLOWPATH_ALLOC(thread_id)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_RESOLVE_STRING(value)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_LOADED_FOR_CLASS(filename, classname)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_ENTRYPOINT_FOUND(methodname)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_JIT_USE_RESOLVED_STRING(method_name, string_id)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_IMPLICIT_NULLCHECK(pc)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_AOT_MANAGER(aot_file, action)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CODEGEN_SIMPLIFICATION(inst, reason)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_VOLATILE_FIELD(method_name, class_name, field_name)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_ETS_CACHE(message)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define EVENT_CODEGEN(message)
#endif

}  // namespace ark

#endif  // PANDA_EVENTS_GEN_H
