Convert certain push number opcodes to literals (#2328)

Binary operations are much faster with literal arguments.
The byte immediates are still kept for other cases, e.g. array declarations.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2018-05-18 10:22:53 +02:00
committed by yichoi
parent 64b16bf190
commit 5560c76b41
10 changed files with 232 additions and 81 deletions
+85 -8
View File
@@ -1745,7 +1745,7 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
*/
bool
lexer_construct_number_object (parser_context_t *context_p, /**< context */
bool push_number_allowed, /**< push number support is allowed */
bool is_expr, /**< expression is parsed */
bool is_negative_number) /**< sign is negative */
{
parser_list_iterator_t literal_iterator;
@@ -1773,7 +1773,7 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
while (src_p < src_end_p);
}
if (push_number_allowed)
if (is_expr)
{
int32_t int_num = (int32_t) num;
@@ -1818,22 +1818,99 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
}
literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
literal_p->prop.length = context_p->token.lit_location.length;
literal_p->type = LEXER_UNUSED_LITERAL;
literal_p->status_flags = 0;
context_p->literal_count++;
literal_p->u.value = lit_value;
literal_p->prop.length = 0; /* Unused. */
literal_p->type = LEXER_NUMBER_LITERAL;
literal_p->status_flags = 0;
context_p->lit_object.literal_p = literal_p;
context_p->lit_object.index = (uint16_t) literal_index;
context_p->lit_object.type = LEXER_LITERAL_OBJECT_ANY;
context_p->literal_count++;
return false;
} /* lexer_construct_number_object */
/**
* Convert a push number opcode to push literal opcode
*/
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);
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))
{
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))
{
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));
value = -((ecma_integer_value_t) context_p->last_cbc.value) - 1;
}
ecma_value_t lit_value = ecma_make_integer_value (value);
parser_list_iterator_t literal_iterator;
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
context_p->last_cbc_opcode = two_literals ? CBC_PUSH_TWO_LITERALS : CBC_PUSH_LITERAL;
uint32_t literal_index = 0;
lexer_literal_t *literal_p;
while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
{
if (literal_p->type == LEXER_NUMBER_LITERAL
&& literal_p->u.value == lit_value)
{
if (two_literals)
{
context_p->last_cbc.value = (uint16_t) literal_index;
}
else
{
context_p->last_cbc.literal_index = (uint16_t) literal_index;
}
return;
}
literal_index++;
}
JERRY_ASSERT (literal_index == context_p->literal_count);
if (literal_index >= PARSER_MAXIMUM_NUMBER_OF_LITERALS)
{
parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED);
}
literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
literal_p->u.value = lit_value;
literal_p->prop.length = 0; /* Unused. */
literal_p->type = LEXER_NUMBER_LITERAL;
literal_p->status_flags = 0;
context_p->literal_count++;
if (two_literals)
{
context_p->last_cbc.value = (uint16_t) literal_index;
}
else
{
context_p->last_cbc.literal_index = (uint16_t) literal_index;
}
} /* lexer_convert_push_number_to_push_literal */
/**
* Construct a function literal object.
*