Skip to content

Commit

Permalink
Rearrange fields of ecma_property_t to be naturally aligned. Packed a…
Browse files Browse the repository at this point in the history
…ttribute and __extension__ keywords are removed. The standard approach reduced the binary size by 2K.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg [email protected]
  • Loading branch information
zherczeg committed Mar 3, 2016
1 parent 86cdc4b commit b8b587f
Show file tree
Hide file tree
Showing 31 changed files with 375 additions and 423 deletions.
173 changes: 82 additions & 91 deletions jerry-core/ecma/base/ecma-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,130 +289,121 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
next_property_p = ECMA_GET_POINTER (ecma_property_t,
property_p->next_property_p);

switch ((ecma_property_type_t) property_p->type)
if (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDDATA)
{
case ECMA_PROPERTY_NAMEDDATA:
{
ecma_value_t value = ecma_get_named_data_property_value (property_p);
ecma_value_t value = ecma_get_named_data_property_value (property_p);

if (ecma_is_value_object (value))
{
ecma_object_t *value_obj_p = ecma_get_object_from_value (value);
if (ecma_is_value_object (value))
{
ecma_object_t *value_obj_p = ecma_get_object_from_value (value);

ecma_gc_set_object_visited (value_obj_p, true);
}
ecma_gc_set_object_visited (value_obj_p, true);
}
}
else if (property_p->flags & ECMA_PROPERTY_FLAG_NAMEDACCESSOR)
{
ecma_object_t *getter_obj_p = ecma_get_named_accessor_property_getter (property_p);
ecma_object_t *setter_obj_p = ecma_get_named_accessor_property_setter (property_p);

break;
if (getter_obj_p != NULL)
{
ecma_gc_set_object_visited (getter_obj_p, true);
}

case ECMA_PROPERTY_NAMEDACCESSOR:
if (setter_obj_p != NULL)
{
ecma_object_t *getter_obj_p = ecma_get_named_accessor_property_getter (property_p);
ecma_object_t *setter_obj_p = ecma_get_named_accessor_property_setter (property_p);
ecma_gc_set_object_visited (setter_obj_p, true);
}
}
else
{
JERRY_ASSERT (property_p->flags & ECMA_PROPERTY_FLAG_INTERNAL);

ecma_internal_property_id_t property_id = (ecma_internal_property_id_t) property_p->h.internal_property_type;
uint32_t property_value = property_p->v.internal_property.value;

if (getter_obj_p != NULL)
switch (property_id)
{
case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* a collection of ecma values */
case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* a collection of ecma values */
{
ecma_gc_set_object_visited (getter_obj_p, true);
JERRY_UNIMPLEMENTED ("Indexed array storage is not implemented yet.");
}

if (setter_obj_p != NULL)
case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_object_t
(see above in the routine) */
case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_object_t
(see above in the routine) */
case ECMA_INTERNAL_PROPERTY__COUNT: /* not a real internal property type,
* but number of the real internal property types */
{
ecma_gc_set_object_visited (setter_obj_p, true);
JERRY_UNREACHABLE ();
}

break;
}

case ECMA_PROPERTY_INTERNAL:
{
ecma_internal_property_id_t property_id = (ecma_internal_property_id_t) property_p->u.internal_property.type;
uint32_t property_value = property_p->u.internal_property.value;
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE: /* compressed pointer to a ecma_string_t */
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE: /* compressed pointer to a ecma_number_t */
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE: /* a simple boolean value */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */
case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */
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_BUILT_IN_ID: /* an integer */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC: /* an integer */
case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */
case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE:
{
break;
}

switch (property_id)
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS: /* an ecma value */
{
case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* a collection of ecma values */
case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* a collection of ecma values */
if (ecma_is_value_object (property_value))
{
JERRY_UNIMPLEMENTED ("Indexed array storage is not implemented yet.");
}
ecma_object_t *obj_p = ecma_get_object_from_value (property_value);

case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_object_t
(see above in the routine) */
case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_object_t
(see above in the routine) */
case ECMA_INTERNAL_PROPERTY__COUNT: /* not a real internal property type,
* but number of the real internal property types */
{
JERRY_UNREACHABLE ();
}

case ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE: /* compressed pointer to a ecma_string_t */
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE: /* compressed pointer to a ecma_number_t */
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE: /* a simple boolean value */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */
case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */
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_BUILT_IN_ID: /* an integer */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC: /* an integer */
case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */
case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE:
{
break;
ecma_gc_set_object_visited (obj_p, true);
}

case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS: /* an ecma value */
{
if (ecma_is_value_object (property_value))
{
ecma_object_t *obj_p = ecma_get_object_from_value (property_value);
break;
}

ecma_gc_set_object_visited (obj_p, true);
}
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS: /* a collection of ecma values */
{
ecma_collection_header_t *bound_arg_list_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t,
property_value);

break;
}
ecma_collection_iterator_t bound_args_iterator;
ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p);

case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS: /* a collection of ecma values */
for (ecma_length_t i = 0; i < bound_arg_list_p->unit_number; i++)
{
ecma_collection_header_t *bound_arg_list_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t,
property_value);

ecma_collection_iterator_t bound_args_iterator;
ecma_collection_iterator_init (&bound_args_iterator, bound_arg_list_p);
bool is_moved = ecma_collection_iterator_next (&bound_args_iterator);
JERRY_ASSERT (is_moved);

for (ecma_length_t i = 0; i < bound_arg_list_p->unit_number; i++)
if (ecma_is_value_object (*bound_args_iterator.current_value_p))
{
bool is_moved = ecma_collection_iterator_next (&bound_args_iterator);
JERRY_ASSERT (is_moved);
ecma_object_t *obj_p = ecma_get_object_from_value (*bound_args_iterator.current_value_p);

if (ecma_is_value_object (*bound_args_iterator.current_value_p))
{
ecma_object_t *obj_p = ecma_get_object_from_value (*bound_args_iterator.current_value_p);

ecma_gc_set_object_visited (obj_p, true);
}
ecma_gc_set_object_visited (obj_p, true);
}

break;
}

case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION: /* an object */
case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */
case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */
{
ecma_object_t *obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, property_value);
break;
}

