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