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