Skip to content

Create extended objects instead of internal properties. #1163

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 21, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 25 additions & 3 deletions jerry-core/ecma/base/ecma-alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ JERRY_STATIC_ASSERT (sizeof (ecma_property_pair_t) == sizeof (uint64_t) * 2,

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);
Expand Down Expand Up @@ -96,21 +98,41 @@ DECLARE_ROUTINES_FOR (string)
DECLARE_ROUTINES_FOR (getter_setter_pointers)
DECLARE_ROUTINES_FOR (external_pointer)

/**
* Allocate memory for extended object
*
* @return pointer to allocated memory
*/
inline ecma_extended_object_t * __attr_always_inline___
ecma_alloc_extended_object (void)
{
return jmem_heap_alloc_block (sizeof (ecma_extended_object_t));
} /* 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 */
{
jmem_heap_free_block (ext_object_p, sizeof (ecma_extended_object_t));
} /* ecma_dealloc_extended_object */

/**
* Allocate memory for ecma-property pair
*
* @return pointer to allocated memory
*/
ecma_property_pair_t *
inline ecma_property_pair_t * __attr_always_inline___
ecma_alloc_property_pair (void)
{
return jmem_heap_alloc_block (sizeof (ecma_property_pair_t));
} /* ecma_alloc_property_pair */

/**
* Dealloc memory from an ecma-property
* Dealloc memory of an ecma-property
*/
extern void
inline void __attr_always_inline___
ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p) /**< property pair to be freed */
{
jmem_heap_free_block (property_pair_p, sizeof (ecma_property_pair_t));
Expand Down
12 changes: 12 additions & 0 deletions jerry-core/ecma/base/ecma-alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,18 @@ extern ecma_external_pointer_t *ecma_alloc_external_pointer (void);
*/
extern void ecma_dealloc_external_pointer (ecma_external_pointer_t *);

/*
* Allocate memory for extended object
*
* @return pointer to allocated memory
*/
extern ecma_extended_object_t *ecma_alloc_extended_object (void);

/**
* Dealloc memory of an extended object
*/
extern void ecma_dealloc_extended_object (ecma_extended_object_t *);

/**
* Allocate memory for ecma-property pair
*
Expand Down
40 changes: 34 additions & 6 deletions jerry-core/ecma/base/ecma-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,15 +245,10 @@ ecma_gc_mark_property (ecma_property_t *property_p) /**< property */
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_CODE_BYTECODE: /* pointer to a bytecode array */
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* pointer to a regexp 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_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_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */
{
break;
}
Expand Down Expand Up @@ -355,6 +350,17 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
{
ecma_gc_set_object_visited (proto_p, true);
}

if (!ecma_get_object_is_builtin (object_p)
&& ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;

ecma_object_t *scope_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_func_p->u.function.scope_cp);

ecma_gc_set_object_visited (scope_p, true);
}
}

if (traverse_properties)
Expand Down Expand Up @@ -470,6 +476,28 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */
JERRY_ASSERT (ecma_gc_objects_number > 0);
ecma_gc_objects_number--;

if (!ecma_is_lexical_environment (object_p))
{
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);
return;
}

if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
/* Function with byte-code (not a built-in function). */
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;

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);
return;
}
}

ecma_dealloc_object (object_p);
} /* ecma_gc_sweep */

Expand Down
68 changes: 46 additions & 22 deletions jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ typedef int32_t ecma_integer_value_t;
#define ECMA_IS_VALUE_ERROR(value) \
(unlikely ((value & ECMA_VALUE_ERROR_FLAG) != 0))

/**
* Representation for native external pointer
*/
typedef uintptr_t ecma_external_pointer_t;

/**
* Internal properties' identifiers.
*/
Expand All @@ -186,10 +191,8 @@ typedef enum
ECMA_INTERNAL_PROPERTY_CLASS, /**< [[Class]] */
ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */
ECMA_INTERNAL_PROPERTY_CODE_BYTECODE, /**< pointer to compact bytecode array */
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE, /**< pointer to RegExp bytecode array */

ECMA_INTERNAL_PROPERTY_NATIVE_CODE, /**< native handler location descriptor */
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 */
Expand All @@ -200,20 +203,8 @@ typedef enum
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_THIS,
ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_BOUND_ARGS,

ECMA_INTERNAL_PROPERTY_BUILT_IN_ID, /**< Implementation-defined identifier of built-in object */

ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC, /**< Implementation-defined identifier of built-in routine
* that corresponds to a built-in function object
* ([[Built-in routine's description]])
*/

ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31, /**< Bit-mask of non-instantiated
* built-in's properties (bits 0-31)
*/

ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63, /**< Bit-mask of non-instantiated
* built-in's properties (bits 32-63)
*/
ECMA_INTERNAL_PROPERTY_INSTANTIATED_MASK_32_63, /**< Bit-mask of non-instantiated
* built-in's properties (bits 32-63) */

