Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /gin /v8_platform_page_allocator.cc
blob: 08fb85c0f847d25acae27499a798e89d252779a2 [file] [log] [blame] [edit]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif
#include"v8_platform_page_allocator.h"
#include"base/check_op.h"
#include"base/cpu.h"
#include"base/memory/page_size.h"
#include"build/build_config.h"
#include"partition_alloc/address_space_randomization.h"
#include"partition_alloc/page_allocator_constants.h"
#include"partition_alloc/random.h"
namespace{
template<typename T>
TIfBtiEnabledOr(T enabled_value, T disabled_value){
#if defined(__ARM_FEATURE_BTI_DEFAULT)
return base::CPU::GetInstanceNoAllocation().has_bti()? enabled_value
: disabled_value;
#else
return disabled_value;
#endif
}
// Maps the v8 page permissions into a page configuration from base.
::partition_alloc::PageAccessibilityConfiguration::Permissions
GetPagePermissions(v8::PageAllocator::Permission permission){
// The switch doesn't have a default-case by intention. This means we can
// detect new enum values very easily by a compile error without introducing
// bugs due to unknown (hence, untested) values. On the other hand it
// incurs a slight overhead when rolling V8.
switch(permission){
case v8::PageAllocator::Permission::kRead:
return::partition_alloc::PageAccessibilityConfiguration::kRead;
case v8::PageAllocator::Permission::kReadWrite:
return::partition_alloc::PageAccessibilityConfiguration::kReadWrite;
case v8::PageAllocator::Permission::kReadWriteExecute:
returnIfBtiEnabledOr(
::partition_alloc::PageAccessibilityConfiguration::
kReadWriteExecuteProtected,
::partition_alloc::PageAccessibilityConfiguration::kReadWriteExecute);
case v8::PageAllocator::Permission::kReadExecute:
returnIfBtiEnabledOr(
::partition_alloc::PageAccessibilityConfiguration::
kReadExecuteProtected,
::partition_alloc::PageAccessibilityConfiguration::kReadExecute);
case v8::PageAllocator::Permission::kNoAccessWillJitLater:
return::partition_alloc::PageAccessibilityConfiguration::
kInaccessibleWillJitLater;
case v8::PageAllocator::Permission::kNoAccess:
return::partition_alloc::PageAccessibilityConfiguration::kInaccessible;
}
}
::partition_alloc::PageAccessibilityConfigurationGetPageConfig(
v8::PageAllocator::Permission permission){
return::partition_alloc::PageAccessibilityConfiguration(
GetPagePermissions(permission));
}
}// namespace
namespace gin{
PageAllocator::~PageAllocator()=default;
size_tPageAllocator::AllocatePageSize(){
return partition_alloc::internal::PageAllocationGranularity();
}
size_tPageAllocator::CommitPageSize(){
return base::GetPageSize();
}
voidPageAllocator::SetRandomMmapSeed(int64_t seed){
::partition_alloc::SetMmapSeedForTesting(seed);
}
void*PageAllocator::GetRandomMmapAddr(){
returnreinterpret_cast<void*>(::partition_alloc::GetRandomPageBase());
}
void*PageAllocator::AllocatePages(void* address,
size_t length,
size_t alignment,
v8::PageAllocator::Permission permissions){
partition_alloc::PageAccessibilityConfiguration config=
GetPageConfig(permissions);
return partition_alloc::AllocPages(address, length, alignment, config,
::partition_alloc::PageTag::kV8);
}
boolPageAllocator::FreePages(void* address,size_t length){
partition_alloc::FreePages(address, length);
returntrue;
}
boolPageAllocator::ReleasePages(void* address,
size_t length,
size_t new_length){
DCHECK_LT(new_length, length);
uint8_t* release_base=reinterpret_cast<uint8_t*>(address)+ new_length;
size_t release_size= length- new_length;
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
// On POSIX, we can unmap the trailing pages.
partition_alloc::FreePages(release_base, release_size);
#elif BUILDFLAG(IS_WIN)
// On Windows, we can only de-commit the trailing pages. FreePages() will
// still free all pages in the region including the released tail, so it's
// safe to just decommit the tail.
partition_alloc::DecommitSystemPages(
release_base, release_size,
::partition_alloc::PageAccessibilityDisposition::kRequireUpdate);
#else
#errorUnsupported platform
#endif
returntrue;
}
boolPageAllocator::SetPermissions(void* address,
size_t length,
Permission permissions){
// If V8 sets permissions to none, we can discard the memory.
if(permissions== v8::PageAllocator::Permission::kNoAccess){
// Use PageAccessibilityDisposition::kAllowKeepForPerf as an
// optimization, to avoid perf regression (see crrev.com/c/2563038 for
// details). This may cause the memory region to still be accessible on
// certain platforms, but at least the physical pages will be discarded.
partition_alloc::DecommitSystemPages(
address, length,
::partition_alloc::PageAccessibilityDisposition::kAllowKeepForPerf);
returntrue;
}else{
return partition_alloc::TrySetSystemPagesAccess(address, length,
GetPageConfig(permissions));
}
}
boolPageAllocator::RecommitPages(void* address,
size_t length,
Permission permissions){
partition_alloc::RecommitSystemPages(
reinterpret_cast<uintptr_t>(address), length,GetPageConfig(permissions),
partition_alloc::PageAccessibilityDisposition::kAllowKeepForPerf);
returntrue;
}
boolPageAllocator::DiscardSystemPages(void* address,size_t size){
partition_alloc::DiscardSystemPages(address, size);
returntrue;
}
boolPageAllocator::DecommitPages(void* address,size_t size){
// V8 expects the pages to be inaccessible and zero-initialized upon next
// access.
return partition_alloc::DecommitAndZeroSystemPages(
address, size, partition_alloc::PageTag::kV8);
}
boolPageAllocator::SealPages(void* address,size_t size){
return partition_alloc::SealSystemPages(address, size);
}
partition_alloc::PageAccessibilityConfiguration::Permissions
PageAllocator::GetPageConfigPermissionsForTesting(
v8::PageAllocator::Permission permission){
returnGetPageConfig(permission).permissions;
}
}// namespace gin

[8]ページ先頭

©2009-2025 Movatter.jp