summaryrefslogtreecommitdiffstats
path: root/jemalloc/include
diff options
context:
space:
mode:
authorJason Evans <je@fb.com>2011-03-23 07:37:29 (GMT)
committerJason Evans <je@fb.com>2011-03-23 07:37:29 (GMT)
commit38d9210c464c4ad49655a4da6bc84ea4fbec83d2 (patch)
tree8998181ebe1674e5dee2c110f7ec6ec16479a48e /jemalloc/include
parenteacb896c014d822cf563490d1c1f1cdc3cda24a2 (diff)
downloadjemalloc-38d9210c464c4ad49655a4da6bc84ea4fbec83d2.zip
jemalloc-38d9210c464c4ad49655a4da6bc84ea4fbec83d2.tar.gz
jemalloc-38d9210c464c4ad49655a4da6bc84ea4fbec83d2.tar.bz2
Fix error detection for ipalloc() when profiling.
sa2u() returns 0 on overflow, but the profiling code was blindly calling sa2u() and allowing the error to silently propagate, ultimately ending in a later assertion failure. Refactor all ipalloc() callers to call sa2u(), check for overflow before calling ipalloc(), and pass usize rather than size. This allows ipalloc() to avoid calling sa2u() in the common case.
Diffstat (limited to 'jemalloc/include')
-rw-r--r--jemalloc/include/jemalloc/internal/jemalloc_internal.h.in59
1 files changed, 38 insertions, 21 deletions
diff --git a/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in b/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in
index f82385d..254adb6 100644
--- a/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in
+++ b/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in
@@ -589,7 +589,7 @@ thread_allocated_get(void)
#ifndef JEMALLOC_ENABLE_INLINE
void *imalloc(size_t size);
void *icalloc(size_t size);
-void *ipalloc(size_t size, size_t alignment, bool zero);
+void *ipalloc(size_t usize, size_t alignment, bool zero);
size_t isalloc(const void *ptr);
# ifdef JEMALLOC_IVSALLOC
size_t ivsalloc(const void *ptr);
@@ -623,28 +623,39 @@ icalloc(size_t size)
}
JEMALLOC_INLINE void *
-ipalloc(size_t size, size_t alignment, bool zero)
+ipalloc(size_t usize, size_t alignment, bool zero)
{
void *ret;
- size_t usize;
- size_t run_size
-# ifdef JEMALLOC_CC_SILENCE
- = 0
-# endif
- ;
- usize = sa2u(size, alignment, &run_size);
- if (usize == 0)
- return (NULL);
+ assert(usize != 0);
+ assert(usize == sa2u(usize, alignment, NULL));
+
if (usize <= arena_maxclass && alignment <= PAGE_SIZE)
ret = arena_malloc(usize, zero);
- else if (run_size <= arena_maxclass) {
- ret = arena_palloc(choose_arena(), usize, run_size, alignment,
- zero);
- } else if (alignment <= chunksize)
- ret = huge_malloc(usize, zero);
- else
- ret = huge_palloc(usize, alignment, zero);
+ else {
+ size_t run_size
+#ifdef JEMALLOC_CC_SILENCE
+ = 0
+#endif
+ ;
+
+ /*
+ * Ideally we would only ever call sa2u() once per aligned
+ * allocation request, and the caller of this function has
+ * already done so once. However, it's rather burdensome to
+ * require every caller to pass in run_size, especially given
+ * that it's only relevant to large allocations. Therefore,
+ * just call it again here in order to get run_size.
+ */
+ sa2u(usize, alignment, &run_size);
+ if (run_size <= arena_maxclass) {
+ ret = arena_palloc(choose_arena(), usize, run_size,
+ alignment, zero);
+ } else if (alignment <= chunksize)
+ ret = huge_malloc(usize, zero);
+ else
+ ret = huge_palloc(usize, alignment, zero);
+ }
assert(((uintptr_t)ret & (alignment - 1)) == 0);
return (ret);
@@ -715,7 +726,7 @@ iralloc(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
if (alignment != 0 && ((uintptr_t)ptr & ((uintptr_t)alignment-1))
!= 0) {
- size_t copysize;
+ size_t usize, copysize;
/*
* Existing object alignment is inadquate; allocate new space
@@ -723,12 +734,18 @@ iralloc(void *ptr, size_t size, size_t extra, size_t alignment, bool zero,
*/
if (no_move)
return (NULL);
- ret = ipalloc(size + extra, alignment, zero);
+ usize = sa2u(size + extra, alignment, NULL);
+ if (usize == 0)
+ return (NULL);
+ ret = ipalloc(usize, alignment, zero);
if (ret == NULL) {
if (extra == 0)
return (NULL);
/* Try again, without extra this time. */
- ret = ipalloc(size, alignment, zero);
+ usize = sa2u(size, alignment, NULL);
+ if (usize == 0)
+ return (NULL);
+ ret = ipalloc(usize, alignment, zero);
if (ret == NULL)
return (NULL);
}