mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Speeding up procedure for getting start of a heap block's data space for one-chunked blocks, removing general blocks support from the procedure.
- heap area is aligned on heap chunk size; - mem_heap_get_block_start is renamed to mem_heap_get_chunked_block_start, now this interface is applicable only to one-chunked blocks, and is significantly faster - instead of iterating list of heap blocks to find block header, it just aligns value of pointer to heap chunk size. JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
parent
253e172127
commit
82f9afcde9
@ -30,7 +30,8 @@
|
|||||||
/**
|
/**
|
||||||
* Area for heap
|
* Area for heap
|
||||||
*/
|
*/
|
||||||
static uint8_t mem_heap_area[ MEM_HEAP_AREA_SIZE ] __attribute__ ((aligned (MEM_ALIGNMENT)));
|
static uint8_t mem_heap_area[ MEM_HEAP_AREA_SIZE ] __attribute__ ((aligned (JERRY_MAX (MEM_ALIGNMENT,
|
||||||
|
MEM_HEAP_CHUNK_SIZE))));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The 'try to give memory back' callback
|
* The 'try to give memory back' callback
|
||||||
|
|||||||
@ -396,6 +396,9 @@ mem_is_block_free (const mem_block_header_t *block_header_p) /**< block header *
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Startup initialization of heap
|
* Startup initialization of heap
|
||||||
|
*
|
||||||
|
* Note:
|
||||||
|
* heap start and size should be aligned on MEM_HEAP_CHUNK_SIZE
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
mem_heap_init (uint8_t *heap_start, /**< first address of heap space */
|
mem_heap_init (uint8_t *heap_start, /**< first address of heap space */
|
||||||
@ -403,8 +406,12 @@ mem_heap_init (uint8_t *heap_start, /**< first address of heap space */
|
|||||||
{
|
{
|
||||||
JERRY_ASSERT (heap_start != NULL);
|
JERRY_ASSERT (heap_start != NULL);
|
||||||
JERRY_ASSERT (heap_size != 0);
|
JERRY_ASSERT (heap_size != 0);
|
||||||
JERRY_ASSERT (heap_size % MEM_HEAP_CHUNK_SIZE == 0);
|
|
||||||
|
JERRY_STATIC_ASSERT ((MEM_HEAP_CHUNK_SIZE & (MEM_HEAP_CHUNK_SIZE - 1u)) == 0);
|
||||||
JERRY_ASSERT ((uintptr_t) heap_start % MEM_ALIGNMENT == 0);
|
JERRY_ASSERT ((uintptr_t) heap_start % MEM_ALIGNMENT == 0);
|
||||||
|
JERRY_ASSERT ((uintptr_t) heap_start % MEM_HEAP_CHUNK_SIZE == 0);
|
||||||
|
JERRY_ASSERT (heap_size % MEM_HEAP_CHUNK_SIZE == 0);
|
||||||
|
|
||||||
JERRY_ASSERT (heap_size <= (1u << MEM_HEAP_OFFSET_LOG));
|
JERRY_ASSERT (heap_size <= (1u << MEM_HEAP_OFFSET_LOG));
|
||||||
|
|
||||||
mem_heap.heap_start = heap_start;
|
mem_heap.heap_start = heap_start;
|
||||||
@ -800,6 +807,7 @@ mem_heap_free_block (void *ptr) /**< pointer to beginning of data space of the b
|
|||||||
|
|
||||||
/* marking the block free */
|
/* marking the block free */
|
||||||
block_p->allocated_bytes = 0;
|
block_p->allocated_bytes = 0;
|
||||||
|
block_p->length_type = mem_block_length_type_t::GENERAL;
|
||||||
|
|
||||||
if (next_block_p != NULL)
|
if (next_block_p != NULL)
|
||||||
{
|
{
|
||||||
@ -866,12 +874,12 @@ mem_heap_free_block (void *ptr) /**< pointer to beginning of data space of the b
|
|||||||
} /* mem_heap_free_block */
|
} /* mem_heap_free_block */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find beginning of user data in a block from pointer,
|
* Find beginning of user data in a one-chunked block from pointer,
|
||||||
* pointing into it, i.e. into [block_data_space_start; block_data_space_end) range.
|
* pointing into it, i.e. into [block_data_space_start; block_data_space_end) range.
|
||||||
*
|
*
|
||||||
* Note:
|
* Note:
|
||||||
* Pointer must point to the memory region which was previously allocated
|
* Pointer must point to the one-chunked memory region which was previously allocated
|
||||||
* with mem_heap_alloc_block and is currently valid.
|
* with mem_heap_alloc_chunked_block and is currently valid.
|
||||||
*
|
*
|
||||||
* Note:
|
* Note:
|
||||||
* The interface should only be used for determining where the user space of heap-allocated block begins.
|
* The interface should only be used for determining where the user space of heap-allocated block begins.
|
||||||
@ -880,49 +888,59 @@ mem_heap_free_block (void *ptr) /**< pointer to beginning of data space of the b
|
|||||||
* @return beginning of user data space of block identified by the pointer
|
* @return beginning of user data space of block identified by the pointer
|
||||||
*/
|
*/
|
||||||
void*
|
void*
|
||||||
mem_heap_get_block_start (void *ptr) /**< pointer into a block */
|
mem_heap_get_chunked_block_start (void *ptr) /**< pointer into a block */
|
||||||
{
|
{
|
||||||
mem_check_heap ();
|
JERRY_STATIC_ASSERT ((MEM_HEAP_CHUNK_SIZE & (MEM_HEAP_CHUNK_SIZE - 1u)) == 0);
|
||||||
|
JERRY_ASSERT (((uintptr_t) mem_heap.heap_start % MEM_HEAP_CHUNK_SIZE) == 0);
|
||||||
/*
|
|
||||||
* PERF: consider introducing bitmap of block beginnings
|
|
||||||
*/
|
|
||||||
|
|
||||||
JERRY_ASSERT (mem_heap.heap_start <= ptr
|
JERRY_ASSERT (mem_heap.heap_start <= ptr
|
||||||
&& ptr < mem_heap.heap_start + mem_heap.heap_size);
|
&& ptr < mem_heap.heap_start + mem_heap.heap_size);
|
||||||
|
|
||||||
const mem_block_header_t *block_p = mem_heap.first_block_p;
|
uintptr_t uintptr = (uintptr_t) ptr;
|
||||||
|
uintptr_t uintptr_chunk_aligned = JERRY_ALIGNDOWN (uintptr, MEM_HEAP_CHUNK_SIZE);
|
||||||
|
|
||||||
|
JERRY_ASSERT (uintptr > uintptr_chunk_aligned);
|
||||||
|
|
||||||
|
mem_block_header_t *block_p = (mem_block_header_t *) uintptr_chunk_aligned;
|
||||||
|
JERRY_ASSERT (block_p->length_type == mem_block_length_type_t::ONE_CHUNKED);
|
||||||
|
|
||||||
|
#ifndef JERRY_NDEBUG
|
||||||
|
const mem_block_header_t *block_iter_p = mem_heap.first_block_p;
|
||||||
|
bool is_found = false;
|
||||||
|
|
||||||
/* searching for corresponding block */
|
/* searching for corresponding block */
|
||||||
while (block_p != NULL)
|
while (block_iter_p != NULL)
|
||||||
{
|
{
|
||||||
VALGRIND_DEFINED_STRUCT (block_p);
|
VALGRIND_DEFINED_STRUCT (block_iter_p);
|
||||||
|
|
||||||
const mem_block_header_t *next_block_p = mem_get_next_block_by_direction (block_p,
|
const mem_block_header_t *next_block_p = mem_get_next_block_by_direction (block_iter_p,
|
||||||
MEM_DIRECTION_NEXT);
|
MEM_DIRECTION_NEXT);
|
||||||
bool is_found = (ptr > block_p
|
is_found = (ptr > block_iter_p
|
||||||
&& (ptr < next_block_p
|
&& (ptr < next_block_p
|
||||||
|| next_block_p == NULL));
|
|| next_block_p == NULL));
|
||||||
|
|
||||||
if (is_found)
|
if (is_found)
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (!mem_is_block_free (block_p));
|
JERRY_ASSERT (!mem_is_block_free (block_iter_p));
|
||||||
JERRY_ASSERT (block_p + 1 <= ptr);
|
JERRY_ASSERT (block_iter_p + 1 <= ptr);
|
||||||
JERRY_ASSERT (ptr < ((uint8_t*) (block_p + 1) + block_p->allocated_bytes));
|
JERRY_ASSERT (ptr < ((uint8_t*) (block_iter_p + 1) + block_iter_p->allocated_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
VALGRIND_NOACCESS_STRUCT (block_p);
|
VALGRIND_NOACCESS_STRUCT (block_iter_p);
|
||||||
|
|
||||||
if (is_found)
|
if (is_found)
|
||||||
{
|
{
|
||||||
return (void*) (block_p + 1);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
block_p = next_block_p;
|
block_iter_p = next_block_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
JERRY_UNREACHABLE ();
|
JERRY_ASSERT (is_found && block_p == block_iter_p);
|
||||||
} /* mem_heap_get_block_start */
|
#endif /* !JERRY_NDEBUG */
|
||||||
|
|
||||||
|
return (void*) (block_p + 1);
|
||||||
|
} /* mem_heap_get_chunked_block_start */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get size of one-chunked block data space
|
* Get size of one-chunked block data space
|
||||||
|
|||||||
@ -44,7 +44,7 @@ extern void mem_heap_finalize (void);
|
|||||||
extern void* mem_heap_alloc_block (size_t size_in_bytes, mem_heap_alloc_term_t alloc_term);
|
extern void* mem_heap_alloc_block (size_t size_in_bytes, mem_heap_alloc_term_t alloc_term);
|
||||||
extern void* mem_heap_alloc_chunked_block (mem_heap_alloc_term_t alloc_term);
|
extern void* mem_heap_alloc_chunked_block (mem_heap_alloc_term_t alloc_term);
|
||||||
extern void mem_heap_free_block (void *ptr);
|
extern void mem_heap_free_block (void *ptr);
|
||||||
extern void* mem_heap_get_block_start (void *ptr);
|
extern void* mem_heap_get_chunked_block_start (void *ptr);
|
||||||
extern size_t mem_heap_get_chunked_block_data_size (void);
|
extern size_t mem_heap_get_chunked_block_data_size (void);
|
||||||
extern size_t __attr_pure___ mem_heap_recommend_allocation_size (size_t minimum_allocation_size);
|
extern size_t __attr_pure___ mem_heap_recommend_allocation_size (size_t minimum_allocation_size);
|
||||||
extern void mem_heap_print (bool dump_block_headers, bool dump_block_data, bool dump_stats);
|
extern void mem_heap_print (bool dump_block_headers, bool dump_block_data, bool dump_stats);
|
||||||
|
|||||||
@ -39,6 +39,7 @@ extern "C"
|
|||||||
|
|
||||||
uint8_t *ptrs[test_sub_iters];
|
uint8_t *ptrs[test_sub_iters];
|
||||||
size_t sizes[test_sub_iters];
|
size_t sizes[test_sub_iters];
|
||||||
|
bool is_one_chunked[test_sub_iters];
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_heap_give_some_memory_back (mem_try_give_memory_back_severity_t severity)
|
test_heap_give_some_memory_back (mem_try_give_memory_back_severity_t severity)
|
||||||
@ -82,12 +83,13 @@ test_heap_give_some_memory_back (mem_try_give_memory_back_severity_t severity)
|
|||||||
}
|
}
|
||||||
} /* test_heap_give_some_memory_back */
|
} /* test_heap_give_some_memory_back */
|
||||||
|
|
||||||
|
uint8_t test_native_heap[test_heap_size] __attribute__ ((aligned (JERRY_MAX (MEM_ALIGNMENT,
|
||||||
|
MEM_HEAP_CHUNK_SIZE))));
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int __attr_unused___ argc,
|
main (int __attr_unused___ argc,
|
||||||
char __attr_unused___ **argv)
|
char __attr_unused___ **argv)
|
||||||
{
|
{
|
||||||
uint8_t test_native_heap[test_heap_size];
|
|
||||||
|
|
||||||
mem_heap_init (test_native_heap, sizeof (test_native_heap));
|
mem_heap_init (test_native_heap, sizeof (test_native_heap));
|
||||||
|
|
||||||
srand ((unsigned int) time (NULL));
|
srand ((unsigned int) time (NULL));
|
||||||
@ -103,17 +105,31 @@ main (int __attr_unused___ argc,
|
|||||||
{
|
{
|
||||||
for (uint32_t j = 0; j < test_sub_iters; j++)
|
for (uint32_t j = 0; j < test_sub_iters; j++)
|
||||||
{
|
{
|
||||||
size_t size = (size_t) rand () % test_threshold_block_size;
|
if (rand () % 2)
|
||||||
ptrs[j] = (uint8_t*) mem_heap_alloc_block (size,
|
{
|
||||||
(rand () % 2) ?
|
size_t size = (size_t) rand () % test_threshold_block_size;
|
||||||
MEM_HEAP_ALLOC_LONG_TERM : MEM_HEAP_ALLOC_SHORT_TERM);
|
ptrs[j] = (uint8_t*) mem_heap_alloc_block (size,
|
||||||
sizes[j] = size;
|
(rand () % 2) ?
|
||||||
|
MEM_HEAP_ALLOC_LONG_TERM : MEM_HEAP_ALLOC_SHORT_TERM);
|
||||||
|
sizes[j] = size;
|
||||||
|
is_one_chunked[j] = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptrs[j] = (uint8_t*) mem_heap_alloc_chunked_block ((rand () % 2) ?
|
||||||
|
MEM_HEAP_ALLOC_LONG_TERM : MEM_HEAP_ALLOC_SHORT_TERM);
|
||||||
|
sizes[j] = mem_heap_get_chunked_block_data_size ();
|
||||||
|
is_one_chunked[j] = true;
|
||||||
|
}
|
||||||
|
|
||||||
JERRY_ASSERT (size == 0 || ptrs[j] != NULL);
|
JERRY_ASSERT (sizes[j] == 0 || ptrs[j] != NULL);
|
||||||
memset (ptrs[j], 0, sizes[j]);
|
memset (ptrs[j], 0, sizes[j]);
|
||||||
|
|
||||||
JERRY_ASSERT (ptrs[j] == NULL
|
if (is_one_chunked[j])
|
||||||
|| mem_heap_get_block_start (ptrs[j] + (size_t) rand () % sizes[j]) == ptrs[j]);
|
{
|
||||||
|
JERRY_ASSERT (ptrs[j] != NULL
|
||||||
|
&& mem_heap_get_chunked_block_start (ptrs[j] + (size_t) rand () % sizes[j]) == ptrs[j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mem_heap_print (true);
|
// mem_heap_print (true);
|
||||||
@ -127,8 +143,11 @@ main (int __attr_unused___ argc,
|
|||||||
JERRY_ASSERT (ptrs[j][k] == 0);
|
JERRY_ASSERT (ptrs[j][k] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
JERRY_ASSERT (sizes[j] == 0
|
if (is_one_chunked[j])
|
||||||
|| mem_heap_get_block_start (ptrs[j] + (size_t) rand () % sizes[j]) == ptrs[j]);
|
{
|
||||||
|
JERRY_ASSERT (sizes[j] == 0
|
||||||
|
|| mem_heap_get_chunked_block_start (ptrs[j] + (size_t) rand () % sizes[j]) == ptrs[j]);
|
||||||
|
}
|
||||||
|
|
||||||
mem_heap_free_block (ptrs[j]);
|
mem_heap_free_block (ptrs[j]);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user