mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
This patch extends jmem functionality by adding a realloc function. This opens up other paths of optimization which can result in smaller peak memory usage and faster execution times, due to not having to duplicate memory when we need to extend blocks. JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
242 lines
7.1 KiB
C
242 lines
7.1 KiB
C
/* Copyright JS Foundation and other contributors, http://js.foundation
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef JMEM_H
|
|
#define JMEM_H
|
|
|
|
#include "jrt.h"
|
|
|
|
/** \addtogroup mem Memory allocation
|
|
* @{
|
|
*
|
|
* \addtogroup heap Heap
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* Logarithm of required alignment for allocated units/blocks
|
|
*/
|
|
#define JMEM_ALIGNMENT_LOG 3
|
|
|
|
/**
|
|
* Representation of NULL value for compressed pointers
|
|
*/
|
|
#define JMEM_CP_NULL ((jmem_cpointer_t) 0)
|
|
|
|
/**
|
|
* Required alignment for allocated units/blocks
|
|
*/
|
|
#define JMEM_ALIGNMENT (1u << JMEM_ALIGNMENT_LOG)
|
|
|
|
/**
|
|
* Compressed pointer representations
|
|
*
|
|
* 16 bit representation:
|
|
* The jmem_cpointer_t is defined as uint16_t
|
|
* and it can contain any sixteen bit value.
|
|
*
|
|
* 32 bit representation:
|
|
* The jmem_cpointer_t is defined as uint32_t.
|
|
* The lower JMEM_ALIGNMENT_LOG bits must be zero.
|
|
* The other bits can have any value.
|
|
*
|
|
* The 16 bit representation always encodes an offset from
|
|
* a heap base. The 32 bit representation currently encodes
|
|
* raw 32 bit JMEM_ALIGNMENT aligned pointers on 32 bit systems.
|
|
* This can be extended to encode a 32 bit offset from a heap
|
|
* base on 64 bit systems in the future. There are no plans
|
|
* to support more than 4G address space for JerryScript.
|
|
*/
|
|
|
|
/**
|
|
* Compressed pointer
|
|
*/
|
|
#if ENABLED (JERRY_CPOINTER_32_BIT)
|
|
typedef uint32_t jmem_cpointer_t;
|
|
#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */
|
|
typedef uint16_t jmem_cpointer_t;
|
|
#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */
|
|
|
|
/**
|
|
* Memory usage pressure for reclaiming unused memory.
|
|
*
|
|
* Each failed allocation will try to reclaim memory with increasing pressure,
|
|
* until enough memory is freed to fulfill the allocation request.
|
|
*
|
|
* If not enough memory is freed and JMEM_PRESSURE_FULL is reached,
|
|
* then the engine is shut down with ERR_OUT_OF_MEMORY.
|
|
*/
|
|
typedef enum
|
|
{
|
|
JMEM_PRESSURE_NONE, /**< no memory pressure */
|
|
JMEM_PRESSURE_LOW, /**< low memory pressure */
|
|
JMEM_PRESSURE_HIGH, /**< high memory pressure */
|
|
JMEM_PRESSURE_FULL, /**< memory full */
|
|
} jmem_pressure_t;
|
|
|
|
/**
|
|
* Node for free chunk list
|
|
*/
|
|
typedef struct jmem_pools_chunk_t
|
|
{
|
|
struct jmem_pools_chunk_t *next_p; /**< pointer to next pool chunk */
|
|
} jmem_pools_chunk_t;
|
|
|
|
/**
|
|
* Free region node
|
|
*/
|
|
typedef struct
|
|
{
|
|
uint32_t next_offset; /**< Offset of next region in list */
|
|
uint32_t size; /**< Size of region */
|
|
} jmem_heap_free_t;
|
|
|
|
void jmem_init (void);
|
|
void jmem_finalize (void);
|
|
|
|
void *jmem_heap_alloc_block (const size_t size);
|
|
void *jmem_heap_alloc_block_null_on_error (const size_t size);
|
|
void *jmem_heap_realloc_block (void *ptr, const size_t old_size, const size_t new_size);
|
|
void jmem_heap_free_block (void *ptr, const size_t size);
|
|
|
|
#if ENABLED (JERRY_MEM_STATS)
|
|
/**
|
|
* Heap memory usage statistics
|
|
*/
|
|
typedef struct
|
|
{
|
|
size_t size; /**< heap total size */
|
|
|
|
size_t allocated_bytes; /**< currently allocated bytes */
|
|
size_t peak_allocated_bytes; /**< peak allocated bytes */
|
|
|
|
size_t waste_bytes; /**< bytes waste due to blocks filled partially */
|
|
size_t peak_waste_bytes; /**< peak wasted bytes */
|
|
|
|
size_t byte_code_bytes; /**< allocated memory for byte code */
|
|
size_t peak_byte_code_bytes; /**< peak allocated memory for byte code */
|
|
|
|
size_t string_bytes; /**< allocated memory for strings */
|
|
size_t peak_string_bytes; /**< peak allocated memory for strings */
|
|
|
|
size_t object_bytes; /**< allocated memory for objects */
|
|
size_t peak_object_bytes; /**< peak allocated memory for objects */
|
|
|
|
size_t property_bytes; /**< allocated memory for properties */
|
|
size_t peak_property_bytes; /**< peak allocated memory for properties */
|
|
} jmem_heap_stats_t;
|
|
|
|
void jmem_stats_allocate_byte_code_bytes (size_t property_size);
|
|
void jmem_stats_free_byte_code_bytes (size_t property_size);
|
|
void jmem_stats_allocate_string_bytes (size_t string_size);
|
|
void jmem_stats_free_string_bytes (size_t string_size);
|
|
void jmem_stats_allocate_object_bytes (size_t object_size);
|
|
void jmem_stats_free_object_bytes (size_t string_size);
|
|
void jmem_stats_allocate_property_bytes (size_t property_size);
|
|
void jmem_stats_free_property_bytes (size_t property_size);
|
|
|
|
void jmem_heap_get_stats (jmem_heap_stats_t *);
|
|
void jmem_heap_stats_reset_peak (void);
|
|
void jmem_heap_stats_print (void);
|
|
#endif /* ENABLED (JERRY_MEM_STATS) */
|
|
|
|
jmem_cpointer_t JERRY_ATTR_PURE jmem_compress_pointer (const void *pointer_p);
|
|
void * JERRY_ATTR_PURE jmem_decompress_pointer (uintptr_t compressed_pointer);
|
|
|
|
/**
|
|
* Define a local array variable and allocate memory for the array on the heap.
|
|
*
|
|
* If requested number of elements is zero, assign NULL to the variable.
|
|
*
|
|
* Warning:
|
|
* if there is not enough memory on the heap, shutdown engine with ERR_OUT_OF_MEMORY.
|
|
*/
|
|
#define JMEM_DEFINE_LOCAL_ARRAY(var_name, number, type) \
|
|
{ \
|
|
size_t var_name ## ___size = (size_t) (number) * sizeof (type); \
|
|
type *var_name = (type *) (jmem_heap_alloc_block (var_name ## ___size));
|
|
|
|
/**
|
|
* Free the previously defined local array variable, freeing corresponding block on the heap,
|
|
* if it was allocated (i.e. if the array's size was non-zero).
|
|
*/
|
|
#define JMEM_FINALIZE_LOCAL_ARRAY(var_name) \
|
|
if (var_name != NULL) \
|
|
{ \
|
|
JERRY_ASSERT (var_name ## ___size != 0); \
|
|
\
|
|
jmem_heap_free_block (var_name, var_name ## ___size); \
|
|
} \
|
|
else \
|
|
{ \
|
|
JERRY_ASSERT (var_name ## ___size == 0); \
|
|
} \
|
|
}
|
|
|
|
/**
|
|
* Get value of pointer from specified non-null compressed pointer value
|
|
*/
|
|
#define JMEM_CP_GET_NON_NULL_POINTER(type, cp_value) \
|
|
((type *) (jmem_decompress_pointer (cp_value)))
|
|
|
|
/**
|
|
* Get value of pointer from specified compressed pointer value
|
|
*/
|
|
#define JMEM_CP_GET_POINTER(type, cp_value) \
|
|
(((JERRY_UNLIKELY ((cp_value) == JMEM_CP_NULL)) ? NULL : JMEM_CP_GET_NON_NULL_POINTER (type, cp_value)))
|
|
|
|
/**
|
|
* Set value of non-null compressed pointer so that it will correspond
|
|
* to specified non_compressed_pointer
|
|
*/
|
|
#define JMEM_CP_SET_NON_NULL_POINTER(cp_value, non_compressed_pointer) \
|
|
(cp_value) = jmem_compress_pointer (non_compressed_pointer)
|
|
|
|
/**
|
|
* Set value of compressed pointer so that it will correspond
|
|
* to specified non_compressed_pointer
|
|
*/
|
|
#define JMEM_CP_SET_POINTER(cp_value, non_compressed_pointer) \
|
|
do \
|
|
{ \
|
|
void *ptr_value = (void *) non_compressed_pointer; \
|
|
\
|
|
if (JERRY_UNLIKELY ((ptr_value) == NULL)) \
|
|
{ \
|
|
(cp_value) = JMEM_CP_NULL; \
|
|
} \
|
|
else \
|
|
{ \
|
|
JMEM_CP_SET_NON_NULL_POINTER (cp_value, ptr_value); \
|
|
} \
|
|
} while (false);
|
|
|
|
/**
|
|
* @}
|
|
* \addtogroup poolman Memory pool manager
|
|
* @{
|
|
*/
|
|
|
|
void *jmem_pools_alloc (size_t size);
|
|
void jmem_pools_free (void *chunk_p, size_t size);
|
|
void jmem_pools_collect_empty (void);
|
|
|
|
/**
|
|
* @}
|
|
* @}
|
|
*/
|
|
|
|
#endif /* !JMEM_H */
|