• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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_RAWHEAP_DUMP_H
17 #define ECMASCRIPT_DFX_HPROF_RAWHEAP_DUMP_H
18 
19 #include <functional>
20 
21 #include "ecmascript/dfx/hprof/file_stream.h"
22 #include "ecmascript/dfx/hprof/string_hashmap.h"
23 #include "ecmascript/dfx/hprof/heap_marker.h"
24 #include "ecmascript/dfx/hprof/heap_profiler.h"
25 #include "ecmascript/dfx/hprof/heap_snapshot.h"
26 
27 
28 namespace panda::ecmascript {
29 class ObjectMarker : public HeapMarker, public RootVisitor, public BaseObjectVisitor<ObjectMarker> {
30 public:
31     ObjectMarker() = default;
32     ~ObjectMarker() = default;
33 
34     void VisitRoot(Root type, ObjectSlot slot) override;
35     void VisitRangeRoot(Root type, ObjectSlot start, ObjectSlot end) override;
36     void VisitBaseAndDerivedRoot(Root type, ObjectSlot base, ObjectSlot derived, uintptr_t baseOldObject) override;
37     void VisitObjectRangeImpl(BaseObject *root, uintptr_t start, uintptr_t endAddr, VisitObjectArea area) override;
38 
39     void ProcessMarkObjectsFromRoot();
40     void IterateMarkedObjects(const std::function<void(JSTaggedType)> &visitor);
41     void MarkObject(JSTaggedType addr);
42 
43 private:
44     CQueue<JSTaggedType> bfsQueue_ {};
45     CVector<JSTaggedType> markedObjects_ {};
46 };
47 
48 class RawHeapDump {
49 public:
50     RawHeapDump(const EcmaVM *vm, Stream *stream, HeapSnapshot *snapshot,
51                 EntryIdMap* entryIdMap, const DumpSnapShotOption &dumpOption);
52     virtual ~RawHeapDump();
53 
54     virtual void BinaryDump() = 0;
GetRawHeapFileOffset()55     uint32_t GetRawHeapFileOffset()
56     {
57         return static_cast<uint32_t>(writer_.GetCurrentFileSize());
58     }
59 
60 protected:
61     void MarkRootForDump(ObjectMarker &marker);
62     void MarkHeapObjectForDump(ObjectMarker &marker);
63     void DumpVersion(const std::string &version);
64     void DumpSectionIndex();
65     NodeId GenerateNodeId(JSTaggedType addr);
66     void WriteChunk(char *data, size_t size);
67     void WriteU64(uint64_t value);
68     void WriteU32(uint32_t value);
69     void WriteU16(uint16_t value);
70     void WriteU8(uint8_t value);
71     void WriteHeader(uint32_t offset, uint32_t size);
72     void WritePadding();
73     void AddSectionRecord(uint32_t value);
74     void AddSectionOffset();
75     void AddSectionBlockSize();
76     StringId GenerateStringId(TaggedObject *object);
77     const StringHashMap *GetEcmaStringTable();
78 
79 private:
80     const EcmaVM *vm_ {nullptr};
81     BinaryWriter writer_;
82     HeapSnapshot *snapshot_ {nullptr};
83     EntryIdMap *entryIdMap_ {nullptr};
84     CVector<uint32_t> secIndexVec_ {};
85     CUnorderedMap<JSTaggedType, StringId> objectStrIds_ {};
86     CUnorderedMap<Method *, StringId> functionStrIds_ {};
87     uint32_t fileOffset_ {0};
88     uint32_t preOffset_ {0};
89     bool isOOM_ {false};
90     bool isJSLeakWatcher_ {false};
91     std::chrono::time_point<std::chrono::steady_clock> startTime_;
92 };
93 
94 class RawHeapDumpV1 : public RawHeapDump {
95 public:
96     RawHeapDumpV1(const EcmaVM *vm, Stream *stream, HeapSnapshot *snapshot,
97                   EntryIdMap* entryIdMap, const DumpSnapShotOption &dumpOption);
98     ~RawHeapDumpV1();
99 
100     void BinaryDump() override;
101 
102 private:
103     struct AddrTableItem {
104         uint64_t addr;
105         uint64_t id;
106         uint32_t objSize;
107         uint32_t offset; // offset to the file
108     };
109 
110     void DumpRootTable(ObjectMarker &marker);
111     void DumpStringTable(ObjectMarker &marker);
112     void DumpObjectTable(ObjectMarker &marker);
113     void DumpObjectMemory(ObjectMarker &marker);
114     void UpdateStringTable(ObjectMarker &marker);
115 
116     constexpr static const char *const RAWHEAP_VERSION = "1.0.0";
117     CUnorderedMap<uint64_t, CVector<uint64_t>> strIdMapObjVec_ {};
118 };
119 
120 class RawHeapDumpV2 : public RawHeapDump {
121 public:
122     RawHeapDumpV2(const EcmaVM *vm, Stream *stream, HeapSnapshot *snapshot,
123                   EntryIdMap* entryIdMap, const DumpSnapShotOption &dumpOption);
124     ~RawHeapDumpV2();
125 
126     void BinaryDump() override;
127 
128 private:
129     struct AddrTableItem {
130         uint32_t syntheticAddr;
131         uint32_t size;
132         uint64_t nodeId;
133         uint32_t nativeSize;
134         uint32_t type;
135     };
136 
137     void DumpRootTable(ObjectMarker &marker);
138     void DumpStringTable(ObjectMarker &marker);
139     void DumpObjectTable(ObjectMarker &marker);
140     void DumpObjectMemory(ObjectMarker &marker);
141     void UpdateStringTable(ObjectMarker &marker);
142 
143     uint32_t GenerateRegionId(JSTaggedType addr);
144     uint32_t GenerateSyntheticAddr(JSTaggedType addr);
145 
146     constexpr static const char *const RAWHEAP_VERSION_V2 = "2.0.0";
147     CUnorderedMap<uint64_t, CVector<uint32_t>> strIdMapObjVec_ {};
148     CUnorderedMap<Region *, uint32_t> regionIdMap_ {};
149     uint32_t regionId_ {0};  // region id start from 0x10
150 };
151 }  // namespace panda::ecmascript
152 #endif  // ECMASCRIPT_DFX_HPROF_HEAP_DUMP_H
153