The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / platform-freebsd.cc @ f230a1cf

History | View | Annotate | Download (9.4 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
// Platform specific code for FreeBSD goes here. For the POSIX comaptible parts
29
// the implementation is in platform-posix.cc.
30

    
31
#include <pthread.h>
32
#include <semaphore.h>
33
#include <signal.h>
34
#include <sys/time.h>
35
#include <sys/resource.h>
36
#include <sys/types.h>
37
#include <sys/ucontext.h>
38
#include <stdlib.h>
39

    
40
#include <sys/types.h>  // mmap & munmap
41
#include <sys/mman.h>   // mmap & munmap
42
#include <sys/stat.h>   // open
43
#include <sys/fcntl.h>  // open
44
#include <unistd.h>     // getpagesize
45
// If you don't have execinfo.h then you need devel/libexecinfo from ports.
46
#include <strings.h>    // index
47
#include <errno.h>
48
#include <stdarg.h>
49
#include <limits.h>
50

    
51
#undef MAP_TYPE
52

    
53
#include "v8.h"
54
#include "v8threads.h"
55

    
56
#include "platform.h"
57
#include "vm-state-inl.h"
58

    
59

    
60
namespace v8 {
61
namespace internal {
62

    
63

    
64
const char* OS::LocalTimezone(double time) {
65
  if (std::isnan(time)) return "";
66
  time_t tv = static_cast<time_t>(floor(time/msPerSecond));
67
  struct tm* t = localtime(&tv);
68
  if (NULL == t) return "";
69
  return t->tm_zone;
70
}
71

    
72

    
73
double OS::LocalTimeOffset() {
74
  time_t tv = time(NULL);
75
  struct tm* t = localtime(&tv);
76
  // tm_gmtoff includes any daylight savings offset, so subtract it.
77
  return static_cast<double>(t->tm_gmtoff * msPerSecond -
78
                             (t->tm_isdst > 0 ? 3600 * msPerSecond : 0));
79
}
80

    
81

    
82
void* OS::Allocate(const size_t requested,
83
                   size_t* allocated,
84
                   bool executable) {
85
  const size_t msize = RoundUp(requested, getpagesize());
86
  int prot = PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0);
87
  void* mbase = mmap(NULL, msize, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
88

    
89
  if (mbase == MAP_FAILED) {
90
    LOG(Isolate::Current(), StringEvent("OS::Allocate", "mmap failed"));
91
    return NULL;
92
  }
93
  *allocated = msize;
94
  return mbase;
95
}
96

    
97

    
98
class PosixMemoryMappedFile : public OS::MemoryMappedFile {
99
 public:
100
  PosixMemoryMappedFile(FILE* file, void* memory, int size)
101
    : file_(file), memory_(memory), size_(size) { }
102
  virtual ~PosixMemoryMappedFile();
103
  virtual void* memory() { return memory_; }
104
  virtual int size() { return size_; }
105
 private:
106
  FILE* file_;
107
  void* memory_;
108
  int size_;
109
};
110

    
111

    
112
OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
113
  FILE* file = fopen(name, "r+");
114
  if (file == NULL) return NULL;
115

    
116
  fseek(file, 0, SEEK_END);
117
  int size = ftell(file);
118

    
119
  void* memory =
120
      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
121
  return new PosixMemoryMappedFile(file, memory, size);
122
}
123

    
124

    
125
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
126
    void* initial) {
127
  FILE* file = fopen(name, "w+");
128
  if (file == NULL) return NULL;
129
  int result = fwrite(initial, size, 1, file);
130
  if (result < 1) {
131
    fclose(file);
132
    return NULL;
133
  }
134
  void* memory =
135
      mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(file), 0);
136
  return new PosixMemoryMappedFile(file, memory, size);
137
}
138

    
139

    
140
PosixMemoryMappedFile::~PosixMemoryMappedFile() {
141
  if (memory_) munmap(memory_, size_);
142
  fclose(file_);
143
}
144

    
145

    
146
static unsigned StringToLong(char* buffer) {
147
  return static_cast<unsigned>(strtol(buffer, NULL, 16));  // NOLINT
148
}
149

    
150

    
151
void OS::LogSharedLibraryAddresses(Isolate* isolate) {
152
  static const int MAP_LENGTH = 1024;
153
  int fd = open("/proc/self/maps", O_RDONLY);
154
  if (fd < 0) return;
155
  while (true) {
156
    char addr_buffer[11];
157
    addr_buffer[0] = '0';
158
    addr_buffer[1] = 'x';
159
    addr_buffer[10] = 0;
160
    int result = read(fd, addr_buffer + 2, 8);
161
    if (result < 8) break;
162
    unsigned start = StringToLong(addr_buffer);
163
    result = read(fd, addr_buffer + 2, 1);
164
    if (result < 1) break;
165
    if (addr_buffer[2] != '-') break;
166
    result = read(fd, addr_buffer + 2, 8);
167
    if (result < 8) break;
168
    unsigned end = StringToLong(addr_buffer);
169
    char buffer[MAP_LENGTH];
170
    int bytes_read = -1;
171
    do {
172
      bytes_read++;
173
      if (bytes_read >= MAP_LENGTH - 1)
174
        break;
175
      result = read(fd, buffer + bytes_read, 1);
176
      if (result < 1) break;
177
    } while (buffer[bytes_read] != '\n');
178
    buffer[bytes_read] = 0;
179
    // Ignore mappings that are not executable.
180
    if (buffer[3] != 'x') continue;
181
    char* start_of_path = index(buffer, '/');
182
    // There may be no filename in this line.  Skip to next.
183
    if (start_of_path == NULL) continue;
184
    buffer[bytes_read] = 0;
185
    LOG(isolate SharedLibraryEvent(start_of_path, start, end));
186
  }
187
  close(fd);
188
}
189

    
190

    
191
void OS::SignalCodeMovingGC() {
192
}
193

    
194

    
195

    
196
// Constants used for mmap.
197
static const int kMmapFd = -1;
198
static const int kMmapFdOffset = 0;
199

    
200

    
201
VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
202

    
203

    
204
VirtualMemory::VirtualMemory(size_t size)
205
    : address_(ReserveRegion(size)), size_(size) { }
