14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_DFX_HPROF_HEAP_SNAPSHOT_SERIALIZER_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_DFX_HPROF_HEAP_SNAPSHOT_SERIALIZER_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <fstream> 204514f5e3Sopenharmony_ci#include <limits.h> 214514f5e3Sopenharmony_ci#include <sstream> 224514f5e3Sopenharmony_ci 234514f5e3Sopenharmony_ci#include "ecmascript/dfx/hprof/file_stream.h" 244514f5e3Sopenharmony_ci#include "ecmascript/mem/c_containers.h" 254514f5e3Sopenharmony_ci#include "ecmascript/mem/c_string.h" 264514f5e3Sopenharmony_ci 274514f5e3Sopenharmony_ci#include "securec.h" 284514f5e3Sopenharmony_ci 294514f5e3Sopenharmony_cinamespace panda::ecmascript { 304514f5e3Sopenharmony_ciusing fstream = std::fstream; 314514f5e3Sopenharmony_ciusing stringstream = std::stringstream; 324514f5e3Sopenharmony_ci 334514f5e3Sopenharmony_ciclass HeapSnapshot; 344514f5e3Sopenharmony_ciclass TraceNode; 354514f5e3Sopenharmony_ci 364514f5e3Sopenharmony_ciclass StreamWriter { 374514f5e3Sopenharmony_cipublic: 384514f5e3Sopenharmony_ci explicit StreamWriter(Stream *stream) 394514f5e3Sopenharmony_ci : stream_(stream), chunkSize_(stream->GetSize()), chunk_(chunkSize_), current_(0) 404514f5e3Sopenharmony_ci { 414514f5e3Sopenharmony_ci } 424514f5e3Sopenharmony_ci 434514f5e3Sopenharmony_ci void WriteString(const CString &str) 444514f5e3Sopenharmony_ci { 454514f5e3Sopenharmony_ci auto len = str.size(); 464514f5e3Sopenharmony_ci ASSERT(len <= static_cast<size_t>(INT_MAX)); 474514f5e3Sopenharmony_ci if (len == 0) { 484514f5e3Sopenharmony_ci return; 494514f5e3Sopenharmony_ci } 504514f5e3Sopenharmony_ci const char *cur = str.c_str(); 514514f5e3Sopenharmony_ci const char *end = cur + len; 524514f5e3Sopenharmony_ci while (cur < end) { 534514f5e3Sopenharmony_ci int dstSize = chunkSize_ - current_; 544514f5e3Sopenharmony_ci int writeSize = std::min(static_cast<int>(end - cur), dstSize); 554514f5e3Sopenharmony_ci ASSERT(writeSize > 0); 564514f5e3Sopenharmony_ci if (memcpy_s(chunk_.data() + current_, dstSize, cur, writeSize) != EOK) { 574514f5e3Sopenharmony_ci LOG_FULL(FATAL) << "memcpy_s failed"; 584514f5e3Sopenharmony_ci } 594514f5e3Sopenharmony_ci cur += writeSize; 604514f5e3Sopenharmony_ci current_ += writeSize; 614514f5e3Sopenharmony_ci MaybeWriteChunk(); 624514f5e3Sopenharmony_ci } 634514f5e3Sopenharmony_ci } 644514f5e3Sopenharmony_ci 654514f5e3Sopenharmony_ci void WriteChar(char c) 664514f5e3Sopenharmony_ci { 674514f5e3Sopenharmony_ci ASSERT(c != '\0'); 684514f5e3Sopenharmony_ci ASSERT(current_ < chunkSize_); 694514f5e3Sopenharmony_ci chunk_[current_++] = c; 704514f5e3Sopenharmony_ci MaybeWriteChunk(); 714514f5e3Sopenharmony_ci } 724514f5e3Sopenharmony_ci 734514f5e3Sopenharmony_ci void WriteNumber(uint64_t num) 744514f5e3Sopenharmony_ci { 754514f5e3Sopenharmony_ci WriteString(ToCString(num)); 764514f5e3Sopenharmony_ci } 774514f5e3Sopenharmony_ci 784514f5e3Sopenharmony_ci void End() 794514f5e3Sopenharmony_ci { 804514f5e3Sopenharmony_ci if (current_ > 0) { 814514f5e3Sopenharmony_ci WriteChunk(); 824514f5e3Sopenharmony_ci } 834514f5e3Sopenharmony_ci stream_->EndOfStream(); 844514f5e3Sopenharmony_ci } 854514f5e3Sopenharmony_ci 864514f5e3Sopenharmony_ciprivate: 874514f5e3Sopenharmony_ci void MaybeWriteChunk() 884514f5e3Sopenharmony_ci { 894514f5e3Sopenharmony_ci ASSERT(current_ <= chunkSize_); 904514f5e3Sopenharmony_ci if (current_ == chunkSize_) { 914514f5e3Sopenharmony_ci WriteChunk(); 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci } 944514f5e3Sopenharmony_ci 954514f5e3Sopenharmony_ci void WriteChunk() 964514f5e3Sopenharmony_ci { 974514f5e3Sopenharmony_ci stream_->WriteChunk(chunk_.data(), current_); 984514f5e3Sopenharmony_ci current_ = 0; 994514f5e3Sopenharmony_ci } 1004514f5e3Sopenharmony_ci 1014514f5e3Sopenharmony_ci Stream *stream_ {nullptr}; 1024514f5e3Sopenharmony_ci int chunkSize_ {0}; 1034514f5e3Sopenharmony_ci CVector<char> chunk_; 1044514f5e3Sopenharmony_ci int current_ {0}; 1054514f5e3Sopenharmony_ci}; 1064514f5e3Sopenharmony_ci 1074514f5e3Sopenharmony_ciclass HeapSnapshotJSONSerializer { 1084514f5e3Sopenharmony_cipublic: 1094514f5e3Sopenharmony_ci explicit HeapSnapshotJSONSerializer() = default; 1104514f5e3Sopenharmony_ci ~HeapSnapshotJSONSerializer() = default; 1114514f5e3Sopenharmony_ci NO_MOVE_SEMANTIC(HeapSnapshotJSONSerializer); 1124514f5e3Sopenharmony_ci NO_COPY_SEMANTIC(HeapSnapshotJSONSerializer); 1134514f5e3Sopenharmony_ci static bool Serialize(HeapSnapshot *snapshot, Stream *stream); 1144514f5e3Sopenharmony_ci static void DumpStringTable(HeapSnapshot *snapshot, Stream *stream); 1154514f5e3Sopenharmony_ci 1164514f5e3Sopenharmony_ciprivate: 1174514f5e3Sopenharmony_ci static constexpr char ASCII_US = 31; 1184514f5e3Sopenharmony_ci static constexpr char ASCII_DEL = 127; 1194514f5e3Sopenharmony_ci static constexpr uint8_t UTF8_MAX_BYTES = 4; 1204514f5e3Sopenharmony_ci 1214514f5e3Sopenharmony_ciprivate: 1224514f5e3Sopenharmony_ci static void SerializeSnapshotHeader(HeapSnapshot *snapshot, StreamWriter *writer); 1234514f5e3Sopenharmony_ci static void SerializeNodes(HeapSnapshot *snapshot, StreamWriter *writer); 1244514f5e3Sopenharmony_ci static void SerializeEdges(HeapSnapshot *snapshot, StreamWriter *writer); 1254514f5e3Sopenharmony_ci static void SerializeTraceFunctionInfo(HeapSnapshot *snapshot, StreamWriter *writer); 1264514f5e3Sopenharmony_ci static void SerializeTraceTree(HeapSnapshot *snapshot, StreamWriter *writer); 1274514f5e3Sopenharmony_ci static void SerializeTraceNode(TraceNode *node, StreamWriter *writer); 1284514f5e3Sopenharmony_ci static void SerializeSamples(HeapSnapshot *snapshot, StreamWriter *writer); 1294514f5e3Sopenharmony_ci static void SerializeLocations(StreamWriter *writer); 1304514f5e3Sopenharmony_ci static void SerializeStringTable(HeapSnapshot *snapshot, StreamWriter *writer); 1314514f5e3Sopenharmony_ci static void SerializeString(CString *str, StreamWriter *writer); 1324514f5e3Sopenharmony_ci static void SerializeUnicodeChar(uint32_t unicodeChar, StreamWriter *writer); 1334514f5e3Sopenharmony_ci static void SerializerSnapshotClosure(StreamWriter *writer); 1344514f5e3Sopenharmony_ci}; 1354514f5e3Sopenharmony_ci} // namespace panda::ecmascript 1364514f5e3Sopenharmony_ci#endif // ECMASCRIPT_DFX_HPROF_HEAP_SNAPSHOT_SERIALIZER_H 137