Move push literal number opcodes to basic opcodes (#4609)

`obj[number]` is a widely used structure especially for array element indexing, however super property assignment is not.
This patch moves super-assignment opcodes to ext opcodes and fills the freed 3 basic opcodes with push-literal-number ones.

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik robert.fancsik@h-lab.eu
This commit is contained in:
Robert Fancsik 2021-02-23 10:00:00 +01:00 committed by GitHub
parent 2240a9153a
commit 322265bfb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 52 deletions

View File

@ -30,7 +30,7 @@ extern "C"
/**
* Jerry snapshot format version.
*/
#define JERRY_SNAPSHOT_VERSION (64u)
#define JERRY_SNAPSHOT_VERSION (65u)
/**
* Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.

View File

@ -69,7 +69,7 @@
* CBC_NO_RESULT_OPERATION for ext opcodes
*/
#define CBC_EXT_NO_RESULT_OPERATION(opcode) \
((opcode) >= PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL) \
((opcode) >= PARSER_TO_EXT_OPCODE (CBC_EXT_ASSIGN_SUPER) \
&& (opcode) <= PARSER_TO_EXT_OPCODE (CBC_EXT_SPREAD_CALL_PROP_BLOCK))
#else /* !JERRY_ESNEXT */
/**
@ -288,6 +288,12 @@
VM_OC_PUSH_POS_BYTE | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_PUSH_NUMBER_NEG_BYTE, CBC_HAS_BYTE_ARG, 1, \
VM_OC_PUSH_NEG_BYTE | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_PUSH_LITERAL_PUSH_NUMBER_0, CBC_HAS_LITERAL_ARG, 2, \
VM_OC_PUSH_LIT_0 | VM_OC_GET_LITERAL) \
CBC_OPCODE (CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
VM_OC_PUSH_LIT_POS_BYTE | VM_OC_GET_LITERAL) \
CBC_OPCODE (CBC_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
VM_OC_PUSH_LIT_NEG_BYTE | VM_OC_GET_LITERAL) \
/* Note: These 4 opcodes must me in this order */ \
CBC_OPCODE (CBC_PUSH_PROP, CBC_NO_FLAG, -1, \
VM_OC_PROP_GET | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
@ -522,12 +528,6 @@
VM_OC_ASSIGN_LET_CONST | VM_OC_GET_STACK) \
CBC_OPCODE (CBC_ASSIGN_LET_CONST_LITERAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
VM_OC_ASSIGN_LET_CONST | VM_OC_GET_LITERAL) \
CBC_OPCODE (CBC_ASSIGN_SUPER, CBC_NO_FLAG, -3, \
VM_OC_ASSIGN_SUPER) \
CBC_OPCODE (CBC_ASSIGN_SUPER_PUSH_RESULT, CBC_NO_FLAG, -2, \
VM_OC_ASSIGN_SUPER | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_ASSIGN_SUPER_BLOCK, CBC_NO_FLAG, -3, \
VM_OC_ASSIGN_SUPER | VM_OC_PUT_BLOCK) \
\
/* Last opcode (not a real opcode). */ \
CBC_OPCODE (CBC_END, CBC_NO_FLAG, 0, \
@ -590,12 +590,6 @@
/* Basic opcodes. */ \
CBC_OPCODE (CBC_EXT_CREATE_ARGUMENTS, CBC_HAS_LITERAL_ARG, 0, \
VM_OC_CREATE_ARGUMENTS) \
CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0, CBC_HAS_LITERAL_ARG, 2, \
VM_OC_PUSH_LIT_0 | VM_OC_GET_LITERAL) \
CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
VM_OC_PUSH_LIT_POS_BYTE | VM_OC_GET_LITERAL) \
CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
VM_OC_PUSH_LIT_NEG_BYTE | VM_OC_GET_LITERAL) \
CBC_OPCODE (CBC_EXT_CREATE_VAR_EVAL, CBC_HAS_LITERAL_ARG, 0, \
VM_OC_EXT_VAR_EVAL) \
CBC_OPCODE (CBC_EXT_CREATE_VAR_FUNC_EVAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
@ -716,6 +710,12 @@
VM_OC_RESOLVE_LEXICAL_THIS | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_EXT_LOCAL_EVAL, CBC_HAS_BYTE_ARG, 0, \
VM_OC_LOCAL_EVAL) \
CBC_OPCODE (CBC_EXT_ASSIGN_SUPER, CBC_NO_FLAG, -3, \
VM_OC_ASSIGN_SUPER) \
CBC_OPCODE (CBC_EXT_ASSIGN_SUPER_PUSH_RESULT, CBC_NO_FLAG, -2, \
VM_OC_ASSIGN_SUPER | VM_OC_PUT_STACK) \
CBC_OPCODE (CBC_EXT_ASSIGN_SUPER_BLOCK, CBC_NO_FLAG, -3, \
VM_OC_ASSIGN_SUPER | VM_OC_PUT_BLOCK) \
CBC_OPCODE (CBC_EXT_SUPER_CALL, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
VM_OC_SUPER_CALL) \
CBC_OPCODE (CBC_EXT_SUPER_CALL_PUSH_RESULT, CBC_HAS_POP_STACK_BYTE_ARG, 0, \

View File

@ -507,12 +507,12 @@ util_print_cbc (ecma_compiled_code_t *compiled_code_p) /**< compiled code */
if (flags & CBC_HAS_BYTE_ARG)
{
if (opcode == CBC_PUSH_NUMBER_POS_BYTE
|| ext_opcode == CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
|| opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
{
JERRY_DEBUG_MSG (" number:%d", (int) *byte_code_p + 1);
}
else if (opcode == CBC_PUSH_NUMBER_NEG_BYTE
|| ext_opcode == CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
|| opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
{
JERRY_DEBUG_MSG (" number:%d", -((int) *byte_code_p + 1));
}

View File

@ -2764,22 +2764,22 @@ void
lexer_convert_push_number_to_push_literal (parser_context_t *context_p) /**< context */
{
ecma_integer_value_t value;
bool two_literals = !PARSER_IS_BASIC_OPCODE (context_p->last_cbc_opcode);
bool two_literals = context_p->last_cbc_opcode >= CBC_PUSH_LITERAL_PUSH_NUMBER_0;
if (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_0
|| context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0))
|| context_p->last_cbc_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_0)
{
value = 0;
}
else if (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_POS_BYTE
|| context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE))
|| context_p->last_cbc_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
{
value = ((ecma_integer_value_t) context_p->last_cbc.value) + 1;
}
else
{
JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_NEG_BYTE
|| context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE));
|| context_p->last_cbc_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE);
value = -((ecma_integer_value_t) context_p->last_cbc.value) - 1;
}

