V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
platform-fuchsia.cc
1 // Copyright 2017 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 #include <zircon/process.h>
6 #include <zircon/syscalls.h>
7 
8 #include "src/base/macros.h"
9 #include "src/base/platform/platform-posix-time.h"
10 #include "src/base/platform/platform-posix.h"
11 #include "src/base/platform/platform.h"
12 
13 namespace v8 {
14 namespace base {
15 
16 namespace {
17 
18 uint32_t GetProtectionFromMemoryPermission(OS::MemoryPermission access) {
19  switch (access) {
20  case OS::MemoryPermission::kNoAccess:
21  return 0; // no permissions
22  case OS::MemoryPermission::kRead:
23  return ZX_VM_FLAG_PERM_READ;
24  case OS::MemoryPermission::kReadWrite:
25  return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE;
26  case OS::MemoryPermission::kReadWriteExecute:
27  return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE |
28  ZX_VM_FLAG_PERM_EXECUTE;
29  case OS::MemoryPermission::kReadExecute:
30  return ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_EXECUTE;
31  }
32  UNREACHABLE();
33 }
34 
35 } // namespace
36 
37 TimezoneCache* OS::CreateTimezoneCache() {
38  return new PosixDefaultTimezoneCache();
39 }
40 
41 // static
42 void* OS::Allocate(void* address, size_t size, size_t alignment,
43  OS::MemoryPermission access) {
44  size_t page_size = OS::AllocatePageSize();
45  DCHECK_EQ(0, size % page_size);
46  DCHECK_EQ(0, alignment % page_size);
47  address = AlignedAddress(address, alignment);
48  // Add the maximum misalignment so we are guaranteed an aligned base address.
49  size_t request_size = size + (alignment - page_size);
50 
51  zx_handle_t vmo;
52  if (zx_vmo_create(request_size, ZX_VMO_NON_RESIZABLE, &vmo) != ZX_OK) {
53  return nullptr;
54  }
55  static const char kVirtualMemoryName[] = "v8-virtualmem";
56  zx_object_set_property(vmo, ZX_PROP_NAME, kVirtualMemoryName,
57  strlen(kVirtualMemoryName));
58  uintptr_t reservation;
59  uint32_t prot = GetProtectionFromMemoryPermission(access);
60  zx_status_t status = zx_vmar_map(zx_vmar_root_self(), prot, 0, vmo, 0,
61  request_size, &reservation);
62  // Either the vmo is now referenced by the vmar, or we failed and are bailing,
63  // so close the vmo either way.
64  zx_handle_close(vmo);
65  if (status != ZX_OK) {
66  return nullptr;
67  }
68 
69  uint8_t* base = reinterpret_cast<uint8_t*>(reservation);
70  uint8_t* aligned_base = reinterpret_cast<uint8_t*>(
71  RoundUp(reinterpret_cast<uintptr_t>(base), alignment));
72 
73  // Unmap extra memory reserved before and after the desired block.
74  if (aligned_base != base) {
75  DCHECK_LT(base, aligned_base);
76  size_t prefix_size = static_cast<size_t>(aligned_base - base);
77  zx_vmar_unmap(zx_vmar_root_self(), reinterpret_cast<uintptr_t>(base),
78  prefix_size);
79  request_size -= prefix_size;
80  }
81 
82  size_t aligned_size = RoundUp(size, page_size);
83 
84  if (aligned_size != request_size) {
85  DCHECK_LT(aligned_size, request_size);
86  size_t suffix_size = request_size - aligned_size;
87  zx_vmar_unmap(zx_vmar_root_self(),
88  reinterpret_cast<uintptr_t>(aligned_base + aligned_size),
89  suffix_size);
90  request_size -= suffix_size;
91  }
92 
93  DCHECK(aligned_size == request_size);
94  return static_cast<void*>(aligned_base);
95 }
96 
97 // static
98 bool OS::Free(void* address, const size_t size) {
99  DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % AllocatePageSize());
100  DCHECK_EQ(0, size % AllocatePageSize());
101  return zx_vmar_unmap(zx_vmar_root_self(),
102  reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
103 }
104 
105 // static
106 bool OS::Release(void* address, size_t size) {
107  DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
108  DCHECK_EQ(0, size % CommitPageSize());
109  return zx_vmar_unmap(zx_vmar_root_self(),
110  reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
111 }
112 
113 // static
114 bool OS::SetPermissions(void* address, size_t size, MemoryPermission access) {
115  DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
116  DCHECK_EQ(0, size % CommitPageSize());
117  uint32_t prot = GetProtectionFromMemoryPermission(access);
118  return zx_vmar_protect(zx_vmar_root_self(), prot,
119  reinterpret_cast<uintptr_t>(address), size) == ZX_OK;
120 }
121 
122 // static
123 bool OS::DiscardSystemPages(void* address, size_t size) {
124  // TODO(hpayer): Does Fuchsia have madvise?
125  return true;
126 }
127 
128 // static
129 bool OS::HasLazyCommits() {
130  // TODO(scottmg): Port, https://crbug.com/731217.
131  return false;
132 }
133 
134 std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
135  UNREACHABLE(); // TODO(scottmg): Port, https://crbug.com/731217.
136 }
137 
138 void OS::SignalCodeMovingGC() {
139  UNREACHABLE(); // TODO(scottmg): Port, https://crbug.com/731217.
140 }
141 
142 int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) {
143  const auto kNanosPerMicrosecond = 1000ULL;
144  const auto kMicrosPerSecond = 1000000ULL;
145  const zx_time_t nanos_since_thread_started = zx_clock_get(ZX_CLOCK_THREAD);
146 
147  // First convert to microseconds, rounding up.
148  const uint64_t micros_since_thread_started =
149  (nanos_since_thread_started + kNanosPerMicrosecond - 1ULL) /
150  kNanosPerMicrosecond;
151 
152  *secs = static_cast<uint32_t>(micros_since_thread_started / kMicrosPerSecond);
153  *usecs =
154  static_cast<uint32_t>(micros_since_thread_started % kMicrosPerSecond);
155  return 0;
156 }
157 
158 } // namespace base
159 } // namespace v8
Definition: libplatform.h:13