1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/Platform-Posix.cpp Tue Jul 24 23:53:34 2012 -0700
1.3 @@ -0,0 +1,101 @@
1.4 +/* vim: set ts=4 sw=4 tw=99 et:
1.5 + *
1.6 + * Copyright (C) 2012 David Anderson
1.7 + *
1.8 + * This file is part of JITCraft.
1.9 + *
1.10 + * JITCraft is free software: you can redistribute it and/or modify it under
1.11 + * the terms of the GNU General Public License as published by the Free
1.12 + * Software Foundation, either version 3 of the License, or (at your option)
1.13 + * any later version.
1.14 + *
1.15 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License along with
1.20 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.21 + */
1.22 +#include <sys/mman.h>
1.23 +#include "Platform.h"
1.24 +
1.25 +using namespace jc;
1.26 +
1.27 +static inline int
1.28 +ToProtBits(OS::Protection prot)
1.29 +{
1.30 + switch (prot) {
1.31 + case OS::Prot_ReadWrite:
1.32 + return PROT_READ | PROT_WRITE;
1.33 + case OS::Prot_ReadWriteExecute:
1.34 + return PROT_READ | PROT_WRITE | PROT_EXEC;
1.35 + default:
1.36 + assert(prot == OS::Prot_ReadExecute);
1.37 + return PROT_READ | PROT_EXEC;
1.38 + }
1.39 +}
1.40 +
1.41 +Address
1.42 +OS::MapMemory(size_t amount, MapMode mode, Protection prot_)
1.43 +{
1.44 + int prot = ToProtBits(prot_);
1.45 + void *addr = mmap(NULL, amount, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
1.46 + if (addr == MAP_FAILED)
1.47 + return NULL;
1.48 +
1.49 + return Address(addr);
1.50 +}
1.51 +
1.52 +bool
1.53 +OS::CommitMemory(Address address, size_t amount, Protection prot_)
1.54 +{
1.55 + return true;
1.56 +}
1.57 +
1.58 +void
1.59 +OS::UnmapMemory(Address address, size_t size)
1.60 +{
1.61 + munmap(address, size);
1.62 +}
1.63 +
1.64 +OS::AlignableMapping
1.65 +OS::MapAlignedMemory(size_t amount, size_t alignment, MapMode mode)
1.66 +{
1.67 + assert(amount >= alignment);
1.68 + assert(IsPowerOfTwo(alignment));
1.69 +
1.70 + if (alignment == kPageAlignment) {
1.71 + Address address = MapMemory(amount, mode, Prot_ReadWrite);
1.72 + if (!address)
1.73 + return AlignableMapping();
1.74 + return AlignableMapping(address, alignment, amount);
1.75 + }
1.76 +
1.77 + size_t requested = Min(amount * 2, amount + 2 * alignment);
1.78 + Address address = MapMemory(amount, mode, Prot_ReadWrite);
1.79 + if (!address)
1.80 + return AlignableMapping();
1.81 +
1.82 + size_t begin = 0;
1.83 + Address aligned = AlignedBase(address, alignment);
1.84 + if (!IsAligned(address, alignment)) {
1.85 + // Shave off the first part of the unaligned region.
1.86 + aligned += alignment;
1.87 + begin = size_t(aligned - address);
1.88 + UnmapAlignedMemory(address, begin);
1.89 + }
1.90 +
1.91 + if (requested - begin > amount) {
1.92 + // Shave off the last part of the unaligned region.
1.93 + UnmapAlignedMemory(address + amount, requested - amount - begin);
1.94 + }
1.95 +
1.96 + return AlignableMapping(aligned, alignment, amount);
1.97 +}
1.98 +
1.99 +void
1.100 +OS::UnmapAlignedMemory(Address address, size_t size)
1.101 +{
1.102 + OS::UnmapMemory(address, size);
1.103 +}
1.104 +