Handle lack of weak symbols on some platforms
authorPeter Griess <pgriess@fb.com>
Mon, 23 Sep 2013 23:25:18 +0000 (18:25 -0500)
committerPeter Griess <pgriess@fb.com>
Tue, 26 Nov 2013 15:05:18 +0000 (07:05 -0800)
Summary:
- It turns out that it's not always desirable to perform runtime
resolution of weak symbols. For example, on iOS, weak symbols are
resolved at runtime only if *all* symbol resolution is deferred util
then, which is undesirable for othe reasons. Detect such platforms at
configure time and use that information to populate detail/Malloc.h
with the correct declarations: weak symbols or extern symbols with
a value of nullptr.

Test Plan:
- fbconfig -r folly && fbmake runtests
- ./configure && make check on Ubuntu/FC/Mac

Reviewed By: andrei.alexandrescu@fb.com

FB internal diff: D1002959

folly/Makefile.am
folly/Malloc.h
folly/configure.ac
folly/detail/Malloc.cpp [new file with mode: 0644]
folly/detail/Malloc.h [new file with mode: 0644]
folly/detail/ThreadLocalDetail.h

index b42082b3c5361faf98ec9acc1e9d666787c51c31..a211ade3f9109d99482d339c056b3988ecd6b4fb 100644 (file)
@@ -39,6 +39,7 @@ nobase_follyinclude_HEADERS = \
        detail/FingerprintPolynomial.h \
        detail/Futex.h \
        detail/GroupVarintDetail.h \
+       detail/Malloc.h \
        detail/MPMCPipelineDetail.h \
        detail/SlowFingerprint.h \
        detail/Stats.h \
@@ -161,6 +162,10 @@ nobase_follyinclude_HEADERS += detail/Clock.h
 libfolly_la_SOURCES += detail/Clock.cpp
 endif
 
+if !HAVE_WEAK_SYMBOLS
+libfolly_la_SOURCES += detail/Malloc.cpp
+endif
+
 FingerprintTables.cpp: generate_fingerprint_tables
        ./generate_fingerprint_tables
 
index 8310a9aafddac67b7d2bd789701dbbd71b9183fb..6a66008616729394ed0245b41c11e29c504b36e2 100644 (file)
@@ -26,6 +26,8 @@
 // includes and uses fbstring.
 #if defined(_GLIBCXX_USE_FB) && !defined(_LIBSTDCXX_FBSTRING)
 
+#include "folly/detail/Malloc.h"
+
 #include <string>
 namespace folly {
   using std::goodMallocSize;
@@ -44,6 +46,7 @@ namespace folly {
 #include <bits/functexcept.h>
 #define FOLLY_HAVE_MALLOC_H 1
 #else
+#include "folly/detail/Malloc.h"
 #include "folly/Portability.h"
 #include <stdexcept>
 #endif
@@ -87,16 +90,6 @@ namespace folly {
 
 #endif /* ALLOCM_SUCCESS */
 
-/**
- * Declare rallocm() and malloc_usable_size() as weak symbols.  It
- * will be provided by jemalloc if we are using jemalloc, or it will
- * be NULL if we are using another malloc implementation.
- */
-extern "C" int rallocm(void**, size_t*, size_t, size_t, int)
-__attribute__((weak));
-extern "C" int allocm(void**, size_t*, size_t, int)
-__attribute__((weak));
-
 #ifdef _LIBSTDCXX_FBSTRING
 namespace std _GLIBCXX_VISIBILITY(default) {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
index 2c28d5c2de964df213c370ddd314f8244722e1a0..70afc3f087e930d711799b6db465e6f0ea73170a 100644 (file)
@@ -127,6 +127,20 @@ AC_COMPILE_IFELSE(
              [Define to 1 if we have a usable std::is_trivially_copyable<T>
               implementation.])])
 
+# Figure out if we support weak symbols. If not, we will link in some null
+# stubs for functions that would otherwise be weak.
+AC_LINK_IFELSE(
+  [AC_LANG_SOURCE[
+    extern "C" void configure_link_extern_weak_test() __attribute__((weak));
+    int main(int argc, char** argv) {
+        return configure_link_extern_weak_test == nullptr;
+    }]
+  ],
+  [
+    ac_have_weak_symbols="yes"
+    AC_DEFINE([HAVE_WEAK_SYMBOLS], [1],
+              [Define to 1 if the linker supports weak symbols.])])
+
 # Check for clock_gettime(2). This is not in an AC_CHECK_FUNCS() because we
 # want to link with librt if necessary.
 AC_SEARCH_LIBS([clock_gettime], [rt],
@@ -160,6 +174,7 @@ AC_SUBST(AM_LDFLAGS, "$BOOST_LDFLAGS $BOOST_THREAD_LIB $BOOST_SYSTEM_LIB $BOOST_
 AM_CONDITIONAL([HAVE_STD_THREAD], [test "$ac_cv_header_features" = "yes"])
 AM_CONDITIONAL([HAVE_X86_64], [test "$build_cpu" = "x86_64"])
 AM_CONDITIONAL([HAVE_LINUX], [test "$build_os" == "linux-gnu"])
+AM_CONDITIONAL([HAVE_WEAK_SYMBOLS], [test "$ac_have_weak_symbols" = "yes"])
 
 # Output
 AC_CONFIG_FILES([Makefile
diff --git a/folly/detail/Malloc.cpp b/folly/detail/Malloc.cpp
new file mode 100644 (file)
index 0000000..df076d5
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "folly/detail/Malloc.h"
+
+extern "C" {
+
+int (*rallocm)(void**, size_t*, size_t, size_t, int) = nullptr;
+int (*allocm)(void**, size_t*, size_t, int) = nullptr;
+
+}
diff --git a/folly/detail/Malloc.h b/folly/detail/Malloc.h
new file mode 100644 (file)
index 0000000..484745c
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2013 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FOLLY_DETAIL_MALLOC_H
+#define FOLLY_DETAIL_MALLOC_H
+
+#include <stdlib.h>
+#include "folly/folly-config.h"
+
+extern "C" {
+
+#if FOLLY_HAVE_WEAK_SYMBOLS
+int rallocm(void**, size_t*, size_t, size_t, int) __attribute__((weak));
+int allocm(void**, size_t*, size_t, int) __attribute__((weak));
+#else
+extern int (*rallocm)(void**, size_t*, size_t, size_t, int);
+extern int (*allocm)(void**, size_t*, size_t, int);
+#endif
+
+}
+
+#endif
index 20a74fa56f0678f2580b39d62b69c8bc4e7a606d..7dbe6e7f67f4da705df2d2931ee0a2913268559a 100644 (file)
 #include "folly/Exception.h"
 #include "folly/Malloc.h"
 
-// TODO(tudorb): Remove this declaration after Malloc.h is pushed to
-// third-party.
-extern "C" int allocm(void**, size_t*, size_t, int)
-__attribute__((weak));
-
 namespace folly {
 namespace threadlocal_detail {