1 /* 2 * Copyright (c) 2024 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 RAWHEAP_TRANSLATE_H 17 #define RAWHEAP_TRANSLATE_H 18 19 #include <optional> 20 #include <utility> 21 #include "ecmascript/dfx/hprof/rawheap_translate/metadata_parse.h" 22 #include "ecmascript/dfx/hprof/rawheap_translate/string_hashmap.h" 23 24 namespace rawheap_translate { 25 struct AddrTableItem { 26 uint64_t addr; 27 uint64_t id; 28 uint32_t objSize; 29 uint32_t offset; // offset to the file 30 }; 31 32 struct Node { 33 uint64_t nodeId; // Range from 1 34 uint32_t index; 35 StringId strId; 36 uint8_t type; 37 uint32_t size; 38 uint32_t nativeSize; 39 size_t edgeCount; 40 char *data; 41 NodeNode42 Node(uint32_t nodeIndex) 43 : nodeId(0), 44 index(nodeIndex), 45 strId(1), // 1: for empty string 46 type(8), // 8: default node type 47 size(0), 48 nativeSize(0), 49 edgeCount(0), 50 data(nullptr) 51 { 52 } 53 }; 54 55 enum class EdgeType { CONTEXT, ELEMENT, PROPERTY, INTERNAL, HIDDEN, SHORTCUT, WEAK, DEFAULT = PROPERTY }; 56 57 struct Edge { 58 EdgeType type; 59 std::shared_ptr<Node> from; 60 std::shared_ptr<Node> to; 61 uint32_t nameOrIndex; 62 EdgeEdge63 Edge(EdgeType edgeType, std::shared_ptr<Node> nodeFrom, std::shared_ptr<Node> nodeTo, uint32_t index) 64 : type(edgeType), 65 from(nodeFrom), 66 to(nodeTo), 67 nameOrIndex(index) 68 { 69 } 70 }; 71 72 class RawHeapTranslate { 73 public: RawHeapTranslate()74 RawHeapTranslate() 75 : meta_(std::make_unique<Meta>(Meta())), 76 strTable_(std::make_shared<StringHashMap>(StringHashMap())) {} 77 ~RawHeapTranslate()78 ~RawHeapTranslate() 79 { 80 for (auto mem : memBuf_) { 81 delete mem; 82 } 83 memBuf_.clear(); 84 nodes_.clear(); 85 edges_.clear(); 86 nodesMap_.clear(); 87 } 88 89 bool Translate(const std::string &rawheapPath); 90 GetNodes()91 std::vector<std::shared_ptr<Node>> GetNodes() 92 { 93 return nodes_; 94 } 95 GetEdges()96 std::vector<std::shared_ptr<Edge>> GetEdges() 97 { 98 return edges_; 99 } 100 GetEcmaStringTable()101 std::shared_ptr<StringHashMap> GetEcmaStringTable() 102 { 103 return strTable_; 104 } 105 GetNodeCount()106 size_t GetNodeCount() 107 { 108 return nodes_.size(); 109 } 110 GetEdgeCount()111 size_t GetEdgeCount() 112 { 113 return edges_.size(); 114 } 115 116 private: 117 bool ParseMetaData(std::ifstream &file, uint32_t &offset); 118 bool ReadMetaDataJson(std::ifstream &file, uint32_t &offset, cJSON **json); 119 void DelMetaDataJson(cJSON *json); 120 121 bool ReadSectionInfo(std::ifstream &file, uint32_t endOffset, std::vector<uint32_t> §ions); 122 bool ReadVersion(std::ifstream &file, uint32_t offset, uint32_t size); 123 bool ReadObjTableBySection(std::ifstream &file, const std::vector<uint32_t> §ions); 124 bool ReadObjTable(std::ifstream &file, uint32_t offset, uint32_t size); 125 bool ReadStringTable(std::ifstream &file, uint32_t offset, uint32_t size); 126 bool ReadRootTable(std::ifstream &file, uint32_t offset, uint32_t size); 127 bool ReadFileAtOffset(std::ifstream &file, uint32_t offset, uint32_t size, char *buf); 128 129 void CreateNode(AddrTableItem &item, char *data); 130 void FillNodesAndBuildEdges(); 131 void FillNodes(const std::shared_ptr<Node> &node, char *hclass); 132 void BuildEdges(const std::shared_ptr<Node> &from, char *hclass); 133 void BuildFieldsEdges( 134 const std::shared_ptr<Node> &from, const std::shared_ptr<MetaData> &metadata, uint32_t offset); 135 void BuildGlobalEnvEdges(const std::shared_ptr<Node> &from); 136 void BuildArrayEdges(const std::shared_ptr<Node> &from, const std::shared_ptr<MetaData> &metadata, uint32_t offset); 137 void BuildDictionaryEdges( 138 const std::shared_ptr<Node> &from, const std::shared_ptr<MetaData> &metadata, uint32_t offset); 139 void BuildJSObjectInlEdges(const std::shared_ptr<Node> &from, char *hclass, uint32_t offset); 140 void CreateEdge(const std::shared_ptr<Node> &from, const std::shared_ptr<Node> &to, EdgeType type, uint32_t index); 141 void SetNodeStringId(char *addr, uint32_t size, StringId strId); 142 bool ByteToAddrTableItem(std::ifstream &file, uint32_t offset, uint32_t objNum, std::vector<AddrTableItem> &table); 143 std::optional<std::shared_ptr<Node>> FindNodeFromAddr(uint64_t addr, EdgeType *type); 144 std::optional<std::pair<uint32_t, uint32_t>> CheckAndGetHead( 145 std::ifstream &file, uint32_t offset, uint32_t assertNum); 146 147 static std::shared_ptr<Field> FindFieldInMetaData( 148 const std::shared_ptr<MetaData> &metadata, const std::string &name); 149 static void CheckAndRemoveWeak(uint64_t &addr, EdgeType *type); 150 static bool IsHeapObject(uint64_t addr); 151 static constexpr uint64_t TAG_WEAK = 0x01ULL; 152 static constexpr uint64_t TAG_WEAK_MASK = 0x01ULL; 153 static constexpr uint64_t TAG_HEAPOBJECT_MASK = (0xFFFFULL << 48) | 0x02ULL | 0x04ULL; // 48 means 6 byte shift 154 155 std::vector<char *> memBuf_ {}; 156 std::unique_ptr<Meta> meta_ {nullptr}; 157 std::shared_ptr<StringHashMap> strTable_ {nullptr}; 158 std::vector<std::shared_ptr<Node>> nodes_ {}; 159 std::vector<std::shared_ptr<Edge>> edges_ {}; 160 std::unordered_map<uint64_t, std::shared_ptr<Node>> nodesMap_ {}; 161 }; 162 163 } // namespace rawheap_translate 164 #endif