1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci/** 17425bb815Sopenharmony_ci * Memory pool manager implementation 18425bb815Sopenharmony_ci */ 19425bb815Sopenharmony_ci 20425bb815Sopenharmony_ci#include "jcontext.h" 21425bb815Sopenharmony_ci#include "jmem.h" 22425bb815Sopenharmony_ci#include "jrt-libc-includes.h" 23425bb815Sopenharmony_ci 24425bb815Sopenharmony_ci#define JMEM_ALLOCATOR_INTERNAL 25425bb815Sopenharmony_ci#include "jmem-allocator-internal.h" 26425bb815Sopenharmony_ci 27425bb815Sopenharmony_ci#if ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) 28425bb815Sopenharmony_ci#include "ecma-gc.h" 29425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) */ 30425bb815Sopenharmony_ci 31425bb815Sopenharmony_ci/** \addtogroup mem Memory allocation 32425bb815Sopenharmony_ci * @{ 33425bb815Sopenharmony_ci * 34425bb815Sopenharmony_ci * \addtogroup poolman Memory pool manager 35425bb815Sopenharmony_ci * @{ 36425bb815Sopenharmony_ci */ 37425bb815Sopenharmony_ci 38425bb815Sopenharmony_ci/** 39425bb815Sopenharmony_ci * Finalize pool manager 40425bb815Sopenharmony_ci */ 41425bb815Sopenharmony_civoid 42425bb815Sopenharmony_cijmem_pools_finalize (void) 43425bb815Sopenharmony_ci{ 44425bb815Sopenharmony_ci jmem_pools_collect_empty (); 45425bb815Sopenharmony_ci 46425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (jmem_free_8_byte_chunk_p) == NULL); 47425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 48425bb815Sopenharmony_ci JERRY_ASSERT (JERRY_CONTEXT (jmem_free_16_byte_chunk_p) == NULL); 49425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 50425bb815Sopenharmony_ci} /* jmem_pools_finalize */ 51425bb815Sopenharmony_ci 52425bb815Sopenharmony_ci/** 53425bb815Sopenharmony_ci * Allocate a chunk of specified size 54425bb815Sopenharmony_ci * 55425bb815Sopenharmony_ci * @return pointer to allocated chunk, if allocation was successful, 56425bb815Sopenharmony_ci * or NULL - if not enough memory. 57425bb815Sopenharmony_ci */ 58425bb815Sopenharmony_ciextern inline void * JERRY_ATTR_HOT JERRY_ATTR_ALWAYS_INLINE 59425bb815Sopenharmony_cijmem_pools_alloc (size_t size) /**< size of the chunk */ 60425bb815Sopenharmony_ci{ 61425bb815Sopenharmony_ci#if ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) 62425bb815Sopenharmony_ci ecma_free_unused_memory (JMEM_PRESSURE_LOW); 63425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_MEM_GC_BEFORE_EACH_ALLOC) */ 64425bb815Sopenharmony_ci 65425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 66425bb815Sopenharmony_ci if (size <= 8) 67425bb815Sopenharmony_ci { 68425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ 69425bb815Sopenharmony_ci JERRY_ASSERT (size <= 8); 70425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 71425bb815Sopenharmony_ci 72425bb815Sopenharmony_ci if (JERRY_CONTEXT (jmem_free_8_byte_chunk_p) != NULL) 73425bb815Sopenharmony_ci { 74425bb815Sopenharmony_ci const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p); 75425bb815Sopenharmony_ci 76425bb815Sopenharmony_ci JMEM_VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t)); 77425bb815Sopenharmony_ci JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_p->next_p; 78425bb815Sopenharmony_ci JMEM_VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t)); 79425bb815Sopenharmony_ci 80425bb815Sopenharmony_ci JMEM_HEAP_STAT_ALLOC (8); 81425bb815Sopenharmony_ci return (void *) chunk_p; 82425bb815Sopenharmony_ci } 83425bb815Sopenharmony_ci else 84425bb815Sopenharmony_ci { 85425bb815Sopenharmony_ci void *chunk_p = jmem_heap_alloc_block_internal (8); 86425bb815Sopenharmony_ci JMEM_HEAP_STAT_ALLOC (8); 87425bb815Sopenharmony_ci return chunk_p; 88425bb815Sopenharmony_ci } 89425bb815Sopenharmony_ci 90425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 91425bb815Sopenharmony_ci } 92425bb815Sopenharmony_ci 93425bb815Sopenharmony_ci JERRY_ASSERT (size <= 16); 94425bb815Sopenharmony_ci 95425bb815Sopenharmony_ci if (JERRY_CONTEXT (jmem_free_16_byte_chunk_p) != NULL) 96425bb815Sopenharmony_ci { 97425bb815Sopenharmony_ci const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p); 98425bb815Sopenharmony_ci 99425bb815Sopenharmony_ci JMEM_VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t)); 100425bb815Sopenharmony_ci JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_p->next_p; 101425bb815Sopenharmony_ci JMEM_VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t)); 102425bb815Sopenharmony_ci 103425bb815Sopenharmony_ci JMEM_HEAP_STAT_ALLOC (16); 104425bb815Sopenharmony_ci return (void *) chunk_p; 105425bb815Sopenharmony_ci } 106425bb815Sopenharmony_ci else 107425bb815Sopenharmony_ci { 108425bb815Sopenharmony_ci void *chunk_p = jmem_heap_alloc_block_internal (16); 109425bb815Sopenharmony_ci JMEM_HEAP_STAT_ALLOC (16); 110425bb815Sopenharmony_ci return chunk_p; 111425bb815Sopenharmony_ci } 112425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 113425bb815Sopenharmony_ci} /* jmem_pools_alloc */ 114425bb815Sopenharmony_ci 115425bb815Sopenharmony_ci/** 116425bb815Sopenharmony_ci * Free the chunk 117425bb815Sopenharmony_ci */ 118425bb815Sopenharmony_ciextern inline void JERRY_ATTR_HOT JERRY_ATTR_ALWAYS_INLINE 119425bb815Sopenharmony_cijmem_pools_free (void *chunk_p, /**< pointer to the chunk */ 120425bb815Sopenharmony_ci size_t size) /**< size of the chunk */ 121425bb815Sopenharmony_ci{ 122425bb815Sopenharmony_ci JERRY_ASSERT (chunk_p != NULL); 123425bb815Sopenharmony_ci JMEM_HEAP_STAT_FREE (size); 124425bb815Sopenharmony_ci 125425bb815Sopenharmony_ci jmem_pools_chunk_t *const chunk_to_free_p = (jmem_pools_chunk_t *) chunk_p; 126425bb815Sopenharmony_ci 127425bb815Sopenharmony_ci JMEM_VALGRIND_DEFINED_SPACE (chunk_to_free_p, size); 128425bb815Sopenharmony_ci 129425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 130425bb815Sopenharmony_ci if (size <= 8) 131425bb815Sopenharmony_ci { 132425bb815Sopenharmony_ci#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ 133425bb815Sopenharmony_ci JERRY_ASSERT (size <= 8); 134425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 135425bb815Sopenharmony_ci 136425bb815Sopenharmony_ci chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p); 137425bb815Sopenharmony_ci JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_to_free_p; 138425bb815Sopenharmony_ci 139425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 140425bb815Sopenharmony_ci } 141425bb815Sopenharmony_ci else 142425bb815Sopenharmony_ci { 143425bb815Sopenharmony_ci JERRY_ASSERT (size <= 16); 144425bb815Sopenharmony_ci 145425bb815Sopenharmony_ci chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p); 146425bb815Sopenharmony_ci JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_to_free_p; 147425bb815Sopenharmony_ci } 148425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 149425bb815Sopenharmony_ci 150425bb815Sopenharmony_ci JMEM_VALGRIND_NOACCESS_SPACE (chunk_to_free_p, size); 151425bb815Sopenharmony_ci} /* jmem_pools_free */ 152425bb815Sopenharmony_ci 153425bb815Sopenharmony_ci/** 154425bb815Sopenharmony_ci * Collect empty pool chunks 155425bb815Sopenharmony_ci */ 156425bb815Sopenharmony_civoid 157425bb815Sopenharmony_cijmem_pools_collect_empty (void) 158425bb815Sopenharmony_ci{ 159425bb815Sopenharmony_ci jmem_pools_chunk_t *chunk_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p); 160425bb815Sopenharmony_ci JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = NULL; 161425bb815Sopenharmony_ci 162425bb815Sopenharmony_ci while (chunk_p) 163425bb815Sopenharmony_ci { 164425bb815Sopenharmony_ci JMEM_VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t)); 165425bb815Sopenharmony_ci jmem_pools_chunk_t *const next_p = chunk_p->next_p; 166425bb815Sopenharmony_ci JMEM_VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t)); 167425bb815Sopenharmony_ci 168425bb815Sopenharmony_ci jmem_heap_free_block_internal (chunk_p, 8); 169425bb815Sopenharmony_ci chunk_p = next_p; 170425bb815Sopenharmony_ci } 171425bb815Sopenharmony_ci 172425bb815Sopenharmony_ci#if ENABLED (JERRY_CPOINTER_32_BIT) 173425bb815Sopenharmony_ci chunk_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p); 174425bb815Sopenharmony_ci JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = NULL; 175425bb815Sopenharmony_ci 176425bb815Sopenharmony_ci while (chunk_p) 177425bb815Sopenharmony_ci { 178425bb815Sopenharmony_ci JMEM_VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t)); 179425bb815Sopenharmony_ci jmem_pools_chunk_t *const next_p = chunk_p->next_p; 180425bb815Sopenharmony_ci JMEM_VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t)); 181425bb815Sopenharmony_ci 182425bb815Sopenharmony_ci jmem_heap_free_block_internal (chunk_p, 16); 183425bb815Sopenharmony_ci chunk_p = next_p; 184425bb815Sopenharmony_ci } 185425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ 186425bb815Sopenharmony_ci} /* jmem_pools_collect_empty */ 187425bb815Sopenharmony_ci 188425bb815Sopenharmony_ci/** 189425bb815Sopenharmony_ci * @} 190425bb815Sopenharmony_ci * @} 191425bb815Sopenharmony_ci */ 192