ecma_gc_set_object_visited (obj_p, true);
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION: /* an object */
case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */
case ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP: /* an object */
{
ecma_object_t *obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, property_value);

break;
}
}
ecma_gc_set_object_visited (obj_p, true);

break;
break;
}
}
}
}
Expand Down
96 changes: 40 additions & 56 deletions jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,6 @@ typedef enum
ECMA_SIMPLE_VALUE__COUNT /** count of simple ecma values */
} ecma_simple_value_t;

/**
* Type of ecma-property
*/
typedef enum
{
ECMA_PROPERTY_NAMEDDATA, /**< named data property */
ECMA_PROPERTY_NAMEDACCESSOR, /**< named accessor property */
ECMA_PROPERTY_INTERNAL /**< internal property */
} ecma_property_type_t;

/**
* Description of an ecma value
*
Expand Down Expand Up @@ -213,84 +203,78 @@ typedef enum
} ecma_property_configurable_value_t;

/**
* Width of internal property type field's width
* Property's flag list.
*/
#define ECMA_PROPERTY_INTERNAL_PROPERTY_TYPE_WIDTH (5)
typedef enum
{
ECMA_PROPERTY_FLAG_NAMEDDATA = 1u << 0, /**< property is named data */
ECMA_PROPERTY_FLAG_NAMEDACCESSOR = 1u << 1, /**< property is named accessor */
ECMA_PROPERTY_FLAG_INTERNAL = 1u << 2, /**< property is internal property */
ECMA_PROPERTY_FLAG_CONFIGURABLE = 1u << 3, /**< property is configurable */
ECMA_PROPERTY_FLAG_ENUMERABLE = 1u << 4, /**< property is enumerable */
ECMA_PROPERTY_FLAG_WRITABLE = 1u << 5, /**< property is writable */
ECMA_PROPERTY_FLAG_LCACHED = 1u << 6, /**< property is lcached */
} ecma_property_flags_t;

