14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2022 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#include "ecmascript/platform/map.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include <io.h>
194514f5e3Sopenharmony_ci#include <windows.h>
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_ci#ifdef ERROR
224514f5e3Sopenharmony_ci#undef ERROR
234514f5e3Sopenharmony_ci#endif
244514f5e3Sopenharmony_ci
254514f5e3Sopenharmony_ci#ifdef VOID
264514f5e3Sopenharmony_ci#undef VOID
274514f5e3Sopenharmony_ci#endif
284514f5e3Sopenharmony_ci
294514f5e3Sopenharmony_ci#ifdef CONST
304514f5e3Sopenharmony_ci#undef CONST
314514f5e3Sopenharmony_ci#endif
324514f5e3Sopenharmony_ci
334514f5e3Sopenharmony_ci#include "ecmascript/log_wrapper.h"
344514f5e3Sopenharmony_ci#include "ecmascript/mem/mem.h"
354514f5e3Sopenharmony_ci
364514f5e3Sopenharmony_cinamespace panda::ecmascript {
374514f5e3Sopenharmony_cistatic constexpr int INSUFFICIENT_CONTINUOUS_MEM = 1455;
384514f5e3Sopenharmony_ci
394514f5e3Sopenharmony_ciMemMap PageMap(size_t size, int prot, size_t alignment, void *addr, [[maybe_unused]] int flags)
404514f5e3Sopenharmony_ci{
414514f5e3Sopenharmony_ci    ASSERT(size == AlignUp(size, PageSize()));
424514f5e3Sopenharmony_ci    ASSERT(alignment == AlignUp(alignment, PageSize()));
434514f5e3Sopenharmony_ci    size_t allocSize = size + alignment;
444514f5e3Sopenharmony_ci    void *result = VirtualAlloc(addr, allocSize, MEM_COMMIT, prot);
454514f5e3Sopenharmony_ci    if (result == nullptr) {
464514f5e3Sopenharmony_ci        int errCode = GetLastError();
474514f5e3Sopenharmony_ci        if (errCode == INSUFFICIENT_CONTINUOUS_MEM) {
484514f5e3Sopenharmony_ci            LOG_NO_TAG(ERROR) << "[ArkRuntime Log]Failed to request a continuous segment of " << size
494514f5e3Sopenharmony_ci                              << " virtual memory. Please clean up other heavy processes or restart the computer.";
504514f5e3Sopenharmony_ci        }
514514f5e3Sopenharmony_ci        LOG_ECMA(FATAL) << "PageMap "<< size << ", prot:" << prot << " fail, the error code is: " << errCode;
524514f5e3Sopenharmony_ci    }
534514f5e3Sopenharmony_ci    if (alignment != 0) {
544514f5e3Sopenharmony_ci        auto alignResult = AlignUp(reinterpret_cast<uintptr_t>(result), alignment);
554514f5e3Sopenharmony_ci        return MemMap(result, reinterpret_cast<void *>(alignResult), size);
564514f5e3Sopenharmony_ci    }
574514f5e3Sopenharmony_ci    return MemMap(result, result, size);
584514f5e3Sopenharmony_ci}
594514f5e3Sopenharmony_ci
604514f5e3Sopenharmony_civoid PageUnmap(MemMap it)
614514f5e3Sopenharmony_ci{
624514f5e3Sopenharmony_ci    if (!VirtualFree(it.GetOriginAddr(), 0, MEM_RELEASE)) {
634514f5e3Sopenharmony_ci        int errCode = GetLastError();
644514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "PageUnmap failed, error code is " << errCode;
654514f5e3Sopenharmony_ci    }
664514f5e3Sopenharmony_ci}
674514f5e3Sopenharmony_ci
684514f5e3Sopenharmony_ciMemMap MachineCodePageMap(size_t size, int prot, size_t alignment)
694514f5e3Sopenharmony_ci{
704514f5e3Sopenharmony_ci    MemMap memMap = PageMap(size, prot, alignment);
714514f5e3Sopenharmony_ci    PageTag(memMap.GetMem(), memMap.GetSize(), PageTagType::MACHINE_CODE);
724514f5e3Sopenharmony_ci    return memMap;
734514f5e3Sopenharmony_ci}
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_civoid MachineCodePageUnmap(MemMap it)
764514f5e3Sopenharmony_ci{
774514f5e3Sopenharmony_ci    PageClearTag(it.GetMem(), it.GetSize());
784514f5e3Sopenharmony_ci    if (!PageProtect(it.GetMem(), it.GetSize(), PAGE_PROT_NONE)) {
794514f5e3Sopenharmony_ci        return;
804514f5e3Sopenharmony_ci    }
814514f5e3Sopenharmony_ci    PageUnmap(it);
824514f5e3Sopenharmony_ci}
834514f5e3Sopenharmony_ci
844514f5e3Sopenharmony_civoid PageRelease([[maybe_unused]] void *mem, [[maybe_unused]] size_t size)
854514f5e3Sopenharmony_ci{
864514f5e3Sopenharmony_ci}
874514f5e3Sopenharmony_ci
884514f5e3Sopenharmony_civoid PagePreRead([[maybe_unused]] void *mem, [[maybe_unused]] size_t size)
894514f5e3Sopenharmony_ci{
904514f5e3Sopenharmony_ci}
914514f5e3Sopenharmony_ci
924514f5e3Sopenharmony_civoid PageTag([[maybe_unused]] void *mem, [[maybe_unused]] size_t size, [[maybe_unused]] PageTagType type,
934514f5e3Sopenharmony_ci             [[maybe_unused]] const std::string &spaceName, [[maybe_unused]] const uint32_t threadId)
944514f5e3Sopenharmony_ci{
954514f5e3Sopenharmony_ci}
964514f5e3Sopenharmony_ci
974514f5e3Sopenharmony_civoid PageClearTag([[maybe_unused]] void *mem, [[maybe_unused]] size_t size)
984514f5e3Sopenharmony_ci{
994514f5e3Sopenharmony_ci}
1004514f5e3Sopenharmony_ci
1014514f5e3Sopenharmony_cibool PageProtect(void *mem, size_t size, int prot)
1024514f5e3Sopenharmony_ci{
1034514f5e3Sopenharmony_ci    [[maybe_unused]] DWORD oldProtect;
1044514f5e3Sopenharmony_ci    if (!VirtualProtect(mem, size, prot, &oldProtect)) {
1054514f5e3Sopenharmony_ci        int errCode = GetLastError();
1064514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "PageProtect mem = " << mem << ", size = " << size <<
1074514f5e3Sopenharmony_ci            ", change to " << prot << " failed, error code is " << errCode;
1084514f5e3Sopenharmony_ci        return false;
1094514f5e3Sopenharmony_ci    }
1104514f5e3Sopenharmony_ci    return true;
1114514f5e3Sopenharmony_ci}
1124514f5e3Sopenharmony_ci
1134514f5e3Sopenharmony_cisize_t PageSize()
1144514f5e3Sopenharmony_ci{
1154514f5e3Sopenharmony_ci    SYSTEM_INFO info;
1164514f5e3Sopenharmony_ci    GetSystemInfo(&info);
1174514f5e3Sopenharmony_ci    return info.dwPageSize;
1184514f5e3Sopenharmony_ci}
1194514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
120