Browse Source

Malloc and friends are critical-path: Thus, add an it-wont-happen branch prediction for NULL returns, and skip the malloc(0) check on platforms where malloc(0) returns a pointer.

svn:r8431
Nick Mathewson 17 years ago
parent
commit
2d4950c837
3 changed files with 34 additions and 3 deletions
  1. 2 0
      ChangeLog
  2. 27 0
      configure.in
  3. 5 3
      src/common/util.c

+ 2 - 0
ChangeLog

@@ -3,6 +3,8 @@ Changes in version 0.1.2.2-alpha - 2006-??-??
   o Minor Bugfixes
     - Small performance improvements on parsing and inserting
       descriptors.
+    - Make the common memory allocation path faster on machines where
+      malloc(0) returns a pointer.
 
 Changes in version 0.1.2.1-alpha - 2006-08-27
   o Major features:

+ 27 - 0
configure.in

@@ -558,6 +558,33 @@ if test $tor_cv_null_is_zero = yes; then
             [Define to 1 iff memset(0) sets pointers to NULL])
 fi
 
+# And what happens when we malloc zero?
+
+if test -z "$CROSS_COMPILE"; then
+AC_CACHE_CHECK([whether we can malloc(0) safely.], tor_cv_malloc_zero_works,
+[AC_RUN_IFELSE([AC_LANG_SOURCE(
+[[#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+int main () { return malloc(0)?0:1; }]])],
+       [tor_cv_malloc_zero_works=yes],
+       [tor_cv_malloc_zero_works=no],
+       [tor_cv_malloc_zero_works=cross])])
+
+else
+  # Cross-compiling; let's hope that the target isn't raving mad.
+  AC_MSG_NOTICE([Cross-compiling: we'll assume that we need to check malloc() arguments for 0.])
+  tor_cv_malloc_zero_works=no
+fi
+
+if test $tor_cv_malloc_zero_works = yes; then
+  AC_DEFINE([MALLOC_ZERO_WORKS], 1,
+            [Define to 1 iff malloc(0) returns a pointer])
+fi
+
 # Whether we should use the dmalloc memory allocation debugging library.
 AC_MSG_CHECKING(whether to use dmalloc (debug memory allocation library))
 AC_ARG_WITH(dmalloc,

+ 5 - 3
src/common/util.c

@@ -106,13 +106,15 @@ _tor_malloc(size_t size DMALLOC_PARAMS)
 {
   void *result;
 
+#ifndef MALLOC_ZERO_WORKS
   /* Some libcs don't do the right thing on size==0. Override them. */
   if (size==0) {
     size=1;
   }
+#endif
   result = dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC, 0, 0);
 
-  if (!result) {
+  if (PREDICT(result == NULL, 0)) {
     log_err(LD_MM,"Out of memory. Dying.");
     /* If these functions die within a worker process, they won't call
      * spawn_exit, but that's ok, since the parent will run out of memory soon
@@ -144,7 +146,7 @@ _tor_realloc(void *ptr, size_t size DMALLOC_PARAMS)
   void *result;
 
   result = dmalloc_realloc(file, line, ptr, size, DMALLOC_FUNC_REALLOC, 0);
-  if (!result) {
+  if (PREDICT(result == NULL, 0)) {
     log_err(LD_MM,"Out of memory. Dying.");
     exit(1);
   }
@@ -162,7 +164,7 @@ _tor_strdup(const char *s DMALLOC_PARAMS)
   tor_assert(s);
 
   dup = dmalloc_strdup(file, line, s, 0);
-  if (!dup) {
+  if (PREDICT(dup == NULL, 0)) {
     log_err(LD_MM,"Out of memory. Dying.");
     exit(1);
   }