Introduce parser-time optimization that replaces a function's local variables with registers.
JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
@@ -62,7 +62,7 @@ bool
|
||||
is_reg_variable (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */
|
||||
idx_t var_idx) /**< variable identifier */
|
||||
{
|
||||
return (var_idx >= frame_ctx_p->min_reg_num && var_idx <= frame_ctx_p->max_reg_num);
|
||||
return (var_idx >= frame_ctx_p->min_reg_idx && var_idx <= frame_ctx_p->max_reg_idx);
|
||||
} /* is_reg_variable */
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ get_variable_value (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */
|
||||
if (is_reg_variable (frame_ctx_p, var_idx))
|
||||
{
|
||||
ecma_value_t reg_value = vm_stack_frame_get_reg_value (&frame_ctx_p->stack_frame,
|
||||
var_idx - frame_ctx_p->min_reg_num);
|
||||
var_idx - frame_ctx_p->min_reg_idx);
|
||||
|
||||
JERRY_ASSERT (!ecma_is_value_empty (reg_value));
|
||||
|
||||
@@ -136,7 +136,7 @@ set_variable_value (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
|
||||
ecma_value_t reg_value = vm_stack_frame_get_reg_value (&frame_ctx_p->stack_frame,
|
||||
var_idx - frame_ctx_p->min_reg_num);
|
||||
var_idx - frame_ctx_p->min_reg_idx);
|
||||
|
||||
if (ecma_is_value_number (reg_value)
|
||||
&& ecma_is_value_number (value))
|
||||
@@ -151,8 +151,8 @@ set_variable_value (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */
|
||||
}
|
||||
|
||||
vm_stack_frame_set_reg_value (&frame_ctx_p->stack_frame,
|
||||
var_idx - frame_ctx_p->min_reg_num,
|
||||
ecma_copy_value (value, false));
|
||||
var_idx - frame_ctx_p->min_reg_idx,
|
||||
ecma_copy_value (value, false));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -163,8 +163,8 @@ typedef struct
|
||||
bool is_eval_code; /**< is current code executed with eval */
|
||||
bool is_call_in_direct_eval_form; /** flag, indicating if there is call of 'Direct call to eval' form in
|
||||
* process (see also: OPCODE_CALL_FLAGS_DIRECT_CALL_TO_EVAL_FORM) */
|
||||
idx_t min_reg_num; /**< minimum idx used for register identification */
|
||||
idx_t max_reg_num; /**< maximum idx used for register identification */
|
||||
idx_t min_reg_idx; /**< minimum idx used for register identification */
|
||||
idx_t max_reg_idx; /**< maximum idx used for register identification */
|
||||
ecma_number_t* tmp_num_p; /**< an allocated number (to reduce temporary allocations) */
|
||||
vm_stack_frame_t stack_frame; /**< stack frame associated with the context */
|
||||
|
||||
|
||||
@@ -295,9 +295,10 @@ VM_OP_3 (is_false_jmp_down, IS_FALSE_JMP_DOWN,
|
||||
VM_OP_1 (var_decl, VAR_DECL,
|
||||
variable_name, VM_OP_ARG_TYPE_STRING)
|
||||
|
||||
VM_OP_2 (reg_var_decl, REG_VAR_DECL,
|
||||
VM_OP_3 (reg_var_decl, REG_VAR_DECL,
|
||||
min, VM_OP_ARG_TYPE_REGISTER,
|
||||
max, VM_OP_ARG_TYPE_REGISTER)
|
||||
max, VM_OP_ARG_TYPE_REGISTER,
|
||||
local_var_regs_num, VM_OP_ARG_TYPE_INTEGER_CONST)
|
||||
|
||||
VM_OP_3 (meta, META,
|
||||
type, VM_OP_ARG_TYPE_INTEGER_CONST,
|
||||
|
||||
@@ -76,7 +76,9 @@ vm_stack_get_top_frame (void)
|
||||
void
|
||||
vm_stack_add_frame (vm_stack_frame_t *frame_p, /**< frame to initialize */
|
||||
ecma_value_t *regs_p, /**< array of register variables' values */
|
||||
int32_t regs_num) /**< number of register variables */
|
||||
int32_t regs_num, /**< total number of register variables */
|
||||
int32_t local_vars_regs_num) /**< number of register variables,
|
||||
* used for local variables */
|
||||
{
|
||||
frame_p->prev_frame_p = vm_stack_top_frame_p;
|
||||
vm_stack_top_frame_p = frame_p;
|
||||
@@ -87,10 +89,17 @@ vm_stack_add_frame (vm_stack_frame_t *frame_p, /**< frame to initialize */
|
||||
frame_p->regs_p = regs_p;
|
||||
frame_p->regs_number = regs_num;
|
||||
|
||||
for (int32_t i = 0; i < regs_num; i++)
|
||||
for (int32_t i = 0; i < regs_num - local_vars_regs_num; i++)
|
||||
{
|
||||
regs_p[i] = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
||||
}
|
||||
|
||||
for (int32_t i = regs_num - local_vars_regs_num;
|
||||
i < regs_num;
|
||||
i++)
|
||||
{
|
||||
regs_p[i] = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
} /* vm_stack_add_frame */
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,7 +62,8 @@ vm_stack_get_top_frame (void);
|
||||
extern void
|
||||
vm_stack_add_frame (vm_stack_frame_t *frame_p,
|
||||
ecma_value_t *regs_p,
|
||||
int32_t regs_num);
|
||||
int32_t regs_num,
|
||||
int32_t local_vars_regs_num);
|
||||
extern void vm_stack_free_frame (vm_stack_frame_t *frame_p);
|
||||
extern ecma_value_t vm_stack_frame_get_reg_value (vm_stack_frame_t *frame_p, int32_t reg_index);
|
||||
extern void vm_stack_frame_set_reg_value (vm_stack_frame_t *frame_p, int32_t reg_index, ecma_value_t value);
|
||||
|
||||
@@ -543,11 +543,12 @@ vm_run_from_pos (const vm_instr_t *instrs_p, /**< byte-code array */
|
||||
const vm_instr_t *curr = &instrs_p[start_pos];
|
||||
JERRY_ASSERT (curr->op_idx == VM_OP_REG_VAR_DECL);
|
||||
|
||||
const idx_t min_reg_num = curr->data.reg_var_decl.min;
|
||||
const idx_t max_reg_num = curr->data.reg_var_decl.max;
|
||||
JERRY_ASSERT (max_reg_num >= min_reg_num);
|
||||
const idx_t min_reg_idx = curr->data.reg_var_decl.min;
|
||||
const idx_t max_reg_idx = curr->data.reg_var_decl.max;
|
||||
const idx_t local_var_regs_num = curr->data.reg_var_decl.local_var_regs_num;
|
||||
JERRY_ASSERT (max_reg_idx >= min_reg_idx);
|
||||
|
||||
const int32_t regs_num = max_reg_num - min_reg_num + 1;
|
||||
int32_t regs_num = max_reg_idx - min_reg_idx + 1;
|
||||
|
||||
MEM_DEFINE_LOCAL_ARRAY (regs, regs_num, ecma_value_t);
|
||||
|
||||
@@ -559,10 +560,10 @@ vm_run_from_pos (const vm_instr_t *instrs_p, /**< byte-code array */
|
||||
frame_ctx.is_strict = is_strict;
|
||||
frame_ctx.is_eval_code = is_eval_code;
|
||||
frame_ctx.is_call_in_direct_eval_form = false;
|
||||
frame_ctx.min_reg_num = min_reg_num;
|
||||
frame_ctx.max_reg_num = max_reg_num;
|
||||
frame_ctx.min_reg_idx = min_reg_idx;
|
||||
frame_ctx.max_reg_idx = max_reg_idx;
|
||||
frame_ctx.tmp_num_p = ecma_alloc_number ();
|
||||
vm_stack_add_frame (&frame_ctx.stack_frame, regs, regs_num);
|
||||
vm_stack_add_frame (&frame_ctx.stack_frame, regs, regs_num, local_var_regs_num);
|
||||
|
||||
vm_frame_ctx_t *prev_context_p = vm_top_context_p;
|
||||
vm_top_context_p = &frame_ctx;
|
||||
|
||||
Reference in New Issue
Block a user