123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "courgette/memory_allocator.h"
- #include <stddef.h>
- #include <stdint.h>
- #include <map>
- #include "base/files/file_util.h"
- #include "build/build_config.h"
- #if BUILDFLAG(IS_WIN)
- #include <windows.h>
- namespace {
- // The file is created in the %TEMP% folder.
- // NOTE: Since the file will be used as backing for a memory allocation,
- // it will never be so big that size_t cannot represent its size.
- base::File CreateTempFile() {
- base::FilePath path;
- if (!base::CreateTemporaryFile(&path))
- return base::File();
- int flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
- base::File::FLAG_WRITE | base::File::FLAG_DELETE_ON_CLOSE |
- base::File::FLAG_WIN_TEMPORARY;
- return base::File(path, flags);
- }
- } // namespace
- namespace courgette {
- // FileMapping
- FileMapping::FileMapping() : mapping_(nullptr), view_(nullptr) {}
- FileMapping::~FileMapping() {
- Close();
- }
- bool FileMapping::InitializeView(size_t size) {
- DCHECK(view_ == nullptr);
- DCHECK(mapping_ != nullptr);
- view_ = ::MapViewOfFile(mapping_, FILE_MAP_WRITE, 0, 0, size);
- if (!view_) {
- Close();
- return false;
- }
- return true;
- }
- bool FileMapping::Create(HANDLE file, size_t size) {
- DCHECK(file != INVALID_HANDLE_VALUE);
- DCHECK(!valid());
- mapping_ = ::CreateFileMapping(file, nullptr, PAGE_READWRITE, 0, 0, nullptr);
- if (!mapping_)
- return false;
- return InitializeView(size);
- }
- void FileMapping::Close() {
- if (view_)
- ::UnmapViewOfFile(view_);
- if (mapping_)
- ::CloseHandle(mapping_);
- mapping_ = nullptr;
- view_ = nullptr;
- }
- bool FileMapping::valid() const {
- return view_ != nullptr;
- }
- void* FileMapping::view() const {
- return view_;
- }
- // TempMapping
- TempMapping::TempMapping() {
- }
- TempMapping::~TempMapping() {
- }
- bool TempMapping::Initialize(size_t size) {
- file_ = CreateTempFile();
- if (!file_.IsValid())
- return false;
- // TODO(tommi): The assumption here is that the alignment of pointers (this)
- // is as strict or stricter than the alignment of the element type. This is
- // not always true, e.g. __m128 has 16-byte alignment.
- size += sizeof(this);
- if (!file_.SetLength(size) ||
- !mapping_.Create(file_.GetPlatformFile(), size)) {
- file_.Close();
- return false;
- }
- TempMapping** write = reinterpret_cast<TempMapping**>(mapping_.view());
- write[0] = this;
- return true;
- }
- void* TempMapping::memory() const {
- uint8_t* mem = reinterpret_cast<uint8_t*>(mapping_.view());
- // The 'this' pointer is written at the start of mapping_.view(), so
- // go past it. (See Initialize()).
- if (mem)
- mem += sizeof(this);
- DCHECK(mem);
- return mem;
- }
- bool TempMapping::valid() const {
- return mapping_.valid();
- }
- // static
- TempMapping* TempMapping::GetMappingFromPtr(void* mem) {
- TempMapping* ret = nullptr;
- if (mem) {
- ret = reinterpret_cast<TempMapping**>(mem)[-1];
- }
- DCHECK(ret);
- return ret;
- }
- } // namespace courgette
- #endif // BUILDFLAG(IS_WIN)
|