 Chromium Code Reviews
 Chromium Code Reviews Issue 12619004:
  Speed up tcmalloc by allowing more inlining.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 12619004:
  Speed up tcmalloc by allowing more inlining.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2011, Google Inc. | 1 // Copyright (c) 2011, Google Inc. | 
| 2 // All rights reserved. | 2 // All rights reserved. | 
| 3 // | 3 // | 
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without | 
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are | 
| 6 // met: | 6 // met: | 
| 7 // | 7 // | 
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright | 
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. | 
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 // linked lists. It also contains macros to tell the SizeMap class | 35 // linked lists. It also contains macros to tell the SizeMap class | 
| 36 // how much space a node in the freelist needs so that SizeMap can | 36 // how much space a node in the freelist needs so that SizeMap can | 
| 37 // create large enough size classes. | 37 // create large enough size classes. | 
| 38 | 38 | 
| 39 #ifndef TCMALLOC_FREE_LIST_H_ | 39 #ifndef TCMALLOC_FREE_LIST_H_ | 
| 40 #define TCMALLOC_FREE_LIST_H_ | 40 #define TCMALLOC_FREE_LIST_H_ | 
| 41 | 41 | 
| 42 #include <stddef.h> | 42 #include <stddef.h> | 
| 43 #include "internal_logging.h" | 43 #include "internal_logging.h" | 
| 44 #include "linked_list.h" | 44 #include "linked_list.h" | 
| 45 #include "system-alloc.h" | |
| 45 | 46 | 
| 46 // Remove to enable singly linked lists (the default for open source tcmalloc). | 47 // Remove to enable singly linked lists (the default for open source tcmalloc). | 
| 47 #define TCMALLOC_USE_DOUBLYLINKED_FREELIST | 48 #define TCMALLOC_USE_DOUBLYLINKED_FREELIST | 
| 48 | 49 | 
| 49 namespace tcmalloc { | 50 namespace tcmalloc { | 
| 50 | 51 | 
| 51 #if defined(TCMALLOC_USE_DOUBLYLINKED_FREELIST) | 52 #if defined(TCMALLOC_USE_DOUBLYLINKED_FREELIST) | 
| 52 | 53 | 
| 53 // size class information for common.h. | 54 // size class information for common.h. | 
| 54 static const bool kSupportsDoublyLinkedList = true; | 55 static const bool kSupportsDoublyLinkedList = true; | 
| 55 | 56 | 
| 56 void *FL_Next(void *t); | |
| 57 void FL_Init(void *t); | |
| 58 void FL_Push(void **list, void *element); | |
| 59 void *FL_Pop(void **list); | |
| 60 void FL_PopRange(void **head, int n, void **start, void **end); | 57 void FL_PopRange(void **head, int n, void **start, void **end); | 
| 61 void FL_PushRange(void **head, void *start, void *end); | 58 void FL_PushRange(void **head, void *start, void *end); | 
| 62 size_t FL_Size(void *head); | 59 size_t FL_Size(void *head); | 
| 63 | 60 | 
| 61 template <typename T> inline void FL_EqualityCheck(const T& v0, | |
| 62 const T& v1, | |
| 63 const char* file, | |
| 64 int line) { | |
| 65 if (v0 != v1) Log(kCrash, file, line, "Memory corruption detected."); | |
| 
jar (doing other things)
2013/03/14 00:05:09
Is code optimized (by default) for the true case?
 
gpike
2013/03/14 00:58:37
I looked at the generated code and it seems fine.
 | |
| 66 } | |
| 67 | |
| 68 inline void EnsureNonLoop(void* node, void* next) { | |
| 69 // We only have time to do minimal checking. We don't traverse the list, but | |
| 70 // only look for an immediate loop (cycle back to ourself). | |
| 71 if (node != next) return; | |
| 72 Log(kCrash, __FILE__, __LINE__, "Circular loop in list detected: ", next); | |
| 73 } | |
| 74 | |
| 75 inline void* MaskPtr(void* p) { | |
| 76 // Maximize ASLR entropy and guarantee the result is an invalid address. | |
| 77 const uintptr_t mask = ~(reinterpret_cast<uintptr_t>(TCMalloc_SystemAlloc) | |
| 78 >> 13); | |
| 79 return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ mask); | |
| 80 } | |
| 81 | |
| 82 inline void* UnmaskPtr(void* p) { | |
| 83 return MaskPtr(p); | |
| 84 } | |
| 85 | |
| 86 // Returns value of the |previous| pointer w/out running a sanity | |
| 87 // check. | |
| 88 inline void *FL_Previous_No_Check(void *t) { | |
| 89 return UnmaskPtr(reinterpret_cast<void**>(t)[1]); | |
| 90 } | |
| 91 | |
| 92 // Returns value of the |next| pointer w/out running a sanity check. | |
| 93 inline void *FL_Next_No_Check(void *t) { | |
| 94 return UnmaskPtr(reinterpret_cast<void**>(t)[0]); | |
| 95 } | |
| 96 | |
| 97 inline void *FL_Previous(void *t) { | |
| 98 void *previous = FL_Previous_No_Check(t); | |
| 99 if (previous) { | |
| 100 FL_EqualityCheck(FL_Next_No_Check(previous), t, __FILE__, __LINE__); | |
| 101 } | |
| 102 return previous; | |
| 103 } | |
| 104 | |
| 105 inline void FL_SetPrevious(void *t, void *n) { | |
| 106 EnsureNonLoop(t, n); | |
| 107 reinterpret_cast<void**>(t)[1] = MaskPtr(n); | |
| 108 } | |
| 109 | |
| 110 inline void FL_SetNext(void *t, void *n) { | |
| 111 EnsureNonLoop(t, n); | |
| 112 reinterpret_cast<void**>(t)[0] = MaskPtr(n); | |
| 113 } | |
| 114 | |
| 115 inline void *FL_Next(void *t) { | |
| 116 void *next = FL_Next_No_Check(t); | |
| 117 if (next) { | |
| 118 FL_EqualityCheck(FL_Previous_No_Check(next), t, __FILE__, __LINE__); | |
| 119 } | |
| 120 return next; | |
| 121 } | |
| 122 | |
| 123 // Pops the top element off the linked list whose first element is at | |
| 124 // |*list|, and updates |*list| to point to the next element in the | |
| 125 // list. Returns the address of the element that was removed from the | |
| 126 // linked list. |list| must not be NULL. | |
| 127 inline void *FL_Pop(void **list) { | |
| 128 void *result = *list; | |
| 129 ASSERT(FL_Previous_No_Check(result) == NULL); | |
| 130 *list = FL_Next(result); | |
| 131 if (*list != NULL) { | |
| 132 FL_SetPrevious(*list, NULL); | |
| 133 } | |
| 134 return result; | |
| 135 } | |
| 136 | |
| 137 // Makes the element at |t| a singleton doubly linked list. | |
| 138 inline void FL_Init(void *t) { | |
| 139 FL_SetPrevious(t, NULL); | |
| 140 FL_SetNext(t, NULL); | |
| 141 } | |
| 142 | |
| 143 // Pushes element to a linked list whose first element is at | |
| 144 // |*list|. When this call returns, |list| will point to the new head | |
| 145 // of the linked list. | |
| 146 inline void FL_Push(void **list, void *element) { | |
| 147 void *old = *list; | |
| 148 if (old == NULL) { // Builds singleton list. | |
| 
jar (doing other things)
2013/03/14 00:05:09
In most cases, I'd expect that our lists are non-n
 
gpike
2013/03/14 00:58:37
Within the next few days I want to look at this fu
 | |
| 149 FL_Init(element); | |
| 150 } else { | |
| 151 ASSERT(FL_Previous_No_Check(old) == NULL); | |
| 152 FL_SetNext(element, old); | |
| 153 FL_SetPrevious(old, element); | |
| 154 FL_SetPrevious(element, NULL); | |
| 155 } | |
| 156 *list = element; | |
| 157 } | |
| 158 | |
| 64 #else // TCMALLOC_USE_DOUBLYLINKED_FREELIST not defined | 159 #else // TCMALLOC_USE_DOUBLYLINKED_FREELIST not defined | 
| 65 static const bool kSupportsDoublyLinkedList = false; | 160 static const bool kSupportsDoublyLinkedList = false; | 
| 66 | 161 | 
| 67 inline void *FL_Next(void *t) { | 162 inline void *FL_Next(void *t) { | 
| 68 return SLL_Next(t); | 163 return SLL_Next(t); | 
| 69 } | 164 } | 
| 70 | 165 | 
| 71 inline void FL_Init(void *t) { | 166 inline void FL_Init(void *t) { | 
| 72 SLL_SetNext(t, NULL); | 167 SLL_SetNext(t, NULL); | 
| 73 } | 168 } | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 98 | 193 | 
| 99 inline size_t FL_Size(void *head) { | 194 inline size_t FL_Size(void *head) { | 
| 100 return SLL_Size(head); | 195 return SLL_Size(head); | 
| 101 } | 196 } | 
| 102 | 197 | 
| 103 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST | 198 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST | 
| 104 | 199 | 
| 105 } // namespace tcmalloc | 200 } // namespace tcmalloc | 
| 106 | 201 | 
| 107 #endif // TCMALLOC_FREE_LIST_H_ | 202 #endif // TCMALLOC_FREE_LIST_H_ | 
| OLD | NEW |