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#ifndef RUNTIME_VM_VIRTUAL_MEMORY_H_
6#define RUNTIME_VM_VIRTUAL_MEMORY_H_
7
8#include "platform/utils.h"
9#include "vm/flags.h"
10#include "vm/globals.h"
11#include "vm/memory_region.h"
12
13namespace dart {
14
15class VirtualMemory {
16 public:
17 enum Protection {
18 kNoAccess,
19 kReadOnly,
20 kReadWrite,
21 kReadExecute,
22 kReadWriteExecute
23 };
24
25 // The reserved memory is unmapped on destruction.
26 ~VirtualMemory();
27
28 uword start() const { return region_.start(); }
29 uword end() const { return region_.end(); }
30 void* address() const { return region_.pointer(); }
31 intptr_t size() const { return region_.size(); }
32 intptr_t AliasOffset() const { return alias_.start() - region_.start(); }
33
34 static void Init();
35
36 // Returns true if dual mapping is enabled.
37 static bool DualMappingEnabled();
38
39 bool Contains(uword addr) const { return region_.Contains(addr); }
40 bool ContainsAlias(uword addr) const {
41 return (AliasOffset() != 0) && alias_.Contains(addr);
42 }
43
44 // Changes the protection of the virtual memory area.
45 static void Protect(void* address, intptr_t size, Protection mode);
46 void Protect(Protection mode) { return Protect(address(), size(), mode); }
47
48 // Reserves and commits a virtual memory segment with size. If a segment of
49 // the requested size cannot be allocated, NULL is returned.
50 static VirtualMemory* Allocate(intptr_t size,
51 bool is_executable,
52 const char* name) {
53 return AllocateAligned(size, PageSize(), is_executable, name);
54 }
55 static VirtualMemory* AllocateAligned(intptr_t size,
56 intptr_t alignment,
57 bool is_executable,
58 const char* name);
59
60 // Returns the cached page size. Use only if Init() has been called.
61 static intptr_t PageSize() {
62 ASSERT(page_size_ != 0);
63 return page_size_;
64 }
65
66 static bool InSamePage(uword address0, uword address1);
67
68 // Truncate this virtual memory segment.
69 void Truncate(intptr_t new_size);
70
71 // False for a part of a snapshot added directly to the Dart heap, which
72 // belongs to the embedder and must not be deallocated or have its
73 // protection status changed by the VM.
74 bool vm_owns_region() const { return reserved_.pointer() != NULL; }
75
76 static VirtualMemory* ForImagePage(void* pointer, uword size);
77
78 void release() {
79 // Make sure no pages would be leaked.
80 const uword size_ = size();
81 ASSERT(address() == reserved_.pointer() && size_ == reserved_.size());
82 reserved_ = MemoryRegion(nullptr, 0);
83 }
84
85 private:
86 static intptr_t CalculatePageSize();
87
88 // Free a sub segment. On operating systems that support it this
89 // can give back the virtual memory to the system. Returns true on success.
90 static void FreeSubSegment(void* address, intptr_t size);
91
92 // These constructors are only used internally when reserving new virtual
93 // spaces. They do not reserve any virtual address space on their own.
94 VirtualMemory(const MemoryRegion& region,
95 const MemoryRegion& alias,
96 const MemoryRegion& reserved)
97 : region_(region), alias_(alias), reserved_(reserved) {}
98
99 VirtualMemory(const MemoryRegion& region, const MemoryRegion& reserved)
100 : region_(region), alias_(region), reserved_(reserved) {}
101
102 MemoryRegion region_;
103
104 // Optional secondary mapping of region_ to a virtual space with different
105 // protection, e.g. allowing code execution.
106 MemoryRegion alias_;
107
108 // The underlying reservation not yet given back to the OS.
109 // Its address might disagree with region_ due to aligned allocations.
110 // Its size might disagree with region_ due to Truncate.
111 MemoryRegion reserved_;
112
113 static uword page_size_;
114
115 DISALLOW_IMPLICIT_CONSTRUCTORS(VirtualMemory);
116};
117
118} // namespace dart
119
120#endif // RUNTIME_VM_VIRTUAL_MEMORY_H_
121