Optimize property call opcodes (#2609)

In with contexts the object base value must be resolved before executing a call operation.
Since this happens rarely the base resolving code paths has been seperated to an other VM opcode
so these extra checks do not burden the general property call steps.

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik 2018-11-29 09:00:22 +01:00 committed by Zoltan Herczeg
parent e11c499b4b
commit 24817b27f9
6 changed files with 26 additions and 21 deletions

View File

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

View File

@ -590,6 +590,8 @@
VM_OC_SET_GETTER | VM_OC_GET_STACK_LITERAL) \
CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \
VM_OC_SET_SETTER | VM_OC_GET_STACK_LITERAL) \
CBC_OPCODE (CBC_EXT_RESOLVE_BASE, CBC_NO_FLAG, 0, \
VM_OC_RESOLVE_BASE_FOR_CALL) \
\
/* Class opcodes */ \
CBC_OPCODE (CBC_EXT_INHERIT_AND_SET_CONSTRUCTOR, CBC_NO_FLAG, 0, \

View File

@ -1556,6 +1556,8 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */
CBC_PUSH_IDENT_REFERENCE,
context_p->last_cbc.third_literal_index);
}
parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_BASE);
}
}

View File

@ -476,26 +476,8 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
bool is_call_prop = ((opcode - CBC_CALL) % 6) >= 3;
ecma_value_t this_value = ECMA_VALUE_UNDEFINED;
ecma_value_t *stack_top_p = frame_ctx_p->stack_top_p - arguments_list_len;
if (is_call_prop)
{
this_value = stack_top_p[-3];
if (this_value == ECMA_VALUE_REGISTER_REF)
{
/* Lexical environment cannot be 'this' value. */
stack_top_p[-2] = ECMA_VALUE_UNDEFINED;
this_value = ECMA_VALUE_UNDEFINED;
}
else if (vm_get_implicit_this_value (&this_value))
{
ecma_free_value (stack_top_p[-3]);
stack_top_p[-3] = this_value;
}
}
ecma_value_t this_value = is_call_prop ? stack_top_p[-3] : ECMA_VALUE_UNDEFINED;
ecma_value_t func_value = stack_top_p[-1];
ecma_value_t completion_value;
@ -1978,6 +1960,24 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
*stack_top_p++ = result;
continue;
}
case VM_OC_RESOLVE_BASE_FOR_CALL:
{
ecma_value_t this_value = stack_top_p[-3];
if (this_value == ECMA_VALUE_REGISTER_REF)
{
/* Lexical environment cannot be 'this' value. */
stack_top_p[-2] = ECMA_VALUE_UNDEFINED;
stack_top_p[-3] = ECMA_VALUE_UNDEFINED;
}
else if (vm_get_implicit_this_value (&this_value))
{
ecma_free_value (stack_top_p[-3]);
stack_top_p[-3] = this_value;
}
continue;
}
case VM_OC_PROP_DELETE:
{
result = vm_op_delete_prop (left_value, right_value, is_strict);

View File

@ -158,6 +158,7 @@ typedef enum
VM_OC_EVAL, /**< eval */
VM_OC_CALL, /**< call */
VM_OC_NEW, /**< new */
VM_OC_RESOLVE_BASE_FOR_CALL, /**< resolve base value before call */
VM_OC_JUMP, /**< jump */
VM_OC_BRANCH_IF_STRICT_EQUAL, /**< branch if stric equal */

View File

@ -223,7 +223,7 @@ main (void)
/* Check the snapshot data. Unused bytes should be filled with zeroes */
const uint8_t expected_data[] =
{
0x4A, 0x52, 0x52, 0x59, 0x13, 0x00, 0x00, 0x00,
0x4A, 0x52, 0x52, 0x59, 0x14, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,