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