ECMA_INTERNAL_PROPERTY__COUNT /**< Number of internal properties' types */
} ecma_internal_property_id_t;
Expand Down Expand Up @@ -526,6 +517,44 @@ typedef struct ecma_object_t
jmem_cpointer_t prototype_or_outer_reference_cp;
} ecma_object_t;

/**
* Description of extended ECMA-object.
*
* The extended object is an object with extra fields.
*/
typedef struct
{
ecma_object_t object; /**< object header */

/*
* Description of extra fields. These extra fields depends on the object type.
*/
union
{
/*
* Description of built-in objects.
*/
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;

/*
* Description of function objects.
*/
struct
{
ecma_value_t scope_cp; /**< function scope */
ecma_value_t bytecode_cp; /**< function byte code */
} function;

ecma_external_pointer_t external_function; /**< external function */
} u;
} ecma_extended_object_t;

/**
* Description of ECMA property descriptor
*
Expand Down Expand Up @@ -870,14 +899,9 @@ typedef struct ecma_string_t
} u;
} ecma_string_t;

/**
* Representation for native external pointer
*/
typedef uintptr_t ecma_external_pointer_t;

/**
* Compiled byte code data.
*/
*/
typedef struct
{
uint16_t size; /**< real size >> JMEM_ALIGNMENT_LOG */
Expand Down
12 changes: 3 additions & 9 deletions jerry-core/ecma/base/ecma-helpers-external-pointers.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
*
* Note:
* property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*
Expand All @@ -43,8 +42,7 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea
* property to create */
ecma_external_pointer_t ptr_value) /**< value to store in the property */
{
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|| id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);

bool is_new;
Expand Down Expand Up @@ -96,7 +94,6 @@ ecma_create_external_pointer_property (ecma_object_t *obj_p, /**< object to crea
*
* Note:
* property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*
Expand All @@ -109,8 +106,7 @@ ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get proper
* to get value from */
ecma_external_pointer_t *out_pointer_p) /**< [out] value of the external pointer */
{
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|| id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
JERRY_ASSERT (id == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| id == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);

ecma_property_t *prop_p = ecma_find_internal_property (obj_p, id);
Expand Down Expand Up @@ -142,15 +138,13 @@ ecma_get_external_pointer_value (ecma_object_t *obj_p, /**< object to get proper
*
* Note:
* property identifier should be one of the following:
* - ECMA_INTERNAL_PROPERTY_NATIVE_CODE;
* - ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE;
* - ECMA_INTERNAL_PROPERTY_FREE_CALLBACK.
*/
void
ecma_free_external_pointer_in_property (ecma_property_t *prop_p) /**< internal property */
{
JERRY_ASSERT (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_NATIVE_CODE
|| ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
JERRY_ASSERT (ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE
|| ECMA_PROPERTY_GET_INTERNAL_PROPERTY_TYPE (prop_p) == ECMA_INTERNAL_PROPERTY_FREE_CALLBACK);

#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
Expand Down
16 changes: 4 additions & 12 deletions jerry-core/ecma/base/ecma-helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,12 @@ 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 */
ecma_object_type_t type) /**< object type */
{
ecma_object_t *new_object_p = ecma_alloc_object ();
ecma_object_t *new_object_p = (is_extended ? ((ecma_object_t *) ecma_alloc_extended_object ())
: ecma_alloc_object ());

uint16_t type_flags = (uint16_t) type;

Expand Down Expand Up @@ -805,7 +807,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
break;
}

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 external pointer */
{
Expand All @@ -817,10 +818,7 @@ 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_BUILT_IN_ID: /* an integer */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC: /* 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_INSTANTIATED_MASK_32_63: /* an integer (bit-mask) */
case ECMA_INTERNAL_PROPERTY_BOUND_FUNCTION_TARGET_FUNCTION:
{
break;
Expand Down Expand Up @@ -850,12 +848,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
break;
}

case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */
{
ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t, property_value));
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);
Expand Down
2 changes: 1 addition & 1 deletion jerry-core/ecma/base/ecma-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,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, ecma_object_type_t);
extern ecma_object_t *ecma_create_object (ecma_object_t *, bool, bool, 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___;
Expand Down
1 change: 1 addition & 0 deletions jerry-core/ecma/builtin-objects/ecma-builtin-date.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<

ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE);
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
false,
true,
ECMA_OBJECT_TYPE_GENERAL);
ecma_deref_object (prototype_obj_p);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,10 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar
{
/* 4. 11. 18. */
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
ecma_object_t *function_p = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_BOUND_FUNCTION);
ecma_object_t *function_p = ecma_create_object (prototype_obj_p,
false,
true,
ECMA_OBJECT_TYPE_BOUND_FUNCTION);

ecma_deref_object (prototype_obj_p);

Expand Down
Loading