Make Malloc.h self-contained
authorGiuseppe Ottaviano <ott@fb.com>
Thu, 12 Nov 2015 16:37:48 +0000 (08:37 -0800)
committerfacebook-github-bot-9 <folly-bot@fb.com>
Thu, 12 Nov 2015 17:20:21 +0000 (09:20 -0800)
Reviewed By: philippv

Differential Revision: D2643313

fb-gh-sync-id: 10b9f735725ce47fab4bbfaa5972b3863357365f

folly/Makefile.am
folly/Malloc.cpp [deleted file]
folly/Malloc.h

index 4d5ac131ddad1576909b9e8ea78501609ae581cf..6639093214f4e1ce82166405d9dcf9cb6273aeea 100644 (file)
@@ -310,7 +310,6 @@ libfollybase_la_SOURCES = \
        EscapeTables.cpp \
        Format.cpp \
        FormatTables.cpp \
-       Malloc.cpp \
        StringBase.cpp \
        String.cpp \
        Unicode.cpp
diff --git a/folly/Malloc.cpp b/folly/Malloc.cpp
deleted file mode 100644 (file)
index aa2175c..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2015 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/Malloc.h>
-
-#include <cstdint>
-
-namespace folly {
-
-// How do we determine that we're using jemalloc?
-// In the hackiest way possible. We allocate memory using malloc() and see if
-// the per-thread counter of allocated memory increases. This makes me feel
-// dirty inside. Also note that this requires jemalloc to have been compiled
-// with --enable-stats.
-bool usingJEMallocSlow() {
-  // Some platforms (*cough* OSX *cough*) require weak symbol checks to be
-  // in the form if (mallctl != nullptr). Not if (mallctl) or if (!mallctl)
-  // (!!). http://goo.gl/xpmctm
-  if (mallocx == nullptr || rallocx == nullptr || xallocx == nullptr
-      || sallocx == nullptr || dallocx == nullptr || nallocx == nullptr
-      || mallctl == nullptr || mallctlnametomib == nullptr
-      || mallctlbymib == nullptr) {
-    return false;
-  }
-
-  // "volatile" because gcc optimizes out the reads from *counter, because
-  // it "knows" malloc doesn't modify global state...
-  /* nolint */ volatile uint64_t* counter;
-  size_t counterLen = sizeof(uint64_t*);
-
-  if (mallctl("thread.allocatedp", static_cast<void*>(&counter), &counterLen,
-              nullptr, 0) != 0) {
-    return false;
-  }
-
-  if (counterLen != sizeof(uint64_t*)) {
-    return false;
-  }
-
-  uint64_t origAllocated = *counter;
-
-  void* ptr = malloc(1);
-  if (!ptr) {
-    // wtf, failing to allocate 1 byte
-    return false;
-  }
-  free(ptr);
-
-  return (origAllocated != *counter);
-}
-
-}  // namespaces
index dab215db3dfb64aa231985ebe7cfd453f09f9c86..978cd1339f9c847f06f49f1c8aa058ce2e5ed38b 100644 (file)
@@ -32,8 +32,9 @@
 #define MALLOCX_ZERO (static_cast<int>(0x40))
 #endif
 
-// If using fbstring from libstdc++, then just define stub code
-// here to typedef the fbstring type into the folly namespace.
+// If using fbstring from libstdc++ (see comment in FBString.h), then
+// just define stub code here to typedef the fbstring type into the
+// folly namespace.
 // This provides backwards compatibility for code that explicitly
 // includes and uses fbstring.
 #if defined(_GLIBCXX_USE_FB) && !defined(_LIBSTDCXX_FBSTRING)
@@ -86,7 +87,6 @@ __attribute__((__weak__));
 #define FOLLY_HAVE_MALLOC_H 1
 #else
 #include <folly/detail/Malloc.h> /* nolint */
-#include <folly/Portability.h>
 #endif
 
 // for malloc_usable_size
@@ -100,6 +100,7 @@ __attribute__((__weak__));
 
 #include <cassert>
 #include <cstddef>
+#include <cstdint>
 #include <cstdlib>
 #include <cstring>
 
@@ -112,17 +113,62 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 namespace folly {
 #endif
 
-bool usingJEMallocSlow();
+// Cannot depend on Portability.h when _LIBSTDCXX_FBSTRING.
+#ifdef __GNUC__
+#define FOLLY_MALLOC_NOINLINE __attribute__((__noinline__))
+#else
+#define FOLLY_MALLOC_NOINLINE
+#endif
 
 /**
  * Determine if we are using jemalloc or not.
  */
-inline bool usingJEMalloc() {
+inline bool usingJEMalloc() noexcept {
   // Checking for rallocx != NULL is not sufficient; we may be in a dlopen()ed
   // module that depends on libjemalloc, so rallocx is resolved, but the main
-  // program might be using a different memory allocator. Look at the
-  // implementation of usingJEMallocSlow() for the (hacky) details.
-  static const bool result = usingJEMallocSlow();
+  // program might be using a different memory allocator.
+  // How do we determine that we're using jemalloc? In the hackiest
+  // way possible. We allocate memory using malloc() and see if the
+  // per-thread counter of allocated memory increases. This makes me
+  // feel dirty inside. Also note that this requires jemalloc to have
+  // been compiled with --enable-stats.
+  static const bool result = [] () FOLLY_MALLOC_NOINLINE noexcept {
+    // Some platforms (*cough* OSX *cough*) require weak symbol checks to be
+    // in the form if (mallctl != nullptr). Not if (mallctl) or if (!mallctl)
+    // (!!). http://goo.gl/xpmctm
+    if (mallocx == nullptr || rallocx == nullptr || xallocx == nullptr
+        || sallocx == nullptr || dallocx == nullptr || nallocx == nullptr
+        || mallctl == nullptr || mallctlnametomib == nullptr
+        || mallctlbymib == nullptr) {
+      return false;
+    }
+
+    // "volatile" because gcc optimizes out the reads from *counter, because
+    // it "knows" malloc doesn't modify global state...
+    /* nolint */ volatile uint64_t* counter;
+    size_t counterLen = sizeof(uint64_t*);
+
+    if (mallctl("thread.allocatedp", static_cast<void*>(&counter), &counterLen,
+                nullptr, 0) != 0) {
+      return false;
+    }
+
+    if (counterLen != sizeof(uint64_t*)) {
+      return false;
+    }
+
+    uint64_t origAllocated = *counter;
+
+    void* ptr = malloc(1);
+    if (!ptr) {
+      // wtf, failing to allocate 1 byte
+      return false;
+    }
+    free(ptr);
+
+    return (origAllocated != *counter);
+  }();
+
   return result;
 }