1*2d1272b8SAndroid Build Coastguard Worker /* 2*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2019 Facebook, Inc. 3*2d1272b8SAndroid Build Coastguard Worker * 4*2d1272b8SAndroid Build Coastguard Worker * This is part of HarfBuzz, a text shaping library. 5*2d1272b8SAndroid Build Coastguard Worker * 6*2d1272b8SAndroid Build Coastguard Worker * Permission is hereby granted, without written agreement and without 7*2d1272b8SAndroid Build Coastguard Worker * license or royalty fees, to use, copy, modify, and distribute this 8*2d1272b8SAndroid Build Coastguard Worker * software and its documentation for any purpose, provided that the 9*2d1272b8SAndroid Build Coastguard Worker * above copyright notice and the following two paragraphs appear in 10*2d1272b8SAndroid Build Coastguard Worker * all copies of this software. 11*2d1272b8SAndroid Build Coastguard Worker * 12*2d1272b8SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13*2d1272b8SAndroid Build Coastguard Worker * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14*2d1272b8SAndroid Build Coastguard Worker * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15*2d1272b8SAndroid Build Coastguard Worker * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16*2d1272b8SAndroid Build Coastguard Worker * DAMAGE. 17*2d1272b8SAndroid Build Coastguard Worker * 18*2d1272b8SAndroid Build Coastguard Worker * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19*2d1272b8SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20*2d1272b8SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21*2d1272b8SAndroid Build Coastguard Worker * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22*2d1272b8SAndroid Build Coastguard Worker * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23*2d1272b8SAndroid Build Coastguard Worker * 24*2d1272b8SAndroid Build Coastguard Worker * Facebook Author(s): Behdad Esfahbod 25*2d1272b8SAndroid Build Coastguard Worker */ 26*2d1272b8SAndroid Build Coastguard Worker 27*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_POOL_HH 28*2d1272b8SAndroid Build Coastguard Worker #define HB_POOL_HH 29*2d1272b8SAndroid Build Coastguard Worker 30*2d1272b8SAndroid Build Coastguard Worker #include "hb.hh" 31*2d1272b8SAndroid Build Coastguard Worker 32*2d1272b8SAndroid Build Coastguard Worker /* Memory pool for persistent allocation of small objects. 33*2d1272b8SAndroid Build Coastguard Worker * 34*2d1272b8SAndroid Build Coastguard Worker * Some AI musings on this, not necessarily true: 35*2d1272b8SAndroid Build Coastguard Worker * 36*2d1272b8SAndroid Build Coastguard Worker * This is a very simple implementation, but it's good enough for our 37*2d1272b8SAndroid Build Coastguard Worker * purposes. It's not thread-safe. It's not very fast. It's not 38*2d1272b8SAndroid Build Coastguard Worker * very memory efficient. It's not very cache efficient. It's not 39*2d1272b8SAndroid Build Coastguard Worker * very anything efficient. But it's simple and it works. And it's 40*2d1272b8SAndroid Build Coastguard Worker * good enough for our purposes. If you need something more 41*2d1272b8SAndroid Build Coastguard Worker * sophisticated, use a real allocator. Or use a real language. */ 42*2d1272b8SAndroid Build Coastguard Worker 43*2d1272b8SAndroid Build Coastguard Worker template <typename T, unsigned ChunkLen = 32> 44*2d1272b8SAndroid Build Coastguard Worker struct hb_pool_t 45*2d1272b8SAndroid Build Coastguard Worker { hb_pool_thb_pool_t46*2d1272b8SAndroid Build Coastguard Worker hb_pool_t () : next (nullptr) {} ~hb_pool_thb_pool_t47*2d1272b8SAndroid Build Coastguard Worker ~hb_pool_t () 48*2d1272b8SAndroid Build Coastguard Worker { 49*2d1272b8SAndroid Build Coastguard Worker next = nullptr; 50*2d1272b8SAndroid Build Coastguard Worker 51*2d1272b8SAndroid Build Coastguard Worker + hb_iter (chunks) 52*2d1272b8SAndroid Build Coastguard Worker | hb_apply (hb_free) 53*2d1272b8SAndroid Build Coastguard Worker ; 54*2d1272b8SAndroid Build Coastguard Worker } 55*2d1272b8SAndroid Build Coastguard Worker allochb_pool_t56*2d1272b8SAndroid Build Coastguard Worker T* alloc () 57*2d1272b8SAndroid Build Coastguard Worker { 58*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!next)) 59*2d1272b8SAndroid Build Coastguard Worker { 60*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr; 61*2d1272b8SAndroid Build Coastguard Worker chunk_t *chunk = (chunk_t *) hb_malloc (sizeof (chunk_t)); 62*2d1272b8SAndroid Build Coastguard Worker if (unlikely (!chunk)) return nullptr; 63*2d1272b8SAndroid Build Coastguard Worker chunks.push (chunk); 64*2d1272b8SAndroid Build Coastguard Worker next = chunk->thread (); 65*2d1272b8SAndroid Build Coastguard Worker } 66*2d1272b8SAndroid Build Coastguard Worker 67*2d1272b8SAndroid Build Coastguard Worker T* obj = next; 68*2d1272b8SAndroid Build Coastguard Worker next = * ((T**) next); 69*2d1272b8SAndroid Build Coastguard Worker 70*2d1272b8SAndroid Build Coastguard Worker hb_memset (obj, 0, sizeof (T)); 71*2d1272b8SAndroid Build Coastguard Worker 72*2d1272b8SAndroid Build Coastguard Worker return obj; 73*2d1272b8SAndroid Build Coastguard Worker } 74*2d1272b8SAndroid Build Coastguard Worker releasehb_pool_t75*2d1272b8SAndroid Build Coastguard Worker void release (T* obj) 76*2d1272b8SAndroid Build Coastguard Worker { 77*2d1272b8SAndroid Build Coastguard Worker * (T**) obj = next; 78*2d1272b8SAndroid Build Coastguard Worker next = obj; 79*2d1272b8SAndroid Build Coastguard Worker } 80*2d1272b8SAndroid Build Coastguard Worker 81*2d1272b8SAndroid Build Coastguard Worker private: 82*2d1272b8SAndroid Build Coastguard Worker 83*2d1272b8SAndroid Build Coastguard Worker static_assert (ChunkLen > 1, ""); 84*2d1272b8SAndroid Build Coastguard Worker static_assert (sizeof (T) >= sizeof (void *), ""); 85*2d1272b8SAndroid Build Coastguard Worker static_assert (alignof (T) % alignof (void *) == 0, ""); 86*2d1272b8SAndroid Build Coastguard Worker 87*2d1272b8SAndroid Build Coastguard Worker struct chunk_t 88*2d1272b8SAndroid Build Coastguard Worker { threadhb_pool_t::chunk_t89*2d1272b8SAndroid Build Coastguard Worker T* thread () 90*2d1272b8SAndroid Build Coastguard Worker { 91*2d1272b8SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_LENGTH (arrayZ) - 1; i++) 92*2d1272b8SAndroid Build Coastguard Worker * (T**) &arrayZ[i] = &arrayZ[i + 1]; 93*2d1272b8SAndroid Build Coastguard Worker 94*2d1272b8SAndroid Build Coastguard Worker * (T**) &arrayZ[ARRAY_LENGTH (arrayZ) - 1] = nullptr; 95*2d1272b8SAndroid Build Coastguard Worker 96*2d1272b8SAndroid Build Coastguard Worker return arrayZ; 97*2d1272b8SAndroid Build Coastguard Worker } 98*2d1272b8SAndroid Build Coastguard Worker 99*2d1272b8SAndroid Build Coastguard Worker T arrayZ[ChunkLen]; 100*2d1272b8SAndroid Build Coastguard Worker }; 101*2d1272b8SAndroid Build Coastguard Worker 102*2d1272b8SAndroid Build Coastguard Worker T* next; 103*2d1272b8SAndroid Build Coastguard Worker hb_vector_t<chunk_t *> chunks; 104*2d1272b8SAndroid Build Coastguard Worker }; 105*2d1272b8SAndroid Build Coastguard Worker 106*2d1272b8SAndroid Build Coastguard Worker 107*2d1272b8SAndroid Build Coastguard Worker #endif /* HB_POOL_HH */ 108