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 24 namespace panda::ecmascript { 25 class 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 53 class FunctionCallStat : public PandaRuntimeCallerStat { 54 public: FunctionCallStat(const CString & name,bool isAot)55 explicit FunctionCallStat(const CString &name, bool isAot) : PandaRuntimeCallerStat(name), isAot_(isAot) {} 56 FunctionCallStat() = default; 57 ~FunctionCallStat() = default; 58 IsAot()59 bool IsAot() const 60 { 61 return isAot_; 62 } 63 private: 64 bool isAot_ {false}; 65 }; 66 67 class FunctionCallTimer { 68 public: 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 78 private: 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