summaryrefslogtreecommitdiff
path: root/chromium/third_party/tcmalloc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-12 14:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-10-13 09:35:20 +0000
commitc30a6232df03e1efbd9f3b226777b07e087a1122 (patch)
treee992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/tcmalloc
parent7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff)
downloadqtwebengine-chromium-85-based.tar.gz
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/tcmalloc')
-rw-r--r--chromium/third_party/tcmalloc/README.chromium1
-rw-r--r--chromium/third_party/tcmalloc/chromium/src/free_list.cc133
-rw-r--r--chromium/third_party/tcmalloc/chromium/src/free_list.h108
-rw-r--r--chromium/third_party/tcmalloc/chromium/src/thread_cache.cc16
4 files changed, 138 insertions, 120 deletions
diff --git a/chromium/third_party/tcmalloc/README.chromium b/chromium/third_party/tcmalloc/README.chromium
index 46e65178d25..f7cfe7106ea 100644
--- a/chromium/third_party/tcmalloc/README.chromium
+++ b/chromium/third_party/tcmalloc/README.chromium
@@ -120,3 +120,4 @@ Modifications:
- Remove use of LINKER_INITIALIZED in page_heap_allocator.h, to enable the
compiler to optimize away a static constructor
- Include <atomic> in malloc_extension.h due to std::atomic usage
+- Precompute the pointer mask for doubly linked free lists instead of computing it on each access.
diff --git a/chromium/third_party/tcmalloc/chromium/src/free_list.cc b/chromium/third_party/tcmalloc/chromium/src/free_list.cc
index a486ae64391..5ba4a8d3cea 100644
--- a/chromium/third_party/tcmalloc/chromium/src/free_list.cc
+++ b/chromium/third_party/tcmalloc/chromium/src/free_list.cc
@@ -56,7 +56,7 @@
// empty list, the new list head becomes that which is pointed to by
// the former head's |next| pointer. If the list is doubly linked, the
// new head |previous| pointer gets changed from pointing to the former
-// head to NULL.
+// head to nullptr.
#include "free_list.h"
#include <stddef.h>
@@ -66,15 +66,122 @@
namespace tcmalloc {
+namespace {
+
+// Precomputed pointer mask.
+uintptr_t ptr_mask = 0;
+
+void* MaskPtr(void* p) {
+ return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ ptr_mask);
+}
+
+void* UnmaskPtr(void* p) {
+ return MaskPtr(p);
+}
+
+void EnsureNonLoop(void* node, void* next) {
+ // We only have time to do minimal checking. We don't traverse the list, but
+ // only look for an immediate loop (cycle back to ourself).
+ if (node != next)
+ return;
+ Log(kCrash, __FILE__, __LINE__, "Circular loop in list detected: ", next);
+}
+
+template <typename T>
+void FL_EqualityCheck(const T& v0, const T& v1, const char* file, int line) {
+ if (v0 != v1)
+ Log(kCrash, file, line, "Memory corruption detected.");
+}
+
+// Returns value of the |previous| pointer w/out running a sanity
+// check.
+void* FL_Previous_No_Check(void* t) {
+ return UnmaskPtr(reinterpret_cast<void**>(t)[1]);
+}
+
+// Returns value of the |next| pointer w/out running a sanity check.
+void* FL_Next_No_Check(void* t) {
+ return UnmaskPtr(reinterpret_cast<void**>(t)[0]);
+}
+
+void* FL_Previous(void* t) {
+ void* previous = FL_Previous_No_Check(t);
+ if (previous) {
+ FL_EqualityCheck(FL_Next_No_Check(previous), t, __FILE__, __LINE__);
+ }
+ return previous;
+}
+
+} // namespace
+
+void FL_InitPtrMask(uintptr_t seed) {
+ // Maximize ASLR entropy and guarantee the result is an invalid address.
+ ptr_mask = ~(seed >> 13);
+}
+
+void FL_SetPrevious(void* t, void* n) {
+ EnsureNonLoop(t, n);
+ reinterpret_cast<void**>(t)[1] = MaskPtr(n);
+}
+
+void FL_SetNext(void* t, void* n) {
+ EnsureNonLoop(t, n);
+ reinterpret_cast<void**>(t)[0] = MaskPtr(n);
+}
+
+void* FL_Next(void* t) {
+ void* next = FL_Next_No_Check(t);
+ if (next) {
+ FL_EqualityCheck(FL_Previous_No_Check(next), t, __FILE__, __LINE__);
+ }
+ return next;
+}
+
+// Pops the top element off the linked list whose first element is at
+// |*list|, and updates |*list| to point to the next element in the
+// list. Returns the address of the element that was removed from the
+// linked list. |list| must not be nullptr.
+void* FL_Pop(void** list) {
+ void* result = *list;
+ ASSERT(FL_Previous_No_Check(result) == nullptr);
+ *list = FL_Next(result);
+ if (*list != nullptr) {
+ FL_SetPrevious(*list, nullptr);
+ }
+ return result;
+}
+
+// Makes the element at |t| a singleton doubly linked list.
+void FL_Init(void* t) {
+ FL_SetPrevious(t, nullptr);
+ FL_SetNext(t, nullptr);
+}
+
+// Pushes element to a linked list whose first element is at
+// |*list|. When this call returns, |list| will point to the new head
+// of the linked list.
+void FL_Push(void** list, void* element) {
+ void* old = *list;
+ if (old == nullptr) { // Builds singleton list.
+ FL_Init(element);
+ } else {
+ ASSERT(FL_Previous_No_Check(old) == nullptr);
+ FL_SetNext(element, old);
+ FL_SetPrevious(old, element);
+ FL_SetPrevious(element, nullptr);
+ }
+ *list = element;
+}
+
// Remove |n| elements from linked list at whose first element is at
// |*head|. |head| will be modified to point to the new head.
// |start| will point to the first node of the range, |end| will point
// to the last node in the range. |n| must be <= FL_Size(|*head|)
-// If |n| > 0, |head| must not be NULL.
+// If |n| > 0, |head| must not be nullptr.
void FL_PopRange(void** head, int n, void** start, void** end) {
if (n == 0) {
- *start = NULL;
- *end = NULL;
+ *start = nullptr;
+ *end = nullptr;
return;
}
@@ -85,16 +192,16 @@ void FL_PopRange(void** head, int n, void** start, void** end) {
}
*end = tmp; // |end| now set to point to last node in range.
*head = FL_Next(*end);
- FL_SetNext(*end, NULL); // Unlink range from list.
+ FL_SetNext(*end, nullptr); // Unlink range from list.
if (*head) { // Fixup popped list.
- FL_SetPrevious(*head, NULL);
+ FL_SetPrevious(*head, nullptr);
}
}
// Pushes the nodes in the list beginning at |start| whose last node
// is |end| into the linked list at |*head|. |*head| is updated to
-// point be the new head of the list. |head| must not be NULL.
+// point be the new head of the list. |head| must not be nullptr.
void FL_PushRange(void** head, void* start, void* end) {
if (!start)
return;
@@ -103,12 +210,12 @@ void FL_PushRange(void** head, void* start, void* end) {
// FL_Next and FL_Previous.
FL_Next(start);
FL_Previous(end);
- ASSERT(FL_Previous_No_Check(start) == NULL);
- ASSERT(FL_Next_No_Check(end) == NULL);
+ ASSERT(FL_Previous_No_Check(start) == nullptr);
+ ASSERT(FL_Next_No_Check(end) == nullptr);
if (*head) {
- FL_EqualityCheck(FL_Previous_No_Check(*head), (void*)NULL, __FILE__,
- __LINE__);
+ FL_EqualityCheck(FL_Previous_No_Check(*head), static_cast<void*>(nullptr),
+ __FILE__, __LINE__);
FL_SetNext(end, *head);
FL_SetPrevious(*head, end);
}
@@ -119,8 +226,8 @@ void FL_PushRange(void** head, void* start, void* end) {
size_t FL_Size(void* head) {
int count = 0;
if (head) {
- FL_EqualityCheck(FL_Previous_No_Check(head), (void*)NULL, __FILE__,
- __LINE__);
+ FL_EqualityCheck(FL_Previous_No_Check(head), static_cast<void*>(nullptr),
+ __FILE__, __LINE__);
}
while (head) {
count++;
diff --git a/chromium/third_party/tcmalloc/chromium/src/free_list.h b/chromium/third_party/tcmalloc/chromium/src/free_list.h
index a39114f2831..7065e046488 100644
--- a/chromium/third_party/tcmalloc/chromium/src/free_list.h
+++ b/chromium/third_party/tcmalloc/chromium/src/free_list.h
@@ -42,7 +42,6 @@
#include <stddef.h>
#include "internal_logging.h"
#include "linked_list.h"
-#include "system-alloc.h"
namespace tcmalloc {
@@ -51,110 +50,17 @@ namespace tcmalloc {
// size class information for common.h.
static const bool kSupportsDoublyLinkedList = true;
+void FL_InitPtrMask(uintptr_t seed);
+void FL_Init(void* t);
void FL_PopRange(void** head, int n, void** start, void** end);
void FL_PushRange(void** head, void* start, void* end);
size_t FL_Size(void* head);
-template <typename T>
-inline void FL_EqualityCheck(const T& v0,
- const T& v1,
- const char* file,
- int line) {
- if (v0 != v1)
- Log(kCrash, file, line, "Memory corruption detected.");
-}
-
-inline void EnsureNonLoop(void* node, void* next) {
- // We only have time to do minimal checking. We don't traverse the list, but
- // only look for an immediate loop (cycle back to ourself).
- if (node != next)
- return;
- Log(kCrash, __FILE__, __LINE__, "Circular loop in list detected: ", next);
-}
-
-inline void* MaskPtr(void* p) {
- // Maximize ASLR entropy and guarantee the result is an invalid address.
- const uintptr_t mask =
- ~(reinterpret_cast<uintptr_t>(TCMalloc_SystemAlloc) >> 13);
- return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ mask);
-}
-
-inline void* UnmaskPtr(void* p) {
- return MaskPtr(p);
-}
-
-// Returns value of the |previous| pointer w/out running a sanity
-// check.
-inline void* FL_Previous_No_Check(void* t) {
- return UnmaskPtr(reinterpret_cast<void**>(t)[1]);
-}
-
-// Returns value of the |next| pointer w/out running a sanity check.
-inline void* FL_Next_No_Check(void* t) {
- return UnmaskPtr(reinterpret_cast<void**>(t)[0]);
-}
-
-inline void* FL_Previous(void* t) {
- void* previous = FL_Previous_No_Check(t);
- if (previous) {
- FL_EqualityCheck(FL_Next_No_Check(previous), t, __FILE__, __LINE__);
- }
- return previous;
-}
-
-inline void FL_SetPrevious(void* t, void* n) {
- EnsureNonLoop(t, n);
- reinterpret_cast<void**>(t)[1] = MaskPtr(n);
-}
-
-inline void FL_SetNext(void* t, void* n) {
- EnsureNonLoop(t, n);
- reinterpret_cast<void**>(t)[0] = MaskPtr(n);
-}
-
-inline void* FL_Next(void* t) {
- void* next = FL_Next_No_Check(t);
- if (next) {
- FL_EqualityCheck(FL_Previous_No_Check(next), t, __FILE__, __LINE__);
- }
- return next;
-}
-
-// Pops the top element off the linked list whose first element is at
-// |*list|, and updates |*list| to point to the next element in the
-// list. Returns the address of the element that was removed from the
-// linked list. |list| must not be NULL.
-inline void* FL_Pop(void** list) {
- void* result = *list;
- ASSERT(FL_Previous_No_Check(result) == NULL);
- *list = FL_Next(result);
- if (*list != NULL) {
- FL_SetPrevious(*list, NULL);
- }
- return result;
-}
-
-// Makes the element at |t| a singleton doubly linked list.
-inline void FL_Init(void* t) {
- FL_SetPrevious(t, NULL);
- FL_SetNext(t, NULL);
-}
-
-// Pushes element to a linked list whose first element is at
-// |*list|. When this call returns, |list| will point to the new head
-// of the linked list.
-inline void FL_Push(void** list, void* element) {
- void* old = *list;
- if (old == NULL) { // Builds singleton list.
- FL_Init(element);
- } else {
- ASSERT(FL_Previous_No_Check(old) == NULL);
- FL_SetNext(element, old);
- FL_SetPrevious(old, element);
- FL_SetPrevious(element, NULL);
- }
- *list = element;
-}
+void FL_SetPrevious(void* t, void* n);
+void FL_SetNext(void* t, void* n);
+void* FL_Next(void* t);
+void* FL_Pop(void** list);
+void FL_Push(void** list, void* element);
#else // TCMALLOC_USE_DOUBLYLINKED_FREELIST not defined
static const bool kSupportsDoublyLinkedList = false;
diff --git a/chromium/third_party/tcmalloc/chromium/src/thread_cache.cc b/chromium/third_party/tcmalloc/chromium/src/thread_cache.cc
index 8fea2ca4ad6..4ed9c82ffd8 100644
--- a/chromium/third_party/tcmalloc/chromium/src/thread_cache.cc
+++ b/chromium/third_party/tcmalloc/chromium/src/thread_cache.cc
@@ -34,13 +34,14 @@
#include <config.h>
#include "thread_cache.h"
#include <errno.h>
-#include <string.h> // for memcpy
-#include <algorithm> // for max, min
-#include "base/commandlineflags.h" // for SpinLockHolder
-#include "base/spinlock.h" // for SpinLockHolder
-#include "getenv_safe.h" // for TCMallocGetenvSafe
-#include "central_freelist.h" // for CentralFreeListPadded
+#include <string.h> // for memcpy
+#include <algorithm> // for max, min
+#include "base/commandlineflags.h" // for SpinLockHolder
+#include "base/spinlock.h" // for SpinLockHolder
+#include "central_freelist.h" // for CentralFreeListPadded
+#include "getenv_safe.h" // for TCMallocGetenvSafe
#include "maybe_threads.h"
+#include "system-alloc.h"
using std::min;
using std::max;
@@ -300,6 +301,9 @@ void ThreadCache::InitModule() {
if (tcb) {
set_overall_thread_cache_size(strtoll(tcb, NULL, 10));
}
+#if defined(TCMALLOC_USE_DOUBLYLINKED_FREELIST)
+ FL_InitPtrMask(reinterpret_cast<uintptr_t>(TCMalloc_SystemAlloc));
+#endif
Static::InitStaticVars();
threadcache_allocator.Init();
phinited = 1;