Add 32 bit compressed pointer support.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-09-01 01:44:08 -07:00
parent 9ca78d380f
commit da47dedaed
19 changed files with 271 additions and 173 deletions
+7
View File
@@ -22,6 +22,7 @@ set(FEATURE_PROFILE "full" CACHE STRING "Profile types: full, minimal")
set(FEATURE_ERROR_MESSAGES OFF CACHE BOOL "Enable error messages?")
set(FEATURE_VALGRIND OFF CACHE BOOL "Enable Valgrind support?")
set(FEATURE_VALGRIND_FREYA OFF CACHE BOOL "Enable Valgrind-Freya support?")
set(FEATURE_CPOINTER_32_BIT OFF CACHE BOOL "Enable 32 bit compressed pointers?")
set(FEATURE_MEM_STRESS_TEST OFF CACHE BOOL "Enable mem-stress test?")
set(FEATURE_MEM_STATS OFF CACHE BOOL "Enable memory statistics?")
set(FEATURE_PARSER_DUMP OFF CACHE BOOL "Enable parser byte-code dumps?")
@@ -35,6 +36,7 @@ message(STATUS "FEATURE_PROFILE " ${FEATURE_PROFILE})
message(STATUS "FEATURE_ERROR_MESSAGES " ${FEATURE_ERROR_MESSAGES})
message(STATUS "FEATURE_VALGRIND " ${FEATURE_VALGRIND})
message(STATUS "FEATURE_VALGRIND_FREYA " ${FEATURE_VALGRIND_FREYA})
message(STATUS "FEATURE_CPOINTER_32_BIT " ${FEATURE_CPOINTER_32_BIT})
message(STATUS "FEATURE_MEM_STRESS_TEST " ${FEATURE_MEM_STRESS_TEST})
message(STATUS "FEATURE_MEM_STATS " ${FEATURE_MEM_STATS})
message(STATUS "FEATURE_PARSER_DUMP " ${FEATURE_PARSER_DUMP})
@@ -182,6 +184,11 @@ if(FEATURE_VALGRIND_FREYA)
set(INCLUDE_CORE ${INCLUDE_CORE} ${INCLUDE_THIRD_PARTY_VALGRIND})
endif()
# Enable 32 bit cpointers
if(FEATURE_CPOINTER_32_BIT)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_CPOINTER_32_BIT)
endif()
# Memory management stress-test mode
if(FEATURE_MEM_STRESS_TEST)
set(DEFINES_JERRY ${DEFINES_JERRY} JMEM_GC_BEFORE_EACH_ALLOC)
-14
View File
@@ -39,8 +39,6 @@
*/
#ifndef CONFIG_MEM_HEAP_AREA_SIZE
# define CONFIG_MEM_HEAP_AREA_SIZE (512 * 1024)
#elif CONFIG_MEM_HEAP_AREA_SIZE > (512 * 1024)
# error "Currently, maximum 512 kilobytes heap size is supported"
#endif /* !CONFIG_MEM_HEAP_AREA_SIZE */
/**
@@ -53,18 +51,6 @@
*/
#define CONFIG_MEM_HEAP_DESIRED_LIMIT (JERRY_MIN (CONFIG_MEM_HEAP_AREA_SIZE / 32, CONFIG_MEM_HEAP_MAX_LIMIT))
/**
* Log2 of maximum possible offset in the heap
*
* The option affects size of compressed pointer that in turn
* affects size of ECMA Object Model's data types.
*
* In any case size of any of the types should not exceed CONFIG_MEM_POOL_CHUNK_SIZE.
*
* On the other hand, value 2 ^ CONFIG_MEM_HEAP_OFFSET_LOG should not be less than CONFIG_MEM_HEAP_AREA_SIZE.
*/
#define CONFIG_MEM_HEAP_OFFSET_LOG (19)
/**
* Number of lower bits in key of literal hash table.
*/
+6 -18
View File
@@ -25,22 +25,9 @@ JERRY_STATIC_ASSERT (sizeof (ecma_property_value_t) == sizeof (ecma_value_t),
size_of_ecma_property_value_t_must_be_equal_to_size_of_ecma_value_t);
JERRY_STATIC_ASSERT (((sizeof (ecma_property_value_t) - 1) & sizeof (ecma_property_value_t)) == 0,
size_of_ecma_property_value_t_must_be_power_of_2);
JERRY_STATIC_ASSERT (sizeof (ecma_property_pair_t) == sizeof (uint64_t) * 2,
size_of_ecma_property_pair_t_must_be_equal_to_16_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_object_t) <= sizeof (uint64_t),
size_of_ecma_object_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) <= sizeof (uint64_t) * 2,
size_of_ecma_extended_object_t_must_be_less_than_or_equal_to_16_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_collection_header_t) == sizeof (uint64_t),
size_of_ecma_collection_header_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_collection_chunk_t) == sizeof (uint64_t),
size_of_ecma_collection_chunk_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_string_t) == sizeof (uint64_t),
size_of_ecma_string_t_must_be_less_than_or_equal_to_8_bytes);
JERRY_STATIC_ASSERT (sizeof (ecma_getter_setter_pointers_t) <= sizeof (uint64_t),
size_of_ecma_getter_setter_pointers_t_must_be_less_than_or_equal_to_8_bytes);
/** \addtogroup ecma ECMA
* @{
@@ -67,20 +54,21 @@ JERRY_STATIC_ASSERT (sizeof (ecma_getter_setter_pointers_t) <= sizeof (uint64_t)
#define ALLOC(ecma_type) ecma_ ## ecma_type ## _t * \
ecma_alloc_ ## ecma_type (void) \
{ \
ecma_ ## ecma_type ## _t *p ## ecma_type = (ecma_ ## ecma_type ## _t *) jmem_pools_alloc (); \
ecma_ ## ecma_type ## _t *ecma_type ## _p; \
ecma_type ## _p = (ecma_ ## ecma_type ## _t *) jmem_pools_alloc (sizeof (ecma_ ## ecma_type ## _t)); \
\
JERRY_ASSERT (p ## ecma_type != NULL); \
JERRY_ASSERT (ecma_type ## _p != NULL); \
\
return p ## ecma_type; \
return ecma_type ## _p; \
}
/**
* Deallocation routine template
*/
#define DEALLOC(ecma_type) void \
ecma_dealloc_ ## ecma_type (ecma_ ## ecma_type ## _t *p ## ecma_type) \
ecma_dealloc_ ## ecma_type (ecma_ ## ecma_type ## _t *ecma_type ## _p) \
{ \
jmem_pools_free ((uint8_t *) p ## ecma_type); \
jmem_pools_free ((uint8_t *) ecma_type ## _p, sizeof (ecma_ ## ecma_type ## _t)); \
}
/**
+11
View File
@@ -361,9 +361,16 @@ typedef struct
*/
typedef struct
{
#ifdef JERRY_CPOINTER_32_BIT
jmem_cpointer_t next_property_cp; /**< next cpointer */
#endif /* JERRY_CPOINTER_32_BIT */
ecma_property_t types[ECMA_PROPERTY_PAIR_ITEM_COUNT]; /**< two property type slot. The first represent
* the type of this property (e.g. property pair) */
#ifdef JERRY_CPOINTER_32_BIT
uint16_t padding; /**< an unused value */
#else /* !JERRY_CPOINTER_32_BIT */
jmem_cpointer_t next_property_cp; /**< next cpointer */
#endif /* JERRY_CPOINTER_32_BIT */
} ecma_property_header_t;
/**
@@ -381,7 +388,11 @@ typedef struct
typedef union
{
ecma_value_t value; /**< value of a property */
#ifdef JERRY_CPOINTER_32_BIT
jmem_cpointer_t getter_setter_pair_cp; /**< cpointer to getter setter pair */
#else /* !JERRY_CPOINTER_32_BIT */
ecma_getter_setter_pointers_t getter_setter_pair; /**< getter setter pair */
#endif /* JERRY_CPOINTER_32_BIT */
} ecma_property_value_t;
/**
+2 -3
View File
@@ -43,9 +43,8 @@ JERRY_STATIC_ASSERT ((ECMA_VALUE_FULL_MASK + 1) == (1 << ECMA_VALUE_SHIFT),
JERRY_STATIC_ASSERT (ECMA_VALUE_SHIFT <= JMEM_ALIGNMENT_LOG,
ecma_value_shift_must_be_less_than_or_equal_than_mem_alignment_log);
JERRY_STATIC_ASSERT ((sizeof (ecma_value_t) * JERRY_BITSINBYTE)
>= (sizeof (jmem_cpointer_t) * JERRY_BITSINBYTE + ECMA_VALUE_SHIFT),
ecma_value_must_be_large_enough_to_store_compressed_pointers);
JERRY_STATIC_ASSERT (sizeof (jmem_cpointer_t) <= sizeof (ecma_value_t),
size_of_jmem_cpointer_t_must_be_less_or_equal_to_the_size_of_ecma_value_t);
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
+45 -15
View File
@@ -613,8 +613,16 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
ecma_ref_ecma_string (name_p);
ecma_property_value_t value;
#ifdef JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t));
ECMA_SET_POINTER (getter_setter_pair_p->getter_p, get_p);
ECMA_SET_POINTER (getter_setter_pair_p->setter_p, set_p);
ECMA_SET_POINTER (value.getter_setter_pair_cp, getter_setter_pair_p);
#else /* !JERRY_CPOINTER_32_BIT */
ECMA_SET_POINTER (value.getter_setter_pair.getter_p, get_p);
ECMA_SET_POINTER (value.getter_setter_pair.setter_p, set_p);
#endif /* JERRY_CPOINTER_32_BIT */
return ecma_create_property (object_p, name_p, type_and_flags, value);
} /* ecma_create_named_accessor_property */
@@ -763,20 +771,6 @@ ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property
return property_p;
} /* ecma_get_named_data_property */
/**
* Free the named data property and values it references.
*/
static void
ecma_free_named_data_property (ecma_object_t *object_p, /**< object the property belongs to */
ecma_property_t *property_p) /**< the property */
{
JERRY_ASSERT (object_p != NULL);
JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
ecma_value_t v = ecma_get_named_data_property_value (property_p);
ecma_free_value_if_not_object (v);
} /* ecma_free_named_data_property */
/**
* Free the internal property and values it references.
*/
@@ -873,7 +867,8 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
{
case ECMA_PROPERTY_TYPE_NAMEDDATA:
{
ecma_free_named_data_property (object_p, property_p);
ecma_free_value_if_not_object (ecma_get_named_data_property_value (property_p));
if (ecma_is_property_lcached (property_p))
{
ecma_lcache_invalidate (object_p, name_p, property_p);
@@ -882,6 +877,13 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
}
case ECMA_PROPERTY_TYPE_NAMEDACCESSOR:
{
#ifdef JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp);
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
#endif /* JERRY_CPOINTER_32_BIT */
if (ecma_is_property_lcached (property_p))
{
ecma_lcache_invalidate (object_p, name_p, property_p);
@@ -1083,7 +1085,14 @@ ecma_get_named_accessor_property_getter (const ecma_property_t *prop_p) /**< nam
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
#ifdef JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair_cp);
return ECMA_GET_POINTER (ecma_object_t, getter_setter_pair_p->getter_p);
#else /* !JERRY_CPOINTER_32_BIT */
return ECMA_GET_POINTER (ecma_object_t, ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.getter_p);
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_get_named_accessor_property_getter */
/**
@@ -1096,7 +1105,14 @@ ecma_get_named_accessor_property_setter (const ecma_property_t *prop_p) /**< nam
{
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
#ifdef JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair_cp);
return ECMA_GET_POINTER (ecma_object_t, getter_setter_pair_p->setter_p);
#else /* !JERRY_CPOINTER_32_BIT */
return ECMA_GET_POINTER (ecma_object_t, ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.setter_p);
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_get_named_accessor_property_setter */
/**
@@ -1110,7 +1126,14 @@ ecma_set_named_accessor_property_getter (ecma_object_t *object_p, /**< the prope
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
ecma_assert_object_contains_the_property (object_p, prop_p);
#ifdef JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair_cp);
ECMA_SET_POINTER (getter_setter_pair_p->getter_p, getter_p);
#else /* !JERRY_CPOINTER_32_BIT */
ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.getter_p, getter_p);
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_set_named_accessor_property_getter */
/**
@@ -1124,7 +1147,14 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope
JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (prop_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
ecma_assert_object_contains_the_property (object_p, prop_p);
#ifdef JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_POINTER (ecma_getter_setter_pointers_t,
ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair_cp);
ECMA_SET_POINTER (getter_setter_pair_p->setter_p, setter_p);
#else /* !JERRY_CPOINTER_32_BIT */
ECMA_SET_POINTER (ECMA_PROPERTY_VALUE_PTR (prop_p)->getter_setter_pair.setter_p, setter_p);
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_set_named_accessor_property_setter */
/**
+6 -7
View File
@@ -25,9 +25,6 @@
* @{
*/
JERRY_STATIC_ASSERT (sizeof (ecma_lit_storage_item_t) <= sizeof (uint64_t),
size_of_ecma_lit_storage_item_t_must_be_less_than_or_equal_to_8_bytes);
/**
* Free string list
*/
@@ -50,7 +47,7 @@ ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list
ecma_lit_storage_item_t *prev_item = string_list_p;
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
jmem_pools_free (prev_item);
jmem_pools_free (prev_item, sizeof (ecma_lit_storage_item_t));
}
} /* ecma_free_string_list */
@@ -115,7 +112,8 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string
return result;
}
ecma_lit_storage_item_t *new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc ();
ecma_lit_storage_item_t *new_item_p;
new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t));
new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
@@ -182,7 +180,7 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
ecma_string_t *string_p = (ecma_string_t *) jmem_pools_alloc ();
ecma_string_t *string_p = (ecma_string_t *) jmem_pools_alloc (sizeof (ecma_string_t));
string_p->refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_LITERAL_NUMBER;
string_p->u.lit_number = num;
@@ -195,7 +193,8 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be
return result;
}
ecma_lit_storage_item_t *new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc ();
ecma_lit_storage_item_t *new_item_p;
new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t));
new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
+4 -1
View File
@@ -54,7 +54,10 @@ typedef struct
ecma_object_t *ecma_gc_objects_lists[ECMA_GC_COLOR__COUNT]; /**< List of marked (visited during
* current GC session) and umarked objects */
jmem_heap_free_t *jmem_heap_list_skip_p; /**< This is used to speed up deallocation. */
jmem_pools_chunk_t *jmem_free_chunk_p; /**< list of free pool chunks */
jmem_pools_chunk_t *jmem_free_8_byte_chunk_p; /**< list of free eight byte pool chunks */
#ifdef JERRY_CPOINTER_32_BIT
jmem_pools_chunk_t *jmem_free_16_byte_chunk_p; /**< list of free sixteen byte pool chunks */
#endif /* JERRY_CPOINTER_32_BIT */
jmem_free_unused_memory_callback_t jmem_free_unused_memory_callback; /**< Callback for freeing up memory. */
const lit_utf8_byte_t **lit_magic_string_ex_array; /**< array of external magic strings */
const lit_utf8_size_t *lit_magic_string_ex_sizes; /**< external magic string lengths */
+46 -4
View File
@@ -27,6 +27,14 @@
#define JMEM_ALLOCATOR_INTERNAL
#include "jmem-allocator-internal.h"
#ifdef JERRY_CPOINTER_32_BIT
/* This check will go away when we will support 64 bit compressed pointers. */
JERRY_STATIC_ASSERT (sizeof (uintptr_t) <= sizeof (jmem_cpointer_t),
size_of_uintpt_t_must_be_equal_to_jmem_cpointer_t);
#endif
/**
* Initialize memory allocators.
*/
@@ -59,12 +67,29 @@ jmem_finalize ()
*
* @return packed pointer
*/
uintptr_t
inline jmem_cpointer_t __attr_always_inline___
jmem_compress_pointer (const void *pointer_p) /**< pointer to compress */
{
JERRY_ASSERT (pointer_p != NULL);
JERRY_ASSERT (jmem_is_heap_pointer (pointer_p));
return jmem_heap_compress_pointer (pointer_p);
uintptr_t uint_ptr = (uintptr_t) pointer_p;
JERRY_ASSERT (uint_ptr % JMEM_ALIGNMENT == 0);
#ifdef JERRY_CPOINTER_32_BIT
JERRY_ASSERT (((jmem_cpointer_t) uint_ptr) == uint_ptr);
#else /* !JERRY_CPOINTER_32_BIT */
const uintptr_t heap_start = (uintptr_t) &JERRY_HEAP_CONTEXT (first);
uint_ptr -= heap_start;
uint_ptr >>= JMEM_ALIGNMENT_LOG;
JERRY_ASSERT (uint_ptr <= UINT16_MAX);
JERRY_ASSERT (uint_ptr != JMEM_CP_NULL);
#endif /* JERRY_CPOINTER_32_BIT */
return (jmem_cpointer_t) uint_ptr;
} /* jmem_compress_pointer */
/**
@@ -72,10 +97,27 @@ jmem_compress_pointer (const void *pointer_p) /**< pointer to compress */
*
* @return unpacked pointer
*/
void *
inline void * __attr_always_inline___
jmem_decompress_pointer (uintptr_t compressed_pointer) /**< pointer to decompress */
{
return jmem_heap_decompress_pointer (compressed_pointer);
JERRY_ASSERT (compressed_pointer != JMEM_CP_NULL);
uintptr_t uint_ptr = compressed_pointer;
JERRY_ASSERT (((jmem_cpointer_t) uint_ptr) == uint_ptr);
#ifdef JERRY_CPOINTER_32_BIT
JERRY_ASSERT (uint_ptr % JMEM_ALIGNMENT == 0);
#else /* !JERRY_CPOINTER_32_BIT */
const uintptr_t heap_start = (uintptr_t) &JERRY_HEAP_CONTEXT (first);
uint_ptr <<= JMEM_ALIGNMENT_LOG;
uint_ptr += heap_start;
JERRY_ASSERT (jmem_is_heap_pointer ((void *) uint_ptr));
#endif /* JERRY_CPOINTER_32_BIT */
return (void *) uint_ptr;
} /* jmem_decompress_pointer */
/**
+35 -12
View File
@@ -28,10 +28,43 @@
* @{
*/
/**
* 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
*/
#ifdef JERRY_CPOINTER_32_BIT
typedef uint32_t jmem_cpointer_t;
#else /* !JERRY_CPOINTER_32_BIT */
typedef uint16_t jmem_cpointer_t;
#endif /* JERRY_CPOINTER_32_BIT */
/**
* Width of compressed memory pointer
*/
#ifdef JERRY_CPOINTER_32_BIT
#define JMEM_CP_WIDTH 32
#else /* !JERRY_CPOINTER_32_BIT */
#define JMEM_CP_WIDTH 16
#endif /* JERRY_CPOINTER_32_BIT */
/**
* Representation of NULL value for compressed pointers
@@ -43,16 +76,6 @@ typedef uint16_t jmem_cpointer_t;
*/
#define JMEM_ALIGNMENT (1u << JMEM_ALIGNMENT_LOG)
/**
* Width of compressed memory pointer
*/
#define JMEM_CP_WIDTH (JMEM_HEAP_OFFSET_LOG - JMEM_ALIGNMENT_LOG)
/**
* Compressed pointer value mask
*/
#define JMEM_CP_MASK ((1ull << JMEM_CP_WIDTH) - 1)
/**
* Severity of a 'try give memory back' request
*
@@ -107,7 +130,7 @@ typedef void (*jmem_free_unused_memory_callback_t) (jmem_free_unused_memory_seve
* 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) & JMEM_CP_MASK)
(cp_value) = jmem_compress_pointer (non_compressed_pointer)
/**
* Set value of compressed pointer so that it will correspond
@@ -131,7 +154,7 @@ typedef void (*jmem_free_unused_memory_callback_t) (jmem_free_unused_memory_seve
extern void jmem_init (void);
extern void jmem_finalize (void);
extern uintptr_t jmem_compress_pointer (const void *);
extern jmem_cpointer_t jmem_compress_pointer (const void *);
extern void *jmem_decompress_pointer (uintptr_t);
extern void jmem_register_free_unused_memory_callback (jmem_free_unused_memory_callback_t);
-10
View File
@@ -18,21 +18,11 @@
#include "config.h"
/**
* Log2 of maximum possible offset in the heap
*/
#define JMEM_HEAP_OFFSET_LOG (CONFIG_MEM_HEAP_OFFSET_LOG)
/**
* Size of heap
*/
#define JMEM_HEAP_SIZE ((size_t) (CONFIG_MEM_HEAP_AREA_SIZE))
/**
* Size of pool chunk
*/
#define JMEM_POOL_CHUNK_SIZE ((size_t) (CONFIG_MEM_POOL_CHUNK_SIZE))
/**
* Logarithm of required alignment for allocated units/blocks
*/
+4 -48
View File
@@ -145,8 +145,10 @@ static void jmem_heap_stat_free_iter ();
void
jmem_heap_init (void)
{
JERRY_STATIC_ASSERT ((1u << JMEM_HEAP_OFFSET_LOG) >= JMEM_HEAP_SIZE,
two_pow_mem_heap_offset_should_not_be_less_than_mem_heap_size);
#ifndef JERRY_CPOINTER_32_BIT
JERRY_STATIC_ASSERT (((UINT16_MAX + 1) << JMEM_ALIGNMENT_LOG) >= JMEM_HEAP_SIZE,
maximum_heap_size_for_16_bit_compressed_pointers_is_512K);
#endif /* !JERRY_CPOINTER_32_BIT */
JERRY_ASSERT ((uintptr_t) JERRY_HEAP_CONTEXT (area) % JMEM_ALIGNMENT == 0);
@@ -521,52 +523,6 @@ jmem_heap_free_block (void *ptr, /**< pointer to beginning of data space of the
JMEM_HEAP_STAT_FREE (size);
} /* jmem_heap_free_block */
/**
* Compress pointer
*
* @return packed heap pointer
*/
uintptr_t __attr_pure___ __attribute__((hot))
jmem_heap_compress_pointer (const void *pointer_p) /**< pointer to compress */
{
JERRY_ASSERT (pointer_p != NULL);
JERRY_ASSERT (jmem_is_heap_pointer (pointer_p));
uintptr_t int_ptr = (uintptr_t) pointer_p;
const uintptr_t heap_start = (uintptr_t) &JERRY_HEAP_CONTEXT (first);
JERRY_ASSERT (int_ptr % JMEM_ALIGNMENT == 0);
int_ptr -= heap_start;
int_ptr >>= JMEM_ALIGNMENT_LOG;
JERRY_ASSERT ((int_ptr & ~((1u << JMEM_HEAP_OFFSET_LOG) - 1)) == 0);
JERRY_ASSERT (int_ptr != JMEM_CP_NULL);
return int_ptr;
} /* jmem_heap_compress_pointer */
/**
* Decompress pointer
*
* @return unpacked heap pointer
*/
void * __attr_pure___ __attribute__((hot))
jmem_heap_decompress_pointer (uintptr_t compressed_pointer) /**< pointer to decompress */
{
JERRY_ASSERT (compressed_pointer != JMEM_CP_NULL);
uintptr_t int_ptr = compressed_pointer;
const uintptr_t heap_start = (uintptr_t) &JERRY_HEAP_CONTEXT (first);
int_ptr <<= JMEM_ALIGNMENT_LOG;
int_ptr += heap_start;
JERRY_ASSERT (jmem_is_heap_pointer ((void *) int_ptr));
return (void *) int_ptr;
} /* jmem_heap_decompress_pointer */
#ifndef JERRY_NDEBUG
/**
* Check whether the pointer points to the heap
-2
View File
@@ -34,8 +34,6 @@ extern void jmem_heap_finalize (void);
extern void *jmem_heap_alloc_block (const size_t);
extern void *jmem_heap_alloc_block_null_on_error (const size_t);
extern void jmem_heap_free_block (void *, const size_t);
extern uintptr_t jmem_heap_compress_pointer (const void *);
extern void *jmem_heap_decompress_pointer (uintptr_t);
extern bool jmem_is_heap_pointer (const void *);
#ifdef JMEM_STATS
+88 -26
View File
@@ -77,9 +77,6 @@ static void jmem_pools_stat_dealloc (void);
# define VALGRIND_FREYA_FREELIKE_SPACE(p)
#endif /* JERRY_VALGRIND_FREYA */
JERRY_STATIC_ASSERT (sizeof (jmem_pools_chunk_t) <= JMEM_POOL_CHUNK_SIZE,
size_of_mem_pools_chunk_t_must_be_less_than_or_equal_to_MEM_POOL_CHUNK_SIZE);
/**
* Finalize pool manager
*/
@@ -88,7 +85,10 @@ jmem_pools_finalize (void)
{
jmem_pools_collect_empty ();
JERRY_ASSERT (JERRY_CONTEXT (jmem_free_chunk_p) == NULL);
JERRY_ASSERT (JERRY_CONTEXT (jmem_free_8_byte_chunk_p) == NULL);
#ifdef JERRY_CPOINTER_32_BIT
JERRY_ASSERT (JERRY_CONTEXT (jmem_free_16_byte_chunk_p) == NULL);
#endif /* JERRY_CPOINTER_32_BIT */
} /* jmem_pools_finalize */
/**
@@ -98,49 +98,94 @@ jmem_pools_finalize (void)
* or NULL - if not enough memory.
*/
inline void * __attribute__((hot)) __attr_always_inline___
jmem_pools_alloc (void)
jmem_pools_alloc (size_t size) /**< size of the chunk */
{
#ifdef JMEM_GC_BEFORE_EACH_ALLOC
jmem_run_free_unused_memory_callbacks (JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH);
#endif /* JMEM_GC_BEFORE_EACH_ALLOC */
if (JERRY_CONTEXT (jmem_free_chunk_p) != NULL)
if (size <= 8)
{
const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_chunk_p);
if (JERRY_CONTEXT (jmem_free_8_byte_chunk_p) != NULL)
{
const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p);
JMEM_POOLS_STAT_REUSE ();
VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_p->next_p;
VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
return (void *) chunk_p;
}
else
{
JMEM_POOLS_STAT_NEW_ALLOC ();
return (void *) jmem_heap_alloc_block (8);
}
}
#ifdef JERRY_CPOINTER_32_BIT
JERRY_ASSERT (size <= 16);
if (JERRY_CONTEXT (jmem_free_16_byte_chunk_p) != NULL)
{
const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p);
JMEM_POOLS_STAT_REUSE ();
VALGRIND_DEFINED_SPACE (chunk_p, JMEM_POOL_CHUNK_SIZE);
VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
JERRY_CONTEXT (jmem_free_chunk_p) = chunk_p->next_p;
JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_p->next_p;
VALGRIND_UNDEFINED_SPACE (chunk_p, JMEM_POOL_CHUNK_SIZE);
VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
return (void *) chunk_p;
}
else
{
JMEM_POOLS_STAT_NEW_ALLOC ();
return (void *) jmem_heap_alloc_block (JMEM_POOL_CHUNK_SIZE);
return (void *) jmem_heap_alloc_block (16);
}
#else /* !JERRY_CPOINTER_32_BIT */
JERRY_UNREACHABLE ();
return NULL;
#endif
} /* jmem_pools_alloc */
/**
* Free the chunk
*/
void __attribute__((hot))
jmem_pools_free (void *chunk_p) /**< pointer to the chunk */
inline void __attribute__((hot)) __attr_always_inline___
jmem_pools_free (void *chunk_p, /**< pointer to the chunk */
size_t size) /**< size of the chunk */
{
JERRY_ASSERT (chunk_p != NULL);
jmem_pools_chunk_t *const chunk_to_free_p = (jmem_pools_chunk_t *) chunk_p;
VALGRIND_DEFINED_SPACE (chunk_to_free_p, JMEM_POOL_CHUNK_SIZE);
VALGRIND_DEFINED_SPACE (chunk_to_free_p, size);
chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_chunk_p);
JERRY_CONTEXT (jmem_free_chunk_p) = chunk_to_free_p;
if (size <= 8)
{
chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p);
JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_to_free_p;
}
else
{
#ifdef JERRY_CPOINTER_32_BIT
JERRY_ASSERT (size <= 16);
VALGRIND_NOACCESS_SPACE (chunk_to_free_p, JMEM_POOL_CHUNK_SIZE);
chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p);
JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_to_free_p;
#else /* !JERRY_CPOINTER_32_BIT */
JERRY_UNREACHABLE ();
#endif /* JERRY_CPOINTER_32_BIT */
}
VALGRIND_NOACCESS_SPACE (chunk_to_free_p, size);
JMEM_POOLS_STAT_FREE_POOL ();
} /* jmem_pools_free */
@@ -151,16 +196,35 @@ jmem_pools_free (void *chunk_p) /**< pointer to the chunk */
void
jmem_pools_collect_empty ()
{
while (JERRY_CONTEXT (jmem_free_chunk_p))
{
VALGRIND_DEFINED_SPACE (JERRY_CONTEXT (jmem_free_chunk_p), sizeof (jmem_pools_chunk_t));
jmem_pools_chunk_t *const next_p = JERRY_CONTEXT (jmem_free_chunk_p)->next_p;
VALGRIND_NOACCESS_SPACE (JERRY_CONTEXT (jmem_free_chunk_p), sizeof (jmem_pools_chunk_t));
jmem_pools_chunk_t *chunk_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p);
JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = NULL;
jmem_heap_free_block (JERRY_CONTEXT (jmem_free_chunk_p), JMEM_POOL_CHUNK_SIZE);
while (chunk_p)
{
VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
jmem_pools_chunk_t *const next_p = chunk_p->next_p;
VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
jmem_heap_free_block (chunk_p, 8);
JMEM_POOLS_STAT_DEALLOC ();
JERRY_CONTEXT (jmem_free_chunk_p) = next_p;
chunk_p = next_p;
}
#ifdef JERRY_CPOINTER_32_BIT
chunk_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p);
JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = NULL;
while (chunk_p)
{
VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
jmem_pools_chunk_t *const next_p = chunk_p->next_p;
VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
jmem_heap_free_block (chunk_p, 16);
JMEM_POOLS_STAT_DEALLOC ();
chunk_p = next_p;
}
#endif /* JERRY_CPOINTER_32_BIT */
} /* jmem_pools_collect_empty */
#ifdef JMEM_STATS
@@ -193,12 +257,10 @@ jmem_pools_stats_print (void)
jmem_pools_stats_t *pools_stats = &JERRY_CONTEXT (jmem_pools_stats);
JERRY_DEBUG_MSG ("Pools stats:\n"
" Chunk size: %zu\n"
" Pool chunks: %zu\n"
" Peak pool chunks: %zu\n"
" Free chunks: %zu\n"
" Pool reuse ratio: %zu.%04zu\n",
JMEM_POOL_CHUNK_SIZE,
pools_stats->pools_count,
pools_stats->peak_pools_count,
pools_stats->free_chunks,
+2 -2
View File
@@ -30,8 +30,8 @@
*/
extern void jmem_pools_finalize (void);
extern void *jmem_pools_alloc (void);
extern void jmem_pools_free (void *);
extern void *jmem_pools_alloc (size_t);
extern void jmem_pools_free (void *, size_t);
extern void jmem_pools_collect_empty (void);
#ifdef JMEM_STATS
+1 -1
View File
@@ -68,7 +68,7 @@ vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
}
case VM_CONTEXT_FOR_IN:
{
jmem_cpointer_t current = (uint16_t) vm_stack_top_p[-2];
jmem_cpointer_t current = (jmem_cpointer_t) vm_stack_top_p[-2];
while (current != JMEM_CP_NULL)
{