aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <[email protected]>2014-10-14 00:23:42 +0900
committerMITSUNARI Shigeo <[email protected]>2014-10-14 00:23:42 +0900
commit0fc4b9bd1b9ffe0b82226d34f3ec53c591a68941 (patch)
tree98da375bb49f8a995b4b5c7f5f3694dc503cfcd5
parent23694b5bb0bc9d7f4ac061e8880b7fd5dc7e308b (diff)
downloadxbyak-0fc4b9bd1b9ffe0b82226d34f3ec53c591a68941.tar.gz
xbyak-0fc4b9bd1b9ffe0b82226d34f3ec53c591a68941.zip
default off
-rw-r--r--xbyak/xbyak.h39
1 files changed, 38 insertions, 1 deletions
diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h
index 5dc6931..ce3007a 100644
--- a/xbyak/xbyak.h
+++ b/xbyak/xbyak.h
@@ -24,6 +24,8 @@
#include <iostream>
#endif
+//#define XBYAK_USE_MMAP_ALLOCATOR
+
// This covers -std=(gnu|c)++(0x|11|1y), -stdlib=libc++, and modern Microsoft.
#if ((defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(_LIBCPP_VERSION) ||\
((__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)))
@@ -152,6 +154,7 @@ enum {
ERR_LABEL_ISNOT_SET_BY_L,
ERR_LABEL_IS_ALREADY_SET_BY_L,
ERR_BAD_LABEL_STR,
+ ERR_MUNMAP,
ERR_INTERNAL
};
@@ -201,6 +204,7 @@ public:
"label is not set by L()",
"label is already set by L()",
"bad label string",
+ "err munmap",
"internal error",
};
assert((size_t)err_ < sizeof(errTbl) / sizeof(*errTbl));
@@ -276,6 +280,35 @@ struct Allocator {
virtual bool useProtect() const { return true; }
};
+#ifndef __GNUC__
+ #undef XBYAK_USE_MMAP_ALLOCATOR
+#endif
+#ifdef __GNUC__
+class MmapAllocator : Allocator {
+ typedef XBYAK_STD_UNORDERED_MAP<uintptr_t, size_t> SizeList;
+ SizeList sizeList_;
+public:
+ uint8 *alloc(size_t size)
+ {
+ const size_t alignedSizeM1 = inner::ALIGN_PAGE_SIZE - 1;
+ size = (size + alignedSizeM1) & ~alignedSizeM1;
+ void *p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (p == MAP_FAILED) throw Error(ERR_CANT_ALLOC);
+ assert(p);
+ sizeList_[(uintptr_t)p] = size;
+ return (uint8*)p;
+ }
+ void free(uint8 *p)
+ {
+ if (p == 0) return;
+ SizeList::iterator i = sizeList_.find((uintptr_t)p);
+ if (i == sizeList_.end()) throw Error(ERR_BAD_PARAMETER);
+ if (munmap((void*)i->first, i->second) < 0) throw Error(ERR_MUNMAP);
+ sizeList_.erase(i);
+ }
+};
+#endif
+
class Operand {
private:
uint8 idx_; // 0..15, MSB = 1 if spl/bpl/sil/dil
@@ -599,7 +632,11 @@ class CodeArray {
typedef std::list<AddrInfo> AddrInfoList;
AddrInfoList addrInfoList_;
const Type type_;
+#ifdef XBYAK_USE_MMAP_ALLOCATOR
+ MmapAllocator defaultAllocator_;
+#else
Allocator defaultAllocator_;
+#endif
Allocator *alloc_;
protected:
size_t maxSize_;
@@ -633,7 +670,7 @@ protected:
public:
explicit CodeArray(size_t maxSize, void *userPtr = 0, Allocator *allocator = 0)
: type_(userPtr == AutoGrow ? AUTO_GROW : userPtr ? USER_BUF : ALLOC_BUF)
- , alloc_(allocator ? allocator : &defaultAllocator_)
+ , alloc_(allocator ? allocator : (Allocator*)&defaultAllocator_)
, maxSize_(maxSize)
, top_(type_ == USER_BUF ? reinterpret_cast<uint8*>(userPtr) : alloc_->alloc((std::max<size_t>)(maxSize, 1)))
, size_(0)