| OLD | NEW | 
|---|
| 1 // Copyright (c) 2008, Google Inc. | 1 // Copyright (c) 2008, 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 18 matching lines...) Expand all  Loading... | 
| 29 | 29 | 
| 30 // --- | 30 // --- | 
| 31 // Author: Sanjay Ghemawat <opensource@google.com> | 31 // Author: Sanjay Ghemawat <opensource@google.com> | 
| 32 | 32 | 
| 33 #ifndef TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ | 33 #ifndef TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ | 
| 34 #define TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ | 34 #define TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ | 
| 35 | 35 | 
| 36 #include <stddef.h>                     // for NULL, size_t | 36 #include <stddef.h>                     // for NULL, size_t | 
| 37 | 37 | 
| 38 #include "common.h"            // for MetaDataAlloc | 38 #include "common.h"            // for MetaDataAlloc | 
|  | 39 #include "free_list.h"          // for FL_Push/FL_Pop | 
| 39 #include "internal_logging.h"  // for ASSERT, CRASH | 40 #include "internal_logging.h"  // for ASSERT, CRASH | 
| 40 | 41 | 
| 41 namespace tcmalloc { | 42 namespace tcmalloc { | 
| 42 | 43 | 
| 43 // Simple allocator for objects of a specified type.  External locking | 44 // Simple allocator for objects of a specified type.  External locking | 
| 44 // is required before accessing one of these objects. | 45 // is required before accessing one of these objects. | 
| 45 template <class T> | 46 template <class T> | 
| 46 class PageHeapAllocator { | 47 class PageHeapAllocator { | 
| 47  public: | 48  public: | 
| 48   // We use an explicit Init function because these variables are statically | 49   // We use an explicit Init function because these variables are statically | 
| 49   // allocated and their constructors might not have run by the time some | 50   // allocated and their constructors might not have run by the time some | 
| 50   // other static variable tries to allocate memory. | 51   // other static variable tries to allocate memory. | 
| 51   void Init() { | 52   void Init() { | 
| 52     ASSERT(sizeof(T) <= kAllocIncrement); | 53     ASSERT(sizeof(T) <= kAllocIncrement); | 
| 53     inuse_ = 0; | 54     inuse_ = 0; | 
| 54     free_area_ = NULL; | 55     free_area_ = NULL; | 
| 55     free_avail_ = 0; | 56     free_avail_ = 0; | 
| 56     free_list_ = NULL; | 57     free_list_ = NULL; | 
| 57     // Reserve some space at the beginning to avoid fragmentation. | 58     // Reserve some space at the beginning to avoid fragmentation. | 
| 58     Delete(New()); | 59     Delete(New()); | 
| 59   } | 60   } | 
| 60 | 61 | 
| 61   T* New() { | 62   T* New() { | 
| 62     // Consult free list | 63     // Consult free list | 
| 63     void* result; | 64     void* result; | 
| 64     if (free_list_ != NULL) { | 65     if (free_list_ != NULL) { | 
| 65       result = free_list_; | 66       result = FL_Pop(&free_list_); | 
| 66       free_list_ = *(reinterpret_cast<void**>(result)); |  | 
| 67     } else { | 67     } else { | 
| 68       if (free_avail_ < sizeof(T)) { | 68       if (free_avail_ < sizeof(T)) { | 
| 69         // Need more room. We assume that MetaDataAlloc returns | 69         // Need more room. We assume that MetaDataAlloc returns | 
| 70         // suitably aligned memory. | 70         // suitably aligned memory. | 
| 71         free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement)); | 71         free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement)); | 
| 72         if (free_area_ == NULL) { | 72         if (free_area_ == NULL) { | 
| 73           CRASH("FATAL ERROR: Out of memory trying to allocate internal " | 73           CRASH("FATAL ERROR: Out of memory trying to allocate internal " | 
| 74                 "tcmalloc data (%d bytes, object-size %d)\n", | 74                 "tcmalloc data (%d bytes, object-size %d)\n", | 
| 75                 kAllocIncrement, static_cast<int>(sizeof(T))); | 75                 kAllocIncrement, static_cast<int>(sizeof(T))); | 
| 76         } | 76         } | 
| 77         free_avail_ = kAllocIncrement; | 77         free_avail_ = kAllocIncrement; | 
| 78       } | 78       } | 
| 79       result = free_area_; | 79       result = free_area_; | 
| 80       free_area_ += sizeof(T); | 80       free_area_ += sizeof(T); | 
| 81       free_avail_ -= sizeof(T); | 81       free_avail_ -= sizeof(T); | 
| 82     } | 82     } | 
| 83     inuse_++; | 83     inuse_++; | 
| 84     return reinterpret_cast<T*>(result); | 84     return reinterpret_cast<T*>(result); | 
| 85   } | 85   } | 
| 86 | 86 | 
| 87   void Delete(T* p) { | 87   void Delete(T* p) { | 
| 88     *(reinterpret_cast<void**>(p)) = free_list_; | 88     FL_Push(&free_list_, p); | 
| 89     free_list_ = p; |  | 
| 90     inuse_--; | 89     inuse_--; | 
| 91   } | 90   } | 
| 92 | 91 | 
| 93   int inuse() const { return inuse_; } | 92   int inuse() const { return inuse_; } | 
| 94 | 93 | 
| 95  private: | 94  private: | 
| 96   // How much to allocate from system at a time | 95   // How much to allocate from system at a time | 
| 97   static const int kAllocIncrement = 128 << 10; | 96   static const int kAllocIncrement = 128 << 10; | 
| 98 | 97 | 
| 99   // Free area from which to carve new objects | 98   // Free area from which to carve new objects | 
| 100   char* free_area_; | 99   char* free_area_; | 
| 101   size_t free_avail_; | 100   size_t free_avail_; | 
| 102 | 101 | 
| 103   // Free list of already carved objects | 102   // Free list of already carved objects | 
| 104   void* free_list_; | 103   void* free_list_; | 
| 105 | 104 | 
| 106   // Number of allocated but unfreed objects | 105   // Number of allocated but unfreed objects | 
| 107   int inuse_; | 106   int inuse_; | 
| 108 }; | 107 }; | 
| 109 | 108 | 
| 110 }  // namespace tcmalloc | 109 }  // namespace tcmalloc | 
| 111 | 110 | 
| 112 #endif  // TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ | 111 #endif  // TCMALLOC_PAGE_HEAP_ALLOCATOR_H_ | 
| OLD | NEW | 
|---|