[M108 Migration][HBBTV] Implement ewk_context_register_jsplugin_mime_types API
[platform/framework/web/chromium-efl.git] / courgette / memory_allocator.cc
1 // Copyright 2012 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 "courgette/memory_allocator.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <map>
11
12 #include "base/files/file_util.h"
13 #include "build/build_config.h"
14
15 #if BUILDFLAG(IS_WIN)
16
17 #include <windows.h>
18
19 namespace {
20
21 // The file is created in the %TEMP% folder.
22 // NOTE: Since the file will be used as backing for a memory allocation,
23 // it will never be so big that size_t cannot represent its size.
24 base::File CreateTempFile() {
25   base::FilePath path;
26   if (!base::CreateTemporaryFile(&path))
27     return base::File();
28
29   int flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
30               base::File::FLAG_WRITE | base::File::FLAG_DELETE_ON_CLOSE |
31               base::File::FLAG_WIN_TEMPORARY;
32   return base::File(path, flags);
33 }
34
35 }  // namespace
36
37 namespace courgette {
38
39 // FileMapping
40
41 FileMapping::FileMapping() : mapping_(nullptr), view_(nullptr) {}
42
43 FileMapping::~FileMapping() {
44   Close();
45 }
46
47 bool FileMapping::InitializeView(size_t size) {
48   DCHECK(view_ == nullptr);
49   DCHECK(mapping_ != nullptr);
50   view_ = ::MapViewOfFile(mapping_, FILE_MAP_WRITE, 0, 0, size);
51   if (!view_) {
52     Close();
53     return false;
54   }
55   return true;
56 }
57
58 bool FileMapping::Create(HANDLE file, size_t size) {
59   DCHECK(file != INVALID_HANDLE_VALUE);
60   DCHECK(!valid());
61   mapping_ = ::CreateFileMapping(file, nullptr, PAGE_READWRITE, 0, 0, nullptr);
62   if (!mapping_)
63     return false;
64
65   return InitializeView(size);
66 }
67
68 void FileMapping::Close() {
69   if (view_)
70     ::UnmapViewOfFile(view_);
71   if (mapping_)
72     ::CloseHandle(mapping_);
73   mapping_ = nullptr;
74   view_ = nullptr;
75 }
76
77 bool FileMapping::valid() const {
78   return view_ != nullptr;
79 }
80
81 void* FileMapping::view() const {
82   return view_;
83 }
84
85 // TempMapping
86
87 TempMapping::TempMapping() {
88 }
89
90 TempMapping::~TempMapping() {
91 }
92
93 bool TempMapping::Initialize(size_t size) {
94   file_ = CreateTempFile();
95   if (!file_.IsValid())
96     return false;
97
98   // TODO(tommi): The assumption here is that the alignment of pointers (this)
99   // is as strict or stricter than the alignment of the element type.  This is
100   // not always true, e.g. __m128 has 16-byte alignment.
101   size += sizeof(this);
102   if (!file_.SetLength(size) ||
103       !mapping_.Create(file_.GetPlatformFile(), size)) {
104     file_.Close();
105     return false;
106   }
107
108   TempMapping** write = reinterpret_cast<TempMapping**>(mapping_.view());
109   write[0] = this;
110
111   return true;
112 }
113
114 void* TempMapping::memory() const {
115   uint8_t* mem = reinterpret_cast<uint8_t*>(mapping_.view());
116   // The 'this' pointer is written at the start of mapping_.view(), so
117   // go past it. (See Initialize()).
118   if (mem)
119     mem += sizeof(this);
120   DCHECK(mem);
121   return mem;
122 }
123
124 bool TempMapping::valid() const {
125   return mapping_.valid();
126 }
127
128 // static
129 TempMapping* TempMapping::GetMappingFromPtr(void* mem) {
130   TempMapping* ret = nullptr;
131   if (mem) {
132     ret = reinterpret_cast<TempMapping**>(mem)[-1];
133   }
134   DCHECK(ret);
135   return ret;
136 }
137
138 }  // namespace courgette
139
140 #endif  // BUILDFLAG(IS_WIN)