• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &sections);
122     bool ReadVersion(std::ifstream &file, uint32_t offset, uint32_t size);
123     bool ReadObjTableBySection(std::ifstream &file, const std::vector<uint32_t> &sections);
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