From 911163e7876e2bdd6f575f376b5d2c5e7b787f83 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Sun, 1 Nov 2015 19:22:59 +0300 Subject: [PATCH] Optimize object literal byte-code - store property names as literal arguments, instead passing them through register variables. JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com --- jerry-core/parser/js/opcodes-dumper.cpp | 51 ++++++------------------- jerry-core/parser/js/parser.cpp | 23 +++++++++-- jerry-core/vm/opcodes.cpp | 21 ++++------ jerry-core/vm/vm-opcodes.inc.h | 1 + 4 files changed, 41 insertions(+), 55 deletions(-) diff --git a/jerry-core/parser/js/opcodes-dumper.cpp b/jerry-core/parser/js/opcodes-dumper.cpp index 01d36c8b8..567047718 100644 --- a/jerry-core/parser/js/opcodes-dumper.cpp +++ b/jerry-core/parser/js/opcodes-dumper.cpp @@ -1115,22 +1115,13 @@ dump_prop_name_and_value (jsp_operand_t name, jsp_operand_t value) { JERRY_ASSERT (name.is_literal_operand ()); literal_t lit = lit_get_literal_by_cp (name.get_literal ()); - jsp_operand_t tmp; - if (lit->get_type () == LIT_STR_T - || lit->get_type () == LIT_MAGIC_STR_T - || lit->get_type () == LIT_MAGIC_STR_EX_T) - { - tmp = dump_string_assignment_res (name.get_literal ()); - } - else - { - JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T); - tmp = dump_number_assignment_res (name.get_literal ()); - } + JERRY_ASSERT (lit->get_type () == LIT_STR_T + || lit->get_type () == LIT_MAGIC_STR_T + || lit->get_type () == LIT_MAGIC_STR_EX_T); dump_triple_address (VM_OP_META, jsp_operand_t::make_idx_const_operand (OPCODE_META_TYPE_VARG_PROP_DATA), - tmp, + name, value); } @@ -1140,22 +1131,13 @@ dump_prop_getter_decl (jsp_operand_t name, jsp_operand_t func) JERRY_ASSERT (name.is_literal_operand ()); JERRY_ASSERT (func.is_register_operand ()); literal_t lit = lit_get_literal_by_cp (name.get_literal ()); - jsp_operand_t tmp; - if (lit->get_type () == LIT_STR_T - || lit->get_type () == LIT_MAGIC_STR_T - || lit->get_type () == LIT_MAGIC_STR_EX_T) - { - tmp = dump_string_assignment_res (name.get_literal ()); - } - else - { - JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T); - tmp = dump_number_assignment_res (name.get_literal ()); - } + JERRY_ASSERT (lit->get_type () == LIT_STR_T + || lit->get_type () == LIT_MAGIC_STR_T + || lit->get_type () == LIT_MAGIC_STR_EX_T); dump_triple_address (VM_OP_META, jsp_operand_t::make_idx_const_operand (OPCODE_META_TYPE_VARG_PROP_GETTER), - tmp, + name, func); } @@ -1165,22 +1147,13 @@ dump_prop_setter_decl (jsp_operand_t name, jsp_operand_t func) JERRY_ASSERT (name.is_literal_operand ()); JERRY_ASSERT (func.is_register_operand ()); literal_t lit = lit_get_literal_by_cp (name.get_literal ()); - jsp_operand_t tmp; - if (lit->get_type () == LIT_STR_T - || lit->get_type () == LIT_MAGIC_STR_T - || lit->get_type () == LIT_MAGIC_STR_EX_T) - { - tmp = dump_string_assignment_res (name.get_literal ()); - } - else - { - JERRY_ASSERT (lit->get_type () == LIT_NUMBER_T); - tmp = dump_number_assignment_res (name.get_literal ()); - } + JERRY_ASSERT (lit->get_type () == LIT_STR_T + || lit->get_type () == LIT_MAGIC_STR_T + || lit->get_type () == LIT_MAGIC_STR_EX_T); dump_triple_address (VM_OP_META, jsp_operand_t::make_idx_const_operand (OPCODE_META_TYPE_VARG_PROP_SETTER), - tmp, + name, func); } diff --git a/jerry-core/parser/js/parser.cpp b/jerry-core/parser/js/parser.cpp index 4abcbc700..64f06e469 100644 --- a/jerry-core/parser/js/parser.cpp +++ b/jerry-core/parser/js/parser.cpp @@ -303,14 +303,31 @@ parse_property_name (void) { case TOK_NAME: case TOK_STRING: - case TOK_NUMBER: { return literal_operand (token_data_as_lit_cp ()); } + case TOK_NUMBER: case TOK_SMALL_INT: { - literal_t lit = lit_find_or_create_literal_from_num ((ecma_number_t) token_data ()); - return literal_operand (lit_cpointer_t::compress (lit)); + ecma_number_t num; + + if (tok.type == TOK_NUMBER) + { + literal_t num_lit = lit_get_literal_by_cp (token_data_as_lit_cp ()); + JERRY_ASSERT (num_lit->get_type () == LIT_NUMBER_T); + num = lit_charset_literal_get_number (num_lit); + } + else + { + num = ((ecma_number_t) token_data ()); + } + + lit_utf8_byte_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER]; + lit_utf8_size_t sz = ecma_number_to_utf8_string (num, buff, sizeof (buff)); + JERRY_ASSERT (sz <= ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER); + + literal_t str_lit = lit_find_or_create_literal_from_utf8_string (buff, sz); + return literal_operand (lit_cpointer_t::compress (str_lit)); } case TOK_KEYWORD: { diff --git a/jerry-core/vm/opcodes.cpp b/jerry-core/vm/opcodes.cpp index 3d081b9eb..57204eda6 100644 --- a/jerry-core/vm/opcodes.cpp +++ b/jerry-core/vm/opcodes.cpp @@ -1028,8 +1028,7 @@ opfunc_obj_decl (vm_instr_t instr, /**< instruction */ || type == OPCODE_META_TYPE_VARG_PROP_GETTER || type == OPCODE_META_TYPE_VARG_PROP_SETTER); - const vm_idx_t prop_name_var_idx = next_opcode.data.meta.data_1; - JERRY_ASSERT (vm_is_reg_variable (prop_name_var_idx)); + const vm_idx_t prop_name_idx = next_opcode.data.meta.data_1; const vm_idx_t value_for_prop_desc_var_idx = next_opcode.data.meta.data_2; @@ -1038,18 +1037,15 @@ opfunc_obj_decl (vm_instr_t instr, /**< instruction */ value_for_prop_desc_var_idx, false), ret_value); - ECMA_TRY_CATCH (prop_name_value, - get_variable_value (frame_ctx_p, - prop_name_var_idx, - false), - ret_value); - ECMA_TRY_CATCH (prop_name_str_value, - ecma_op_to_string (prop_name_value), - ret_value); + + lit_cpointer_t prop_name_lit_cp = serializer_get_literal_cp_by_uid (prop_name_idx, + frame_ctx_p->bytecode_header_p, + frame_ctx_p->pos); + JERRY_ASSERT (prop_name_lit_cp.packed_value != MEM_CP_NULL); + ecma_string_t *prop_name_string_p = ecma_new_ecma_string_from_lit_cp (prop_name_lit_cp); bool is_throw_syntax_error = false; - ecma_string_t *prop_name_string_p = ecma_get_string_from_value (prop_name_str_value); ecma_property_t *previous_p = ecma_op_object_get_own_property (obj_p, prop_name_string_p); const bool is_previous_undefined = (previous_p == NULL); @@ -1117,8 +1113,7 @@ opfunc_obj_decl (vm_instr_t instr, /**< instruction */ JERRY_ASSERT (ecma_is_completion_value_normal_true (define_prop_completion) || ecma_is_completion_value_normal_false (define_prop_completion)); - ECMA_FINALIZE (prop_name_str_value); - ECMA_FINALIZE (prop_name_value); + ecma_deref_ecma_string (prop_name_string_p); ECMA_FINALIZE (value_for_prop_desc); diff --git a/jerry-core/vm/vm-opcodes.inc.h b/jerry-core/vm/vm-opcodes.inc.h index 2f3e712ad..e1fe4f9da 100644 --- a/jerry-core/vm/vm-opcodes.inc.h +++ b/jerry-core/vm/vm-opcodes.inc.h @@ -300,6 +300,7 @@ VM_OP_3 (reg_var_decl, REG_VAR_DECL, VM_OP_3 (meta, META, type, VM_OP_ARG_TYPE_INTEGER_CONST, data_1, VM_OP_ARG_TYPE_INTEGER_CONST | + VM_OP_ARG_TYPE_STRING | VM_OP_ARG_TYPE_VARIABLE, data_2, VM_OP_ARG_TYPE_INTEGER_CONST | VM_OP_ARG_TYPE_VARIABLE)