summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-22 09:26:46 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-05-22 09:26:46 +0000
commit70b4b6dc8b54f7e4e5c48460ecd2843573c5a9a4 (patch)
tree184197f5a81b98b1ff022802920fbbc6a16fa186 /gc.c
parent0d6d23b25db0e7d14969504eeba6ac31581a79a2 (diff)
* gc.c (vm_xcalloc): use calloc provided by platforms.
fixes #4754 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31690 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/gc.c b/gc.c
index d63300231f..28fa233adc 100644
--- a/gc.c
+++ b/gc.c
@@ -702,11 +702,9 @@ garbage_collect_with_gvl(rb_objspace_t *objspace)
static void vm_xfree(rb_objspace_t *objspace, void *ptr);
-static void *
-vm_xmalloc(rb_objspace_t *objspace, size_t size)
+static inline void
+vm_malloc_prepare(rb_objspace_t *objspace, size_t size)
{
- void *mem;
-
if ((ssize_t)size < 0) {
negative_size_allocation_error("negative allocation size (or too big)");
}
@@ -720,15 +718,11 @@ vm_xmalloc(rb_objspace_t *objspace, size_t size)
(malloc_increase+size) > malloc_limit) {
garbage_collect_with_gvl(objspace);
}
- mem = malloc(size);
- if (!mem) {
- if (garbage_collect_with_gvl(objspace)) {
- mem = malloc(size);
- }
- if (!mem) {
- ruby_memerror();
- }
- }
+}
+
+static inline void *
+vm_malloc_fixup(rb_objspace_t *objspace, void *mem, size_t size)
+{
malloc_increase += size;
#if CALC_EXACT_MALLOC_SIZE
@@ -741,6 +735,24 @@ vm_xmalloc(rb_objspace_t *objspace, size_t size)
return mem;
}
+#define TRY_WITH_GC(alloc) do { \
+ if (!(alloc) && \
+ (!garbage_collect_with_gvl(objspace) || \
+ !(alloc))) { \
+ ruby_memerror(); \
+ } \
+ } while (0)
+
+static void *
+vm_xmalloc(rb_objspace_t *objspace, size_t size)
+{
+ void *mem;
+
+ vm_malloc_prepare(objspace, size);
+ TRY_WITH_GC(mem = malloc(size));
+ return vm_malloc_fixup(objspace, mem, size);
+}
+
static void *
vm_xrealloc(rb_objspace_t *objspace, void *ptr, size_t size)
{
@@ -803,23 +815,37 @@ ruby_xmalloc(size_t size)
return vm_xmalloc(&rb_objspace, size);
}
-void *
-ruby_xmalloc2(size_t n, size_t size)
+static inline size_t
+xmalloc2_size(size_t n, size_t size)
{
size_t len = size * n;
if (n != 0 && size != len / n) {
rb_raise(rb_eArgError, "malloc: possible integer overflow");
}
- return vm_xmalloc(&rb_objspace, len);
+ return len;
}
void *
-ruby_xcalloc(size_t n, size_t size)
+ruby_xmalloc2(size_t n, size_t size)
{
- void *mem = ruby_xmalloc2(n, size);
- memset(mem, 0, n * size);
+ return vm_xmalloc(&rb_objspace, xmalloc2_size(n, size));
+}
- return mem;
+static void *
+vm_xcalloc(rb_objspace_t *objspace, size_t count, size_t elsize)
+{
+ void *mem;
+ const size_t size = xmalloc2_size(count, elsize);
+
+ vm_malloc_prepare(objspace, size);
+ TRY_WITH_GC(mem = calloc(count, elsize));
+ return vm_malloc_fixup(objspace, mem, size);
+}
+
+void *
+ruby_xcalloc(size_t n, size_t size)
+{
+ return vm_xcalloc(&rb_objspace, n, size);
}
void *