1 /*
2 * Copyright (c) 2021-2022 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 #include "mem_proc.h"
17 #ifdef SIMULATOR_MEMORY_ANALYSIS
18 #include <cstdio>
19 #include <windows.h>
20 #include <psapi.h>
21 #include "ace_log.h"
22 #include "gfx_utils/file.h"
23 #include "jerryscript-core.h"
24 #include "jerryscript.h"
25 #include "js_fwk_common.h"
26 #include "securec.h"
27 #include "time.h"
28
29 namespace OHOS {
30 namespace ACELite {
31 constexpr uint8_t MSG_LENGTH = 100;
32
33 constexpr uint32_t UNIT = 1024;
34
GetInstance()35 AceMemProc *AceMemProc::GetInstance()
36 {
37 static AceMemProc instance;
38 return &instance;
39 }
40
ClearUp()41 void AceMemProc::ClearUp()
42 {
43 if (!IsEnabled()) {
44 return;
45 }
46 // backup prev txt, create a new txt
47 struct stat fileStat;
48
49 int32_t state = stat(MEM_LOG_FILE_PATH, &fileStat);
50 if ((state != 0) || (fileStat.st_size == 0)) {
51 HILOG_ERROR(HILOG_MODULE_ACE, "Back up file error.");
52 return;
53 }
54 // it exists and not empty
55 time_t seconds = time(NULL);
56 char markdata[MSG_LENGTH];
57 if (sprintf_s(markdata, MSG_LENGTH, "%ti.txt", seconds) < 0) {
58 close(state);
59 return;
60 }
61 char *fullPath = RelocateJSSourceFilePath(MEM_BACK_UP_LOG_FILE_PREFIX, markdata);
62 if (fullPath == nullptr) {
63 HILOG_ERROR(HILOG_MODULE_ACE, "Back up file error.");
64 } else {
65 rename(MEM_LOG_FILE_PATH, fullPath);
66 ace_free(fullPath);
67 fullPath = nullptr;
68 }
69 close(state);
70 }
71
SysMemTracing()72 void AceMemProc::SysMemTracing()
73 {
74 if (!IsEnabled()) {
75 return;
76 }
77 HANDLE handle = GetCurrentProcess();
78 PROCESS_MEMORY_COUNTERS pmc = {0};
79 if (!GetProcessMemoryInfo(handle, reinterpret_cast<PROCESS_MEMORY_COUNTERS *>(&pmc), sizeof(pmc))) {
80 HILOG_ERROR(HILOG_MODULE_ACE, "Get process memory error.");
81 return;
82 }
83
84 FILE *fp = fopen(MEM_LOG_FILE_PATH, "a+");
85 if (fp == nullptr) {
86 HILOG_ERROR(HILOG_MODULE_ACE, "Get file error.");
87 return;
88 }
89
90 // physical memory
91 char markdata[MSG_LENGTH];
92 if (sprintf_s(markdata, MSG_LENGTH, "Phy:%d(KB)\n", uint32_t(pmc.WorkingSetSize / UNIT)) < 0) {
93 HILOG_ERROR(HILOG_MODULE_ACE, "Output file error.");
94 fclose(fp);
95 fp = nullptr;
96 return;
97 }
98 fputs(markdata, fp);
99
100 // virtual memory
101 if (sprintf_s(markdata, MSG_LENGTH, "Vir:%d(KB)\n", uint32_t(pmc.PagefileUsage / UNIT)) < 0) {
102 HILOG_ERROR(HILOG_MODULE_ACE, "Output file error.");
103 fclose(fp);
104 fp = nullptr;
105 return;
106 }
107 fputs(markdata, fp);
108
109 fflush(fp);
110 fclose(fp);
111 fp = nullptr;
112 }
113
JerryMemTracing()114 void AceMemProc::JerryMemTracing()
115 {
116 if (!IsEnabled()) {
117 return;
118 }
119 jerry_heap_stats_t stats = {0};
120 if (!jerry_get_memory_stats(&stats)) {
121 HILOG_ERROR(HILOG_MODULE_ACE, "Get jerry heap stats error.");
122 return;
123 }
124
125 FILE *fp = fopen(MEM_LOG_FILE_PATH, "a+");
126 if (fp == nullptr) {
127 HILOG_ERROR(HILOG_MODULE_ACE, "Get file error");
128 return;
129 }
130
131 size_t total = stats.size;
132 size_t current = stats.allocated_bytes;
133 size_t peak = stats.peak_allocated_bytes;
134 // jerry total memory
135 char markdata[MSG_LENGTH];
136 if (sprintf_s(markdata, MSG_LENGTH, "jerry heap total:%d(KB)\n", uint32_t(total / UNIT)) < 0) {
137 HILOG_ERROR(HILOG_MODULE_ACE, "Output file error.");
138 fclose(fp);
139 fp = nullptr;
140 return;
141 }
142 fputs(markdata, fp);
143
144 // jerry current memory
145 if (sprintf_s(markdata, MSG_LENGTH, "jerry heap current:%d(KB)\n", uint32_t(current / UNIT)) < 0) {
146 HILOG_ERROR(HILOG_MODULE_ACE, "Output file error.");
147 fclose(fp);
148 fp = nullptr;
149 return;
150 }
151 fputs(markdata, fp);
152
153 // jerry peak memory
154 if (sprintf_s(markdata, MSG_LENGTH, "jerry heap peak:%d(KB)\n", uint32_t(peak / UNIT)) < 0) {
155 HILOG_ERROR(HILOG_MODULE_ACE, "Output file error.");
156 fclose(fp);
157 fp = nullptr;
158 return;
159 }
160 fputs(markdata, fp);
161
162 fflush(fp);
163 fclose(fp);
164 fp = nullptr;
165 }
166
IsEnabled()167 bool AceMemProc::IsEnabled()
168 {
169 return IsFileExisted(MEM_PROC_ENABLE_FLAG_FILE);
170 }
171 } // namespace ACELite
172 } // namespace OHOS
173 #endif // SIMULATOR_MEMORY_ANALYSIS
174