Skip to content

Optimize conditional jumps. #1104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ typedef enum
* - immutable binding values
* - special register or stack values for vm
*/
ECMA_SIMPLE_VALUE_EMPTY,
ECMA_SIMPLE_VALUE_UNDEFINED, /**< undefined value */
ECMA_SIMPLE_VALUE_NULL, /**< null value */
ECMA_SIMPLE_VALUE_EMPTY, /**< uninitialized value */
ECMA_SIMPLE_VALUE_ARRAY_HOLE, /**< array hole, used for initialization of an array literal */
ECMA_SIMPLE_VALUE_FALSE, /**< boolean false */
ECMA_SIMPLE_VALUE_TRUE, /**< boolean true */
ECMA_SIMPLE_VALUE_ARRAY_HOLE, /**< array hole, used for initialization of an array literal */
ECMA_SIMPLE_VALUE_UNDEFINED, /**< undefined value */
ECMA_SIMPLE_VALUE_NULL, /**< null value */
ECMA_SIMPLE_VALUE_REGISTER_REF, /**< register reference, a special "base" value for vm */
ECMA_SIMPLE_VALUE__COUNT /** count of simple ecma values */
} ecma_simple_value_t;
Expand Down
43 changes: 39 additions & 4 deletions jerry-core/ecma/base/ecma-helpers-value.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ JERRY_STATIC_ASSERT (sizeof (uintptr_t) > sizeof (ecma_value_t),

#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */

JERRY_STATIC_ASSERT ((ECMA_SIMPLE_VALUE_FALSE | 0x1) == ECMA_SIMPLE_VALUE_TRUE
&& ECMA_SIMPLE_VALUE_FALSE != ECMA_SIMPLE_VALUE_TRUE,
only_the_lowest_bit_must_be_different_for_simple_value_true_and_false);

/**
* Get type field of ecma value
*
Expand Down Expand Up @@ -109,6 +113,18 @@ ecma_get_pointer_from_ecma_value (ecma_value_t value) /**< value */
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
} /* ecma_get_pointer_from_ecma_value */

/**
* Check if the value is simple ecma-value.
*
* @return true - if the value is a simple value,
* false - otherwise.
*/
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_simple (ecma_value_t value) /**< ecma value */
{
return (value & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_SIMPLE_VALUE;
} /* ecma_is_value_simple */

/**
* Check whether the value is a given simple value.
*
Expand Down Expand Up @@ -167,7 +183,7 @@ ecma_is_value_null (ecma_value_t value) /**< ecma value */
inline bool __attr_pure___ __attr_always_inline___
ecma_is_value_boolean (ecma_value_t value) /**< ecma value */
{
return ecma_is_value_true (value) || ecma_is_value_false (value);
return ecma_is_value_true (value | (1 << ECMA_DIRECT_SHIFT));
} /* ecma_is_value_boolean */

/**
Expand Down Expand Up @@ -500,6 +516,14 @@ ecma_get_integer_from_value (ecma_value_t value) /**< ecma value */
return ((ecma_integer_value_t) value) >> ECMA_DIRECT_SHIFT;
} /* ecma_get_integer_from_value */

inline ecma_number_t __attr_pure___ __attr_always_inline___
ecma_get_float_from_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);

return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_float_from_value */

/**
* Get floating point value from an ecma value
*
Expand All @@ -513,9 +537,7 @@ ecma_get_number_from_value (ecma_value_t value) /**< ecma value */
return (ecma_number_t) ecma_get_integer_from_value (value);
}

JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);

return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
return ecma_get_float_from_value (value);
} /* ecma_get_number_from_value */

/**
Expand Down Expand Up @@ -563,6 +585,19 @@ ecma_get_object_from_value (ecma_value_t value) /**< ecma value */
return (ecma_object_t *) ecma_get_pointer_from_ecma_value (value);
} /* ecma_get_object_from_value */

/**
* Invert a boolean value
*
* @return ecma value
*/
inline ecma_value_t __attr_pure___ __attr_always_inline___
ecma_invert_boolean_value (ecma_value_t value) /**< ecma value */
{
JERRY_ASSERT (ecma_is_value_boolean (value));

return (value ^ (1 << ECMA_DIRECT_SHIFT));
} /* ecma_invert_boolean_value */

/**
* Get the value from an error ecma value
*
Expand Down
39 changes: 21 additions & 18 deletions jerry-core/ecma/base/ecma-helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,26 +114,27 @@
}

/* ecma-helpers-value.c */
extern bool ecma_is_value_empty (ecma_value_t);
extern bool ecma_is_value_undefined (ecma_value_t);
extern bool ecma_is_value_null (ecma_value_t);
extern bool ecma_is_value_boolean (ecma_value_t);
extern bool ecma_is_value_true (ecma_value_t);
extern bool ecma_is_value_false (ecma_value_t);
extern bool ecma_is_value_array_hole (ecma_value_t);