View File

@ -251,7 +251,7 @@ typedef enum
((((token_type) - LEXER_INCREASE) * 6) + CBC_PRE_INCR)
#define LEXER_BINARY_OP_TOKEN_TO_OPCODE(token_type) \
((cbc_opcode_t) ((((token_type) - LEXER_BIT_OR) * 3) + CBC_BIT_OR))
((uint16_t) ((((token_type) - LEXER_BIT_OR) * 3) + CBC_BIT_OR))
#define LEXER_BINARY_LVALUE_OP_TOKEN_TO_OPCODE(token_type) \
((cbc_opcode_t) ((((token_type) - LEXER_ASSIGN_ADD) * 2) + CBC_ASSIGN_ADD))

View File

@ -2885,12 +2885,14 @@ parser_append_binary_single_assignment_token (parser_context_t *context_p, /**<
else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP_LITERAL))
{
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_LITERAL_ASSIGNMENT_REFERENCE);
assign_opcode = CBC_ASSIGN_SUPER;
parser_stack_push_uint8 (context_p, CBC_EXT_ASSIGN_SUPER);
assign_opcode = CBC_EXT_OPCODE;
}
else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_SUPER_PROP))
{
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_PROP_ASSIGNMENT_REFERENCE);
assign_opcode = CBC_ASSIGN_SUPER;
parser_stack_push_uint8 (context_p, CBC_EXT_ASSIGN_SUPER);
assign_opcode = CBC_EXT_OPCODE;
}
#endif /* JERRY_ESNEXT */
else
@ -2982,9 +2984,9 @@ parser_append_binary_token (parser_context_t *context_p) /**< context */
#if JERRY_ESNEXT
parser_check_invalid_new_target (context_p, CBC_ASSIGN);
parser_raise_error (context_p, PARSER_ERR_INVALID_LHS_ASSIGNMENT);
#else /* !JERRY_ES2015 */
#else /* !JERRY_ESNEXT */
parser_emit_cbc_ext (context_p, CBC_EXT_THROW_REFERENCE_ERROR);
#endif /* JERRY_ES2015 */
#endif /* JERRY_ESNEXT */
parser_emit_cbc (context_p, CBC_PUSH_PROP_REFERENCE);
}
@ -3035,7 +3037,7 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
while (true)
{
uint8_t token = context_p->stack_top_uint8;
cbc_opcode_t opcode;
uint16_t opcode;
/* For left-to-right operators (all binary operators except assignment
* and logical operators), the byte code is flushed if the precedence
@ -3054,22 +3056,34 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
if (token == LEXER_ASSIGN)
{
opcode = (cbc_opcode_t) context_p->stack_top_uint8;
parser_stack_pop_uint8 (context_p);
uint16_t index = PARSER_INVALID_LITERAL_INDEX;
opcode = context_p->stack_top_uint8;
if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
#if JERRY_ESNEXT
if (JERRY_UNLIKELY (opcode == CBC_EXT_OPCODE))
{
JERRY_ASSERT (opcode == CBC_ASSIGN_SET_IDENT
|| opcode == CBC_ASSIGN_PROP_LITERAL
|| opcode == CBC_ASSIGN_PROP_THIS_LITERAL
|| opcode == CBC_ASSIGN_LET_CONST
|| opcode == CBC_INIT_ARG_OR_CATCH
|| opcode == CBC_INIT_LET
|| opcode == CBC_INIT_CONST);
parser_stack_pop_uint8 (context_p);
JERRY_ASSERT (context_p->stack_top_uint8 == CBC_EXT_ASSIGN_SUPER);
opcode = PARSER_TO_EXT_OPCODE (context_p->stack_top_uint8);
parser_stack_pop_uint8 (context_p);
}
else
#endif /* JERRY_ESNEXT */
{
parser_stack_pop_uint8 (context_p);
index = parser_stack_pop_uint16 (context_p);
if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
{
JERRY_ASSERT (opcode == CBC_ASSIGN_SET_IDENT
|| opcode == CBC_ASSIGN_PROP_LITERAL
|| opcode == CBC_ASSIGN_PROP_THIS_LITERAL
|| opcode == CBC_ASSIGN_LET_CONST
|| opcode == CBC_INIT_ARG_OR_CATCH
|| opcode == CBC_INIT_LET
|| opcode == CBC_INIT_CONST);
index = parser_stack_pop_uint16 (context_p);
}
}
#if JERRY_ESNEXT
@ -3182,7 +3196,7 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
continue;
}
}
parser_emit_cbc (context_p, (uint16_t) opcode);
parser_emit_cbc (context_p, opcode);
}
} /* parser_process_binary_opcodes */

