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 "ecmascript/platform/map.h" 17 18#include <io.h> 19#include <windows.h> 20 21#ifdef ERROR 22#undef ERROR 23#endif 24 25#ifdef VOID 26#undef VOID 27#endif 28 29#ifdef CONST 30#undef CONST 31#endif 32 33#include "ecmascript/log_wrapper.h" 34#include "ecmascript/mem/mem.h" 35 36namespace panda::ecmascript { 37static constexpr int INSUFFICIENT_CONTINUOUS_MEM = 1455; 38 39MemMap PageMap(size_t size, int prot, size_t alignment, void *addr, [[maybe_unused]] int flags) 40{ 41 ASSERT(size == AlignUp(size, PageSize())); 42 ASSERT(alignment == AlignUp(alignment, PageSize())); 43 size_t allocSize = size + alignment; 44 void *result = VirtualAlloc(addr, allocSize, MEM_COMMIT, prot); 45 if (result == nullptr) { 46 int errCode = GetLastError(); 47 if (errCode == INSUFFICIENT_CONTINUOUS_MEM) { 48 LOG_NO_TAG(ERROR) << "[ArkRuntime Log]Failed to request a continuous segment of " << size 49 << " virtual memory. Please clean up other heavy processes or restart the computer."; 50 } 51 LOG_ECMA(FATAL) << "PageMap "<< size << ", prot:" << prot << " fail, the error code is: " << errCode; 52 } 53 if (alignment != 0) { 54 auto alignResult = AlignUp(reinterpret_cast<uintptr_t>(result), alignment); 55 return MemMap(result, reinterpret_cast<void *>(alignResult), size); 56 } 57 return MemMap(result, result, size); 58} 59 60void PageUnmap(MemMap it) 61{ 62 if (!VirtualFree(it.GetOriginAddr(), 0, MEM_RELEASE)) { 63 int errCode = GetLastError(); 64 LOG_ECMA(ERROR) << "PageUnmap failed, error code is " << errCode; 65 } 66} 67 68MemMap MachineCodePageMap(size_t size, int prot, size_t alignment) 69{ 70 MemMap memMap = PageMap(size, prot, alignment); 71 PageTag(memMap.GetMem(), memMap.GetSize(), PageTagType::MACHINE_CODE); 72 return memMap; 73} 74 75void MachineCodePageUnmap(MemMap it) 76{ 77 PageClearTag(it.GetMem(), it.GetSize()); 78 if (!PageProtect(it.GetMem(), it.GetSize(), PAGE_PROT_NONE)) { 79 return; 80 } 81 PageUnmap(it); 82} 83 84void PageRelease([[maybe_unused]] void *mem, [[maybe_unused]] size_t size) 85{ 86} 87 88void PagePreRead([[maybe_unused]] void *mem, [[maybe_unused]] size_t size) 89{ 90} 91 92void PageTag([[maybe_unused]] void *mem, [[maybe_unused]] size_t size, [[maybe_unused]] PageTagType type, 93 [[maybe_unused]] const std::string &spaceName, [[maybe_unused]] const uint32_t threadId) 94{ 95} 96 97void PageClearTag([[maybe_unused]] void *mem, [[maybe_unused]] size_t size) 98{ 99} 100 101bool PageProtect(void *mem, size_t size, int prot) 102{ 103 [[maybe_unused]] DWORD oldProtect; 104 if (!VirtualProtect(mem, size, prot, &oldProtect)) { 105 int errCode = GetLastError(); 106 LOG_ECMA(ERROR) << "PageProtect mem = " << mem << ", size = " << size << 107 ", change to " << prot << " failed, error code is " << errCode; 108 return false; 109 } 110 return true; 111} 112 113size_t PageSize() 114{ 115 SYSTEM_INFO info; 116 GetSystemInfo(&info); 117 return info.dwPageSize; 118} 119} // namespace panda::ecmascript 120