Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: third_party/tcmalloc/chromium/src/free_list.cc

Issue 12619004: Speed up tcmalloc by allowing more inlining. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 // For both types of lists: when a pop operation is performed on a non 55 // For both types of lists: when a pop operation is performed on a non
56 // empty list, the new list head becomes that which is pointed to by 56 // empty list, the new list head becomes that which is pointed to by
57 // the former head's |next| pointer. If the list is doubly linked, the 57 // the former head's |next| pointer. If the list is doubly linked, the
58 // new head |previous| pointer gets changed from pointing to the former 58 // new head |previous| pointer gets changed from pointing to the former
59 // head to NULL. 59 // head to NULL.
60 60
61 61
62 #include <limits> 62 #include <limits>
63 #include <stddef.h> 63 #include <stddef.h>
64 #include "free_list.h" 64 #include "free_list.h"
65 #include "system-alloc.h"
66 65
67 #if defined(TCMALLOC_USE_DOUBLYLINKED_FREELIST) 66 #if defined(TCMALLOC_USE_DOUBLYLINKED_FREELIST)
68 67
69 using tcmalloc::kCrash;
70
71 // TODO(jar): We should use C++ rather than a macro here.
72 #define MEMORY_CHECK(v1, v2) \
73 if (v1 != v2) Log(kCrash, __FILE__, __LINE__, "Memory corruption detected.")
74
75 namespace {
76 void EnsureNonLoop(void* node, void* next) {
77 // We only have time to do minimal checking. We don't traverse the list, but
78 // only look for an immediate loop (cycle back to ourself).
79 if (node != next) return;
80 Log(kCrash, __FILE__, __LINE__, "Circular loop in list detected: ", next);
81 }
82
83 inline void* MaskPtr(void* p) {
84 // Maximize ASLR entropy and guarantee the result is an invalid address.
85 const uintptr_t mask = ~(reinterpret_cast<uintptr_t>(TCMalloc_SystemAlloc)
86 >> 13);
87 return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ mask);
88 }
89
90 inline void* UnmaskPtr(void* p) {
91 return MaskPtr(p);
92 }
93
94 // Returns value of the |previous| pointer w/out running a sanity
95 // check.
96 inline void *FL_Previous_No_Check(void *t) {
97 return UnmaskPtr(reinterpret_cast<void**>(t)[1]);
98 }
99
100 // Returns value of the |next| pointer w/out running a sanity check.
101 inline void *FL_Next_No_Check(void *t) {
102 return UnmaskPtr(reinterpret_cast<void**>(t)[0]);
103 }
104
105 void *FL_Previous(void *t) {
106 void *previous = FL_Previous_No_Check(t);
107 if (previous) {
108 MEMORY_CHECK(FL_Next_No_Check(previous), t);
109 }
110 return previous;
111 }
112
113 inline void FL_SetPrevious(void *t, void *n) {
114 EnsureNonLoop(t, n);
115 reinterpret_cast<void**>(t)[1] = MaskPtr(n);
116 }
117
118 inline void FL_SetNext(void *t, void *n) {
119 EnsureNonLoop(t, n);
120 reinterpret_cast<void**>(t)[0] = MaskPtr(n);
121 }
122
123 } // namespace
124
125 namespace tcmalloc { 68 namespace tcmalloc {
126 69
127 void *FL_Next(void *t) {
128 void *next = FL_Next_No_Check(t);
129 if (next) {
130 MEMORY_CHECK(FL_Previous_No_Check(next), t);
131 }
132 return next;
133 }
134
135 // Makes the element at |t| a singleton doubly linked list.
136 void FL_Init(void *t) {
137 FL_SetPrevious(t, NULL);
138 FL_SetNext(t, NULL);
139 }
140
141 // Pushes element to a linked list whose first element is at
142 // |*list|. When this call returns, |list| will point to the new head
143 // of the linked list.
144 void FL_Push(void **list, void *element) {
145 void *old = *list;
146 if (old == NULL) { // Builds singleton list.
147 FL_Init(element);
148 } else {
149 ASSERT(FL_Previous_No_Check(old) == NULL);
150 FL_SetNext(element, old);
151 FL_SetPrevious(old, element);
152 FL_SetPrevious(element, NULL);
153 }
154 *list = element;
155 }
156
157 // Pops the top element off the linked list whose first element is at
158 // |*list|, and updates |*list| to point to the next element in the
159 // list. Returns the address of the element that was removed from the
160 // linked list. |list| must not be NULL.
161 void *FL_Pop(void **list) {
162 void *result = *list;
163 ASSERT(FL_Previous_No_Check(result) == NULL);
164 *list = FL_Next(result);
165 if (*list != NULL) {
166 FL_SetPrevious(*list, NULL);
167 }
168 return result;
169 }
170
171 // Remove |n| elements from linked list at whose first element is at 70 // Remove |n| elements from linked list at whose first element is at
172 // |*head|. |head| will be modified to point to the new head. 71 // |*head|. |head| will be modified to point to the new head.
173 // |start| will point to the first node of the range, |end| will point 72 // |start| will point to the first node of the range, |end| will point
174 // to the last node in the range. |n| must be <= FL_Size(|*head|) 73 // to the last node in the range. |n| must be <= FL_Size(|*head|)
175 // If |n| > 0, |head| must not be NULL. 74 // If |n| > 0, |head| must not be NULL.
176 void FL_PopRange(void **head, int n, void **start, void **end) { 75 void FL_PopRange(void **head, int n, void **start, void **end) {
177 if (n == 0) { 76 if (n == 0) {
178 *start = NULL; 77 *start = NULL;
179 *end = NULL; 78 *end = NULL;
180 return; 79 return;
(...skipping 20 matching lines...) Expand all
201 if (!start) return; 100 if (!start) return;
202 101
203 // Sanity checking of ends of list to push is done by calling 102 // Sanity checking of ends of list to push is done by calling
204 // FL_Next and FL_Previous. 103 // FL_Next and FL_Previous.
205 FL_Next(start); 104 FL_Next(start);
206 FL_Previous(end); 105 FL_Previous(end);
207 ASSERT(FL_Previous_No_Check(start) == NULL); 106 ASSERT(FL_Previous_No_Check(start) == NULL);
208 ASSERT(FL_Next_No_Check(end) == NULL); 107 ASSERT(FL_Next_No_Check(end) == NULL);
209 108
210 if (*head) { 109 if (*head) {
211 MEMORY_CHECK(FL_Previous_No_Check(*head), NULL); 110 FL_EqualityCheck(FL_Previous_No_Check(*head), (void*)NULL,
111 __FILE__, __LINE__);
212 FL_SetNext(end, *head); 112 FL_SetNext(end, *head);
213 FL_SetPrevious(*head, end); 113 FL_SetPrevious(*head, end);
214 } 114 }
215 *head = start; 115 *head = start;
216 } 116 }
217 117
218 // Calculates the size of the list that begins at |head|. 118 // Calculates the size of the list that begins at |head|.
219 size_t FL_Size(void *head){ 119 size_t FL_Size(void *head){
220 int count = 0; 120 int count = 0;
221 if (head) { 121 if (head) {
222 MEMORY_CHECK(FL_Previous_No_Check(head), NULL); 122 FL_EqualityCheck(FL_Previous_No_Check(head), (void*)NULL,
123 __FILE__, __LINE__);
223 } 124 }
224 while (head) { 125 while (head) {
225 count++; 126 count++;
226 head = FL_Next(head); 127 head = FL_Next(head);
227 } 128 }
228 return count; 129 return count;
229 } 130 }
230 131
231 } // namespace tcmalloc 132 } // namespace tcmalloc
232 133
233 #else 134 #else
234 #include "linked_list.h" // for SLL_SetNext 135 #include "linked_list.h" // for SLL_SetNext
235 136
236 namespace { 137 namespace {
237 138
238 inline void FL_SetNext(void *t, void *n) { 139 inline void FL_SetNext(void *t, void *n) {
239 tcmalloc::SLL_SetNext(t,n); 140 tcmalloc::SLL_SetNext(t,n);
240 } 141 }
241 142
242 } 143 }
243 144
244 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST 145 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698