From 2c86712e21dd090d778ca90ede0f6e118e7c8b64 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Tue, 9 Dec 2014 18:24:16 +0300 Subject: [PATCH] Introducing number chunk for storage of temporary (stack-only) number operands. --- src/libcoreint/interpreter.c | 4 + src/libcoreint/opcodes-ecma-arithmetics.c | 9 +- src/libcoreint/opcodes-ecma-bitwise.c | 4 +- src/libcoreint/opcodes.c | 115 ++++++++++------------ src/libcoreint/opcodes.h | 1 + 5 files changed, 60 insertions(+), 73 deletions(-) diff --git a/src/libcoreint/interpreter.c b/src/libcoreint/interpreter.c index a5a7c9ac6..9c4c13c70 100644 --- a/src/libcoreint/interpreter.c +++ b/src/libcoreint/interpreter.c @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "ecma-alloc.h" #include "ecma-builtins.h" #include "ecma-gc.h" #include "ecma-globals.h" @@ -469,6 +470,7 @@ run_int_from_pos (opcode_counter_t start_pos, int_data.min_reg_num = min_reg_num; int_data.max_reg_num = max_reg_num; int_data.regs_p = regs; + int_data.tmp_num_p = ecma_alloc_number (); #ifdef MEM_STATS interp_mem_stats_context_enter (&int_data, start_pos); @@ -481,6 +483,8 @@ run_int_from_pos (opcode_counter_t start_pos, || ecma_is_completion_value_return (completion) || ecma_is_completion_value_exit (completion)); + ecma_dealloc_number (int_data.tmp_num_p); + for (uint32_t reg_index = 0; reg_index < regs_num; reg_index++) diff --git a/src/libcoreint/opcodes-ecma-arithmetics.c b/src/libcoreint/opcodes-ecma-arithmetics.c index c917ef79a..24443e872 100644 --- a/src/libcoreint/opcodes-ecma-arithmetics.c +++ b/src/libcoreint/opcodes-ecma-arithmetics.c @@ -57,7 +57,7 @@ do_number_arithmetic (int_data_t *int_data, /**< interpreter context */ left_p = ecma_get_number_from_completion_value (num_left_value); right_p = ecma_get_number_from_completion_value (num_right_value); - res_p = ecma_alloc_number (); + res_p = int_data->tmp_num_p; switch (op) { @@ -92,8 +92,6 @@ do_number_arithmetic (int_data_t *int_data, /**< interpreter context */ dst_var_idx, ecma_make_number_value (res_p)); - ecma_dealloc_number (res_p); - ECMA_FINALIZE (num_right_value); ECMA_FINALIZE (num_left_value); @@ -364,14 +362,13 @@ opfunc_unary_minus (opcode_t opdata, /**< operation data */ ecma_number_t *var_p, *res_p; var_p = ecma_get_number_from_completion_value (num_value); - res_p = ecma_alloc_number (); + res_p = int_data->tmp_num_p; + *res_p = ecma_number_negate (*var_p); ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_number_value (res_p)); - ecma_dealloc_number (res_p); - ECMA_FINALIZE (num_value); ECMA_FINALIZE (var_value); diff --git a/src/libcoreint/opcodes-ecma-bitwise.c b/src/libcoreint/opcodes-ecma-bitwise.c index 4483e4c40..e249c3055 100644 --- a/src/libcoreint/opcodes-ecma-bitwise.c +++ b/src/libcoreint/opcodes-ecma-bitwise.c @@ -57,7 +57,7 @@ do_number_bitwise_logic (int_data_t *int_data, /**< interpreter context */ left_p = ecma_get_number_from_completion_value (num_left_value); right_p = ecma_get_number_from_completion_value (num_right_value); - ecma_number_t* res_p = ecma_alloc_number (); + ecma_number_t* res_p = int_data->tmp_num_p; int32_t left_int32 = ecma_number_to_int32 (*left_p); // int32_t right_int32 = ecma_number_to_int32 (*right_p); @@ -108,8 +108,6 @@ do_number_bitwise_logic (int_data_t *int_data, /**< interpreter context */ dst_var_idx, ecma_make_number_value (res_p)); - ecma_dealloc_number (res_p); - ECMA_FINALIZE (num_right_value); ECMA_FINALIZE (num_left_value); diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 9b3fd688b..ef686e4a9 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -89,66 +89,61 @@ opfunc_assignment (opcode_t opdata, /**< operation data */ int_data->pos++; - ecma_completion_value_t get_value_completion = 0; - - switch (type_value_right) + if (type_value_right == OPCODE_ARG_TYPE_SIMPLE) { - case OPCODE_ARG_TYPE_SIMPLE: - { - get_value_completion = ecma_make_simple_completion_value (src_val_descr); - break; - } - case OPCODE_ARG_TYPE_STRING: - { - ecma_string_t *ecma_string_p = ecma_new_ecma_string_from_lit_index (src_val_descr); - - get_value_completion = ecma_make_normal_completion_value (ecma_make_string_value (ecma_string_p)); - break; - } - case OPCODE_ARG_TYPE_VARIABLE: - { - get_value_completion = get_variable_value (int_data, - src_val_descr, - false); - - break; - } - case OPCODE_ARG_TYPE_NUMBER: - { - ecma_number_t *num_p = ecma_alloc_number (); - const literal lit = deserialize_literal_by_id (src_val_descr); - JERRY_ASSERT (lit.type == LIT_NUMBER); - *num_p = lit.data.num; - - get_value_completion = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); - break; - } - case OPCODE_ARG_TYPE_SMALLINT: - { - ecma_number_t *num_p = ecma_alloc_number (); - *num_p = src_val_descr; - - get_value_completion = ecma_make_normal_completion_value (ecma_make_number_value (num_p)); - break; - } + return set_variable_value (int_data, + dst_var_idx, + ecma_make_simple_value (src_val_descr)); } - - if (unlikely (ecma_is_completion_value_throw (get_value_completion))) + else if (type_value_right == OPCODE_ARG_TYPE_STRING) { - return get_value_completion; + ecma_string_t *string_p = ecma_new_ecma_string_from_lit_index (src_val_descr); + + ecma_completion_value_t completion = set_variable_value (int_data, + dst_var_idx, + ecma_make_string_value (string_p)); + + ecma_deref_ecma_string (string_p); + + return completion; + } + else if (type_value_right == OPCODE_ARG_TYPE_VARIABLE) + { + ecma_completion_value_t ret_value; + + ECMA_TRY_CATCH (get_value_completion, + get_variable_value (int_data, + src_val_descr, + false), + ret_value); + + ret_value = set_variable_value (int_data, + dst_var_idx, + ecma_get_completion_value_value (get_value_completion)); + + ECMA_FINALIZE (get_value_completion); + + return ret_value; + } + else if (type_value_right == OPCODE_ARG_TYPE_NUMBER) + { + ecma_number_t *num_p = int_data->tmp_num_p; + + const literal lit = deserialize_literal_by_id (src_val_descr); + JERRY_ASSERT (lit.type == LIT_NUMBER); + + *num_p = lit.data.num; + + return set_variable_value (int_data, dst_var_idx, ecma_make_number_value (num_p)); } else { - JERRY_ASSERT (ecma_is_completion_value_normal (get_value_completion)); + JERRY_ASSERT (type_value_right == OPCODE_ARG_TYPE_SMALLINT); + ecma_number_t *num_p = int_data->tmp_num_p; - ecma_value_t value_to_assign = ecma_get_completion_value_value (get_value_completion); - ecma_completion_value_t assignment_completion_value = set_variable_value (int_data, - dst_var_idx, - value_to_assign); + *num_p = src_val_descr; - ecma_free_completion_value (get_value_completion); - - return assignment_completion_value; + return set_variable_value (int_data, dst_var_idx, ecma_make_number_value (num_p)); } } /* opfunc_assignment */ @@ -176,7 +171,7 @@ opfunc_pre_incr (opcode_t opdata, /**< operation data */ ECMA_TRY_CATCH (old_num_value, ecma_op_to_number (ecma_get_completion_value_value (old_value)), ret_value); // 4. - ecma_number_t* new_num_p = ecma_alloc_number (); + ecma_number_t* new_num_p = int_data->tmp_num_p; ecma_number_t* old_num_p = ecma_get_number_from_completion_value (old_num_value); *new_num_p = ecma_number_add (*old_num_p, ECMA_NUMBER_ONE); @@ -194,8 +189,6 @@ opfunc_pre_incr (opcode_t opdata, /**< operation data */ new_num_value); JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res)); - ecma_dealloc_number (new_num_p); - ECMA_FINALIZE (old_num_value); ECMA_FINALIZE (old_value); @@ -226,7 +219,7 @@ opfunc_pre_decr (opcode_t opdata, /**< operation data */ ECMA_TRY_CATCH (old_num_value, ecma_op_to_number (ecma_get_completion_value_value (old_value)), ret_value); // 4. - ecma_number_t* new_num_p = ecma_alloc_number (); + ecma_number_t* new_num_p = int_data->tmp_num_p; ecma_number_t* old_num_p = ecma_get_number_from_completion_value (old_num_value); *new_num_p = ecma_number_substract (*old_num_p, ECMA_NUMBER_ONE); @@ -244,8 +237,6 @@ opfunc_pre_decr (opcode_t opdata, /**< operation data */ new_num_value); JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res)); - ecma_dealloc_number (new_num_p); - ECMA_FINALIZE (old_num_value); ECMA_FINALIZE (old_value); @@ -276,7 +267,7 @@ opfunc_post_incr (opcode_t opdata, /**< operation data */ ECMA_TRY_CATCH (old_num_value, ecma_op_to_number (ecma_get_completion_value_value (old_value)), ret_value); // 4. - ecma_number_t* new_num_p = ecma_alloc_number (); + ecma_number_t* new_num_p = int_data->tmp_num_p; ecma_number_t* old_num_p = ecma_get_number_from_completion_value (old_num_value); *new_num_p = ecma_number_add (*old_num_p, ECMA_NUMBER_ONE); @@ -286,8 +277,6 @@ opfunc_post_incr (opcode_t opdata, /**< operation data */ incr_var_idx, ecma_make_number_value (new_num_p)); - ecma_dealloc_number (new_num_p); - // assignment of operator result to register variable ecma_completion_value_t reg_assignment_res = set_variable_value (int_data, dst_var_idx, @@ -324,7 +313,7 @@ opfunc_post_decr (opcode_t opdata, /**< operation data */ ECMA_TRY_CATCH (old_num_value, ecma_op_to_number (ecma_get_completion_value_value (old_value)), ret_value); // 4. - ecma_number_t* new_num_p = ecma_alloc_number (); + ecma_number_t* new_num_p = int_data->tmp_num_p; ecma_number_t* old_num_p = ecma_get_number_from_completion_value (old_num_value); *new_num_p = ecma_number_substract (*old_num_p, ECMA_NUMBER_ONE); @@ -334,8 +323,6 @@ opfunc_post_decr (opcode_t opdata, /**< operation data */ decr_var_idx, ecma_make_number_value (new_num_p)); - ecma_dealloc_number (new_num_p); - // assignment of operator result to register variable ecma_completion_value_t reg_assignment_res = set_variable_value (int_data, dst_var_idx, diff --git a/src/libcoreint/opcodes.h b/src/libcoreint/opcodes.h index f3f0e65f1..ccf12fbb6 100644 --- a/src/libcoreint/opcodes.h +++ b/src/libcoreint/opcodes.h @@ -80,6 +80,7 @@ typedef struct idx_t min_reg_num; /**< minimum idx used for register identification */ idx_t max_reg_num; /**< maximum idx used for register identification */ ecma_value_t *regs_p; /**< register variables */ + ecma_number_t* tmp_num_p; /**< an allocated number (to reduce temporary allocations) */ #ifdef MEM_STATS size_t context_peak_allocated_heap_bytes;