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

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

Issue 7671034: doubly-linked free-lists for thread caches and page heaps (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: clean up code, improve macro name Created 9 years, 4 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 // ---
31 // Author: Rebecca Shapiro <bxx@google.com>
32 // This file contains functions that implement doubly linked
33 // linked lists.
34
35 #ifdef TCMALLOC_USE_DOUBLYLINKED_FREELIST
36
37 #include <stddef.h>
38 #include "internal_logging.h" //for ASSERT
39
40 #define MEMORY_CHECK(v1, v2) if (v1 != v2) DieFromMemoryCorruption();
41 namespace {
42 // Intentionally cause a segmentation fault.
43 inline void DieFromMemoryCorruption() {
44 char *p = NULL;
45 *p += 1; // Segfault.
46 }
47
48 // Returns value of the Previous pointer w/out running a sanity check.
49 inline void *FL_Previous_No_Check(void *t) {
50 return *(reinterpret_cast<void**> (reinterpret_cast<void **>(t) + 1));
jar (doing other things) 2011/08/25 02:07:50 The second cast, on the left, appears redundant, a
bxx 2011/08/25 20:23:18 Done.
51 }
52
53 // Returns value of the Next pointer w/out running a sanity check.
54 inline void *FL_Next_No_Check(void *t) {
55 return *(reinterpret_cast<void**>(t));
56 }
57
58 } // namespace
59
60 namespace tcmalloc {
61 void *FL_Previous(void *t) {
62 void *previous = FL_Previous_No_Check(t);
63 if (previous)
64 MEMORY_CHECK(FL_Next_No_Check(previous), t);
65 return previous;
66 }
67
68 void *FL_Next(void *t) {
69 void *next = FL_Next_No_Check(t);
70 if (next)
71 MEMORY_CHECK(FL_Previous_No_Check(next), t);
72 return next;
73 }
74
75 inline void FL_SetPrevious(void *t, void *n) {
76 *(reinterpret_cast<void **>(t) + 1) = n;
77 }
78
79 inline void FL_SetNext(void *t, void *n) {
80 *(reinterpret_cast<void**>(t)) = n;
81 }
82
83 // Makes the memory pointed at t a singleton doubly linked list.
84 inline void FL_Init(void *t) {
85 FL_SetPrevious(t, NULL);
86 FL_SetNext(t, NULL);
87 }
88
89 // Pushes element to a linked list located at *list. When this call
90 // returns, list will point to the new head of the linked list.
91 void FL_Push(void **list, void *element) {
92 void *old = *list;
93 if (old == NULL) { // Builds singleton list.
94 FL_Init(element);
95 } else {
96 ASSERT(FL_Previous_No_Check(old) == NULL);
97 FL_SetNext(element, old);
98 FL_SetPrevious(old, element);
99 FL_SetPrevious(element, NULL);
100 }
101 *list = element;
102 }
103
104 // Pops the top element off the linked list that begins at *list, and
105 // upates *list to point to the next element in the list. Return the
jar (doing other things) 2011/08/25 02:07:50 typo: upates-->updates
bxx 2011/08/25 20:23:18 Done.
106 // address of the element that was removed from the linked list.
107 // *list must not be NULL.
108 void *FL_Pop(void **list) {
109 void *result = *list;
110 ASSERT(FL_Previous_No_Check(result) == NULL);
111 *list = FL_Next(result); // Fixes remainder of list.
jar (doing other things) 2011/08/25 02:07:50 Not sure what comment means... probably you should
bxx 2011/08/25 20:23:18 Done.
112 if (*list != NULL)
113 FL_SetPrevious(*list, NULL);
114
115 return result;
116 }
117
118 // Remove N elements from a linked list to which head points. head will be
119 // modified to point to the new head. start will point to the first
120 // node of the range, end points to last node in range
121 // This function assumes that you aren't trying to pop N > FL_Size(*head)
122 // nodes, and that *head is not NULL.
123 void FL_PopRange(void **head, int N, void **start, void **end) {
124 if (N == 0) {
125 *start = NULL;
126 *end = NULL;
127 return;
128 }
129
130 *start = *head; // Remember the first node in the range.
131 void *tmp = *head;
132 for (int i = 1; i < N; ++i) // Find end of range.
133 tmp = FL_Next(tmp);
134
135 *end = tmp; // end now set to point to last node in range.
136 *head = FL_Next(*end);
137 FL_SetNext(*end, NULL); // Unlink range from list.
138
139 if (*head ) { // Fixup popped list.
140 FL_SetPrevious(*head, NULL);
141 }
142 }
143
144 // Pushes the nodes of the doubly linked list that begins at the node
145 // located at start and ends at he node end into the linked list at
jar (doing other things) 2011/08/25 02:07:50 typo: "at he node" --> "at the node" IMO, you sho
bxx 2011/08/25 20:23:18 Done.
146 // location *head *head is updated to point be the new head of the
147 // list. *head must not be NULL.
148 void FL_PushRange(void **head, void *start, void *end) {
149 if (!start) return;
150
151 // Sanity checking of ends of list to push before pushing is done
152 // when calling FL_Next, FL_Previous.
153 FL_Next(start);
154 FL_Previous(end);
155 ASSERT(FL_Previous_No_Check(start) == NULL);
156 ASSERT(FL_Next_No_Check(end) == NULL);
157
158 if (*head) {
159 ASSERT(FL_Previous_No_Check(*head) == NULL);
jar (doing other things) 2011/08/25 02:07:50 This is a critical check, and should not be debug
bxx 2011/08/25 20:23:18 Done.
160 FL_Next(*head);
jar (doing other things) 2011/08/25 02:07:50 IMO, you shouldn't bother with this interior check
bxx 2011/08/25 20:23:18 Done.
161 FL_SetNext(end, *head);
162 FL_SetPrevious(*head, end);
163 }
164 *head = start;
165 }
166
167 } // namespace tcmalloc
168
169 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698