6#if defined(DART_HOST_OS_FUCHSIA)
10#include <zircon/process.h>
11#include <zircon/status.h>
12#include <zircon/syscalls.h>
25#if defined(VIRTUAL_MEMORY_LOGGING)
26#define LOG_ERR(msg, ...) \
27 OS::PrintErr("VMVM: %s:%d: " msg, __FILE__, __LINE__, ##__VA_ARGS__)
28#define LOG_INFO(msg, ...) \
29 OS::PrintErr("VMVM: %s:%d: " msg, __FILE__, __LINE__, ##__VA_ARGS__)
31#define LOG_ERR(msg, ...)
32#define LOG_INFO(msg, ...)
39uword VirtualMemory::page_size_ = 0;
41#if defined(DART_COMPRESSED_POINTERS)
42static zx_handle_t compressed_heap_vmar_ = ZX_HANDLE_INVALID;
43static uword compressed_heap_base_ = 0;
45static zx_handle_t vmex_resource_ = ZX_HANDLE_INVALID;
47intptr_t VirtualMemory::CalculatePageSize() {
48 const intptr_t page_size = getpagesize();
55 if (FLAG_old_gen_heap_size < 0 || FLAG_old_gen_heap_size >
kMaxAddrSpaceMB) {
57 "warning: value specified for --old_gen_heap_size %d is larger than"
58 " the physically addressable range, using 0(unlimited) instead.`\n",
59 FLAG_old_gen_heap_size);
60 FLAG_old_gen_heap_size = 0;
62 if (FLAG_new_gen_semi_max_size < 0 ||
65 "warning: value specified for --new_gen_semi_max_size %d is larger"
66 " than the physically addressable range, using %" Pd " instead.`\n",
71#if defined(DART_COMPRESSED_POINTERS)
72 if (compressed_heap_vmar_ == ZX_HANDLE_INVALID) {
73 const zx_vm_option_t align_flag =
75 const zx_vm_option_t
options = ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE |
76 ZX_VM_CAN_MAP_SPECIFIC | align_flag;
79 zx_vmar_allocate(zx_vmar_root_self(),
options, 0, kCompressedHeapSize,
80 &compressed_heap_vmar_, &
region);
81 if (status != ZX_OK) {
82 LOG_ERR(
"zx_vmar_allocate(0x%lx) failed: %s\n", kCompressedHeapSize,
83 zx_status_get_string(status));
85 compressed_heap_base_ =
reinterpret_cast<uword>(
region);
91 page_size_ = CalculatePageSize();
92 vmex_resource_ = vmex_resource;
96 vmex_resource_ = ZX_HANDLE_INVALID;
99#if defined(DART_COMPRESSED_POINTERS)
100 zx_vmar_destroy(compressed_heap_vmar_);
101 compressed_heap_vmar_ = ZX_HANDLE_INVALID;
102 compressed_heap_base_ = 0;
106static zx_handle_t getVmarForAddress(
uword address) {
107#if defined(DART_COMPRESSED_POINTERS)
108 if (address - compressed_heap_base_ < kCompressedHeapSize) {
109 return compressed_heap_vmar_;
112 return zx_vmar_root_self();
115static void Unmap(zx_handle_t vmar,
uword start,
uword end) {
122 zx_status_t status = zx_vmar_unmap(vmar, start,
size);
123 if (status != ZX_OK) {
124 FATAL(
"zx_vmar_unmap failed: %s\n", zx_status_get_string(status));
143 ASSERT((ZX_VM_ALIGN_1KB <= align_flag) && (align_flag <= ZX_VM_ALIGN_4GB));
145#if defined(DART_COMPRESSED_POINTERS)
149 vmar = compressed_heap_vmar_;
151 vmar = zx_vmar_root_self();
154 zx_handle_t vmar = zx_vmar_root_self();
156 zx_handle_t vmo = ZX_HANDLE_INVALID;
157 zx_status_t status = zx_vmo_create(
size, 0u, &vmo);
158 if (status == ZX_ERR_NO_MEMORY) {
159 LOG_ERR(
"zx_vmo_create(0x%lx) failed: %s\n",
size,
160 zx_status_get_string(status));
162 }
else if (status != ZX_OK) {
163 FATAL(
"zx_vmo_create(0x%lx) failed: %s\n",
size,
164 zx_status_get_string(status));
167 if (
name !=
nullptr) {
168 zx_object_set_property(vmo, ZX_PROP_NAME,
name, strlen(
name));
174 status = zx_vmo_replace_as_executable(vmo, vmex_resource_, &vmo);
175 if (status == ZX_ERR_NO_MEMORY) {
176 LOG_ERR(
"zx_vmo_replace_as_executable() failed: %s\n",
177 zx_status_get_string(status));
178 zx_handle_close(vmo);
180 }
else if (status != ZX_OK) {
181 FATAL(
"zx_vmo_replace_as_executable() failed: %s\n",
182 zx_status_get_string(status));
186 const zx_vm_option_t region_options =
187 ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | align_flag |
188 ((is_executable && !FLAG_write_protect_code) ? ZX_VM_PERM_EXECUTE : 0);
190 status = zx_vmar_map(vmar, region_options, 0, vmo, 0u,
size, &
base);
192 if (status != ZX_OK) {
193 LOG_ERR(
"zx_vmar_map(%u, 0x%lx, 0x%lx) failed: %s\n", region_options,
base,
194 size, zx_status_get_string(status));
195 zx_handle_close(vmo);
198 void* region_ptr =
reinterpret_cast<void*
>(
base);
201 zx_handle_close(vmo);
203#if defined(DART_COMPRESSED_POINTERS)
204 if (!is_executable) {
216 Unmap(getVmarForAddress(reserved_.
start()), reserved_.
start(),
218 LOG_INFO(
"zx_vmar_unmap(0x%lx, 0x%lx) success\n", reserved_.
start(),
223bool VirtualMemory::FreeSubSegment(
void* address, intptr_t
size) {
233 ASSERT(thread ==
nullptr || thread->IsDartMutatorThread() ||
234 thread->isolate() ==
nullptr ||
235 thread->isolate()->mutator_thread()->IsAtSafepoint());
238 const uword end_address = start_address +
size;
246 prot = ZX_VM_PERM_READ;
249 prot = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;
252 prot = ZX_VM_PERM_READ | ZX_VM_PERM_EXECUTE;
255 prot = ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_PERM_EXECUTE;
259 zx_vmar_protect(getVmarForAddress(page_address), prot, page_address,
260 end_address - page_address);
261 LOG_INFO(
"zx_vmar_protect(%u, 0x%lx, 0x%lx)\n", prot, page_address,
262 end_address - page_address);
263 if (status != ZX_OK) {
264 FATAL(
"zx_vmar_protect(0x%lx, 0x%lx) failed: %s\n", page_address,
265 end_address - page_address, zx_status_get_string(status));
271 uword end_address = start_address +
size;
273 zx_status_t status = zx_vmar_op_range(
274 getVmarForAddress(
reinterpret_cast<uword>(
address)), ZX_VMAR_OP_DONT_NEED,
275 page_address, end_address - page_address,
nullptr, 0);
276 LOG_INFO(
"zx_vmar_op_range(DONTNEED, 0x%lx, 0x%lx)\n", page_address,
277 end_address - page_address);
278 if (status != ZX_OK) {
279 FATAL(
"zx_vmar_op_range(DONTNEED, 0x%lx, 0x%lx) failed: %s\n", page_address,
280 end_address - page_address, zx_status_get_string(status));
#define RELEASE_ASSERT(cond)
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static Thread * Current()
static constexpr int ShiftForPowerOfTwo(T x)
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)
ClipOpAndAA opAA SkRegion region
const intptr_t kDefaultNewGenSemiMaxSize
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