| 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 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 #ifdef TCMALLOC_USE_DOUBLYLINKED_FREELIST | 62 #ifdef TCMALLOC_USE_DOUBLYLINKED_FREELIST | 
| 63 | 63 | 
| 64 #include <stddef.h> | 64 #include <stddef.h> | 
| 65 #include "internal_logging.h" //for ASSERT | 65 #include "free_list.h" | 
| 66 | 66 | 
|  | 67 // TODO(jar): We should use C++ rather than a macro here. | 
| 67 #define MEMORY_CHECK(v1, v2) \ | 68 #define MEMORY_CHECK(v1, v2) \ | 
| 68   if (v1 != v2) CRASH("Memory corruption detected.\n") | 69   if (v1 != v2) CRASH("Memory corruption detected.\n") | 
| 69 | 70 | 
| 70 namespace { | 71 namespace { | 
|  | 72 void EnsureNonLoop(void* node, void* next) { | 
|  | 73   // We only have time to do minimal checking.  We don't traverse the list, but | 
|  | 74   // only look for an immediate loop (cycle back to ourself). | 
|  | 75   if (node != next) return; | 
|  | 76   CRASH("Circular loop in list detected: %p\n", next); | 
|  | 77 } | 
|  | 78 | 
| 71 // Returns value of the |previous| pointer w/out running a sanity | 79 // Returns value of the |previous| pointer w/out running a sanity | 
| 72 // check. | 80 // check. | 
| 73 inline void *FL_Previous_No_Check(void *t) { | 81 inline void *FL_Previous_No_Check(void *t) { | 
| 74   return reinterpret_cast<void**>(t)[1]; | 82   return reinterpret_cast<void**>(t)[1]; | 
| 75 } | 83 } | 
| 76 | 84 | 
| 77 // Returns value of the |next| pointer w/out running a sanity check. | 85 // Returns value of the |next| pointer w/out running a sanity check. | 
| 78 inline void *FL_Next_No_Check(void *t) { | 86 inline void *FL_Next_No_Check(void *t) { | 
| 79   return reinterpret_cast<void**>(t)[0]; | 87   return reinterpret_cast<void**>(t)[0]; | 
| 80 } | 88 } | 
| 81 | 89 | 
| 82 void *FL_Previous(void *t) { | 90 void *FL_Previous(void *t) { | 
| 83   void *previous = FL_Previous_No_Check(t); | 91   void *previous = FL_Previous_No_Check(t); | 
| 84   if (previous) { | 92   if (previous) { | 
| 85     MEMORY_CHECK(FL_Next_No_Check(previous), t); | 93     MEMORY_CHECK(FL_Next_No_Check(previous), t); | 
| 86   } | 94   } | 
| 87   return previous; | 95   return previous; | 
| 88 } | 96 } | 
| 89 | 97 | 
| 90 inline void FL_SetPrevious(void *t, void *n) { | 98 inline void FL_SetPrevious(void *t, void *n) { | 
|  | 99   EnsureNonLoop(t, n); | 
| 91   reinterpret_cast<void**>(t)[1] = n; | 100   reinterpret_cast<void**>(t)[1] = n; | 
| 92 } | 101 } | 
| 93 | 102 | 
| 94 inline void FL_SetNext(void *t, void *n) { | 103 inline void FL_SetNext(void *t, void *n) { | 
|  | 104   EnsureNonLoop(t, n); | 
| 95   reinterpret_cast<void**>(t)[0] = n; | 105   reinterpret_cast<void**>(t)[0] = n; | 
| 96 } | 106 } | 
| 97 | 107 | 
| 98 } // namespace | 108 } // namespace | 
| 99 | 109 | 
| 100 namespace tcmalloc { | 110 namespace tcmalloc { | 
| 101 | 111 | 
| 102 void *FL_Next(void *t) { | 112 void *FL_Next(void *t) { | 
| 103   void *next = FL_Next_No_Check(t); | 113   void *next = FL_Next_No_Check(t); | 
| 104   if (next) { | 114   if (next) { | 
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 210 | 220 | 
| 211 namespace { | 221 namespace { | 
| 212 | 222 | 
| 213 inline void FL_SetNext(void *t, void *n) { | 223 inline void FL_SetNext(void *t, void *n) { | 
| 214   tcmalloc::SLL_SetNext(t,n); | 224   tcmalloc::SLL_SetNext(t,n); | 
| 215 } | 225 } | 
| 216 | 226 | 
| 217 } | 227 } | 
| 218 | 228 | 
| 219 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST | 229 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST | 
| OLD | NEW | 
|---|