Reduce the memory consumption of function objects. (#1954)
Several properties of strict and bound functions are moved to lazy property instantiation. The memory consumption of bound functions are also reduced when only a this is present. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
committed by
Dániel Bátyai
parent
82a94d0f88
commit
e897858c64
@@ -336,12 +336,23 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
|
||||
ecma_gc_set_object_visited (target_func_obj_p, true);
|
||||
|
||||
ecma_length_t args_length = ext_function_p->u.bound_function.args_length;
|
||||
ecma_value_t args_len_or_this = ext_function_p->u.bound_function.args_len_or_this;
|
||||
|
||||
if (!ecma_is_value_integer_number (args_len_or_this))
|
||||
{
|
||||
if (ecma_is_value_object (args_len_or_this))
|
||||
{
|
||||
ecma_gc_set_object_visited (ecma_get_object_from_value (args_len_or_this), true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ecma_integer_value_t args_length = ecma_get_integer_from_value (args_len_or_this);
|
||||
ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
|
||||
|
||||
JERRY_ASSERT (args_length > 0);
|
||||
|
||||
for (ecma_length_t i = 0; i < args_length; i++)
|
||||
for (ecma_integer_value_t i = 0; i < args_length; i++)
|
||||
{
|
||||
if (ecma_is_value_object (args_p[i]))
|
||||
{
|
||||
@@ -659,15 +670,25 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
|
||||
if (object_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
|
||||
{
|
||||
ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) object_p;
|
||||
ecma_length_t args_length = ext_function_p->u.bound_function.args_length;
|
||||
|
||||
ecma_value_t args_len_or_this = ext_function_p->u.bound_function.args_len_or_this;
|
||||
|
||||
if (!ecma_is_value_integer_number (args_len_or_this))
|
||||
{
|
||||
ecma_free_value_if_not_object (args_len_or_this);
|
||||
ecma_dealloc_extended_object (ext_function_p, sizeof (ecma_extended_object_t));
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_integer_value_t args_length = ecma_get_integer_from_value (args_len_or_this);
|
||||
ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
|
||||
|
||||
for (ecma_length_t i = 0; i < args_length; i++)
|
||||
for (ecma_integer_value_t i = 0; i < args_length; i++)
|
||||
{
|
||||
ecma_free_value_if_not_object (args_p[i]);
|
||||
}
|
||||
|
||||
size_t args_size = args_length * sizeof (ecma_value_t);
|
||||
size_t args_size = ((size_t) args_length) * sizeof (ecma_value_t);
|
||||
ecma_dealloc_extended_object (ext_function_p, sizeof (ecma_extended_object_t) + args_size);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -768,7 +768,7 @@ typedef struct
|
||||
struct
|
||||
{
|
||||
ecma_value_t target_function; /**< target function */
|
||||
ecma_length_t args_length; /**< length of arguments */
|
||||
ecma_value_t args_len_or_this; /**< length of arguments or this value */
|
||||
} bound_function;
|
||||
|
||||
ecma_external_handler_t external_handler_cb; /**< external function */
|
||||
|
||||
@@ -1337,29 +1337,41 @@ ecma_string_raw_chars (const ecma_string_t *string_p, /**< ecma-string */
|
||||
} /* ecma_string_raw_chars */
|
||||
|
||||
/**
|
||||
* Checks whether ecma string is empty or not
|
||||
* Checks whether the string equals to the magic string id.
|
||||
*
|
||||
* @return true - if empty
|
||||
* @return true - if the string equals to the magic string id
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
ecma_string_is_empty (const ecma_string_t *str_p) /**< ecma-string */
|
||||
inline bool __attr_always_inline___
|
||||
ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, /**< property name */
|
||||
lit_magic_string_id_t id) /**< magic string id */
|
||||
{
|
||||
return (ECMA_STRING_GET_CONTAINER (str_p) == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
&& str_p->u.magic_string_id == LIT_MAGIC_STRING__EMPTY);
|
||||
return (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
&& string_p->u.magic_string_id == id);
|
||||
} /* ecma_compare_ecma_string_to_magic_id */
|
||||
|
||||
/**
|
||||
* Checks whether ecma string is empty or not
|
||||
*
|
||||
* @return true - if the string is an empty string
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool __attr_always_inline___
|
||||
ecma_string_is_empty (const ecma_string_t *string_p) /**< ecma-string */
|
||||
{
|
||||
return ecma_compare_ecma_string_to_magic_id (string_p, LIT_MAGIC_STRING__EMPTY);
|
||||
} /* ecma_string_is_empty */
|
||||
|
||||
/**
|
||||
* Checks whether the string equals to "length".
|
||||
*
|
||||
* @return true if the string equals to "length"
|
||||
* false otherwise
|
||||
* @return true - if the string equals to "length"
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool __attr_always_inline___
|
||||
ecma_string_is_length (const ecma_string_t *string_p) /**< property name */
|
||||
{
|
||||
return (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING
|
||||
&& string_p->u.magic_string_id == LIT_MAGIC_STRING_LENGTH);
|
||||
return ecma_compare_ecma_string_to_magic_id (string_p, LIT_MAGIC_STRING_LENGTH);
|
||||
} /* ecma_string_is_length */
|
||||
|
||||
/**
|
||||
|
||||
@@ -201,7 +201,8 @@ const lit_utf8_byte_t *ecma_string_raw_chars (const ecma_string_t *string_p, lit
|
||||
void ecma_init_ecma_string_from_uint32 (ecma_string_t *string_desc_p, uint32_t uint32_number);
|
||||
void ecma_init_ecma_length_string (ecma_string_t *string_desc_p);
|
||||
void ecma_init_ecma_magic_string (ecma_string_t *string_desc_p, lit_magic_string_id_t id);
|
||||
bool ecma_string_is_empty (const ecma_string_t *str_p);
|
||||
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);
|
||||
bool ecma_string_is_empty (const ecma_string_t *string_p);
|
||||
bool ecma_string_is_length (const ecma_string_t *string_p);
|
||||
|
||||
jmem_cpointer_t ecma_string_to_property_name (ecma_string_t *prop_name_p, ecma_property_t *name_type_p);
|
||||
|
||||
Reference in New Issue
Block a user