• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2019  Facebook, Inc.
3  *
4  *  This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Facebook Author(s): Behdad Esfahbod
25  */
26 
27 #ifndef HB_POOL_HH
28 #define HB_POOL_HH
29 
30 #include "hb.hh"
31 
32 /* Memory pool for persistent allocation of small objects. */
33 
34 template <typename T, unsigned ChunkLen = 16>
35 struct hb_pool_t
36 {
hb_pool_thb_pool_t37   hb_pool_t () : next (nullptr) {}
~hb_pool_thb_pool_t38   ~hb_pool_t ()
39   {
40     next = nullptr;
41 
42     + hb_iter (chunks)
43     | hb_apply (hb_free)
44     ;
45   }
46 
allochb_pool_t47   T* alloc ()
48   {
49     if (unlikely (!next))
50     {
51       if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr;
52       chunk_t *chunk = (chunk_t *) hb_calloc (1, sizeof (chunk_t));
53       if (unlikely (!chunk)) return nullptr;
54       chunks.push (chunk);
55       next = chunk->thread ();
56     }
57 
58     T* obj = next;
59     next = * ((T**) next);
60 
61     hb_memset (obj, 0, sizeof (T));
62 
63     return obj;
64   }
65 
releasehb_pool_t66   void release (T* obj)
67   {
68     * (T**) obj = next;
69     next = obj;
70   }
71 
72   private:
73 
74   static_assert (ChunkLen > 1, "");
75   static_assert (sizeof (T) >= sizeof (void *), "");
76   static_assert (alignof (T) % alignof (void *) == 0, "");
77 
78   struct chunk_t
79   {
threadhb_pool_t::chunk_t80     T* thread ()
81     {
82       for (unsigned i = 0; i < ARRAY_LENGTH (arrayZ) - 1; i++)
83 	* (T**) &arrayZ[i] = &arrayZ[i + 1];
84 
85       * (T**) &arrayZ[ARRAY_LENGTH (arrayZ) - 1] = nullptr;
86 
87       return arrayZ;
88     }
89 
90     T arrayZ[ChunkLen];
91   };
92 
93   T* next;
94   hb_vector_t<chunk_t *> chunks;
95 };
96 
97 
98 #endif /* HB_POOL_HH */
99