/* Copyright 2015 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "jrt.h" #include "jsp-mm.h" #include "mem-allocator.h" #include "mem-heap.h" /** \addtogroup jsparser ECMAScript parser * @{ * * \addtogroup managedmem Managed memory allocation * @{ */ /** * Header of a managed block, allocated by parser */ typedef struct __attribute__ ((alignment (MEM_ALIGNMENT))) { mem_cpointer_t prev_block_cp; /**< previous managed block */ mem_cpointer_t next_block_cp; /**< next managed block */ } jsp_mm_header_t; /** * List used for tracking memory blocks */ jsp_mm_header_t *jsp_mm_blocks_p = NULL; /** * Initialize managed memory allocator */ void jsp_mm_init (void) { JERRY_ASSERT (jsp_mm_blocks_p == NULL); } /* jsp_mm_init */ /** * Finalize managed memory allocator */ void jsp_mm_finalize (void) { JERRY_ASSERT (jsp_mm_blocks_p == NULL); } /* jsp_mm_finalize */ /** * Recommend allocation size * * Note: * The interface is used by collection allocators * for storage of data that takes the specified * amount of bytes upon allocation, but probably * would require more. * * To reduce probability of reallocation in future, * the allocators can request more space in first * allocation request. * * The interface helps to choose appropriate space * to allocate, considering amount of heap space, * that would be waste if allocation size * would not be increased. * * @return recommended allocation size */ size_t jsp_mm_recommend_size (size_t minimum_size) /**< minimum required size */ { size_t block_and_header_size = mem_heap_recommend_allocation_size (minimum_size + sizeof (jsp_mm_header_t)); return block_and_header_size - sizeof (jsp_mm_header_t); } /* jsp_mm_recommend_size */ /** * Allocate a managed memory block of specified size * * @return pointer to data space of allocated block */ void* jsp_mm_alloc (size_t size) /**< size of block to allocate */ { void *ptr_p = mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM); jsp_mm_header_t *tmem_header_p = (jsp_mm_header_t*) ptr_p; tmem_header_p->prev_block_cp = MEM_CP_NULL; MEM_CP_SET_POINTER (tmem_header_p->next_block_cp, jsp_mm_blocks_p); if (jsp_mm_blocks_p != NULL) { MEM_CP_SET_POINTER (jsp_mm_blocks_p->prev_block_cp, tmem_header_p); } jsp_mm_blocks_p = tmem_header_p; return (void *) (tmem_header_p + 1); } /* jsp_mm_alloc */ /** * Free a managed memory block */ void jsp_mm_free (void *ptr) /**< pointer to data space of allocated block */ { jsp_mm_header_t *tmem_header_p = ((jsp_mm_header_t *) ptr) - 1; jsp_mm_header_t *prev_block_p = MEM_CP_GET_POINTER (jsp_mm_header_t, tmem_header_p->prev_block_cp); jsp_mm_header_t *next_block_p = MEM_CP_GET_POINTER (jsp_mm_header_t, tmem_header_p->next_block_cp); if (prev_block_p != NULL) { prev_block_p->next_block_cp = tmem_header_p->next_block_cp; } else { JERRY_ASSERT (jsp_mm_blocks_p == tmem_header_p); jsp_mm_blocks_p = next_block_p; } if (next_block_p != NULL) { next_block_p->prev_block_cp = tmem_header_p->prev_block_cp; } mem_heap_free_block (tmem_header_p); } /* jsp_mm_free */ /** * Free all currently allocated managed memory blocks */ void jsp_mm_free_all (void) { while (jsp_mm_blocks_p != NULL) { jsp_mm_header_t *next_block_p = MEM_CP_GET_POINTER (jsp_mm_header_t, jsp_mm_blocks_p->next_block_cp); mem_heap_free_block (jsp_mm_blocks_p); jsp_mm_blocks_p = next_block_p; } } /* jsp_mm_free_all */ /** * @} * @} */