1 /* 2 * Copyright (c) 2021-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_SNAPSHOT_SERIALIZER_H 17 #define ECMASCRIPT_DFX_HPROF_HEAP_SNAPSHOT_SERIALIZER_H 18 19 #include <fstream> 20 #include <limits.h> 21 #include <sstream> 22 23 #include "ecmascript/mem/c_string.h" 24 #include "ecmascript/dfx/hprof/file_stream.h" 25 #include "ecmascript/mem/c_containers.h" 26 27 #include "securec.h" 28 29 namespace panda::ecmascript { 30 using fstream = std::fstream; 31 using stringstream = std::stringstream; 32 33 class HeapSnapshot; 34 class TraceNode; 35 36 class StreamWriter { 37 public: StreamWriter(Stream * stream)38 explicit StreamWriter(Stream *stream) 39 : stream_(stream), chunkSize_(stream->GetSize()), chunk_(chunkSize_), current_(0) 40 { 41 } 42 Write(const CString & str)43 void Write(const CString &str) 44 { 45 ASSERT(str.size() <= static_cast<size_t>(INT_MAX)); 46 auto len = static_cast<int>(str.size()); 47 const char *cur = str.c_str(); 48 const char *end = cur + len; 49 while (cur < end) { 50 int dstSize = chunkSize_ - current_; 51 int writeSize = std::min(static_cast<int>(end - cur), dstSize); 52 if (memcpy_s(chunk_.data() + current_, dstSize, cur, writeSize) != EOK) { 53 LOG_FULL(FATAL) << "memcpy_s failed"; 54 } 55 cur += writeSize; 56 current_ += writeSize; 57 58 if (current_ == chunkSize_) { 59 WriteChunk(); 60 } 61 } 62 } 63 Write(uint64_t num)64 void Write(uint64_t num) 65 { 66 Write(ToCString(num)); 67 } 68 End()69 void End() 70 { 71 if (current_ > 0) { 72 WriteChunk(); 73 } 74 stream_->EndOfStream(); 75 } 76 77 private: WriteChunk()78 void WriteChunk() 79 { 80 stream_->WriteChunk(chunk_.data(), current_); 81 current_ = 0; 82 } 83 84 Stream *stream_ {nullptr}; 85 int chunkSize_ {0}; 86 CVector<char> chunk_; 87 int current_ {0}; 88 }; 89 90 class HeapSnapshotJSONSerializer { 91 public: 92 explicit HeapSnapshotJSONSerializer() = default; 93 ~HeapSnapshotJSONSerializer(); 94 NO_MOVE_SEMANTIC(HeapSnapshotJSONSerializer); 95 NO_COPY_SEMANTIC(HeapSnapshotJSONSerializer); 96 bool Serialize(HeapSnapshot *snapshot, Stream *stream); 97 98 private: 99 void SerializeSnapshotHeader(); 100 void SerializeNodes(); 101 void SerializeEdges(); 102 void SerializeTraceFunctionInfo(); 103 void SerializeTraceTree(); 104 void SerializeTraceNode(TraceNode *node); 105 void SerializeSamples(); 106 void SerializeLocations(); 107 void SerializeStringTable(); 108 void SerializerSnapshotClosure(); 109 110 HeapSnapshot *snapshot_ {nullptr}; 111 StreamWriter *writer_ {nullptr}; 112 }; 113 } // namespace panda::ecmascript 114 #endif // ECMASCRIPT_DFX_HPROF_HEAP_SNAPSHOT_SERIALIZER_H 115