Home | History | Annotate | Download | only in memory
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // AlignedMemory is a POD type that gives you a portable way to specify static
      6 // or local stack data of a given alignment and size. For example, if you need
      7 // static storage for a class, but you want manual control over when the object
      8 // is constructed and destructed (you don't want static initialization and
      9 // destruction), use AlignedMemory:
     10 //
     11 //   static AlignedMemory<sizeof(MyClass), ALIGNOF(MyClass)> my_class;
     12 //
     13 //   // ... at runtime:
     14 //   new(my_class.void_data()) MyClass();
     15 //
     16 //   // ... use it:
     17 //   MyClass* mc = my_class.data_as<MyClass>();
     18 //
     19 //   // ... later, to destruct my_class:
     20 //   my_class.data_as<MyClass>()->MyClass::~MyClass();
     21 //
     22 // Alternatively, a runtime sized aligned allocation can be created:
     23 //
     24 //   float* my_array = static_cast<float*>(AlignedAlloc(size, alignment));
     25 //
     26 //   // ... later, to release the memory:
     27 //   AlignedFree(my_array);
     28 //
     29 // Or using scoped_ptr_malloc:
     30 //
     31 //   scoped_ptr_malloc<float, ScopedPtrAlignedFree> my_array(
     32 //       static_cast<float*>(AlignedAlloc(size, alignment)));
     33 
     34 #ifndef BASE_MEMORY_ALIGNED_MEMORY_H_
     35 #define BASE_MEMORY_ALIGNED_MEMORY_H_
     36 
     37 #include "base/base_export.h"
     38 #include "base/basictypes.h"
     39 #include "base/compiler_specific.h"
     40 
     41 #if defined(COMPILER_MSVC)
     42 #include <malloc.h>
     43 #else
     44 #include <stdlib.h>
     45 #endif
     46 
     47 namespace base {
     48 
     49 // AlignedMemory is specialized for all supported alignments.
     50 // Make sure we get a compiler error if someone uses an unsupported alignment.
     51 template <size_t Size, size_t ByteAlignment>
     52 struct AlignedMemory {};
     53 
     54 #define BASE_DECL_ALIGNED_MEMORY(byte_alignment) \
     55     template <size_t Size> \
     56     class AlignedMemory<Size, byte_alignment> { \
     57      public: \
     58       ALIGNAS(byte_alignment) uint8 data_[Size]; \
     59       void* void_data() { return static_cast<void*>(data_); } \
     60       const void* void_data() const { \
     61         return static_cast<const void*>(data_); \
     62       } \
     63       template<typename Type> \
     64       Type* data_as() { return static_cast<Type*>(void_data()); } \
     65       template<typename Type> \
     66       const Type* data_as() const { \
     67         return static_cast<const Type*>(void_data()); \
     68       } \
     69      private: \
     70       void* operator new(size_t); \
     71       void operator delete(void*); \
     72     }
     73 
     74 // Specialization for all alignments is required because MSVC (as of VS 2008)
     75 // does not understand ALIGNAS(ALIGNOF(Type)) or ALIGNAS(template_param).
     76 // Greater than 4096 alignment is not supported by some compilers, so 4096 is
     77 // the maximum specified here.
     78 BASE_DECL_ALIGNED_MEMORY(1);
     79 BASE_DECL_ALIGNED_MEMORY(2);
     80 BASE_DECL_ALIGNED_MEMORY(4);
     81 BASE_DECL_ALIGNED_MEMORY(8);
     82 BASE_DECL_ALIGNED_MEMORY(16);
     83 BASE_DECL_ALIGNED_MEMORY(32);
     84 BASE_DECL_ALIGNED_MEMORY(64);
     85 BASE_DECL_ALIGNED_MEMORY(128);
     86 BASE_DECL_ALIGNED_MEMORY(256);
     87 BASE_DECL_ALIGNED_MEMORY(512);
     88 BASE_DECL_ALIGNED_MEMORY(1024);
     89 BASE_DECL_ALIGNED_MEMORY(2048);
     90 BASE_DECL_ALIGNED_MEMORY(4096);
     91 
     92 #undef BASE_DECL_ALIGNED_MEMORY
     93 
     94 BASE_EXPORT void* AlignedAlloc(size_t size, size_t alignment);
     95 
     96 inline void AlignedFree(void* ptr) {
     97 #if defined(COMPILER_MSVC)
     98   _aligned_free(ptr);
     99 #else
    100   free(ptr);
    101 #endif
    102 }
    103 
    104 // Helper class for use with scoped_ptr_malloc.
    105 class BASE_EXPORT ScopedPtrAlignedFree {
    106  public:
    107   inline void operator()(void* ptr) const {
    108     AlignedFree(ptr);
    109   }
    110 };
    111 
    112 }  // namespace base
    113 
    114 #endif  // BASE_MEMORY_ALIGNED_MEMORY_H_
    115