/**
* Pair of pointers - to property's getter and setter
*/
typedef struct
{
__extension__ mem_cpointer_t getter_p : ECMA_POINTER_FIELD_WIDTH; /**< pointer to getter object */
__extension__ mem_cpointer_t setter_p : ECMA_POINTER_FIELD_WIDTH; /**< pointer to setter object */
mem_cpointer_t getter_p; /**< pointer to getter object */
mem_cpointer_t setter_p; /**< pointer to setter object */
} ecma_getter_setter_pointers_t;

/**
* Description of ecma-property
*/
typedef struct __attr_packed___ ecma_property_t
typedef struct ecma_property_t
{
/** Property's type (ecma_property_type_t) */
unsigned int type : 2;

/** Compressed pointer to next property */
__extension__ mem_cpointer_t next_property_p : ECMA_POINTER_FIELD_WIDTH;
mem_cpointer_t next_property_p;

/** Property's flags (ecma_property_flags_t) */
uint8_t flags;

/** Property's details (depending on Type) */
/** Property's header part (depending on Type) */
union
{
/** Description of named data property */
struct __attr_packed___ ecma_named_data_property_t
{
/** Value */
__extension__ ecma_value_t value : ECMA_VALUE_SIZE;
/** Named data property value upper bits */
uint8_t named_data_property_value_high;
/** Internal property type */
uint8_t internal_property_type;
} h;

/** Property's value part (depending on Type) */
union
{
/** Description of named data property (second part) */
struct
{
/** Compressed pointer to property's name (pointer to String) */
__extension__ mem_cpointer_t name_p : ECMA_POINTER_FIELD_WIDTH;

/** Flag indicating whether the property is registered in LCache */
unsigned int is_lcached : 1;

/** Attribute 'Writable' (ecma_property_writable_value_t) */
unsigned int writable : 1;

/** Attribute 'Enumerable' (ecma_property_enumerable_value_t) */
unsigned int enumerable : 1;
mem_cpointer_t name_p;

/** Attribute 'Configurable' (ecma_property_configurable_value_t) */
unsigned int configurable : 1;
/** Lower 16 bits of value */
uint16_t value_low;
} named_data_property;

/** Description of named accessor property */
struct __attr_packed___ ecma_named_accessor_property_t
/** Description of named accessor property (second part) */
struct
{
/** Compressed pointer to property's name (pointer to String) */
__extension__ mem_cpointer_t name_p : ECMA_POINTER_FIELD_WIDTH;

/** Attribute 'Enumerable' (ecma_property_enumerable_value_t) */
unsigned int enumerable : 1;

/** Attribute 'Configurable' (ecma_property_configurable_value_t) */
unsigned int configurable : 1;

/** Flag indicating whether the property is registered in LCache */
unsigned int is_lcached : 1;
mem_cpointer_t name_p;

/** Compressed pointer to pair of pointers - to property's getter and setter */
__extension__ mem_cpointer_t getter_setter_pair_cp : ECMA_POINTER_FIELD_WIDTH;
mem_cpointer_t getter_setter_pair_cp;
} named_accessor_property;

/** Description of internal property */
struct __attr_packed___ ecma_internal_property_t
/** Description of internal property (second part) */
struct
{
/** Internal property's type */
unsigned int type : ECMA_PROPERTY_INTERNAL_PROPERTY_TYPE_WIDTH;

/** Value (may be a compressed pointer) */
uint32_t value;
} internal_property;
} u;
} v;
} ecma_property_t;

/**
Expand Down
Loading

0 comments on commit b8b587f

Please sign in to comment.