Remove several internal property types for primitive objects. (#1399)

Class and value internal properties are always exists for primitive
types (e.g. Boolean, Regex) so they can be stored right after the
object. This improve property access (since internal properties are
searched by a slow linear algorithm) and reduces memory consumption,
since only 8 byte is allocated for these two properties instead of
16 which is the size of a property pair.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-10-19 15:36:15 +02:00
committed by GitHub
parent 2ef89eafbf
commit fd98d649b6
29 changed files with 487 additions and 419 deletions
+5 -4
View File
@@ -92,18 +92,19 @@ DECLARE_ROUTINES_FOR (external_pointer)
* @return pointer to allocated memory
*/
inline ecma_extended_object_t * __attr_always_inline___
ecma_alloc_extended_object (void)
ecma_alloc_extended_object (size_t size) /**< size of object */
{
return jmem_heap_alloc_block (sizeof (ecma_extended_object_t));
return jmem_heap_alloc_block (size);
} /* ecma_alloc_extended_object */
/**
* Dealloc memory of an extended object
*/
inline void __attr_always_inline___
ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p) /**< property pair to be freed */
ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, /**< property pair to be freed */
size_t size) /**< size of object */
{
jmem_heap_free_block (ext_object_p, sizeof (ecma_extended_object_t));
jmem_heap_free_block (ext_object_p, size);
} /* ecma_dealloc_extended_object */
/**
+2 -2
View File
@@ -114,12 +114,12 @@ extern void ecma_dealloc_external_pointer (ecma_external_pointer_t *);
*
* @return pointer to allocated memory
*/
extern ecma_extended_object_t *ecma_alloc_extended_object (void);
extern ecma_extended_object_t *ecma_alloc_extended_object (size_t);
/**
* Dealloc memory of an extended object
*/
extern void ecma_dealloc_extended_object (ecma_extended_object_t *);
extern void ecma_dealloc_extended_object (ecma_extended_object_t *, size_t);
/**
* Allocate memory for ecma-property pair
+56 -6
View File
@@ -203,10 +203,6 @@ ecma_gc_mark_property (ecma_property_t *property_p) /**< property */
switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p))
{
case ECMA_INTERNAL_PROPERTY_ECMA_VALUE: /* an ecma_value_t except object */
case ECMA_INTERNAL_PROPERTY_DATE_FLOAT: /* pointer to a ecma_number_t */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* pointer to a regexp bytecode array */
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an object's native free callback */
case ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */
@@ -440,10 +436,64 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
if (!ecma_is_lexical_environment (object_p))
{
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
switch (ext_object_p->u.class_prop.class_id)
{
/* The undefined id represents an uninitialized class. */
case LIT_MAGIC_STRING_UNDEFINED:
case LIT_MAGIC_STRING_ARGUMENTS_UL:
case LIT_MAGIC_STRING_BOOLEAN_UL:
case LIT_MAGIC_STRING_ERROR_UL:
{
break;
}
case LIT_MAGIC_STRING_STRING_UL:
case LIT_MAGIC_STRING_NUMBER_UL:
{
ecma_free_value (ext_object_p->u.class_prop.value);
break;
}
case LIT_MAGIC_STRING_DATE_UL:
{
ecma_number_t *num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t,
ext_object_p->u.class_prop.value);
ecma_dealloc_number (num_p);
break;
}
case LIT_MAGIC_STRING_REGEXP_UL:
{
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
ext_object_p->u.class_prop.value);
if (bytecode_p != NULL)
{
ecma_bytecode_deref (bytecode_p);
}
break;
}
default:
{
JERRY_UNREACHABLE ();
break;
}
}
size_t size = (ecma_get_object_is_builtin (object_p) ? sizeof (ecma_extended_built_in_object_t)
: sizeof (ecma_extended_object_t));
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, size);
return;
}
if (ecma_get_object_is_builtin (object_p)
|| ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
{
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p);
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, sizeof (ecma_extended_object_t));
return;
}
@@ -455,7 +505,7 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
ext_func_p->u.function.bytecode_cp));
ecma_dealloc_extended_object (ext_func_p);
ecma_dealloc_extended_object (ext_func_p, sizeof (ecma_extended_object_t));
return;
}
}
+30 -14
View File
@@ -197,15 +197,11 @@ typedef uintptr_t ecma_external_pointer_t;
*/
typedef enum
{
ECMA_INTERNAL_PROPERTY_CLASS, /**< [[Class]] */
ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE, /**< pointer to RegExp bytecode array */
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */
ECMA_INTERNAL_PROPERTY_FREE_CALLBACK, /**< object's native free callback */
ECMA_INTERNAL_PROPERTY_ECMA_VALUE, /**< [[Primitive value]] for String, Number, and Boolean */
ECMA_INTERNAL_PROPERTY_DATE_FLOAT, /**< float number value type for date objects */
/** Bound function internal properties **/
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION,
@@ -479,10 +475,10 @@ typedef enum
{
ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not String (15.5),
* Function (15.3), Arguments (10.6), Array (15.4) objects */
ECMA_OBJECT_TYPE_FUNCTION = 1, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 2, /**< External (host) function object */
ECMA_OBJECT_TYPE_ARRAY = 3, /**< Array object (15.4) */
ECMA_OBJECT_TYPE_STRING = 4, /**< String objects (15.5) */
ECMA_OBJECT_TYPE_CLASS = 1, /**< Objects with class property */
ECMA_OBJECT_TYPE_FUNCTION = 2, /**< Function objects (15.3), created through 13.2 routine */
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 3, /**< External (host) function object */
ECMA_OBJECT_TYPE_ARRAY = 4, /**< Array object (15.4) */
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 5, /**< Function objects (15.3), created through 15.3.4.5 routine */
ECMA_OBJECT_TYPE_ARGUMENTS = 6, /**< Arguments object (10.6) */
@@ -565,6 +561,17 @@ typedef struct
jmem_cpointer_t prototype_or_outer_reference_cp;
} ecma_object_t;
/**
* Description of built-in properties of an object.
*/
typedef struct
{
uint8_t id; /**< built-in id */
uint8_t length; /**< length for built-in functions */
uint16_t routine_id; /**< routine id for built-in functions */
uint32_t instantiated_bitset; /**< bit set for instantiated properties */
} ecma_built_in_props_t;
/**
* Description of extended ECMA-object.
*
@@ -579,16 +586,16 @@ typedef struct
*/
union
{
ecma_built_in_props_t built_in; /**< built-in object part */
/*
* Description of built-in objects.
* Description of objects with class.
*/
struct
{
uint8_t id; /**< built-in id */
uint8_t length; /**< length for built-in functions */
uint16_t routine_id; /**< routine id for built-in functions */
uint32_t instantiated_bitset; /**< bit set for instantiated properties */
} built_in;
uint16_t class_id; /**< class id of the object */
ecma_value_t value; /**< value of the object (e.g. boolean, number, string, etc.) */
} class_prop;
/*
* Description of function objects.
@@ -603,6 +610,15 @@ typedef struct
} u;
} ecma_extended_object_t;
/**
* Description of built-in extended ECMA-object.
*/
typedef struct
{
ecma_extended_object_t extended_object; /**< extended object part */
ecma_built_in_props_t built_in; /**< built-in object part */
} ecma_extended_built_in_object_t;
/**
* Description of ECMA property descriptor
*
+9 -37
View File
@@ -90,21 +90,21 @@ JERRY_STATIC_ASSERT ((ECMA_OBJECT_MAX_REF | (ECMA_OBJECT_REF_ONE - 1)) == UINT16
*/
ecma_object_t *
ecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe of the object (or NULL) */
bool is_extended, /**< extended object */
bool is_extensible, /**< value of extensible attribute */
size_t ext_object_size, /**< size of extended objects */
ecma_object_type_t type) /**< object type */
{
ecma_object_t *new_object_p = (is_extended ? ((ecma_object_t *) ecma_alloc_extended_object ())
: ecma_alloc_object ());
ecma_object_t *new_object_p;
uint16_t type_flags = (uint16_t) type;
if (is_extensible)
if (ext_object_size > 0)
{
type_flags = (uint16_t) (type_flags | ECMA_OBJECT_FLAG_EXTENSIBLE);
new_object_p = (ecma_object_t *) ecma_alloc_extended_object (ext_object_size);
}
else
{
new_object_p = ecma_alloc_object ();
}
new_object_p->type_flags_refs = type_flags;
new_object_p->type_flags_refs = (uint16_t) (type | ECMA_OBJECT_FLAG_EXTENSIBLE);
ecma_init_gc_info (new_object_p);
@@ -775,22 +775,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
switch (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (property_p))
{
case ECMA_INTERNAL_PROPERTY_ECMA_VALUE: /* ecma-value property except object */
{
JERRY_ASSERT (!ecma_is_value_object (property_value));
ecma_free_value (property_value);
break;
}
case ECMA_INTERNAL_PROPERTY_DATE_FLOAT: /* pointer to a ecma_number_t */
{
ecma_number_t *num_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, property_value);
ecma_dealloc_number (num_p);
break;
}
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an external pointer */
{
@@ -801,7 +785,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */
case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION:
{
@@ -831,17 +814,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
JERRY_UNREACHABLE ();
break;
}
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* compressed pointer to a regexp bytecode array */
{
ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, property_value);
if (bytecode_p != NULL)
{
ecma_bytecode_deref (bytecode_p);
}
break;
}
}
} /* ecma_free_internal_property */
+1 -1
View File
@@ -250,7 +250,7 @@ extern bool
ecma_collection_iterator_next (ecma_collection_iterator_t *);
/* ecma-helpers.c */
extern ecma_object_t *ecma_create_object (ecma_object_t *, bool, bool, ecma_object_type_t);
extern ecma_object_t *ecma_create_object (ecma_object_t *, size_t, ecma_object_type_t);
extern ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *);
extern ecma_object_t *ecma_create_object_lex_env (ecma_object_t *, ecma_object_t *, bool);
extern bool ecma_is_lexical_environment (const ecma_object_t *) __attr_pure___;