Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
virtual_memory.cc
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/virtual_memory.h"
6
7#include "platform/assert.h"
8#include "platform/utils.h"
9
10#if defined(DART_HOST_OS_MACOS)
11#include <mach/mach.h>
12#endif
13
14namespace dart {
15
16bool VirtualMemory::InSamePage(uword address0, uword address1) {
17 return (Utils::RoundDown(address0, PageSize()) ==
18 Utils::RoundDown(address1, PageSize()));
19}
20
21void VirtualMemory::Truncate(intptr_t new_size) {
22 ASSERT(Utils::IsAligned(new_size, PageSize()));
23 ASSERT(new_size <= size());
24 if (reserved_.size() ==
25 region_.size()) { // Don't create holes in reservation.
26 if (FreeSubSegment(reinterpret_cast<void*>(start() + new_size),
27 size() - new_size)) {
28 reserved_.set_size(new_size);
29 }
30 }
31 region_.Subregion(region_, 0, new_size);
32}
33
35 // Memory for precompilated instructions was allocated by the embedder, so
36 // create a VirtualMemory without allocating.
37 MemoryRegion region(pointer, size);
38 MemoryRegion reserved(nullptr, 0); // null reservation indicates VM should
39 // not attempt to free this memory.
40 VirtualMemory* memory = new VirtualMemory(region, reserved);
41 ASSERT(!memory->vm_owns_region());
42 return memory;
43}
44
45#if !defined(DART_TARGET_OS_FUCHSIA)
46// TODO(52579): Reenable on Fuchsia.
47
49 const intptr_t aligned_size = Utils::RoundUp(size(), PageSize());
50 ASSERT_LESS_OR_EQUAL(aligned_size, target->size());
51
52#if defined(DART_HOST_OS_MACOS) && defined(DART_PRECOMPILED_RUNTIME)
53 // Mac is special cased because iOS doesn't allow allocating new executable
54 // memory, so the default approach would fail. We are allowed to make new
55 // mappings of existing executable memory using vm_remap though, which is
56 // effectively the same for non-writable memory.
57 const mach_port_t task = mach_task_self();
58 const vm_address_t source_address = reinterpret_cast<vm_address_t>(address());
59 const vm_size_t mem_size = aligned_size;
60 const vm_prot_t read_execute = VM_PROT_READ | VM_PROT_EXECUTE;
61 vm_prot_t current_protection = read_execute;
62 vm_prot_t max_protection = read_execute;
63 vm_address_t target_address =
64 reinterpret_cast<vm_address_t>(target->address());
65 kern_return_t status = vm_remap(
66 task, &target_address, mem_size,
67 /*mask=*/0,
68 /*flags=*/VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, task, source_address,
69 /*copy=*/true, &current_protection, &max_protection,
70 /*inheritance=*/VM_INHERIT_NONE);
71 if (status != KERN_SUCCESS) {
72 return false;
73 }
74 ASSERT(reinterpret_cast<void*>(target_address) == target->address());
75 ASSERT_EQUAL(current_protection & read_execute, read_execute);
76 ASSERT_EQUAL(max_protection & read_execute, read_execute);
77 return true;
78
79#else // defined(DART_HOST_OS_MACOS)
80 // TODO(52497): Use dual mapping on platforms where it's supported.
81 // Check that target doesn't overlap with this.
82 ASSERT(target->start() >= end() || target->end() <= start());
83 memcpy(target->address(), address(), size()); // NOLINT
84 Protect(target->address(), aligned_size, kReadExecute);
85 return true;
86#endif // defined(DART_HOST_OS_MACOS)
87}
88
89#endif // !defined(DART_TARGET_OS_FUCHSIA)
90
91} // namespace dart
#define ASSERT_LESS_OR_EQUAL(expected, actual)
Definition assert.h:313
#define ASSERT_EQUAL(expected, actual)
Definition assert.h:309
void Subregion(const MemoryRegion &from, uword offset, uword size)
void set_size(uword new_size)
uword size() const
static constexpr T RoundUp(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:105
static constexpr T RoundDown(T x, intptr_t alignment)
Definition utils.h:93
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:77
static void Protect(void *address, intptr_t size, Protection mode)
static intptr_t PageSize()
bool vm_owns_region() const
intptr_t size() const
bool DuplicateRX(VirtualMemory *target)
static bool InSamePage(uword address0, uword address1)
void Truncate(intptr_t new_size)
void * address() const
uword start() const
static VirtualMemory * ForImagePage(void *pointer, uword size)
#define ASSERT(E)
uint32_t * target
uintptr_t uword
Definition globals.h:501