extern bool ecma_is_value_integer_number (ecma_value_t);
extern bool ecma_are_values_integer_numbers (ecma_value_t, ecma_value_t);
extern bool ecma_is_value_float_number (ecma_value_t);
extern bool ecma_is_value_number (ecma_value_t);
extern bool ecma_is_value_string (ecma_value_t);
extern bool ecma_is_value_object (ecma_value_t);
extern bool ecma_is_value_error (ecma_value_t);
extern bool ecma_is_value_simple (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_empty (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_undefined (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_null (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_boolean (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_true (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_false (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_array_hole (ecma_value_t) __attr_pure___;

extern bool ecma_is_value_integer_number (ecma_value_t) __attr_pure___;
extern bool ecma_are_values_integer_numbers (ecma_value_t, ecma_value_t) __attr_pure___;
extern bool ecma_is_value_float_number (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_number (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_string (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_object (ecma_value_t) __attr_pure___;
extern bool ecma_is_value_error (ecma_value_t) __attr_pure___;

extern void ecma_check_value_type_is_spec_defined (ecma_value_t);

extern ecma_value_t ecma_make_simple_value (const ecma_simple_value_t value);
extern ecma_value_t ecma_make_integer_value (ecma_integer_value_t);
extern ecma_value_t ecma_make_simple_value (const ecma_simple_value_t value) __attr_const___;
extern ecma_value_t ecma_make_integer_value (ecma_integer_value_t) __attr_const___;
extern ecma_value_t ecma_make_nan_value (void);
extern ecma_value_t ecma_make_number_value (ecma_number_t);
extern ecma_value_t ecma_make_int32_value (int32_t);
Expand All @@ -142,12 +143,14 @@ extern ecma_value_t ecma_make_string_value (const ecma_string_t *);
extern ecma_value_t ecma_make_object_value (const ecma_object_t *);
extern ecma_value_t ecma_make_error_value (ecma_value_t);
extern ecma_value_t ecma_make_error_obj_value (const ecma_object_t *);
extern ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t);
extern ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t) __attr_pure___;
extern ecma_number_t ecma_get_float_from_value (ecma_value_t value) __attr_pure___;
extern ecma_number_t ecma_get_number_from_value (ecma_value_t) __attr_pure___;
extern uint32_t ecma_get_uint32_from_value (ecma_value_t) __attr_pure___;
extern ecma_string_t *ecma_get_string_from_value (ecma_value_t) __attr_pure___;
extern ecma_object_t *ecma_get_object_from_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_get_value_from_error_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_invert_boolean_value (ecma_value_t) __attr_pure___;
extern ecma_value_t ecma_copy_value (ecma_value_t);
extern ecma_value_t ecma_fast_copy_value (ecma_value_t);
extern ecma_value_t ecma_copy_value_if_not_object (ecma_value_t);
Expand Down
12 changes: 6 additions & 6 deletions jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c
Original file line number Diff line number Diff line change
Expand Up @@ -2027,8 +2027,8 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu
/* 7.c.ii */
ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value);

/* 7.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */
if (ecma_is_value_false (ecma_op_to_boolean (call_value)))
/* 7.c.iii */
if (!ecma_op_to_boolean (call_value))
{
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
}
Expand Down Expand Up @@ -2125,8 +2125,8 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum
/* 7.c.ii */
ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value);

/* 7.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */
if (ecma_is_value_true (ecma_op_to_boolean (call_value)))
/* 7.c.iii */
if (ecma_op_to_boolean (call_value))
{
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
}
Expand Down Expand Up @@ -2430,8 +2430,8 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg
/* 9.c.ii */
ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value);

/* 9.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */
if (ecma_is_value_true (ecma_op_to_boolean (call_value)))
/* 9.c.iii */
if (ecma_op_to_boolean (call_value))
{
ecma_string_t *to_index_string_p = ecma_new_ecma_string_from_uint32 (new_array_index);

Expand Down
3 changes: 2 additions & 1 deletion jerry-core/ecma/builtin-objects/ecma-builtin-boolean.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ ecma_builtin_boolean_dispatch_call (const ecma_value_t *arguments_list_p, /**< a
arg_value = arguments_list_p[0];
}

return ecma_op_to_boolean (arg_value);
return ecma_make_simple_value (ecma_op_to_boolean (arg_value) ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
} /* ecma_builtin_boolean_dispatch_call */

/**
Expand Down
13 changes: 6 additions & 7 deletions jerry-core/ecma/operations/ecma-boolean-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,7 @@
ecma_value_t
ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boolean constructor */
{
ecma_value_t conv_to_boolean_completion = ecma_op_to_boolean (arg);

if (ecma_is_value_error (conv_to_boolean_completion))
{
return conv_to_boolean_completion;
}
bool boolean_value = ecma_op_to_boolean (arg);

#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE);
Expand All @@ -64,7 +59,11 @@ ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boo

ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p,
ECMA_INTERNAL_PROPERTY_ECMA_VALUE);
ecma_set_internal_property_value (prim_value_prop_p, conv_to_boolean_completion);

ecma_value_t prim_value = ecma_make_simple_value (boolean_value ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);

ecma_set_internal_property_value (prim_value_prop_p, prim_value);

return ecma_make_object_value (obj_p);
} /* ecma_op_create_boolean_object */
Expand Down
7 changes: 2 additions & 5 deletions jerry-core/ecma/operations/ecma-comparison.c
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,12 @@ ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */
{
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);

ecma_value_t first_converted_value = left_first ? x : y;
ecma_value_t second_converted_value = left_first ? y : x;

// 1., 2.
ECMA_TRY_CATCH (prim_first_converted_value,
ecma_op_to_primitive (first_converted_value, ECMA_PREFERRED_TYPE_NUMBER),
ecma_op_to_primitive (x, ECMA_PREFERRED_TYPE_NUMBER),
ret_value);
ECMA_TRY_CATCH (prim_second_converted_value,
ecma_op_to_primitive (second_converted_value, ECMA_PREFERRED_TYPE_NUMBER),
ecma_op_to_primitive (y, ECMA_PREFERRED_TYPE_NUMBER),
ret_value);

const ecma_value_t px = left_first ? prim_first_converted_value : prim_second_converted_value;
Expand Down
Loading