14d6c458bSopenharmony_ci/*
24d6c458bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License.
54d6c458bSopenharmony_ci * You may obtain a copy of the License at
64d6c458bSopenharmony_ci *
74d6c458bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84d6c458bSopenharmony_ci *
94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and
134d6c458bSopenharmony_ci * limitations under the License.
144d6c458bSopenharmony_ci */
154d6c458bSopenharmony_ci
164d6c458bSopenharmony_ci#include "commonlibrary/ets_utils/tools/log.h"
174d6c458bSopenharmony_ci#include "napi/native_api.h"
184d6c458bSopenharmony_ci#include "native_engine.h"
194d6c458bSopenharmony_ci#include "napi/native_node_api.h"
204d6c458bSopenharmony_ci#include "securec.h"
214d6c458bSopenharmony_ci
224d6c458bSopenharmony_cinamespace OHOS::JsSysModule::Dfx {
234d6c458bSopenharmony_ci    constexpr int NUMBER_OF_PARAMETER_TWO = 2;
244d6c458bSopenharmony_ci    static napi_value DumpHeapSnapshot(napi_env env, napi_callback_info info)
254d6c458bSopenharmony_ci    {
264d6c458bSopenharmony_ci        size_t argc = NUMBER_OF_PARAMETER_TWO;
274d6c458bSopenharmony_ci        size_t requireArgc = NUMBER_OF_PARAMETER_TWO;
284d6c458bSopenharmony_ci        napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
294d6c458bSopenharmony_ci        NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
304d6c458bSopenharmony_ci        napi_value argv[NUMBER_OF_PARAMETER_TWO] = { 0 };
314d6c458bSopenharmony_ci        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
324d6c458bSopenharmony_ci        std::string tempStr = "";
334d6c458bSopenharmony_ci        size_t tempStrsize = 0;
344d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, argv[0], nullptr, 0, &tempStrsize) != napi_ok) {
354d6c458bSopenharmony_ci            HILOG_ERROR("can not get argv[0] size");
364d6c458bSopenharmony_ci            return nullptr;
374d6c458bSopenharmony_ci        }
384d6c458bSopenharmony_ci        tempStr.reserve(tempStrsize + 1);
394d6c458bSopenharmony_ci        tempStr.resize(tempStrsize);
404d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, argv[0], tempStr.data(), tempStrsize + 1, &tempStrsize) != napi_ok) {
414d6c458bSopenharmony_ci            HILOG_ERROR("can not get argv[0] value");
424d6c458bSopenharmony_ci            return nullptr;
434d6c458bSopenharmony_ci        }
444d6c458bSopenharmony_ci        std::string pathStr = tempStr;
454d6c458bSopenharmony_ci        bool isVmMode = true;
464d6c458bSopenharmony_ci        napi_get_value_bool(env, argv[1], &isVmMode);
474d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
484d6c458bSopenharmony_ci        engine->DumpHeapSnapshot(pathStr, isVmMode);
494d6c458bSopenharmony_ci        napi_value result = nullptr;
504d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_undefined(env, &result));
514d6c458bSopenharmony_ci        return result;
524d6c458bSopenharmony_ci    }
534d6c458bSopenharmony_ci
544d6c458bSopenharmony_ci    static napi_value BuildNativeAndJsStackTrace(napi_env env, napi_callback_info info)
554d6c458bSopenharmony_ci    {
564d6c458bSopenharmony_ci        napi_value result = nullptr;
574d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
584d6c458bSopenharmony_ci        std::string stackTraceResult = "";
594d6c458bSopenharmony_ci        bool temp = engine->BuildNativeAndJsStackTrace(stackTraceResult);
604d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_string_utf8(env, stackTraceResult.c_str(), stackTraceResult.size(), &result));
614d6c458bSopenharmony_ci        if (temp) {
624d6c458bSopenharmony_ci            return result;
634d6c458bSopenharmony_ci        } else {
644d6c458bSopenharmony_ci            return nullptr;
654d6c458bSopenharmony_ci        }
664d6c458bSopenharmony_ci    }
674d6c458bSopenharmony_ci
684d6c458bSopenharmony_ci    static napi_value StartHeapTracking(napi_env env, napi_callback_info info)
694d6c458bSopenharmony_ci    {
704d6c458bSopenharmony_ci        size_t argc = NUMBER_OF_PARAMETER_TWO;
714d6c458bSopenharmony_ci        size_t requireArgc = NUMBER_OF_PARAMETER_TWO;
724d6c458bSopenharmony_ci        napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
734d6c458bSopenharmony_ci        NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
744d6c458bSopenharmony_ci        napi_value argv[NUMBER_OF_PARAMETER_TWO] = { 0 };
754d6c458bSopenharmony_ci        napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
764d6c458bSopenharmony_ci        double timeInterval = 0;
774d6c458bSopenharmony_ci        if (napi_get_value_double(env, argv[0], &timeInterval) != napi_ok) {
784d6c458bSopenharmony_ci            HILOG_ERROR("can not get argv[0] value");
794d6c458bSopenharmony_ci            return nullptr;
804d6c458bSopenharmony_ci        }
814d6c458bSopenharmony_ci        bool isVmMode = true;
824d6c458bSopenharmony_ci        if (napi_get_value_bool(env, argv[1], &isVmMode) != napi_ok) {
834d6c458bSopenharmony_ci            HILOG_ERROR("can not get argv[1] value");
844d6c458bSopenharmony_ci            return nullptr;
854d6c458bSopenharmony_ci        }
864d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
874d6c458bSopenharmony_ci        auto startResult = engine->StartHeapTracking(timeInterval, isVmMode);
884d6c458bSopenharmony_ci        napi_value result = nullptr;
894d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, startResult, &result));
904d6c458bSopenharmony_ci        return result;
914d6c458bSopenharmony_ci    }
924d6c458bSopenharmony_ci
934d6c458bSopenharmony_ci    static napi_value StopHeapTracking(napi_env env, napi_callback_info info)
944d6c458bSopenharmony_ci    {
954d6c458bSopenharmony_ci        size_t argc = 1;
964d6c458bSopenharmony_ci        size_t requireArgc = 1;
974d6c458bSopenharmony_ci        napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr);
984d6c458bSopenharmony_ci        NAPI_ASSERT(env, argc <= requireArgc, "Wrong number of arguments");
994d6c458bSopenharmony_ci        napi_value argv = nullptr;
1004d6c458bSopenharmony_ci        napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
1014d6c458bSopenharmony_ci        std::string tempStr = "";
1024d6c458bSopenharmony_ci        size_t tempStrsize = 0;
1034d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, argv, nullptr, 0, &tempStrsize) != napi_ok) {
1044d6c458bSopenharmony_ci            HILOG_ERROR("can not get argv size");
1054d6c458bSopenharmony_ci            return nullptr;
1064d6c458bSopenharmony_ci        }
1074d6c458bSopenharmony_ci        tempStr.reserve(tempStrsize);
1084d6c458bSopenharmony_ci        tempStr.resize(tempStrsize);
1094d6c458bSopenharmony_ci        if (napi_get_value_string_utf8(env, argv, tempStr.data(), tempStrsize + 1, &tempStrsize) != napi_ok) {
1104d6c458bSopenharmony_ci            HILOG_ERROR("can not get argv value");
1114d6c458bSopenharmony_ci            return nullptr;
1124d6c458bSopenharmony_ci        }
1134d6c458bSopenharmony_ci        std::string filePath = tempStr;
1144d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
1154d6c458bSopenharmony_ci        auto stopResult = engine->StopHeapTracking(filePath);
1164d6c458bSopenharmony_ci        napi_value result = nullptr;
1174d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_boolean(env, stopResult, &result));
1184d6c458bSopenharmony_ci        return result;
1194d6c458bSopenharmony_ci    }
1204d6c458bSopenharmony_ci
1214d6c458bSopenharmony_ci    static napi_value PrintStatisticResult(napi_env env, napi_callback_info info)
1224d6c458bSopenharmony_ci    {
1234d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
1244d6c458bSopenharmony_ci        engine->PrintStatisticResult();
1254d6c458bSopenharmony_ci        napi_value result = nullptr;
1264d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_undefined(env, &result));
1274d6c458bSopenharmony_ci        return result;
1284d6c458bSopenharmony_ci    }
1294d6c458bSopenharmony_ci
1304d6c458bSopenharmony_ci    static napi_value StartRuntimeStat(napi_env env, napi_callback_info info)
1314d6c458bSopenharmony_ci    {
1324d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
1334d6c458bSopenharmony_ci        engine->StartRuntimeStat();
1344d6c458bSopenharmony_ci        napi_value result = nullptr;
1354d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_undefined(env, &result));
1364d6c458bSopenharmony_ci        return result;
1374d6c458bSopenharmony_ci    }
1384d6c458bSopenharmony_ci
1394d6c458bSopenharmony_ci    static napi_value StopRuntimeStat(napi_env env, napi_callback_info info)
1404d6c458bSopenharmony_ci    {
1414d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
1424d6c458bSopenharmony_ci        engine->StopRuntimeStat();
1434d6c458bSopenharmony_ci        napi_value result = nullptr;
1444d6c458bSopenharmony_ci        NAPI_CALL(env, napi_get_undefined(env, &result));
1454d6c458bSopenharmony_ci        return result;
1464d6c458bSopenharmony_ci    }
1474d6c458bSopenharmony_ci
1484d6c458bSopenharmony_ci    static napi_value GetArrayBufferSize(napi_env env, napi_callback_info info)
1494d6c458bSopenharmony_ci    {
1504d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
1514d6c458bSopenharmony_ci        auto value = static_cast<uint32_t>(engine->GetArrayBufferSize());
1524d6c458bSopenharmony_ci        napi_value result = nullptr;
1534d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_uint32(env, value, &result));
1544d6c458bSopenharmony_ci        return result;
1554d6c458bSopenharmony_ci    }
1564d6c458bSopenharmony_ci
1574d6c458bSopenharmony_ci    static napi_value GetHeapTotalSize(napi_env env, napi_callback_info info)
1584d6c458bSopenharmony_ci    {
1594d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
1604d6c458bSopenharmony_ci        auto value = static_cast<uint32_t>(engine->GetHeapTotalSize());
1614d6c458bSopenharmony_ci        napi_value result = nullptr;
1624d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_uint32(env, value, &result));
1634d6c458bSopenharmony_ci        return result;
1644d6c458bSopenharmony_ci    }
1654d6c458bSopenharmony_ci
1664d6c458bSopenharmony_ci    static napi_value GetHeapUsedSize(napi_env env, napi_callback_info info)
1674d6c458bSopenharmony_ci    {
1684d6c458bSopenharmony_ci        NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
1694d6c458bSopenharmony_ci        auto value = static_cast<uint32_t>(engine->GetHeapUsedSize());
1704d6c458bSopenharmony_ci        napi_value result = nullptr;
1714d6c458bSopenharmony_ci        NAPI_CALL(env, napi_create_uint32(env, value, &result));
1724d6c458bSopenharmony_ci        return result;
1734d6c458bSopenharmony_ci    }
1744d6c458bSopenharmony_ci
1754d6c458bSopenharmony_ci    static napi_value DfxInit(napi_env env, napi_value exports)
1764d6c458bSopenharmony_ci    {
1774d6c458bSopenharmony_ci        static napi_property_descriptor desc[] = {
1784d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("dumpHeapSnapshot", DumpHeapSnapshot),
1794d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("buildNativeAndJsStackTrace", BuildNativeAndJsStackTrace),
1804d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("startHeapTracking", StartHeapTracking),
1814d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("stopHeapTracking", StopHeapTracking),
1824d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("printStatisticResult", PrintStatisticResult),
1834d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("startRuntimeStat", StartRuntimeStat),
1844d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("stopRuntimeStat", StopRuntimeStat),
1854d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("getArrayBufferSize", GetArrayBufferSize),
1864d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("getHeapTotalSize", GetHeapTotalSize),
1874d6c458bSopenharmony_ci            DECLARE_NAPI_FUNCTION("getHeapUsedSize", GetHeapUsedSize),
1884d6c458bSopenharmony_ci        };
1894d6c458bSopenharmony_ci        NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
1904d6c458bSopenharmony_ci        return exports;
1914d6c458bSopenharmony_ci    }
1924d6c458bSopenharmony_ci
1934d6c458bSopenharmony_ci    // dfx module define
1944d6c458bSopenharmony_ci    static napi_module dfxModule = {
1954d6c458bSopenharmony_ci        .nm_version = 1,
1964d6c458bSopenharmony_ci        .nm_flags = 0,
1974d6c458bSopenharmony_ci        .nm_filename = nullptr,
1984d6c458bSopenharmony_ci        .nm_register_func = DfxInit,
1994d6c458bSopenharmony_ci        .nm_modname = "dfx",
2004d6c458bSopenharmony_ci        .nm_priv = reinterpret_cast<void*>(0),
2014d6c458bSopenharmony_ci        .reserved = {0},
2024d6c458bSopenharmony_ci    };
2034d6c458bSopenharmony_ci
2044d6c458bSopenharmony_ci    // dfx module register
2054d6c458bSopenharmony_ci    extern "C"
2064d6c458bSopenharmony_ci    __attribute__((constructor)) void RegisterModule()
2074d6c458bSopenharmony_ci    {
2084d6c458bSopenharmony_ci        napi_module_register(&dfxModule);
2094d6c458bSopenharmony_ci    }
2104d6c458bSopenharmony_ci} // namespace OHOS::JsSysModule::Dfx
211