Bug 635790 - Don't depend on gnu89 inline. r=pbiggar
authorRafael Ávila de Espíndola <espindola@desktop.lan>
Wed, 27 Apr 2011 10:05:07 +0200
changeset 68787 1e64d699aa012c88e45473b97ce43c70f91f5046
parent 68786 fa0295a97f1bb58251479ac0734eef96b1394249
child 68788 c17c9e2c88454380b1702fbea13e52330ad7a287
push id99
push usereakhgari@mozilla.com
push dateTue, 24 May 2011 18:03:59 +0000
treeherdermozilla-aurora@26d6981b3d6a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspbiggar
bugs635790
milestone6.0a1
Bug 635790 - Don't depend on gnu89 inline. r=pbiggar
memory/jemalloc/jemalloc.c
--- a/memory/jemalloc/jemalloc.c
+++ b/memory/jemalloc/jemalloc.c
@@ -5887,29 +5887,47 @@ RETURN:
 #endif
 		errno = ENOMEM;
 	}
 
 	UTRACE(0, size, ret);
 	return (ret);
 }
 
+/* In ELF systems the default visibility allows symbols to be preempted at
+   runtime. This in turn prevents the uses of memalign in this file from
+   being optimized. What we do in here is define two aliasing symbols
+   (they point to the same code): memalign and memalign_internal.
+   The internal version has hidden visibility and is used in every reference
+   from this file.
+   For more information on this technique, see section 2.2.7
+   (Avoid Using Exported Symbols) in
+   http://www.akkadia.org/drepper/dsohowto.pdf */
 #ifdef MOZ_MEMORY_SOLARIS
 #  ifdef __SUNPRO_C
 void *
 memalign(size_t alignment, size_t size);
 #pragma no_inline(memalign)
 #  elif (defined(__GNU_C__))
 __attribute__((noinline))
 #  endif
 #else
-inline
-#endif
+#if (defined(__GNUC__))
+__attribute__((visibility ("hidden")))
+#endif
+#endif
+
+#if (defined(__GNUC__))
+#define MEMALIGN memalign_internal
+#else
+#define MEMALIGN memalign
+#endif
+
 void *
-memalign(size_t alignment, size_t size)
+MEMALIGN(size_t alignment, size_t size)
 {
 	void *ret;
 
 	assert(((alignment - 1) & alignment) == 0);
 
 	if (malloc_init()) {
 		ret = NULL;
 		goto RETURN;
@@ -5938,16 +5956,22 @@ RETURN:
 		": (malloc) Error in memalign(): out of memory\n", "", "");
 		abort();
 	}
 #endif
 	UTRACE(0, size, ret);
 	return (ret);
 }
 
+#if (defined(__GNUC__))
+extern __typeof(memalign_internal)
+        memalign __attribute__((alias ("memalign_internal"),
+				visibility ("default")));
+#endif
+
 ZONE_INLINE
 int
 posix_memalign(void **memptr, size_t alignment, size_t size)
 {
 	void *result;
 
 	/* Make sure that alignment is a large enough power of 2. */
 	if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *)) {
@@ -5962,33 +5986,33 @@ posix_memalign(void **memptr, size_t ali
 		return (EINVAL);
 	}
 
 	/* The 0-->1 size promotion is done in the memalign() call below */
 
 #ifdef MOZ_MEMORY_DARWIN
 	result = moz_memalign(alignment, size);
 #else
-	result = memalign(alignment, size);
+	result = MEMALIGN(alignment, size);
 #endif
 	if (result == NULL)
 		return (ENOMEM);
 
 	*memptr = result;
 	return (0);
 }
 
 ZONE_INLINE
 void *
 valloc(size_t size)
 {
 #ifdef MOZ_MEMORY_DARWIN
 	return (moz_memalign(pagesize, size));
 #else
-	return (memalign(pagesize, size));
+	return (MEMALIGN(pagesize, size));
 #endif
 }
 
 ZONE_INLINE
 void *
 calloc(size_t num, size_t size)
 {
 	void *ret;
@@ -6523,17 +6547,17 @@ jemalloc_darwin_init(void)
  * These definitions interpose hooks in glibc.  The functions are actually
  * passed an extra argument for the caller return address, which will be
  * ignored.
  */
 #ifndef WRAP_MALLOC
 void (*__free_hook)(void *ptr) = free;
 void *(*__malloc_hook)(size_t size) = malloc;
 void *(*__realloc_hook)(void *ptr, size_t size) = realloc;
-void *(*__memalign_hook)(size_t alignment, size_t size) = memalign;
+void *(*__memalign_hook)(size_t alignment, size_t size) = MEMALIGN;
 #endif
 
 #elif defined(RTLD_DEEPBIND)
 /*
  * XXX On systems that support RTLD_GROUP or DF_1_GROUP, do their
  * implementations permit similar inconsistencies?  Should STV_SINGLETON
  * visibility be used for interposition where available?
  */