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_DFX_VMSTAT_FCUNTION_CALL_TIMER_H
17#define ECMASCRIPT_DFX_VMSTAT_FCUNTION_CALL_TIMER_H
18
19#include "ecmascript/dfx/vmstat/caller_stat.h"
20#include "ecmascript/mem/c_containers.h"
21#include "ecmascript/mem/c_string.h"
22#include "ecmascript/method.h"
23
24namespace panda::ecmascript {
25class EcmaVM;
26
27// Description:
28// FunctionCallTimer is a tool used to count the number of calls, maximum time, total time, and average time of JS&TS
29// functions in an application or use case.
30
31// Use:
32// If you want to use FunctionCallTimer, open the ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER macro.
33
34// Implementation:
35// In AOT, StartCallTimer and EndCallTimer are inserted before and after the function call and generator reentry into
36// aot. In ASM interpreter, StartCallTimer is inserted into JSCallDispatch and Resumegenerator instruction. EndCallTimer
37// is inserted into the Return, ReturnUndefined and suspend related instruction.
38// It should be particularly pointed out that native functions are not counted separately at present considering
39// the performance overhead during statistics.
40// The specific calculation method is given in the following example.
41
42// T1(StartCallTimer)
43// foo() {
44//     T2(StartCallTimer)
45//     bar();
46//     T3(EndCallTimer)
47// }
48// T4(EndCallTimer)
49
50// bar's self time is (T3 - T2).
51// foo's self time is (T2 - T1) + (T4 - T3).
52
53class FunctionCallStat : public PandaRuntimeCallerStat {
54public:
55    explicit FunctionCallStat(const CString &name, bool isAot) : PandaRuntimeCallerStat(name), isAot_(isAot) {}
56    FunctionCallStat() = default;
57    ~FunctionCallStat() = default;
58
59    bool IsAot() const
60    {
61        return isAot_;
62    }
63private:
64    bool isAot_ {false};
65};
66
67class FunctionCallTimer {
68public:
69    FunctionCallTimer() = default;
70    ~FunctionCallTimer() = default;
71    void StartCount(size_t id, bool isAot);
72    void StopCount(Method *method);
73    void PrintAllStats();
74    CString GetFullName(Method *method);
75    void InitialStatAndTimer(Method *method, size_t methodId, bool isAot);
76    void ResetStat();
77
78private:
79    PandaRuntimeTimer *currentTimer_ = nullptr;
80    CMap<size_t, FunctionCallStat> aotCallStat_ {};
81    CMap<size_t, FunctionCallStat> intCallStat_ {};
82    CMap<size_t, PandaRuntimeTimer> callTimer_ {};
83};
84}
85#endif // ECMASCRIPT_DFX_VMSTAT_FCUNTION_CALL_TIMER_H