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_HPROF_HEAP_SAMPLING_H 17 #define ECMASCRIPT_DFX_HPROF_HEAP_SAMPLING_H 18 19 #include "ecmascript/dfx/stackinfo/js_stackgetter.h" 20 #include "ecmascript/mem/heap.h" 21 22 namespace panda::ecmascript { 23 struct CallFrameInfo { 24 std::string codeType_ = ""; 25 std::string functionName_ = ""; 26 std::string moduleName_ = ""; 27 int columnNumber_ = -1; 28 int lineNumber_ = -1; 29 int scriptId_ = 0; 30 std::string url_ = ""; 31 }; 32 33 struct Sample { SampleSample34 Sample(size_t size, uint32_t nodeId, uint64_t ordinal, unsigned int count) 35 : size_(size), 36 nodeId_(nodeId), 37 ordinal_(ordinal), 38 count_(count) {} 39 const size_t size_; 40 const uint32_t nodeId_; 41 const uint64_t ordinal_; 42 const unsigned int count_; 43 }; 44 45 struct SamplingNode { 46 std::map<size_t, unsigned int> allocations_; 47 std::map<MethodKey, std::unique_ptr<struct SamplingNode>> children_; 48 CallFrameInfo callFrameInfo_; 49 uint32_t id_ = 0; 50 size_t selfSize_ = 0; 51 }; 52 53 struct SamplingInfo { 54 struct SamplingNode head_; 55 CVector<struct Sample> samples_; 56 }; 57 58 class HeapSampling { 59 public: 60 HeapSampling(const EcmaVM *vm, Heap *const heap, uint64_t interval, int stackDepth); 61 const struct SamplingInfo* GetAllocationProfile(); 62 void ImplementSampling([[maybe_unused]] Address addr, size_t size); 63 virtual ~HeapSampling(); 64 65 private: 66 void GetStack(); 67 struct SamplingNode *PushAndGetNode(); 68 CallFrameInfo GetMethodInfo(const MethodKey &methodKey); 69 struct SamplingNode *FindOrAddNode(struct SamplingNode *node, const MethodKey &methodKey); 70 bool PushStackInfo(const struct MethodKey &methodKey); 71 bool PushFrameInfo(const FrameInfoTemp &frameInfoTemp); 72 void ResetFrameLength(); 73 uint32_t CreateNodeId(); 74 uint64_t CreateSampleId(); 75 void FillScriptIdAndStore(); 76 std::string AddRunningState(char *functionName, RunningState state, kungfu::DeoptType type); 77 unsigned int AdjustSampleCount(size_t size, unsigned int count) const; 78 void CalNodeSelfSize(SamplingNode *node); 79 80 private: 81 const EcmaVM *vm_; 82 [[maybe_unused]] Heap *const heap_; 83 [[maybe_unused]] uint64_t rate_; 84 std::unique_ptr<struct SamplingInfo> samplingInfo_; 85 int stackDepth_; 86 AllocationInspector allocationInspector_; 87 uint32_t nodeId_ = 0; 88 size_t sampleId_ = 0; 89 CMap<struct MethodKey, struct CallFrameInfo> stackInfoMap_; 90 CVector<struct MethodKey> frameStack_; 91 CMap<std::string, int> scriptIdMap_; 92 CVector<FrameInfoTemp> frameInfoTemps_; 93 }; 94 } // namespace panda::ecmascript 95 #endif // ECMASCRIPT_DFX_HPROF_HEAP_SAMPLING_H