206

    
207

    
208
VirtualMemory::VirtualMemory(size_t size, size_t alignment)
209
    : address_(NULL), size_(0) {
210
  ASSERT(IsAligned(alignment, static_cast<intptr_t>(OS::AllocateAlignment())));
211
  size_t request_size = RoundUp(size + alignment,
212
                                static_cast<intptr_t>(OS::AllocateAlignment()));
213
  void* reservation = mmap(OS::GetRandomMmapAddr(),
214
                           request_size,
215
                           PROT_NONE,
216
                           MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
217
                           kMmapFd,
218
                           kMmapFdOffset);
219
  if (reservation == MAP_FAILED) return;
220

    
221
  Address base = static_cast<Address>(reservation);
222
  Address aligned_base = RoundUp(base, alignment);
223
  ASSERT_LE(base, aligned_base);
224

    
225
  // Unmap extra memory reserved before and after the desired block.
226
  if (aligned_base != base) {
227
    size_t prefix_size = static_cast<size_t>(aligned_base - base);
228
    OS::Free(base, prefix_size);
229
    request_size -= prefix_size;
230
  }
231

    
232
  size_t aligned_size = RoundUp(size, OS::AllocateAlignment());
233
  ASSERT_LE(aligned_size, request_size);
234

    
235
  if (aligned_size != request_size) {
236
    size_t suffix_size = request_size - aligned_size;
237
    OS::Free(aligned_base + aligned_size, suffix_size);
238
    request_size -= suffix_size;
239
  }
240

    
241
  ASSERT(aligned_size == request_size);
242

    
243
  address_ = static_cast<void*>(aligned_base);
244
  size_ = aligned_size;
245
}
246

    
247

    
248
VirtualMemory::~VirtualMemory() {
249
  if (IsReserved()) {
250
    bool result = ReleaseRegion(address(), size());
251
    ASSERT(result);
252
    USE(result);
253
  }
254
}
255

    
256

    
257
bool VirtualMemory::IsReserved() {
258
  return address_ != NULL;
259
}
260

    
261

    
262
void VirtualMemory::Reset() {
263
  address_ = NULL;
264
  size_ = 0;
265
}
266

    
267

    
268
bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
269
  return CommitRegion(address, size, is_executable);
270
}
271

    
272

    
273
bool VirtualMemory::Uncommit(void* address, size_t size) {
274
  return UncommitRegion(address, size);
275
}
276

    
277

    
278
bool VirtualMemory::Guard(void* address) {
279
  OS::Guard(address, OS::CommitPageSize());
280
  return true;
281
}
282

    
283

    
284
void* VirtualMemory::ReserveRegion(size_t size) {
285
  void* result = mmap(OS::GetRandomMmapAddr(),
286
                      size,
287
                      PROT_NONE,
288
                      MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
289
                      kMmapFd,
290
                      kMmapFdOffset);
291

    
292
  if (result == MAP_FAILED) return NULL;
293

    
294
  return result;
295
}
296

    
297

    
298
bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
299
  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
300
  if (MAP_FAILED == mmap(base,
301
                         size,
302
                         prot,
303
                         MAP_PRIVATE | MAP_ANON | MAP_FIXED,
304
                         kMmapFd,
305
                         kMmapFdOffset)) {
306
    return false;
307
  }
308
  return true;
309
}
310

    
311

    
312
bool VirtualMemory::UncommitRegion(void* base, size_t size) {
313
  return mmap(base,
314
              size,
315
              PROT_NONE,
316
              MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | MAP_FIXED,
317
              kMmapFd,
318
              kMmapFdOffset) != MAP_FAILED;
319
}
320

    
321

    
322
bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
323
  return munmap(base, size) == 0;
324
}
325

    
326

    
327
bool VirtualMemory::HasLazyCommits() {
328
  // TODO(alph): implement for the platform.
329
  return false;
330
}
331

    
332
} }  // namespace v8::internal