Optimize put result phase in the interpreter.

Skip put result phase for opcodes which put their
result onto the stack or they don't have result at all.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2016-06-10 00:26:59 -07:00
parent eed84a7dd9
commit 495b24eebc
+130 -72
View File
@@ -846,7 +846,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
case VM_OC_NONE: case VM_OC_NONE:
{ {
JERRY_ASSERT (opcode == CBC_EXT_DEBUGGER); JERRY_ASSERT (opcode == CBC_EXT_DEBUGGER);
break; continue;
} }
case VM_OC_POP: case VM_OC_POP:
{ {
@@ -856,59 +856,59 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
} }
case VM_OC_POP_BLOCK: case VM_OC_POP_BLOCK:
{ {
result = *(--stack_top_p); ecma_fast_free_value (block_result);
break; block_result = *(--stack_top_p);
continue;
} }
case VM_OC_PUSH: case VM_OC_PUSH:
{ {
*(stack_top_p++) = left_value; *stack_top_p++ = left_value;
continue; continue;
} }
case VM_OC_PUSH_TWO: case VM_OC_PUSH_TWO:
{ {
*(stack_top_p++) = left_value; *stack_top_p++ = left_value;
*(stack_top_p++) = right_value; *stack_top_p++ = right_value;
continue; continue;
} }
case VM_OC_PUSH_THREE: case VM_OC_PUSH_THREE:
{ {
uint16_t literal_index; uint16_t literal_index;
*(stack_top_p++) = left_value; *stack_top_p++ = left_value;
left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
READ_LITERAL_INDEX (literal_index); READ_LITERAL_INDEX (literal_index);
READ_LITERAL (literal_index, left_value); READ_LITERAL (literal_index, left_value);
*(stack_top_p++) = right_value; *stack_top_p++ = right_value;
*(stack_top_p++) = left_value; *stack_top_p++ = left_value;
continue; continue;
} }
case VM_OC_PUSH_UNDEFINED: case VM_OC_PUSH_UNDEFINED:
case VM_OC_VOID:
{ {
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); *stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
break; continue;
} }
case VM_OC_PUSH_TRUE: case VM_OC_PUSH_TRUE:
{ {
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); *stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
break; continue;
} }
case VM_OC_PUSH_FALSE: case VM_OC_PUSH_FALSE:
{ {
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); *stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
break; continue;
} }
case VM_OC_PUSH_NULL: case VM_OC_PUSH_NULL:
{ {
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_NULL); *stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_NULL);
break; continue;
} }
case VM_OC_PUSH_THIS: case VM_OC_PUSH_THIS:
{ {
result = ecma_copy_value (frame_ctx_p->this_binding); *stack_top_p++ = ecma_copy_value (frame_ctx_p->this_binding);
break; continue;
} }
case VM_OC_PUSH_NUMBER_0: case VM_OC_PUSH_NUMBER_0:
{ {
@@ -933,9 +933,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_object_t *obj_p = ecma_create_object (prototype_p, ecma_object_t *obj_p = ecma_create_object (prototype_p,
true, true,
ECMA_OBJECT_TYPE_GENERAL); ECMA_OBJECT_TYPE_GENERAL);
result = ecma_make_object_value (obj_p);
ecma_deref_object (prototype_p); ecma_deref_object (prototype_p);
break; *stack_top_p++ = ecma_make_object_value (obj_p);
continue;
} }
case VM_OC_SET_PROPERTY: case VM_OC_SET_PROPERTY:
{ {
@@ -946,7 +946,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (ecma_is_value_string (right_value)) if (ecma_is_value_string (right_value))
{ {
prop_name_p = ecma_get_string_from_value (right_value); prop_name_p = ecma_get_string_from_value (right_value);
property_p = ecma_find_named_property (object_p, prop_name_p);
} }
else else
{ {
@@ -958,9 +957,10 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
} }
prop_name_p = ecma_get_string_from_value (result); prop_name_p = ecma_get_string_from_value (result);
property_p = ecma_find_named_property (object_p, prop_name_p);
} }
property_p = ecma_find_named_property (object_p, prop_name_p);
if (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA) if (property_p != NULL && ECMA_PROPERTY_GET_TYPE (property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA)
{ {
ecma_delete_property (object_p, property_p); ecma_delete_property (object_p, property_p);
@@ -980,7 +980,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
ecma_deref_ecma_string (prop_name_p); ecma_deref_ecma_string (prop_name_p);
} }
break;
goto free_both_values;
} }
case VM_OC_SET_GETTER: case VM_OC_SET_GETTER:
case VM_OC_SET_SETTER: case VM_OC_SET_SETTER:
@@ -989,7 +990,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
stack_top_p[-1], stack_top_p[-1],
left_value, left_value,
right_value); right_value);
break;
goto free_both_values;
} }
case VM_OC_PUSH_ARRAY: case VM_OC_PUSH_ARRAY:
{ {
@@ -999,12 +1001,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
continue;
} }
case VM_OC_PUSH_ELISON: case VM_OC_PUSH_ELISON:
{ {
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_ARRAY_HOLE); *stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_ARRAY_HOLE);
break; continue;
} }
case VM_OC_APPEND_ARRAY: case VM_OC_APPEND_ARRAY:
{ {
@@ -1056,13 +1060,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_value_assign_uint32 (&ECMA_PROPERTY_VALUE_PTR (length_prop_p)->value, ecma_value_assign_uint32 (&ECMA_PROPERTY_VALUE_PTR (length_prop_p)->value,
length_num); length_num);
break; continue;
} }
case VM_OC_PUSH_UNDEFINED_BASE: case VM_OC_PUSH_UNDEFINED_BASE:
{ {
result = stack_top_p[-1]; stack_top_p[0] = stack_top_p[-1];
stack_top_p[-1] = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); stack_top_p[-1] = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
break; stack_top_p++;
continue;
} }
case VM_OC_IDENT_REFERENCE: case VM_OC_IDENT_REFERENCE:
{ {
@@ -1076,7 +1081,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
*stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_REGISTER_REF); *stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_REGISTER_REF);
*stack_top_p++ = literal_index; *stack_top_p++ = literal_index;
result = ecma_copy_value (frame_ctx_p->registers_p[literal_index]); *stack_top_p++ = ecma_copy_value (frame_ctx_p->registers_p[literal_index]);
} }
else else
{ {
@@ -1106,8 +1111,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_ref_object (ref_base_lex_env_p); ecma_ref_object (ref_base_lex_env_p);
*stack_top_p++ = ecma_make_object_value (ref_base_lex_env_p); *stack_top_p++ = ecma_make_object_value (ref_base_lex_env_p);
*stack_top_p++ = ecma_make_string_value (name_p); *stack_top_p++ = ecma_make_string_value (name_p);
*stack_top_p++ = result;
} }
break; continue;
} }
case VM_OC_PROP_REFERENCE: case VM_OC_PROP_REFERENCE:
{ {
@@ -1380,12 +1386,19 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
goto error; goto error;
} }
if (VM_OC_HAS_PUT_RESULT (opcode_data)) if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)))
{ {
break;
}
ecma_fast_free_value (result); ecma_fast_free_value (result);
}
else if (opcode_data & VM_OC_PUT_STACK)
{
*stack_top_p++ = result;
}
else
{
ecma_fast_free_value (block_result);
block_result = result;
}
continue; continue;
} }
case VM_OC_NEW: case VM_OC_NEW:
@@ -1414,8 +1427,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
goto error; goto error;
} }
JERRY_ASSERT (VM_OC_HAS_PUT_RESULT (opcode_data)); *stack_top_p++ = result;
break; continue;
} }
case VM_OC_PROP_DELETE: case VM_OC_PROP_DELETE:
{ {
@@ -1425,7 +1438,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
JERRY_ASSERT (ecma_is_value_boolean (result));
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_DELETE: case VM_OC_DELETE:
{ {
@@ -1435,8 +1452,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (literal_index < register_end) if (literal_index < register_end)
{ {
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); *stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
break; continue;
} }
result = vm_op_delete_var (literal_start_p[literal_index], result = vm_op_delete_var (literal_start_p[literal_index],
@@ -1447,7 +1464,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
JERRY_ASSERT (ecma_is_value_boolean (result));
*stack_top_p++ = result;
continue;
} }
case VM_OC_JUMP: case VM_OC_JUMP:
{ {
@@ -1505,7 +1526,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_left_value;
} }
case VM_OC_MINUS: case VM_OC_MINUS:
{ {
@@ -1515,7 +1538,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_left_value;
} }
case VM_OC_NOT: case VM_OC_NOT:
{ {
@@ -1525,7 +1550,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_left_value;
} }
case VM_OC_BIT_NOT: case VM_OC_BIT_NOT:
{ {
@@ -1537,7 +1564,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_left_value;
}
case VM_OC_VOID:
{
*stack_top_p++ = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
goto free_left_value;
} }
case VM_OC_TYPEOF_IDENT: case VM_OC_TYPEOF_IDENT:
{ {
@@ -1559,17 +1593,16 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (ref_base_lex_env_p == NULL) if (ref_base_lex_env_p == NULL)
{ {
ecma_deref_ecma_string (name_p); result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
ecma_string_t *string_p = ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED);
result = ecma_make_string_value (string_p);
break;
} }
else
{
result = ecma_op_get_value_lex_env_base (ref_base_lex_env_p, result = ecma_op_get_value_lex_env_base (ref_base_lex_env_p,
name_p, name_p,
is_strict); is_strict);
}
ecma_deref_ecma_string (name_p); ecma_deref_ecma_string (name_p);
if (ecma_is_value_error (result)) if (ecma_is_value_error (result))
@@ -1589,7 +1622,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_left_value;
} }
case VM_OC_ADD: case VM_OC_ADD:
{ {
@@ -1657,7 +1692,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_NOT_EQUAL: case VM_OC_NOT_EQUAL:
{ {
@@ -1667,7 +1704,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_STRICT_EQUAL: case VM_OC_STRICT_EQUAL:
{ {
@@ -1675,7 +1714,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
result = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE result = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE); : ECMA_SIMPLE_VALUE_FALSE);
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_STRICT_NOT_EQUAL: case VM_OC_STRICT_NOT_EQUAL:
{ {
@@ -1683,7 +1724,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
result = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE result = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
: ECMA_SIMPLE_VALUE_TRUE); : ECMA_SIMPLE_VALUE_TRUE);
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_BIT_OR: case VM_OC_BIT_OR:
{ {
@@ -1765,7 +1808,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_GREATER: case VM_OC_GREATER:
{ {
@@ -1775,7 +1820,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_LESS_EQUAL: case VM_OC_LESS_EQUAL:
{ {
@@ -1785,7 +1832,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_GREATER_EQUAL: case VM_OC_GREATER_EQUAL:
{ {
@@ -1795,7 +1844,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_IN: case VM_OC_IN:
{ {
@@ -1805,7 +1856,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_INSTANCEOF: case VM_OC_INSTANCEOF:
{ {
@@ -1815,7 +1868,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{ {
goto error; goto error;
} }
break;
*stack_top_p++ = result;
goto free_both_values;
} }
case VM_OC_WITH: case VM_OC_WITH:
{ {
@@ -1891,7 +1946,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
context_top_p[-2] = chunk_p->next_chunk_cp; context_top_p[-2] = chunk_p->next_chunk_cp;
ecma_dealloc_collection_chunk (chunk_p); ecma_dealloc_collection_chunk (chunk_p);
break;
*stack_top_p++ = result;
continue;
} }
case VM_OC_FOR_IN_HAS_NEXT: case VM_OC_FOR_IN_HAS_NEXT:
{ {
@@ -2024,7 +2081,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
} }
JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p); JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
break; continue;
} }
case VM_OC_JUMP_AND_EXIT_CONTEXT: case VM_OC_JUMP_AND_EXIT_CONTEXT:
{ {
@@ -2052,12 +2109,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
default: default:
{ {
JERRY_UNREACHABLE (); JERRY_UNREACHABLE ();
break; continue;
} }
} }
if (VM_OC_HAS_PUT_RESULT (opcode_data)) JERRY_ASSERT (VM_OC_HAS_PUT_RESULT (opcode_data));
{
if (opcode_data & VM_OC_PUT_IDENT) if (opcode_data & VM_OC_PUT_IDENT)
{ {
uint16_t literal_index; uint16_t literal_index;
@@ -2153,10 +2210,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_fast_free_value (block_result); ecma_fast_free_value (block_result);
block_result = result; block_result = result;
} }
}
ecma_fast_free_value (left_value); free_both_values:
ecma_fast_free_value (right_value); ecma_fast_free_value (right_value);
free_left_value:
ecma_fast_free_value (left_value);
} }
error: error: