1 /*
2  * Copyright (c) 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 "commonlibrary/ets_utils/tools/log.h"
17 #include "napi/native_api.h"
18 #include "native_engine.h"
19 #include "napi/native_node_api.h"
20 #include "securec.h"
21 
22 namespace OHOS::JsSysModule::Dfx {
23     constexpr int NUMBER_OF_PARAMETER_TWO = 2;
DumpHeapSnapshot(napi_env env,napi_callback_info info)24     static napi_value DumpHeapSnapshot(napi_env env, napi_callback_info info)
25     {
26         size_t argc = NUMBER_OF_PARAMETER_TWO;
27         size_t requireArgc = NUMBER_OF_PARAMETER_TWO;
28         napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
29         NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
30         napi_value argv[NUMBER_OF_PARAMETER_TWO] = { 0 };
31         napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
32         std::string tempStr = "";
33         size_t tempStrsize = 0;
34         if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &tempStrsize) != napi_ok) {
35             HILOG_ERROR("can not get argv[0] size");
36             return nullptr;
37         }
38         tempStr.reserve(tempStrsize + 1);
39         tempStr.resize(tempStrsize);
40         if (napi_get_value_string_utf8(env, argv[0], tempStr.data(), tempStrsize + 1, &tempStrsize) != napi_ok) {
41             HILOG_ERROR("can not get argv[0] value");
42             return nullptr;
43         }
44         std::string pathStr = tempStr;
45         bool isVmMode = true;
46         napi_get_value_bool(env, argv[1], &isVmMode);
47         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
48         engine->DumpHeapSnapshot(pathStr, isVmMode);
49         napi_value result = nullptr;
50         NAPI_CALL(env, napi_get_undefined(env, &result));
51         return result;
52     }
53 
BuildNativeAndJsStackTrace(napi_env env,napi_callback_info info)54     static napi_value BuildNativeAndJsStackTrace(napi_env env, napi_callback_info info)
55     {
56         napi_value result = nullptr;
57         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
58         std::string stackTraceResult = "";
59         bool temp = engine->BuildNativeAndJsStackTrace(stackTraceResult);
60         NAPI_CALL(env, napi_create_string_utf8(env, stackTraceResult.c_str(), stackTraceResult.size(), &result));
61         if (temp) {
62             return result;
63         } else {
64             return nullptr;
65         }
66     }
67 
StartHeapTracking(napi_env env,napi_callback_info info)68     static napi_value StartHeapTracking(napi_env env, napi_callback_info info)
69     {
70         size_t argc = NUMBER_OF_PARAMETER_TWO;
71         size_t requireArgc = NUMBER_OF_PARAMETER_TWO;
72         napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
73         NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
74         napi_value argv[NUMBER_OF_PARAMETER_TWO] = { 0 };
75         napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
76         double timeInterval = 0;
77         if (napi_get_value_double(env, argv[0], &timeInterval) != napi_ok) {
78             HILOG_ERROR("can not get argv[0] value");
79             return nullptr;
80         }
81         bool isVmMode = true;
82         if (napi_get_value_bool(env, argv[1], &isVmMode) != napi_ok) {
83             HILOG_ERROR("can not get argv[1] value");
84             return nullptr;
85         }
86         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
87         auto startResult = engine->StartHeapTracking(timeInterval, isVmMode);
88         napi_value result = nullptr;
89         NAPI_CALL(env, napi_get_boolean(env, startResult, &result));
90         return result;
91     }
92 
StopHeapTracking(napi_env env,napi_callback_info info)93     static napi_value StopHeapTracking(napi_env env, napi_callback_info info)
94     {
95         size_t argc = 1;
96         size_t requireArgc = 1;
97         napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
98         NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
99         napi_value argv = nullptr;
100         napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
101         std::string tempStr = "";
102         size_t tempStrsize = 0;
103         if (napi_get_value_string_utf8(env, argv, nullptr, 0, &tempStrsize) != napi_ok) {
104             HILOG_ERROR("can not get argv size");
105             return nullptr;
106         }
107         tempStr.reserve(tempStrsize);
108         tempStr.resize(tempStrsize);
109         if (napi_get_value_string_utf8(env, argv, tempStr.data(), tempStrsize + 1, &tempStrsize) != napi_ok) {
110             HILOG_ERROR("can not get argv value");
111             return nullptr;
112         }
113         std::string filePath = tempStr;
114         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
115         auto stopResult = engine->StopHeapTracking(filePath);
116         napi_value result = nullptr;
117         NAPI_CALL(env, napi_get_boolean(env, stopResult, &result));
118         return result;
119     }
120 
PrintStatisticResult(napi_env env,napi_callback_info info)121     static napi_value PrintStatisticResult(napi_env env, napi_callback_info info)
122     {
123         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
124         engine->PrintStatisticResult();
125         napi_value result = nullptr;
126         NAPI_CALL(env, napi_get_undefined(env, &result));
127         return result;
128     }
129 
StartRuntimeStat(napi_env env,napi_callback_info info)130     static napi_value StartRuntimeStat(napi_env env, napi_callback_info info)
131     {
132         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
133         engine->StartRuntimeStat();
134         napi_value result = nullptr;
135         NAPI_CALL(env, napi_get_undefined(env, &result));
136         return result;
137     }
138 
StopRuntimeStat(napi_env env,napi_callback_info info)139     static napi_value StopRuntimeStat(napi_env env, napi_callback_info info)
140     {
141         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
142         engine->StopRuntimeStat();
143         napi_value result = nullptr;
144         NAPI_CALL(env, napi_get_undefined(env, &result));
145         return result;
146     }
147 
GetArrayBufferSize(napi_env env,napi_callback_info info)148     static napi_value GetArrayBufferSize(napi_env env, napi_callback_info info)
149     {
150         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
151         auto value = static_cast<uint32_t>(engine->GetArrayBufferSize());
152         napi_value result = nullptr;
153         NAPI_CALL(env, napi_create_uint32(env, value, &result));
154         return result;
155     }
156 
GetHeapTotalSize(napi_env env,napi_callback_info info)157     static napi_value GetHeapTotalSize(napi_env env, napi_callback_info info)
158     {
159         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
160         auto value = static_cast<uint32_t>(engine->GetHeapTotalSize());
161         napi_value result = nullptr;
162         NAPI_CALL(env, napi_create_uint32(env, value, &result));
163         return result;
164     }
165 
GetHeapUsedSize(napi_env env,napi_callback_info info)166     static napi_value GetHeapUsedSize(napi_env env, napi_callback_info info)
167     {
168         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
169         auto value = static_cast<uint32_t>(engine->GetHeapUsedSize());
170         napi_value result = nullptr;
171         NAPI_CALL(env, napi_create_uint32(env, value, &result));
172         return result;
173     }
174 
DfxInit(napi_env env,napi_value exports)175     static napi_value DfxInit(napi_env env, napi_value exports)
176     {
177         static napi_property_descriptor desc[] = {
178             DECLARE_NAPI_FUNCTION("dumpHeapSnapshot", DumpHeapSnapshot),
179             DECLARE_NAPI_FUNCTION("buildNativeAndJsStackTrace", BuildNativeAndJsStackTrace),
180             DECLARE_NAPI_FUNCTION("startHeapTracking", StartHeapTracking),
181             DECLARE_NAPI_FUNCTION("stopHeapTracking", StopHeapTracking),
182             DECLARE_NAPI_FUNCTION("printStatisticResult", PrintStatisticResult),
183             DECLARE_NAPI_FUNCTION("startRuntimeStat", StartRuntimeStat),
184             DECLARE_NAPI_FUNCTION("stopRuntimeStat", StopRuntimeStat),
185             DECLARE_NAPI_FUNCTION("getArrayBufferSize", GetArrayBufferSize),
186             DECLARE_NAPI_FUNCTION("getHeapTotalSize", GetHeapTotalSize),
187             DECLARE_NAPI_FUNCTION("getHeapUsedSize", GetHeapUsedSize),
188         };
189         NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
190         return exports;
191     }
192 
193     // dfx module define
194     static napi_module dfxModule = {
195         .nm_version = 1,
196         .nm_flags = 0,
197         .nm_filename = nullptr,
198         .nm_register_func = DfxInit,
199         .nm_modname = "dfx",
200         .nm_priv = reinterpret_cast<void*>(0),
201         .reserved = {0},
202     };
203 
204     // dfx module register
205     extern "C"
RegisterModule()206     __attribute__((constructor)) void RegisterModule()
207     {
208         napi_module_register(&dfxModule);
209     }
210 } // namespace OHOS::JsSysModule::Dfx
211