Add ecma_fast_copy_value and ecma_fast_free_value to improve performance of hot paths.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-05-23 02:12:52 -07:00
parent 9f29cc168d
commit 53414b2c88
3 changed files with 54 additions and 17 deletions
+35
View File
@@ -614,6 +614,23 @@ ecma_copy_value (ecma_value_t value) /**< value description */
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
} /* ecma_copy_value */ } /* ecma_copy_value */
/**
* Copy ecma value.
*
* Note:
* this function is similar to ecma_copy_value, but it is
* faster for direct values since no function call is performed.
* It also increases the binary size so it is recommended for
* critical code paths only.
*
* @return copy of the given value
*/
inline ecma_value_t __attr_always_inline___
ecma_fast_copy_value (ecma_value_t value) /**< value description */
{
return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT) ? value : ecma_copy_value (value);
} /* ecma_fast_copy_value */
/** /**
* Copy the ecma value if not an object * Copy the ecma value if not an object
* *
@@ -778,6 +795,24 @@ ecma_free_value (ecma_value_t value) /**< value description */
} }
} /* ecma_free_value */ } /* ecma_free_value */
/**
* Free the ecma value
*
* Note:
* this function is similar to ecma_free_value, but it is
* faster for direct values since no function call is performed.
* It also increases the binary size so it is recommended for
* critical code paths only.
*/
inline void __attr_always_inline___
ecma_fast_free_value (ecma_value_t value) /**< value description */
{
if (ecma_get_value_type_field (value) != ECMA_TYPE_DIRECT)
{
ecma_free_value (value);
}
} /* ecma_fast_free_value */
/** /**
* Free the ecma value if not an object * Free the ecma value if not an object
*/ */
+2
View File
@@ -149,11 +149,13 @@ extern ecma_string_t *ecma_get_string_from_value (ecma_value_t) __attr_pure___;
extern ecma_object_t *ecma_get_object_from_value (ecma_value_t) __attr_pure___; extern ecma_object_t *ecma_get_object_from_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_get_value_from_error_value (ecma_value_t) __attr_pure___; extern ecma_value_t ecma_get_value_from_error_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_copy_value (ecma_value_t); extern ecma_value_t ecma_copy_value (ecma_value_t);
extern ecma_value_t ecma_fast_copy_value (ecma_value_t);
extern ecma_value_t ecma_copy_value_if_not_object (ecma_value_t); extern ecma_value_t ecma_copy_value_if_not_object (ecma_value_t);
extern void ecma_value_assign_value (ecma_value_t *, ecma_value_t); extern void ecma_value_assign_value (ecma_value_t *, ecma_value_t);
extern void ecma_value_assign_number (ecma_value_t *, ecma_number_t); extern void ecma_value_assign_number (ecma_value_t *, ecma_number_t);
extern void ecma_value_assign_uint32 (ecma_value_t *, uint32_t); extern void ecma_value_assign_uint32 (ecma_value_t *, uint32_t);
extern void ecma_free_value (ecma_value_t); extern void ecma_free_value (ecma_value_t);
extern void ecma_fast_free_value (ecma_value_t);
extern void ecma_free_value_if_not_object (ecma_value_t); extern void ecma_free_value_if_not_object (ecma_value_t);
/* ecma-helpers-string.c */ /* ecma-helpers-string.c */
+17 -17
View File
@@ -387,7 +387,7 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
/* Free registers. */ /* Free registers. */
for (uint32_t i = 0; i < arguments_list_len; i++) for (uint32_t i = 0; i < arguments_list_len; i++)
{ {
ecma_free_value (stack_top_p[i]); ecma_fast_free_value (stack_top_p[i]);
} }
if (is_call_prop) if (is_call_prop)
@@ -442,7 +442,7 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
/* Free registers. */ /* Free registers. */
for (uint32_t i = 0; i < arguments_list_len; i++) for (uint32_t i = 0; i < arguments_list_len; i++)
{ {
ecma_free_value (stack_top_p[i]); ecma_fast_free_value (stack_top_p[i]);
} }
ecma_free_value (stack_top_p[-1]); ecma_free_value (stack_top_p[-1]);
@@ -482,7 +482,7 @@ enum
if ((literal_index) < register_end) \ if ((literal_index) < register_end) \
{ \ { \
/* Note: There should be no specialization for arguments. */ \ /* Note: There should be no specialization for arguments. */ \
(target_value) = ecma_copy_value (frame_ctx_p->registers_p[literal_index]); \ (target_value) = ecma_fast_copy_value (frame_ctx_p->registers_p[literal_index]); \
target_free_op; \ target_free_op; \
} \ } \
else \ else \
@@ -2182,13 +2182,13 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (literal_index < register_end) if (literal_index < register_end)
{ {
ecma_free_value (frame_ctx_p->registers_p[literal_index]); ecma_fast_free_value (frame_ctx_p->registers_p[literal_index]);
frame_ctx_p->registers_p[literal_index] = result; frame_ctx_p->registers_p[literal_index] = result;
if (opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)) if (opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))
{ {
result = ecma_copy_value (result); result = ecma_fast_copy_value (result);
} }
} }
else else
@@ -2215,7 +2215,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))) if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)))
{ {
ecma_free_value (result); ecma_fast_free_value (result);
} }
} }
} }
@@ -2226,13 +2226,13 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (object == ecma_make_simple_value (ECMA_SIMPLE_VALUE_REGISTER_REF)) if (object == ecma_make_simple_value (ECMA_SIMPLE_VALUE_REGISTER_REF))
{ {
ecma_free_value (frame_ctx_p->registers_p[property]); ecma_fast_free_value (frame_ctx_p->registers_p[property]);
frame_ctx_p->registers_p[property] = result; frame_ctx_p->registers_p[property] = result;
if (opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)) if (opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))
{ {
result = ecma_copy_value (result); result = ecma_fast_copy_value (result);
} }
} }
else else
@@ -2253,7 +2253,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))) if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)))
{ {
ecma_free_value (result); ecma_fast_free_value (result);
} }
} }
} }
@@ -2264,31 +2264,31 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
} }
else if (opcode_data & VM_OC_PUT_BLOCK) else if (opcode_data & VM_OC_PUT_BLOCK)
{ {
ecma_free_value (block_result); ecma_fast_free_value (block_result);
block_result = result; block_result = result;
} }
} }
if (free_flags & VM_FREE_LEFT_VALUE) if (free_flags & VM_FREE_LEFT_VALUE)
{ {
ecma_free_value (left_value); ecma_fast_free_value (left_value);
} }
if (free_flags & VM_FREE_RIGHT_VALUE) if (free_flags & VM_FREE_RIGHT_VALUE)
{ {
ecma_free_value (right_value); ecma_fast_free_value (right_value);
} }
} }
error: error:
if (free_flags & VM_FREE_LEFT_VALUE) if (free_flags & VM_FREE_LEFT_VALUE)
{ {
ecma_free_value (left_value); ecma_fast_free_value (left_value);
} }
if (free_flags & VM_FREE_RIGHT_VALUE) if (free_flags & VM_FREE_RIGHT_VALUE)
{ {
ecma_free_value (right_value); ecma_fast_free_value (right_value);
} }
if (unlikely (ecma_is_value_error (last_completion_value))) if (unlikely (ecma_is_value_error (last_completion_value)))
@@ -2319,7 +2319,7 @@ error:
{ {
/* In most cases there is no context. */ /* In most cases there is no context. */
ecma_free_value (block_result); ecma_fast_free_value (block_result);
return last_completion_value; return last_completion_value;
} }
@@ -2438,7 +2438,7 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
for (uint32_t i = 0; i < arg_list_len; i++) for (uint32_t i = 0; i < arg_list_len; i++)
{ {
frame_ctx_p->registers_p[i] = ecma_copy_value (arg_p[i]); frame_ctx_p->registers_p[i] = ecma_fast_copy_value (arg_p[i]);
} }
/* The arg_list_len contains the end of the copied arguments. /* The arg_list_len contains the end of the copied arguments.
@@ -2486,7 +2486,7 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
/* Free arguments and registers */ /* Free arguments and registers */
for (uint32_t i = 0; i < register_end; i++) for (uint32_t i = 0; i < register_end; i++)
{ {
ecma_free_value (frame_ctx_p->registers_p[i]); ecma_fast_free_value (frame_ctx_p->registers_p[i]);
} }
vm_top_context_p = prev_context_p; vm_top_context_p = prev_context_p;