[M120 Migration] Set IO|GPU thread type with higher priorites
[platform/framework/web/chromium-efl.git] / gin / v8_platform_page_allocator.cc
1 // Copyright 2021 The Chromium Authors
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 "v8_platform_page_allocator.h"
6
7 #include "base/allocator/partition_allocator/src/partition_alloc/address_space_randomization.h"
8 #include "base/allocator/partition_allocator/src/partition_alloc/page_allocator_constants.h"
9 #include "base/allocator/partition_allocator/src/partition_alloc/random.h"
10 #include "base/check_op.h"
11 #include "base/cpu.h"
12 #include "base/memory/page_size.h"
13 #include "build/build_config.h"
14
15 namespace {
16
17 // Maps the v8 page permissions into a page configuration from base.
18 ::partition_alloc::PageAccessibilityConfiguration::Permissions
19 GetPagePermissions(v8::PageAllocator::Permission permission) {
20   switch (permission) {
21     case v8::PageAllocator::Permission::kRead:
22       return ::partition_alloc::PageAccessibilityConfiguration::kRead;
23     case v8::PageAllocator::Permission::kReadWrite:
24       return ::partition_alloc::PageAccessibilityConfiguration::kReadWrite;
25     case v8::PageAllocator::Permission::kReadWriteExecute:
26       // at the moment bti-protection is not enabled for this path since some
27       // projects may still be using non-bti compliant code.
28       return ::partition_alloc::PageAccessibilityConfiguration::
29           kReadWriteExecute;
30     case v8::PageAllocator::Permission::kReadExecute:
31 #if defined(__ARM_FEATURE_BTI_DEFAULT)
32       return base::CPU::GetInstanceNoAllocation().has_bti()
33                  ? ::partition_alloc::PageAccessibilityConfiguration::
34                        kReadExecuteProtected
35                  : ::partition_alloc::PageAccessibilityConfiguration::
36                        kReadExecute;
37 #else
38       return ::partition_alloc::PageAccessibilityConfiguration::kReadExecute;
39 #endif
40     case v8::PageAllocator::Permission::kNoAccessWillJitLater:
41       return ::partition_alloc::PageAccessibilityConfiguration::
42           kInaccessibleWillJitLater;
43     default:
44       DCHECK_EQ(v8::PageAllocator::Permission::kNoAccess, permission);
45       return ::partition_alloc::PageAccessibilityConfiguration::kInaccessible;
46   }
47 }
48
49 ::partition_alloc::PageAccessibilityConfiguration GetPageConfig(
50     v8::PageAllocator::Permission permission) {
51   return ::partition_alloc::PageAccessibilityConfiguration(
52       GetPagePermissions(permission));
53 }
54
55 }  // namespace
56
57 namespace gin {
58 PageAllocator::~PageAllocator() = default;
59
60 size_t PageAllocator::AllocatePageSize() {
61   return partition_alloc::internal::PageAllocationGranularity();
62 }
63
64 size_t PageAllocator::CommitPageSize() {
65   return base::GetPageSize();
66 }
67
68 void PageAllocator::SetRandomMmapSeed(int64_t seed) {
69   ::partition_alloc::SetMmapSeedForTesting(seed);
70 }
71
72 void* PageAllocator::GetRandomMmapAddr() {
73   return reinterpret_cast<void*>(::partition_alloc::GetRandomPageBase());
74 }
75
76 void* PageAllocator::AllocatePages(void* address,
77                                    size_t length,
78                                    size_t alignment,
79                                    v8::PageAllocator::Permission permissions) {
80   partition_alloc::PageAccessibilityConfiguration config =
81       GetPageConfig(permissions);
82   return partition_alloc::AllocPages(address, length, alignment, config,
83                                      ::partition_alloc::PageTag::kV8);
84 }
85
86 bool PageAllocator::FreePages(void* address, size_t length) {
87   partition_alloc::FreePages(address, length);
88   return true;
89 }
90
91 bool PageAllocator::ReleasePages(void* address,
92                                  size_t length,
93                                  size_t new_length) {
94   DCHECK_LT(new_length, length);
95   uint8_t* release_base = reinterpret_cast<uint8_t*>(address) + new_length;
96   size_t release_size = length - new_length;
97 #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
98   // On POSIX, we can unmap the trailing pages.
99   partition_alloc::FreePages(release_base, release_size);
100 #elif BUILDFLAG(IS_WIN)
101   // On Windows, we can only de-commit the trailing pages. FreePages() will
102   // still free all pages in the region including the released tail, so it's
103   // safe to just decommit the tail.
104   partition_alloc::DecommitSystemPages(
105       release_base, release_size,
106       ::partition_alloc::PageAccessibilityDisposition::kRequireUpdate);
107 #else
108 #error Unsupported platform
109 #endif
110   return true;
111 }
112
113 bool PageAllocator::SetPermissions(void* address,
114                                    size_t length,
115                                    Permission permissions) {
116   // If V8 sets permissions to none, we can discard the memory.
117   if (permissions == v8::PageAllocator::Permission::kNoAccess) {
118     // Use PageAccessibilityDisposition::kAllowKeepForPerf as an
119     // optimization, to avoid perf regression (see crrev.com/c/2563038 for
120     // details). This may cause the memory region to still be accessible on
121     // certain platforms, but at least the physical pages will be discarded.
122     partition_alloc::DecommitSystemPages(
123         address, length,
124         ::partition_alloc::PageAccessibilityDisposition::kAllowKeepForPerf);
125     return true;
126   } else {
127     return partition_alloc::TrySetSystemPagesAccess(address, length,
128                                                     GetPageConfig(permissions));
129   }
130 }
131
132 bool PageAllocator::RecommitPages(void* address,
133                                   size_t length,
134                                   Permission permissions) {
135   partition_alloc::RecommitSystemPages(
136       reinterpret_cast<uintptr_t>(address), length, GetPageConfig(permissions),
137       partition_alloc::PageAccessibilityDisposition::kAllowKeepForPerf);
138   return true;
139 }
140
141 bool PageAllocator::DiscardSystemPages(void* address, size_t size) {
142   partition_alloc::DiscardSystemPages(address, size);
143   return true;
144 }
145
146 bool PageAllocator::DecommitPages(void* address, size_t size) {
147   // V8 expects the pages to be inaccessible and zero-initialized upon next
148   // access.
149   partition_alloc::DecommitAndZeroSystemPages(address, size);
150   return true;
151 }
152
153 partition_alloc::PageAccessibilityConfiguration::Permissions
154 PageAllocator::GetPageConfigPermissionsForTesting(
155     v8::PageAllocator::Permission permission) {
156   return GetPageConfig(permission).permissions;
157 }
158
159 }  // namespace gin