Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /gin /array_buffer.cc
blob: 4a8807c4e11d5248527b4170c2bce1bb94166179 [file] [log] [blame] [edit]
// Copyright 2013 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"gin/array_buffer.h"
#include<stddef.h>
#include<stdlib.h>
#include"base/bits.h"
#include"base/check_op.h"
#include"base/no_destructor.h"
#include"build/build_config.h"
#include"gin/per_isolate_data.h"
#include"partition_alloc/page_allocator.h"
#include"partition_alloc/partition_alloc.h"
#include"partition_alloc/partition_root.h"
#include"v8/include/v8-initialization.h"
#if BUILDFLAG(IS_POSIX)
#include<sys/mman.h>
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
#endif// BUILDFLAG(IS_POSIX)
namespace gin{
// ArrayBufferAllocator -------------------------------------------------------
partition_alloc::PartitionRoot*ArrayBufferAllocator::partition_=nullptr;
void*ArrayBufferAllocator::Allocate(size_t length){
constexpr partition_alloc::AllocFlags flags=
partition_alloc::AllocFlags::kZeroFill|
partition_alloc::AllocFlags::kReturnNull;
returnAllocateInternal<flags>(length);
}
void*ArrayBufferAllocator::AllocateUninitialized(size_t length){
constexpr partition_alloc::AllocFlags flags=
partition_alloc::AllocFlags::kReturnNull;
returnAllocateInternal<flags>(length);
}
template<partition_alloc::AllocFlags flags>
void*ArrayBufferAllocator::AllocateInternal(size_t length){
#ifdef V8_ENABLE_SANDBOX
// The V8 sandbox requires all ArrayBuffer backing stores to be allocated
// inside the sandbox address space. This isn't guaranteed if allocation
// override hooks (which are e.g. used by GWP-ASan) are enabled or if a
// memory tool (e.g. ASan) overrides malloc, so disable both.
constexprauto new_flags= flags|
partition_alloc::AllocFlags::kNoOverrideHooks|
partition_alloc::AllocFlags::kNoMemoryToolOverride;
#else
constexprauto new_flags= flags;
#endif
return partition_->AllocInline<new_flags>(length,
"gin::ArrayBufferAllocator");
}
voidArrayBufferAllocator::Free(void* data,size_t length){
#ifdef V8_ENABLE_SANDBOX
// See |AllocateMemoryWithFlags|.
partition_->Free<partition_alloc::FreeFlags::kNoMemoryToolOverride>(data);
#else
partition_->Free(data);
#endif
}
// static
ArrayBufferAllocator*ArrayBufferAllocator::SharedInstance(){
staticArrayBufferAllocator* instance=newArrayBufferAllocator();
return instance;
}
// static
voidArrayBufferAllocator::InitializePartition(){
partition_alloc::PartitionOptions opts;
opts.backup_ref_ptr= partition_alloc::PartitionOptions::kDisabled;
opts.use_configurable_pool= partition_alloc::PartitionOptions::kAllowed;
static base::NoDestructor<partition_alloc::PartitionAllocator>
partition_allocator(opts);
partition_= partition_allocator->root();
}
// ArrayBuffer ----------------------------------------------------------------
ArrayBuffer::ArrayBuffer()=default;
ArrayBuffer::ArrayBuffer(v8::Isolate* isolate, v8::Local<v8::ArrayBuffer> array)
: backing_store_(array->GetBackingStore()){}
ArrayBuffer::~ArrayBuffer()=default;
ArrayBuffer&ArrayBuffer::operator=(constArrayBuffer& other)=default;
// Converter<ArrayBuffer> -----------------------------------------------------
boolConverter<ArrayBuffer>::FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
ArrayBuffer* out){
if(!val->IsArrayBuffer())
returnfalse;
*out=ArrayBuffer(isolate, v8::Local<v8::ArrayBuffer>::Cast(val));
returntrue;
}
// ArrayBufferView ------------------------------------------------------------
ArrayBufferView::ArrayBufferView()
: offset_(0),
num_bytes_(0){
}
ArrayBufferView::ArrayBufferView(v8::Isolate* isolate,
v8::Local<v8::ArrayBufferView> view)
: array_buffer_(isolate, view->Buffer()),
offset_(view->ByteOffset()),
num_bytes_(view->ByteLength()){
}
ArrayBufferView::~ArrayBufferView()=default;
ArrayBufferView&ArrayBufferView::operator=(constArrayBufferView& other)=
default;
// Converter<ArrayBufferView> -------------------------------------------------
boolConverter<ArrayBufferView>::FromV8(v8::Isolate* isolate,
v8::Local<v8::Value> val,
ArrayBufferView* out){
if(!val->IsArrayBufferView())
returnfalse;
*out=ArrayBufferView(isolate, v8::Local<v8::ArrayBufferView>::Cast(val));
returntrue;
}
// ArrayBufferSharedMemoryMapper ---------------------------------------------
namespace{
#ifdef V8_ENABLE_SANDBOX
// When the V8 sandbox is enabled, shared memory backing ArrayBuffers must be
// mapped into the sandbox address space. This custom SharedMemoryMapper
// implements this.
classArrayBufferSharedMemoryMapper:public base::SharedMemoryMapper{
public:
std::optional<base::span<uint8_t>>Map(
base::subtle::PlatformSharedMemoryHandle handle,
bool write_allowed,
uint64_t offset,
size_t size) override{
v8::VirtualAddressSpace* address_space= v8::V8::GetSandboxAddressSpace();
size_t allocation_granularity= address_space->allocation_granularity();
v8::PlatformSharedMemoryHandle v8_handle;
#if BUILDFLAG(IS_APPLE)
v8_handle= v8::SharedMemoryHandleFromMachMemoryEntry(handle);
#elif BUILDFLAG(IS_FUCHSIA)
v8_handle= v8::SharedMemoryHandleFromVMO(handle->get());
#elif BUILDFLAG(IS_WIN)
v8_handle= v8::SharedMemoryHandleFromFileMapping(handle);
#elif BUILDFLAG(IS_ANDROID)
v8_handle= v8::SharedMemoryHandleFromFileDescriptor(handle);
#elif BUILDFLAG(IS_POSIX)
v8_handle= v8::SharedMemoryHandleFromFileDescriptor(handle.fd);
#else
#error"Unknown platform"
#endif
// Size and offset must be a multiple of the page allocation granularity.
// The caller already ensures that the offset is a multiple of the
// allocation granularity though.
CHECK_EQ(0UL, offset% allocation_granularity);
size_t mapping_size= base::bits::AlignUp(size, allocation_granularity);
v8::PagePermissions permissions= write_allowed
? v8::PagePermissions::kReadWrite
: v8::PagePermissions::kRead;
uintptr_t mapping= v8::V8::GetSandboxAddressSpace()->AllocateSharedPages(
0, mapping_size, permissions, v8_handle, offset);
if(!mapping)
return std::nullopt;
return base::span(reinterpret_cast<uint8_t*>(mapping), size);
}
voidUnmap(base::span<uint8_t> mapping) override{
v8::VirtualAddressSpace* address_space= v8::V8::GetSandboxAddressSpace();
size_t allocation_granularity= address_space->allocation_granularity();
uintptr_t address=reinterpret_cast<uintptr_t>(mapping.data());
CHECK_EQ(0UL, address% allocation_granularity);
size_t mapping_size=
base::bits::AlignUp(mapping.size(), allocation_granularity);
address_space->FreeSharedPages(address, mapping_size);
}
};
#endif// V8_ENABLE_SANDBOX
}// namespace
base::SharedMemoryMapper*GetSharedMemoryMapperForArrayBuffers(){
#if V8_ENABLE_SANDBOX
staticArrayBufferSharedMemoryMapper instance;
return&instance;
#else
return base::SharedMemoryMapper::GetDefaultInstance();
#endif
}
}// namespace gin

[8]ページ先頭

©2009-2025 Movatter.jp