1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_COMPILER_PROFILER_STUB_BUILDER_H
17#define ECMASCRIPT_COMPILER_PROFILER_STUB_BUILDER_H
18
19#include "ecmascript/compiler/profiler_operation.h"
20#include "ecmascript/compiler/stub_builder.h"
21
22namespace panda::ecmascript::kungfu {
23class SlotIDInfo {
24public:
25    enum class SlotIDInfoType : uint8_t {
26        PC,
27        SLOT_ID,
28        PC_FORMAT,
29    };
30
31    SlotIDInfo(GateRef info, SlotIDInfoType slotType) : slotType_(slotType)
32    {
33        ASSERT(slotType != SlotIDInfoType::PC_FORMAT);
34        if (slotType == SlotIDInfoType::PC) {
35            pc_ = info;
36        } else {
37            ASSERT(slotType == SlotIDInfoType::SLOT_ID);
38            slotID_ = info;
39        }
40    }
41
42    SlotIDInfo(GateRef pc, SlotIDFormat format)
43        : slotType_(SlotIDInfoType::PC_FORMAT), pc_(pc), format_(format) {}
44
45    ~SlotIDInfo() = default;
46
47    GateRef GetSlotID() const
48    {
49        return slotID_;
50    }
51
52    SlotIDInfoType GetSlotType() const
53    {
54        return slotType_;
55    }
56
57    GateRef GetPC() const
58    {
59        return pc_;
60    }
61
62    SlotIDFormat GetFormat() const
63    {
64        return format_;
65    }
66
67private:
68    SlotIDInfoType slotType_;
69    GateRef slotID_ = 0;
70    GateRef pc_ = 0;
71    SlotIDFormat format_ = SlotIDFormat::IMM16;
72};
73
74struct OffsetInfo {
75    GateRef offset = 0;
76    GateRef pc = 0;
77    bool isPc = true;
78};
79
80class ProfilerStubBuilder : public StubBuilder {
81public:
82    explicit ProfilerStubBuilder(StubBuilder *parent) : StubBuilder(parent) {}
83    explicit ProfilerStubBuilder(Environment *env) : StubBuilder(env) {}
84    ~ProfilerStubBuilder() override = default;
85    NO_MOVE_SEMANTIC(ProfilerStubBuilder);
86    NO_COPY_SEMANTIC(ProfilerStubBuilder);
87    void GenerateCircuit() override {}
88
89    // used for interpreter builtin
90    void PGOProfiler(GateRef glue, GateRef pc, GateRef func, GateRef profileTypeInfo,
91        const std::vector<GateRef> &values, SlotIDFormat format, OperationType type);
92    // used for baseline builtin
93    void PGOProfiler(GateRef glue, GateRef func, GateRef profileTypeInfo, GateRef slotIdOrOffset,
94        const std::vector<GateRef> &values, OperationType type);
95
96    void TryDump(GateRef glue, GateRef func, GateRef profileTypeInfo);
97    void TryPreDump(GateRef glue, GateRef func, GateRef profileTypeInfo);
98
99    void ProfileCall(
100        GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef target, GateRef profileTypeInfo);
101    void ProfileNativeCall(
102        GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef target, GateRef profileTypeInfo);
103    void ProfileGetterSetterCall(GateRef glue, GateRef target);
104    void ProfileOpType(
105        GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef profileTypeInfo, GateRef type);
106    void ProfileDefineClass(
107        GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef constructor, GateRef profileTypeInfo);
108    void ProfileCreateObject(
109        GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef newObj, GateRef profileTypeInfo);
110    void ProfileBranch(GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef profileTypeInfo, bool isTrue);
111    void ProfileGetIterator(
112        GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef iterator, GateRef profileTypeInfo);
113
114    GateRef UpdateTrackTypeInPropAttr(GateRef attr, GateRef value, ProfileOperation callback);
115    void UpdatePropAttrIC(GateRef glue, GateRef receiver, GateRef value, GateRef handler, ProfileOperation callback);
116    void UpdatePropAttrWithValue(
117        GateRef glue, GateRef receiver, GateRef attr, GateRef value, ProfileOperation callback);
118
119    GateRef IsProfileTypeInfoDumped(GateRef profileTypeInfo, ProfileOperation callback);
120
121    void TryJitCompile(GateRef glue, OffsetInfo opCodeInfo, GateRef func, GateRef profileTypeInfo);
122    GateRef IsCompiledOrTryCompile(GateRef glue, GateRef func, GateRef profileTypeInfo, ProfileOperation callback);
123    GateRef IsCompiledOrTryCompile(GateRef glue, GateRef func, GateRef profileTypeInfo);
124    GateRef GetJitHotnessThreshold(GateRef profileTypeInfo);
125    void SetJitHotnessCnt(GateRef glue, GateRef profileTypeInfo, GateRef hotnessCnt);
126
127private:
128    static constexpr size_t MAX_PROFILE_CALL_COUNT = 10000;
129    static constexpr size_t MIN_PROFILE_CALL_INTERVAL = 5;
130    static constexpr size_t BITS_OF_WORD = 8;
131    static constexpr size_t HIGH_WORD_OFFSET = 2;
132    static constexpr size_t LOW_WORD_OFFSET = 1;
133
134    void TryPreDumpInner(GateRef glue, GateRef func, GateRef profileTypeInfo);
135
136    GateRef GetSlotID(const SlotIDInfo &slotInfo);
137    GateRef GetBitFieldOffsetFromProfileTypeInfo(GateRef profileTypeInfo);
138    GateRef IsProfileTypeInfoDumped(GateRef profileTypeInfo);
139    GateRef IsProfileTypeInfoPreDumped(GateRef profileTypeInfo);
140    GateRef IsProfileTypeInfoWithBigMethod(GateRef profileTypeInfo);
141    GateRef IsProfileTypeInfoHotAndValid(GateRef profileTypeInfo);
142    GateRef IsEnableForceIC(GateRef glue);
143    void SetDumpPeriodIndex(GateRef glue, GateRef profileTypeInfo);
144    void SetPreDumpPeriodIndex(GateRef glue, GateRef profileTypeInfo);
145    GateRef TaggedToTrackType(GateRef value);
146    GateRef GetIterationFunctionId(GateRef glue, GateRef iterator);
147    GateRef TryGetBuiltinFunctionId(GateRef target);
148    GateRef GetJitHotnessCnt(GateRef profileTypeInfo);
149    GateRef GetJitHotnessThresholdOffset(GateRef profileTypeInfo);
150    GateRef GetJitHotnessCntOffset(GateRef profileTypeInfo);
151    GateRef GetJitCallThresholdOffset(GateRef profileTypeInfo);
152    GateRef GetJitCallThreshold(GateRef profileTypeInfo);
153    GateRef GetJitCallCntOffset(GateRef profileTypeInfo);
154    GateRef GetJitCallCnt(GateRef profileTypeInfo);
155    GateRef GetOsrHotnessThresholdOffset(GateRef profileTypeInfo);
156    GateRef GetOsrHotnessThreshold(GateRef profileTypeInfo);
157    GateRef GetBaselineJitHotnessThresholdOffset(GateRef profileTypeInfo);
158    GateRef GetBaselineJitHotnessThreshold(GateRef profileTypeInfo);
159    GateRef GetOsrHotnessCntOffset(GateRef profileTypeInfo);
160    GateRef GetOsrHotnessCnt(GateRef profileTypeInfo);
161    void PGOProfiler(GateRef glue, GateRef func, GateRef profileTypeInfo, SlotIDInfo slotIdInfo,
162        const std::vector<GateRef> &values, OperationType type);
163};
164} // namespace panda::ecmascript::kungfu
165#endif // ECMASCRIPT_COMPILER_PROFILER_STUB_BUILDER_H
166