From 3af0079a0eb4bf149d7e7c5acd3c95dfd049f622 Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Mon, 26 Aug 2019 15:59:27 +0200 Subject: [PATCH] Introduce CBC_MOV_IDENT opcode to improve performance (#3020) After this patch CBC_ASSIGN_SET_IDENT is transformed to CBC_MOV_IDENT if the opcode has register stored literal argument. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu --- jerry-core/parser/js/byte-code.h | 2 ++ jerry-core/parser/js/js-parser.c | 16 +++++++++++----- jerry-core/vm/vm.c | 13 +++++++++++++ jerry-core/vm/vm.h | 1 + 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/jerry-core/parser/js/byte-code.h b/jerry-core/parser/js/byte-code.h index 6ddf3c1fd..77685d918 100644 --- a/jerry-core/parser/js/byte-code.h +++ b/jerry-core/parser/js/byte-code.h @@ -472,6 +472,8 @@ VM_OC_ASSIGN_PROP_THIS | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_STACK) \ CBC_OPCODE (CBC_ASSIGN_PROP_THIS_LITERAL_BLOCK, CBC_HAS_LITERAL_ARG, -1, \ VM_OC_ASSIGN_PROP_THIS | VM_OC_GET_LITERAL | VM_OC_PUT_REFERENCE | VM_OC_PUT_BLOCK) \ + CBC_OPCODE (CBC_MOV_IDENT, CBC_HAS_LITERAL_ARG, -1, \ + VM_OC_MOV_IDENT | VM_OC_GET_STACK | VM_OC_PUT_IDENT) \ \ /* Last opcode (not a real opcode). */ \ CBC_OPCODE (CBC_END, CBC_NO_FLAG, 0, \ diff --git a/jerry-core/parser/js/js-parser.c b/jerry-core/parser/js/js-parser.c index bfa088050..06fc9d80b 100644 --- a/jerry-core/parser/js/js-parser.c +++ b/jerry-core/parser/js/js-parser.c @@ -1863,6 +1863,8 @@ parser_post_processing (parser_context_t *context_p) /**< context */ page_p = context_p->byte_code.first_p; offset = 0; real_offset = 0; + uint8_t last_register_index = (uint8_t) JERRY_MIN (context_p->register_count, + (PARSER_MAXIMUM_NUMBER_OF_REGISTERS - 1)); while (page_p != last_page_p || offset < last_position) { @@ -1943,11 +1945,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */ #endif /* ENABLED (JERRY_LINE_INFO) */ } - if (flags & CBC_HAS_BRANCH_ARG) - { - *branch_mark_p |= CBC_HIGHEST_BIT_MASK; - } - /* Only literal and call arguments can be combined. */ JERRY_ASSERT (!(flags & CBC_HAS_BRANCH_ARG) || !(flags & (CBC_HAS_BYTE_ARG | CBC_HAS_LITERAL_ARG))); @@ -1956,6 +1953,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */ { uint8_t first_byte = page_p->bytes[offset]; + uint8_t *opcode_pos_p = dst_p - 1; *dst_p++ = first_byte; real_offset++; PARSER_NEXT_BYTE_UPDATE (page_p, offset, real_offset); @@ -1980,6 +1978,11 @@ parser_post_processing (parser_context_t *context_p) /**< context */ } else { + if (opcode == CBC_ASSIGN_SET_IDENT && JERRY_LIKELY (first_byte < last_register_index)) + { + *opcode_pos_p = CBC_MOV_IDENT; + } + break; } } @@ -1990,10 +1993,12 @@ parser_post_processing (parser_context_t *context_p) /**< context */ *dst_p++ = page_p->bytes[offset]; real_offset++; PARSER_NEXT_BYTE_UPDATE (page_p, offset, real_offset); + continue; } if (flags & CBC_HAS_BRANCH_ARG) { + *branch_mark_p |= CBC_HIGHEST_BIT_MASK; bool prefix_zero = true; /* The leading zeroes are dropped from the stream. */ @@ -2020,6 +2025,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */ *dst_p++ = page_p->bytes[offset]; real_offset++; PARSER_NEXT_BYTE_UPDATE (page_p, offset, real_offset); + continue; } } diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 28949b771..d816f065c 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -1941,6 +1941,19 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ left_value = ECMA_VALUE_UNDEFINED; break; } + case VM_OC_MOV_IDENT: + { + uint16_t literal_index; + + READ_LITERAL_INDEX (literal_index); + + JERRY_ASSERT (literal_index < register_end); + JERRY_ASSERT (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK))); + + ecma_fast_free_value (frame_ctx_p->registers_p[literal_index]); + frame_ctx_p->registers_p[literal_index] = left_value; + continue; + } case VM_OC_ASSIGN_PROP: { result = stack_top_p[-1]; diff --git a/jerry-core/vm/vm.h b/jerry-core/vm/vm.h index b42535158..b2a2f25d2 100644 --- a/jerry-core/vm/vm.h +++ b/jerry-core/vm/vm.h @@ -148,6 +148,7 @@ typedef enum VM_OC_PROP_DELETE, /**< delete property */ VM_OC_DELETE, /**< delete */ + VM_OC_MOV_IDENT, /**< move identifier register reference */ VM_OC_ASSIGN, /**< assign */ VM_OC_ASSIGN_PROP, /**< assign property */ VM_OC_ASSIGN_PROP_THIS, /**< assign prop this */