/** * Long path for mem_pools_alloc * * @return true - if there is a free chunk in mem_pools, * false - otherwise (not enough memory). */ static bool __attr_noinline___ mem_pools_alloc_longpath (void) { /** * If there are no free chunks, allocate new pool. */ if (mem_free_chunks_number == 0) { mem_pool_state_t *pool_state = (mem_pool_state_t*) mem_heap_alloc_block (MEM_POOL_SIZE, MEM_HEAP_ALLOC_LONG_TERM); JERRY_ASSERT (pool_state != NULL); mem_pool_init (pool_state, MEM_POOL_SIZE); MEM_CP_SET_POINTER (pool_state->next_pool_cp, mem_pools); mem_pools = pool_state; mem_free_chunks_number += MEM_POOL_CHUNKS_NUMBER; MEM_POOLS_STAT_ALLOC_POOL (); } else { /** * There is definitely at least one pool of specified type with at least one free chunk. * * Search for the pool. */ mem_pool_state_t *pool_state = mem_pools, *prev_pool_state_p = NULL; while (pool_state->first_free_chunk == MEM_POOL_CHUNKS_NUMBER) { prev_pool_state_p = pool_state; pool_state = MEM_CP_GET_NON_NULL_POINTER (mem_pool_state_t, pool_state->next_pool_cp); } JERRY_ASSERT (prev_pool_state_p != NULL && pool_state != mem_pools); prev_pool_state_p->next_pool_cp = pool_state->next_pool_cp; MEM_CP_SET_NON_NULL_POINTER (pool_state->next_pool_cp, mem_pools); mem_pools = pool_state; } return true; } /* mem_pools_alloc_longpath */
/** * Long path for mem_pools_alloc */ static void __attr_noinline___ mem_pools_alloc_longpath (void) { mem_check_pools (); JERRY_ASSERT (mem_free_chunk_p == NULL); JERRY_ASSERT (MEM_POOL_SIZE <= mem_heap_get_chunked_block_data_size ()); JERRY_ASSERT (MEM_POOL_CHUNKS_NUMBER >= 1); MEM_HEAP_VALGRIND_FREYA_MEMPOOL_REQUEST (); mem_pool_chunk_t *pool_start_p = (mem_pool_chunk_t*) mem_heap_alloc_chunked_block (MEM_HEAP_ALLOC_LONG_TERM); if (mem_free_chunk_p != NULL) { /* some chunks were freed due to GC invoked by heap allocator */ MEM_HEAP_VALGRIND_FREYA_MEMPOOL_REQUEST (); mem_heap_free_block (pool_start_p); return; } #ifndef JERRY_NDEBUG mem_free_chunks_number += MEM_POOL_CHUNKS_NUMBER; #endif /* !JERRY_NDEBUG */ JERRY_STATIC_ASSERT (MEM_POOL_CHUNK_SIZE % MEM_ALIGNMENT == 0); JERRY_STATIC_ASSERT (sizeof (mem_pool_chunk_t) == MEM_POOL_CHUNK_SIZE); JERRY_STATIC_ASSERT (sizeof (mem_pool_chunk_index_t) <= MEM_POOL_CHUNK_SIZE); JERRY_ASSERT ((mem_pool_chunk_index_t) MEM_POOL_CHUNKS_NUMBER == MEM_POOL_CHUNKS_NUMBER); JERRY_ASSERT (MEM_POOL_SIZE == MEM_POOL_CHUNKS_NUMBER * MEM_POOL_CHUNK_SIZE); JERRY_ASSERT (((uintptr_t) pool_start_p) % MEM_ALIGNMENT == 0); mem_pool_chunk_t *prev_free_chunk_p = NULL; for (mem_pool_chunk_index_t chunk_index = 0; chunk_index < MEM_POOL_CHUNKS_NUMBER; chunk_index++) { mem_pool_chunk_t *chunk_p = pool_start_p + chunk_index; if (prev_free_chunk_p != NULL) { prev_free_chunk_p->u.free.next_p = chunk_p; } prev_free_chunk_p = chunk_p; } prev_free_chunk_p->u.free.next_p = NULL; #ifdef JERRY_VALGRIND for (mem_pool_chunk_index_t chunk_index = 0; chunk_index < MEM_POOL_CHUNKS_NUMBER; chunk_index++) { mem_pool_chunk_t *chunk_p = pool_start_p + chunk_index; VALGRIND_NOACCESS_SPACE (chunk_p, MEM_POOL_CHUNK_SIZE); } #endif /* JERRY_VALGRIND */ mem_free_chunk_p = pool_start_p; MEM_POOLS_STAT_ALLOC_POOL (); mem_check_pools (); } /* mem_pools_alloc_longpath */