diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c index 76eb83fc2..f5c77f61a 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.c +++ b/jerry-core/ecma/base/ecma-helpers-value.c @@ -614,6 +614,23 @@ ecma_copy_value (ecma_value_t value) /**< value description */ JERRY_UNREACHABLE (); } /* 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 * @@ -778,6 +795,24 @@ ecma_free_value (ecma_value_t value) /**< value description */ } } /* 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 */ diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index d039ae285..0833e5496 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -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_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_fast_copy_value (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_number (ecma_value_t *, ecma_number_t); extern void ecma_value_assign_uint32 (ecma_value_t *, uint32_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); /* ecma-helpers-string.c */ diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index d7030983b..ddfb944f4 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -387,7 +387,7 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ /* Free registers. */ 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) @@ -442,7 +442,7 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ /* Free registers. */ 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]); @@ -482,7 +482,7 @@ enum if ((literal_index) < register_end) \ { \ /* 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; \ } \ else \ @@ -2182,13 +2182,13 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ 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; if (opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)) { - result = ecma_copy_value (result); + result = ecma_fast_copy_value (result); } } 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))) { - 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)) { - 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; if (opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)) { - result = ecma_copy_value (result); + result = ecma_fast_copy_value (result); } } 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))) { - 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) { - ecma_free_value (block_result); + ecma_fast_free_value (block_result); block_result = result; } } 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) { - ecma_free_value (right_value); + ecma_fast_free_value (right_value); } } error: 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) { - ecma_free_value (right_value); + ecma_fast_free_value (right_value); } if (unlikely (ecma_is_value_error (last_completion_value))) @@ -2319,7 +2319,7 @@ error: { /* In most cases there is no context. */ - ecma_free_value (block_result); + ecma_fast_free_value (block_result); 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++) { - 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. @@ -2486,7 +2486,7 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */ /* Free arguments and registers */ 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;