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_OPERATION_H 17 #define ECMASCRIPT_COMPILER_PROFILER_OPERATION_H 18 19 #include <functional> 20 #include <initializer_list> 21 22 #include "ecmascript/compiler/share_gate_meta_data.h" 23 24 namespace panda::ecmascript::kungfu { 25 enum class OperationType : uint8_t { 26 CALL, 27 NATIVE_CALL, 28 GETTER_SETTER_CALL, 29 OPERATION_TYPE, 30 DEFINE_CLASS, 31 CREATE_OBJECT, 32 TRUE_BRANCH, 33 FALSE_BRANCH, 34 TRY_DUMP, 35 TRY_PREDUMP, 36 ITERATOR_FUNC_KIND, 37 TRY_JIT, 38 }; 39 40 using SlotIDFormat = BytecodeInstruction::Format; 41 42 #define COMBINE_TYPE_CALL_BACK(curType, type) \ 43 callback.ProfileCombineOpType( \ 44 *(curType), type, [this](GateRef curType, GateRef type)->GateRef{ return Int64Or(curType, type); }) 45 46 using Callback = std::function<void(const std::initializer_list<GateRef> &, OperationType)>; 47 class ProfileOperation { 48 public: ProfileOperation()49 ProfileOperation() : callback_(nullptr), jitCallback_(nullptr) {} ProfileOperation(Callback callback, Callback jitCallback)50 explicit ProfileOperation(Callback callback, Callback jitCallback) : callback_(callback), 51 jitCallback_(jitCallback) {} 52 IsEmpty() const53 inline bool IsEmpty() const 54 { 55 return callback_ == nullptr; 56 } 57 IsJitEmpty() const58 inline bool IsJitEmpty() const 59 { 60 return jitCallback_ == nullptr; 61 } 62 ProfileCall(GateRef func) const63 inline void ProfileCall(GateRef func) const 64 { 65 if (callback_) { 66 callback_({ func }, OperationType::CALL); 67 } 68 } 69 ProfileNativeCall(GateRef func) const70 inline void ProfileNativeCall(GateRef func) const 71 { 72 if (callback_) { 73 callback_({ func }, OperationType::NATIVE_CALL); 74 } 75 } 76 ProfileGetterSetterCall(GateRef func) const77 inline void ProfileGetterSetterCall(GateRef func) const 78 { 79 if (callback_) { 80 callback_({ func }, OperationType::GETTER_SETTER_CALL); 81 } 82 } 83 ProfileOpType(GateRef type) const84 inline void ProfileOpType(GateRef type) const 85 { 86 if (callback_) { 87 callback_({ type }, OperationType::OPERATION_TYPE); 88 } 89 } 90 91 template <typename TypeCombine> ProfileCombineOpType(GateRef curType, GateRef type, TypeCombine combine) const92 inline void ProfileCombineOpType(GateRef curType, GateRef type, TypeCombine combine) const 93 { 94 if (callback_) { 95 GateRef ret = combine(curType, type); 96 callback_({ ret }, OperationType::OPERATION_TYPE); 97 } 98 } 99 ProfileDefineClass(GateRef constructor) const100 inline void ProfileDefineClass(GateRef constructor) const 101 { 102 if (callback_) { 103 callback_({ constructor }, OperationType::DEFINE_CLASS); 104 } 105 } 106 ProfileCreateObject(GateRef newObj) const107 inline void ProfileCreateObject(GateRef newObj) const 108 { 109 if (callback_) { 110 callback_({ newObj }, OperationType::CREATE_OBJECT); 111 } 112 } 113 TryDump() const114 inline void TryDump() const 115 { 116 if (callback_) { 117 callback_({ }, OperationType::TRY_DUMP); 118 } 119 } 120 TryJitCompile() const121 inline void TryJitCompile() const 122 { 123 if (callback_) { 124 callback_({ }, OperationType::TRY_JIT); 125 } else if (jitCallback_) { 126 jitCallback_({ }, OperationType::TRY_JIT); 127 } 128 } 129 TryPreDump() const130 inline void TryPreDump() const 131 { 132 if (callback_) { 133 callback_({ }, OperationType::TRY_PREDUMP); 134 } 135 } 136 ProfileBranch(bool isTrue) const137 inline void ProfileBranch(bool isTrue) const 138 { 139 if (callback_) { 140 callback_({}, isTrue ? OperationType::TRUE_BRANCH : OperationType::FALSE_BRANCH); 141 } 142 } 143 ProfileGetIterator(GateRef iterator) const144 inline void ProfileGetIterator(GateRef iterator) const 145 { 146 if (callback_) { 147 callback_({ iterator }, OperationType::ITERATOR_FUNC_KIND); 148 } 149 } 150 151 private: 152 Callback callback_; 153 Callback jitCallback_; 154 }; 155 } // namespace panda::ecmascript::kungfu 156 #endif // ECMASCRIPT_COMPILER_PROFILER_OPERATION_H 157