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