10 #include <semaphore.h> 21 #include "src/base/macros.h" 22 #include "src/base/platform/platform-posix.h" 23 #include "src/base/platform/platform.h" 24 #include "src/base/win32-headers.h" 33 DWORD GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
35 case OS::MemoryPermission::kNoAccess:
37 case OS::MemoryPermission::kRead:
39 case OS::MemoryPermission::kReadWrite:
40 return PAGE_READWRITE;
41 case OS::MemoryPermission::kReadWriteExecute:
42 return PAGE_EXECUTE_READWRITE;
43 case OS::MemoryPermission::kReadExecute:
44 return PAGE_EXECUTE_READ;
49 uint8_t* RandomizedVirtualAlloc(
size_t size, DWORD flags, DWORD protect,
51 LPVOID base =
nullptr;
54 if (protect != PAGE_READWRITE) {
55 base = VirtualAlloc(hint, size, flags, protect);
59 if (base ==
nullptr) {
60 base = VirtualAlloc(
nullptr, size, flags, protect);
63 return reinterpret_cast<uint8_t*
>(base);
69 const char* LocalTimezone(
double time)
override;
71 double LocalTimeOffset(
double time_ms,
bool is_utc)
override;
76 const char* CygwinTimezoneCache::LocalTimezone(
double time) {
77 if (std::isnan(time))
return "";
78 time_t tv =
static_cast<time_t
>(std::floor(time/msPerSecond));
80 struct tm* t = localtime_r(&tv, &tm);
81 if (
nullptr == t)
return "";
85 double LocalTimeOffset(
double time_ms,
bool is_utc) {
87 time_t utc = time(
nullptr);
90 struct tm* loc = localtime_r(&utc, &tm);
93 return static_cast<double>((mktime(loc) - utc) * msPerSecond -
94 (loc->tm_isdst > 0 ? 3600 * msPerSecond : 0));
98 void* OS::Allocate(
void* address,
size_t size,
size_t alignment,
99 MemoryPermission access) {
100 size_t page_size = AllocatePageSize();
101 DCHECK_EQ(0, size % page_size);
102 DCHECK_EQ(0, alignment % page_size);
103 DCHECK_LE(page_size, alignment);
104 address = AlignedAddress(address, alignment);
106 DWORD flags = (access == OS::MemoryPermission::kNoAccess)
108 : MEM_RESERVE | MEM_COMMIT;
109 DWORD protect = GetProtectionFromMemoryPermission(access);
112 uint8_t* base = RandomizedVirtualAlloc(size, flags, protect, address);
113 if (base ==
nullptr)
return nullptr;
116 uint8_t* aligned_base = RoundUp(base, alignment);
117 if (base == aligned_base)
return reinterpret_cast<void*
>(base);
120 CHECK(Free(base, size));
127 size_t padded_size = size + (alignment - page_size);
128 const int kMaxAttempts = 3;
129 aligned_base =
nullptr;
130 for (
int i = 0;
i < kMaxAttempts; ++
i) {
131 base = RandomizedVirtualAlloc(padded_size, flags, protect, address);
132 if (base ==
nullptr)
return nullptr;
136 CHECK(Free(base, padded_size));
137 aligned_base = RoundUp(base, alignment);
138 base =
reinterpret_cast<uint8_t*
>(
139 VirtualAlloc(aligned_base, size, flags, protect));
142 if (base !=
nullptr)
break;
144 DCHECK_IMPLIES(base, base == aligned_base);
145 return reinterpret_cast<void*
>(base);
149 bool OS::Free(
void* address,
const size_t size) {
150 DCHECK_EQ(0, static_cast<uintptr_t>(address) % AllocatePageSize());
151 DCHECK_EQ(0, size % AllocatePageSize());
153 return VirtualFree(address, 0, MEM_RELEASE) != 0;
157 bool OS::Release(
void* address,
size_t size) {
158 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
159 DCHECK_EQ(0, size % CommitPageSize());
160 return VirtualFree(address, size, MEM_DECOMMIT) != 0;
164 bool OS::SetPermissions(
void* address,
size_t size, MemoryPermission access) {
165 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
166 DCHECK_EQ(0, size % CommitPageSize());
167 if (access == MemoryPermission::kNoAccess) {
168 return VirtualFree(address, size, MEM_DECOMMIT) != 0;
170 DWORD protect = GetProtectionFromMemoryPermission(access);
171 return VirtualAlloc(address, size, MEM_COMMIT, protect) !=
nullptr;
175 bool OS::DiscardSystemPages(
void* address,
size_t size) {
178 using DiscardVirtualMemoryFunction =
179 DWORD(WINAPI*)(PVOID virtualAddress, SIZE_T size);
180 static std::atomic<DiscardVirtualMemoryFunction> discard_virtual_memory(
181 reinterpret_cast<DiscardVirtualMemoryFunction>(-1));
182 if (discard_virtual_memory ==
183 reinterpret_cast<DiscardVirtualMemoryFunction>(-1))
184 discard_virtual_memory =
185 reinterpret_cast<DiscardVirtualMemoryFunction
>(GetProcAddress(
186 GetModuleHandle(L
"Kernel32.dll"),
"DiscardVirtualMemory"));
189 DiscardVirtualMemoryFunction discard_function = discard_virtual_memory.load();
190 if (discard_function) {
191 DWORD ret = discard_function(address, size);
192 if (!ret)
return true;
196 void* ptr = VirtualAlloc(address, size, MEM_RESET, PAGE_READWRITE);
202 bool OS::HasLazyCommits() {
207 std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
208 std::vector<SharedLibraryAddresses> result;
212 FILE* fp = fopen(
"/proc/self/maps",
"r");
213 if (fp ==
nullptr)
return result;
216 const int kLibNameLen = FILENAME_MAX + 1;
217 char* lib_name =
reinterpret_cast<char*
>(malloc(kLibNameLen));
222 char attr_r, attr_w, attr_x, attr_p;
224 if (fscanf(fp,
"%" V8PRIxPTR
"-%" V8PRIxPTR, &start, &end) != 2)
break;
225 if (fscanf(fp,
" %c%c%c%c", &attr_r, &attr_w, &attr_x, &attr_p) != 4)
break;
228 if (attr_r ==
'r' && attr_w !=
'w' && attr_x ==
'x') {
233 }
while ((c != EOF) && (c !=
'\n') && (c !=
'/'));
241 if (fgets(lib_name, kLibNameLen, fp) ==
nullptr)
break;
246 lib_name[strlen(lib_name) - 1] =
'\0';
249 snprintf(lib_name, kLibNameLen,
250 "%08" V8PRIxPTR
"-%08" V8PRIxPTR, start, end);
252 result.push_back(SharedLibraryAddress(lib_name, start, end));
258 }
while ((c != EOF) && (c !=
'\n'));
267 void OS::SignalCodeMovingGC() {