6#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX) || \
7 defined(DART_HOST_OS_MACOS)
15#include <sys/syscall.h>
18#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
29#if defined(VIRTUAL_MEMORY_LOGGING)
30#define LOG_INFO(msg, ...) OS::PrintErr(msg, ##__VA_ARGS__)
32#define LOG_INFO(msg, ...)
40#define MAP_FAILED reinterpret_cast<void*>(-1)
42#if defined(DART_HOST_OS_IOS)
43#define LARGE_RESERVATIONS_MAY_FAIL
48#if defined(DART_TARGET_OS_LINUX)
53uword VirtualMemory::page_size_ = 0;
54VirtualMemory* VirtualMemory::compressed_heap_ =
nullptr;
56static void* Map(
void*
addr,
81 if (munmap(
reinterpret_cast<void*
>(start),
size) != 0) {
90static void* GenericMapAligned(
void* hint,
94 intptr_t allocated_size,
96 void* address = Map(hint, allocated_size, prot, map_flags, -1, 0);
97 if (address == MAP_FAILED) {
104 Unmap(
base, aligned_base);
105 Unmap(aligned_base +
size,
base + allocated_size);
106 return reinterpret_cast<void*
>(aligned_base);
109intptr_t VirtualMemory::CalculatePageSize() {
110 const intptr_t page_size = getpagesize();
116#if defined(DART_COMPRESSED_POINTERS) && defined(LARGE_RESERVATIONS_MAY_FAIL)
119static MemoryRegion ClipToAlignedRegion(MemoryRegion
region,
size_t alignment) {
125 region.end() >= aligned_base ?
region.end() - aligned_base : 0;
127 if (size_below >= size_above) {
128 Unmap(aligned_base, aligned_base + size_above);
129 return MemoryRegion(
reinterpret_cast<void*
>(
base), size_below);
132 if (size_above > alignment) {
133 Unmap(aligned_base + alignment, aligned_base + size_above);
134 size_above = alignment;
136 return MemoryRegion(
reinterpret_cast<void*
>(aligned_base), size_above);
141 if (FLAG_old_gen_heap_size < 0 || FLAG_old_gen_heap_size >
kMaxAddrSpaceMB) {
143 "warning: value specified for --old_gen_heap_size %d is larger than"
144 " the physically addressable range, using 0(unlimited) instead.`\n",
145 FLAG_old_gen_heap_size);
146 FLAG_old_gen_heap_size = 0;
148 if (FLAG_new_gen_semi_max_size < 0 ||
151 "warning: value specified for --new_gen_semi_max_size %d is larger"
152 " than the physically addressable range, using %" Pd " instead.`\n",
156 page_size_ = CalculatePageSize();
157#if defined(DART_COMPRESSED_POINTERS)
158 ASSERT(compressed_heap_ ==
nullptr);
159#if defined(LARGE_RESERVATIONS_MAY_FAIL)
164 for (
size_t allocated_size = kCompressedHeapSize + kCompressedHeapAlignment;
165 allocated_size >= kCompressedPageSize; allocated_size >>= 1) {
166 void*
address = GenericMapAligned(
167 nullptr, PROT_NONE, allocated_size, kCompressedPageSize,
168 allocated_size + kCompressedPageSize,
169 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE);
170 if (
address ==
nullptr)
continue;
173 region = ClipToAlignedRegion(
region, kCompressedHeapAlignment);
178 compressed_heap_ = Reserve(kCompressedHeapSize, kCompressedHeapAlignment);
180 if (compressed_heap_ ==
nullptr) {
184 FATAL(
"Failed to reserve region for compressed heap: %d (%s)",
error,
188 compressed_heap_->
size());
191#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
192 FILE*
fp = fopen(
"/proc/sys/vm/max_map_count",
"r");
194 size_t max_map_count = 0;
195 int count = fscanf(
fp,
"%zu", &max_map_count);
198 size_t max_heap_pages = FLAG_old_gen_heap_size *
MB /
kPageSize;
199 if (max_map_count < max_heap_pages) {
201 "warning: vm.max_map_count (%zu) is not large enough to support "
202 "--old_gen_heap_size=%d. Consider increasing it with `sysctl -w "
203 "vm.max_map_count=%zu`\n",
204 max_map_count, FLAG_old_gen_heap_size, max_heap_pages);
212#if defined(DART_COMPRESSED_POINTERS)
213 delete compressed_heap_;
216#if defined(DART_COMPRESSED_POINTERS)
217 compressed_heap_ =
nullptr;
235#if defined(DART_COMPRESSED_POINTERS)
240 if (
region.pointer() ==
nullptr) {
241#if defined(LARGE_RESERVATIONS_MAY_FAIL)
245 GenericMapAligned(
nullptr, PROT_READ | PROT_WRITE,
size, alignment,
246 size + alignment, MAP_PRIVATE | MAP_ANONYMOUS);
249 kCompressedHeapAlignment);
250 uword ok_end = ok_start + kCompressedHeapSize;
253 if ((
start >= ok_start) && (
end <= ok_end)) {
267 const intptr_t allocated_size =
size + alignment -
PageSize();
269 PROT_READ | PROT_WRITE |
270 ((is_executable && !FLAG_write_protect_code) ? PROT_EXEC : 0);
272 int map_flags = MAP_PRIVATE | MAP_ANONYMOUS;
273#if (defined(DART_HOST_OS_MACOS) && !defined(DART_HOST_OS_IOS))
274 if (is_executable && IsAtLeastOS10_14()) {
275 map_flags |= MAP_JIT;
279 void* hint =
nullptr;
289 GenericMapAligned(hint, prot,
size, alignment, allocated_size, map_flags);
290#if defined(DART_HOST_OS_LINUX)
296 if (
address ==
nullptr && hint !=
nullptr &&
297 Utils::IsWindowsSubsystemForLinux()) {
298 address = GenericMapAligned(
nullptr, prot,
size, alignment, allocated_size,
306#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_LINUX)
309#if !defined(PR_SET_VMA)
310#define PR_SET_VMA 0x53564d41
312#if !defined(PR_SET_VMA_ANON_NAME)
313#define PR_SET_VMA_ANON_NAME 0
322VirtualMemory* VirtualMemory::Reserve(intptr_t
size, intptr_t alignment) {
326 intptr_t allocated_size =
size + alignment -
PageSize();
328 GenericMapAligned(
nullptr, PROT_NONE,
size, alignment, allocated_size,
329 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE);
337void VirtualMemory::Commit(
void* address, intptr_t
size) {
341 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
342 if (
result == MAP_FAILED) {
351void VirtualMemory::Decommit(
void* address, intptr_t
size) {
356 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_FIXED, -1, 0);
357 if (
result == MAP_FAILED) {
367#if defined(DART_COMPRESSED_POINTERS)
369 (
this != compressed_heap_)) {
376 Unmap(reserved_.
start(), reserved_.
end());
380bool VirtualMemory::FreeSubSegment(
void* address, intptr_t
size) {
381#if defined(DART_COMPRESSED_POINTERS)
395 ASSERT(thread ==
nullptr || thread->IsDartMutatorThread() ||
396 thread->isolate() ==
nullptr ||
397 thread->isolate()->mutator_thread()->IsAtSafepoint());
400 uword end_address = start_address +
size;
411 prot = PROT_READ | PROT_WRITE;
414 prot = PROT_READ | PROT_EXEC;
417 prot = PROT_READ | PROT_WRITE | PROT_EXEC;
420 if (mprotect(
reinterpret_cast<void*
>(page_address),
421 end_address - page_address, prot) != 0) {
425 LOG_INFO(
"mprotect(0x%" Px ", 0x%" Px ", %u) failed\n", page_address,
426 end_address - page_address, prot);
430 LOG_INFO(
"mprotect(0x%" Px ", 0x%" Px ", %u) ok\n", page_address,
431 end_address - page_address, prot);
436 uword end_address = start_address +
size;
438#if defined(DART_HOST_OS_MACOS)
439 int advice = MADV_FREE;
441 int advice = MADV_DONTNEED;
443 if (madvise(
reinterpret_cast<void*
>(page_address), end_address - page_address,
static const size_t kBufferSize
#define RELEASE_ASSERT(cond)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static Thread * Current()
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
static char * StrError(int err, char *buffer, size_t bufsize)
static constexpr T RoundDown(T x, intptr_t alignment)
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
static constexpr bool IsPowerOfTwo(T x)
static VirtualMemory * AllocateAligned(intptr_t size, intptr_t alignment, bool is_executable, bool is_compressed, const char *name)
static void Protect(void *address, intptr_t size, Protection mode)
static intptr_t PageSize()
bool vm_owns_region() const
static void DontNeed(void *address, intptr_t size)
FlutterSemanticsFlag flags
const uint8_t uint32_t uint32_t GError ** error
ClipOpAndAA opAA SkRegion region
bool Contains(const Container &container, const Value &value)
static constexpr intptr_t kPageSize
static void * Allocate(uword size, Zone *zone)
const intptr_t kDefaultNewGenSemiMaxSize
DART_EXPORT char * Dart_Initialize(Dart_InitializeParams *params)
static void Free(FreeList *free_list, uword address, intptr_t size, bool is_protected)
const intptr_t kMaxAddrSpaceMB
DECLARE_FLAG(bool, show_invisible_frames)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size