• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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