• 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/dfx/hprof/file_stream.h"
24 #include "ecmascript/mem/c_containers.h"
25 #include "ecmascript/mem/c_string.h"
26 #include "ecmascript/dfx/hprof/string_hashmap.h"
27 
28 #include "securec.h"
29 
30 namespace panda::ecmascript {
31 using fstream = std::fstream;
32 using stringstream = std::stringstream;
33 
34 class HeapSnapshot;
35 class TraceNode;
36 
37 class StreamWriter {
38 public:
StreamWriter(Stream * stream)39     explicit StreamWriter(Stream *stream)
40         : stream_(stream), chunkSize_(stream->GetSize()), chunk_(chunkSize_), current_(0)
41     {
42     }
43 
WriteString(const CString & str)44     void WriteString(const CString &str)
45     {
46         auto len = str.size();
47         ASSERT(len <= static_cast<size_t>(INT_MAX));
48         if (len == 0) {
49             return;
50         }
51         const char *cur = str.c_str();
52         const char *end = cur + len;
53         while (cur < end) {
54             int dstSize = chunkSize_ - current_;
55             int writeSize = std::min(static_cast<int>(end - cur), dstSize);
56             ASSERT(writeSize > 0);
57             if (memcpy_s(chunk_.data() + current_, dstSize, cur, writeSize) != EOK) {
58                 LOG_FULL(FATAL) << "memcpy_s failed";
59             }
60             cur += writeSize;
61             current_ += writeSize;
62             MaybeWriteChunk();
63         }
64     }
65 
WriteChar(char c)66     void WriteChar(char c)
67     {
68         ASSERT(c != '\0');
69         ASSERT(current_ < chunkSize_);
70         chunk_[current_++] = c;
71         MaybeWriteChunk();
72     }
73 
WriteNumber(uint64_t num)74     void WriteNumber(uint64_t num)
75     {
76         WriteString(ToCString(num));
77     }
78 
End()79     void End()
80     {
81         if (current_ > 0) {
82             WriteChunk();
83         }
84         stream_->EndOfStream();
85     }
86 
87 private:
MaybeWriteChunk()88     void MaybeWriteChunk()
89     {
90         ASSERT(current_ <= chunkSize_);
91         if (current_ == chunkSize_) {
92             WriteChunk();
93         }
94     }
95 
WriteChunk()96     void WriteChunk()
97     {
98         stream_->WriteChunk(chunk_.data(), current_);
99         current_ = 0;
100     }
101 
102     Stream *stream_ {nullptr};
103     int chunkSize_ {0};
104     CVector<char> chunk_;
105     int current_ {0};
106 };
107 
108 class HeapSnapshotJSONSerializer {
109 public:
110     explicit HeapSnapshotJSONSerializer() = default;
111     ~HeapSnapshotJSONSerializer() = default;
112     NO_MOVE_SEMANTIC(HeapSnapshotJSONSerializer);
113     NO_COPY_SEMANTIC(HeapSnapshotJSONSerializer);
114     static bool Serialize(HeapSnapshot *snapshot, Stream *stream);
115 
116 private:
117     static constexpr char ASCII_US = 31;
118     static constexpr char ASCII_DEL = 127;
119     static constexpr uint8_t UTF8_MAX_BYTES = 4;
120 
121 private:
122     static void SerializeSnapshotHeader(HeapSnapshot *snapshot, StreamWriter *writer);
123     static void SerializeNodes(HeapSnapshot *snapshot, StreamWriter *writer);
124     static void SerializeEdges(HeapSnapshot *snapshot, StreamWriter *writer);
125     static void SerializeTraceFunctionInfo(HeapSnapshot *snapshot, StreamWriter *writer);
126     static void SerializeTraceTree(HeapSnapshot *snapshot, StreamWriter *writer);
127     static void SerializeTraceNode(TraceNode *node, StreamWriter *writer);
128     static void SerializeSamples(HeapSnapshot *snapshot, StreamWriter *writer);
129     static void SerializeLocations(StreamWriter *writer);
130     static void SerializeStringTable(HeapSnapshot *snapshot, StreamWriter *writer);
131     static void SerializeString(CString *str, StreamWriter *writer);
132     static void SerializeUnicodeChar(uint32_t unicodeChar, StreamWriter *writer);
133     static void SerializerSnapshotClosure(StreamWriter *writer);
134 };
135 }  // namespace panda::ecmascript
136 #endif  // ECMASCRIPT_DFX_HPROF_HEAP_SNAPSHOT_SERIALIZER_H
137