v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
platform-zos.cc
Go to the documentation of this file.
1// Copyright 2024 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Platform-specific code for z/OS goes here. For the POSIX-compatible
6// parts, the implementation is in platform-posix.cc.
7
8// TODO(gabylb): zos - most OS class members here will be removed once mmap
9// is fully implemented on z/OS, after which those in platform-posix.cc will
10// be used.
11
12#include <fcntl.h>
13#include <sys/mman.h>
14#include <sys/stat.h>
15
18
19namespace {
20
21__attribute__((constructor)) void init() {
22 zoslib_config_t config;
23 init_zoslib_config(&config);
24 init_zoslib(config);
25}
26
27} // namespace
28
29namespace v8 {
30namespace base {
31
32void OS::Free(void* address, const size_t size) {
33 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % AllocatePageSize());
34 DCHECK_EQ(0, size % AllocatePageSize());
35 CHECK_EQ(0, __zfree(address, size));
36}
37
38void OS::Release(void* address, size_t size) {
39 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
40 DCHECK_EQ(0, size % CommitPageSize());
41 CHECK_EQ(0, __zfree(address, size));
42}
43
44void* OS::Allocate(void* hint, size_t size, size_t alignment,
45 MemoryPermission access) {
46 return __zalloc(size, alignment);
47}
48
50 const char* LocalTimezone(double time) override;
51 double LocalTimeOffset(double time_ms, bool is_utc) override;
52 ~ZOSTimezoneCache() override {}
53};
54
55const char* ZOSTimezoneCache::LocalTimezone(double time) {
56 if (isnan(time)) return "";
57 time_t tv = static_cast<time_t>(std::floor(time / msPerSecond));
58 struct tm tm;
59 struct tm* t = localtime_r(&tv, &tm);
60 if (t == nullptr) return "";
61 return tzname[0];
62}
63
64double ZOSTimezoneCache::LocalTimeOffset(double time_ms, bool is_utc) {
65 time_t tv = time(nullptr);
66 struct tm tmv;
67 struct tm* gmt = gmtime_r(&tv, &tmv);
68 double gm_secs = gmt->tm_sec + (gmt->tm_min * 60) + (gmt->tm_hour * 3600);
69 struct tm* localt = localtime_r(&tv, &tmv);
70 double local_secs =
71 localt->tm_sec + (localt->tm_min * 60) + (localt->tm_hour * 3600);
72 return (local_secs - gm_secs) * msPerSecond -
73 (localt->tm_isdst > 0 ? 3600 * msPerSecond : 0);
74}
75
77
78// static
79void* OS::AllocateShared(void* hint, size_t size, MemoryPermission access,
80 PlatformSharedMemoryHandle handle, uint64_t offset) {
81 DCHECK_EQ(0, size % AllocatePageSize());
82 int prot = GetProtectionFromMemoryPermission(access);
84 return mmap(hint, size, prot, MAP_SHARED, fd, offset);
85}
86
87// static
88void OS::FreeShared(void* address, size_t size) {
89 DCHECK_EQ(0, size % AllocatePageSize());
90 CHECK_EQ(0, munmap(address, size));
91}
92
93bool AddressSpaceReservation::AllocateShared(void* address, size_t size,
96 uint64_t offset) {
97 DCHECK(Contains(address, size));
98 int prot = GetProtectionFromMemoryPermission(access);
100 return mmap(address, size, prot, MAP_SHARED | MAP_FIXED, fd, offset) !=
101 MAP_FAILED;
102}
103
104bool AddressSpaceReservation::FreeShared(void* address, size_t size) {
105 DCHECK(Contains(address, size));
106 return mmap(address, size, PROT_NONE, MAP_FIXED | MAP_PRIVATE, -1, 0) !=
107 MAP_FAILED;
108}
109
110std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
111 std::vector<SharedLibraryAddress> result;
112 return result;
113}
114
116
118
119// static
120bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
121 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
122 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
123 DCHECK_EQ(0, size % CommitPageSize());
124 return true;
125}
126
127void OS::SetDataReadOnly(void* address, size_t size) {
128 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
129 DCHECK_EQ(0, size % CommitPageSize());
130}
131
132// static
133bool OS::RecommitPages(void* address, size_t size, MemoryPermission access) {
134 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
135 DCHECK_EQ(0, size % CommitPageSize());
136 return SetPermissions(address, size, access);
137}
138
139// static
140bool OS::DiscardSystemPages(void* address, size_t size) {
141 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
142 DCHECK_EQ(0, size % CommitPageSize());
143 return true;
144}
145
146// static
147bool OS::DecommitPages(void* address, size_t size) {
148 DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
149 DCHECK_EQ(0, size % CommitPageSize());
150 return true;
151}
152
153// static
154bool OS::HasLazyCommits() { return false; }
155
157 public:
158 PosixMemoryMappedFile(FILE* file, void* memory, size_t size, bool ismmap)
159 : file_(file), memory_(memory), size_(size), ismmap_(ismmap) {}
161 void* memory() const final { return memory_; }
162 size_t size() const final { return size_; }
163
164 private:
165 FILE* const file_;
166 void* const memory_;
167 size_t const size_;
169};
170
171// static
173 FileMode mode) {
174 const char* fopen_mode = (mode == FileMode::kReadOnly) ? "r" : "r+";
175 int open_mode = (mode == FileMode::kReadOnly) ? O_RDONLY : O_RDWR;
176 // use open() instead of fopen() to prevent auto-conversion
177 // (which doesn't support untagged file with ASCII content)
178 void* memory = nullptr;
179 if (int fd = ::open(name, open_mode)) {
180 FILE* file = fdopen(fd, fopen_mode); // for PosixMemoryMappedFile()
181 off_t size = lseek(fd, 0, SEEK_END);
182 if (size == 0) return new PosixMemoryMappedFile(file, nullptr, 0, false);
183 bool ismmap;
184 if (size > 0) {
185 int prot = PROT_READ;
186 int flags = MAP_PRIVATE;
187 if (mode == FileMode::kReadWrite) {
188 prot |= PROT_WRITE;
189 flags = MAP_SHARED;
190 memory = mmap(OS::GetRandomMmapAddr(), size, prot, flags, fd, 0);
191 ismmap = true;
192 } else {
193 memory = __zalloc_for_fd(size, name, fd, 0);
194 ismmap = false;
195 }
196 if (memory != MAP_FAILED)
197 return new PosixMemoryMappedFile(file, memory, size, ismmap);
198 } else {
199 perror("lseek");
200 }
201 fclose(file); // also closes fd
202 }
203 return nullptr;
204}
205
206// static
208 size_t size, void* initial) {
209 if (FILE* file = fopen(name, "w+")) {
210 if (size == 0) return new PosixMemoryMappedFile(file, 0, 0, false);
211 size_t result = fwrite(initial, 1, size, file);
212 if (result == size && !ferror(file)) {
213 void* memory = mmap(OS::GetRandomMmapAddr(), result,
214 PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
215 if (memory != MAP_FAILED) {
216 return new PosixMemoryMappedFile(file, memory, result, true);
217 }
218 }
219 fclose(file);
220 }
221 return nullptr;
222}
223
225 if (memory_ != nullptr) {
226 if (ismmap_)
227 munmap(memory_, RoundUp(size_, OS::AllocatePageSize()));
228 else
229 __zfree(memory_, size_);
230 }
231 fclose(file_);
232}
233
234} // namespace base
235} // namespace v8
bool Contains(void *region_addr, size_t region_size) const
Definition platform.h:459
V8_WARN_UNUSED_RESULT bool FreeShared(void *address, size_t size)
V8_WARN_UNUSED_RESULT bool AllocateShared(void *address, size_t size, OS::MemoryPermission access, PlatformSharedMemoryHandle handle, uint64_t offset)
static MemoryMappedFile * create(const char *name, size_t size, void *initial)
static MemoryMappedFile * open(const char *name, FileMode mode=FileMode::kReadWrite)
friend class PosixMemoryMappedFile
Definition platform.h:366
static V8_WARN_UNUSED_RESULT void * AllocateShared(size_t size, MemoryPermission access)
static void * GetRandomMmapAddr()
static void SignalCodeMovingGC()
static bool HasLazyCommits()
static V8_WARN_UNUSED_RESULT bool DiscardSystemPages(void *address, size_t size)
static size_t AllocatePageSize()
static void SetDataReadOnly(void *address, size_t size)
static void FreeShared(void *address, size_t size)
static V8_WARN_UNUSED_RESULT bool SetPermissions(void *address, size_t size, MemoryPermission access)
static V8_WARN_UNUSED_RESULT bool DecommitPages(void *address, size_t size)
static size_t CommitPageSize()
static void Release(void *address, size_t size)
static V8_WARN_UNUSED_RESULT bool RecommitPages(void *address, size_t size, MemoryPermission access)
static std::vector< SharedLibraryAddress > GetSharedLibraryAddresses()
static V8_WARN_UNUSED_RESULT void * Allocate(void *address, size_t size, size_t alignment, MemoryPermission access)
static TimezoneCache * CreateTimezoneCache()
friend class MemoryMappedFile
Definition platform.h:365
static void Free(void *address, size_t size)
static void AdjustSchedulingParams()
PosixMemoryMappedFile(FILE *file, void *memory, size_t size, bool ismmap)
const char * LocalTimezone(double time) override
double LocalTimeOffset(double time_ms, bool is_utc) override
const int size_
Definition assembler.cc:132
int32_t offset
TimeRecord time
ZoneVector< RpoNumber > & result
int GetProtectionFromMemoryPermission(OS::MemoryPermission access)
__attribute__((tls_model(V8_TLS_MODEL))) extern thread_local Isolate *g_current_isolate_ V8_CONSTINIT
int FileDescriptorFromSharedMemoryHandle(PlatformSharedMemoryHandle handle)
intptr_t PlatformSharedMemoryHandle
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
constexpr T RoundUp(T x, intptr_t m)
Definition macros.h:387