Esempio n. 1
0
/**
 * 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 */
Esempio n. 2
0
/**
 * 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 */