View File

@ -274,12 +274,8 @@ typedef struct
|| (opcode) == CBC_PUSH_TWO_LITERALS \
|| (opcode) == CBC_PUSH_THREE_LITERALS)
#define PARSER_IS_PUSH_NUMBER(opcode) \
((opcode) == CBC_PUSH_NUMBER_0 \
|| (opcode) == CBC_PUSH_NUMBER_POS_BYTE \
|| (opcode) == CBC_PUSH_NUMBER_NEG_BYTE \
|| (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0) \
|| (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE) \
|| (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE))
((opcode) >= CBC_PUSH_NUMBER_0 \
&& (opcode) <= CBC_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
#define PARSER_IS_MUTABLE_PUSH_LITERAL(opcode) \
((opcode) >= CBC_PUSH_LITERAL && (opcode) <= CBC_PUSH_THIS_LITERAL)

View File

@ -250,13 +250,13 @@ parser_flush_cbc (parser_context_t *context_p) /**< context */
if (flags & CBC_HAS_BYTE_ARG)
{
if ((last_opcode == CBC_PUSH_NUMBER_POS_BYTE)
|| (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)))
if (last_opcode == CBC_PUSH_NUMBER_POS_BYTE
|| last_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
{
JERRY_DEBUG_MSG (" number:%d", (int) context_p->last_cbc.value + 1);
}
else if ((last_opcode == CBC_PUSH_NUMBER_NEG_BYTE)
|| (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)))
else if (last_opcode == CBC_PUSH_NUMBER_NEG_BYTE
|| last_opcode == CBC_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
{
JERRY_DEBUG_MSG (" number:%d", -((int) context_p->last_cbc.value + 1));
}
@ -424,7 +424,7 @@ parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */
return;
}
context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0);
context_p->last_cbc_opcode = CBC_PUSH_LITERAL_PUSH_NUMBER_0;
context_p->last_cbc.literal_index = lit_value;
return;
}
@ -440,8 +440,8 @@ parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */
}
else
{
opcode = PARSER_TO_EXT_OPCODE (is_negative_number ? CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE
: CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE);
opcode = (is_negative_number ? CBC_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE
: CBC_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE);
JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 2);
context_p->last_cbc.literal_index = lit_value;