| 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 |