summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-18 11:15:50 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-18 11:15:50 +0000
commit1d006f353d77d3f297c9ee42149eeca45bf90117 (patch)
tree0195ddcc695fd93cc927950bdd062cd7e71680d9 /gc.c
parent3175fbf194acfa93282cdd6bc03ec29fb4fd608a (diff)
* gc.c (aligned_malloc, aligned_free): added fallback implementations
for platforms like OSX Leopard. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35083 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/gc.c b/gc.c
index 76f58ee0e6..538830e344 100644
--- a/gc.c
+++ b/gc.c
@@ -1106,7 +1106,18 @@ aligned_malloc(size_t alignment, size_t size)
#elif defined(HAVE_MEMALIGN)
res = memalign(alignment, size);
#else
-#error no memalign function
+ char* aligned;
+ res = malloc(alignment + size + sizeof(void*));
+ aligned = (char*)res + alignment + sizeof(void*);
+ aligned -= ((VALUE)aligned & (alignment - 1));
+ ((void**)aligned)[-1] = res;
+ res = (void*)aligned;
+#endif
+
+#if defined(_DEBUG) || defined(GC_DEBUG)
+ /* alignment must be a power of 2 */
+ assert((alignment - 1) & alignment == 0);
+ assert(alignment % sizeof(void*) == 0);
#endif
return res;
}
@@ -1118,8 +1129,10 @@ aligned_free(void *ptr)
__mingw_aligned_free(ptr);
#elif defined _WIN32 && !defined __CYGWIN__
_aligned_free(ptr);
-#else
+#elif defined(HAVE_MEMALIGN) && defined(HAVE_POSIX_MEMALIGN)
free(ptr);
+#else
+ free(((void**)ptr)[-1]);
#endif
}