Skip to content

Commit 89e367b

Browse files
authored
Optimize typed array access (#4806)
Use uint32 indexes instead of double indexes. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg [email protected]
1 parent 960b997 commit 89e367b

File tree

10 files changed

+194
-181
lines changed

10 files changed

+194
-181
lines changed

jerry-core/api/jerry.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3309,7 +3309,11 @@ jerry_has_own_property (const jerry_value_t obj_val, /**< object value */
33093309
}
33103310
#endif /* JERRY_BUILTIN_PROXY */
33113311

3312-
return ecma_make_boolean_value (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p));
3312+
#if JERRY_BUILTIN_TYPEDARRAY
3313+
return jerry_return (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p));
3314+
#else /* !JERRY_BUILTIN_TYPEDARRAY */
3315+
return ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p);
3316+
#endif /* JERRY_BUILTIN_TYPEDARRAY */
33133317
} /* jerry_has_own_property */
33143318

33153319
/**

jerry-core/ecma/base/ecma-globals.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,19 @@ typedef enum
514514
*/
515515
#define ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP ECMA_PROPERTY_TYPE_DELETED
516516

517+
/**
518+
* Type of property not found and an exception is thrown.
519+
*/
520+
#define ECMA_PROPERTY_TYPE_NOT_FOUND_AND_THROW \
521+
(ECMA_PROPERTY_FLAG_LCACHED | (ECMA_DIRECT_STRING_SPECIAL << ECMA_PROPERTY_NAME_TYPE_SHIFT))
522+
523+
/**
524+
* Checks whether a property is not found.
525+
*/
526+
#define ECMA_PROPERTY_IS_FOUND(property) \
527+
(((property) & (ECMA_PROPERTY_FLAG_DATA | (ECMA_DIRECT_STRING_SPECIAL << ECMA_PROPERTY_NAME_TYPE_SHIFT))) \
528+
!= (ECMA_DIRECT_STRING_SPECIAL << ECMA_PROPERTY_NAME_TYPE_SHIFT))
529+
517530
/**
518531
* Abstract property representation.
519532
*

jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ ecma_builtin_object_prototype_object_has_own_property (ecma_object_t *obj_p, /**
147147
}
148148
#endif /* JERRY_BUILTIN_PROXY */
149149

150-
return ecma_make_boolean_value (ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p));
150+
return ecma_op_ordinary_object_has_own_property (obj_p, prop_name_p);
151151
} /* ecma_builtin_object_prototype_object_has_own_property */
152152

153153
/**

jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,7 @@ static ecma_value_t
13521352
ecma_builtin_typedarray_prototype_at (ecma_typedarray_info_t *info_p, /**< object info */
13531353
const ecma_value_t index) /**< index argument */
13541354
{
1355-
ecma_length_t len = (ecma_length_t) info_p->length;
1355+
ecma_length_t len = info_p->length;
13561356
ecma_length_t res_index;
13571357
ecma_value_t return_value = ecma_builtin_helper_calculate_index (index, len, &res_index);
13581358

@@ -1361,7 +1361,12 @@ ecma_builtin_typedarray_prototype_at (ecma_typedarray_info_t *info_p, /**< objec
13611361
return return_value;
13621362
}
13631363

1364-
return ecma_get_typedarray_element (info_p, (ecma_number_t) res_index);
1364+
if (res_index >= UINT32_MAX)
1365+
{
1366+
return ECMA_VALUE_UNDEFINED;
1367+
}
1368+
1369+
return ecma_get_typedarray_element (info_p, (uint32_t) res_index);
13651370
} /* ecma_builtin_typedarray_prototype_at */
13661371

13671372
/**

jerry-core/ecma/operations/ecma-objects-general.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,10 @@ ecma_op_general_object_delete (ecma_object_t *obj_p, /**< the object */
102102
ECMA_PROPERTY_GET_NO_OPTIONS);
103103

104104
/* 2. */
105-
if (property == ECMA_PROPERTY_TYPE_NOT_FOUND || property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
105+
if (!ECMA_PROPERTY_IS_FOUND (property))
106106
{
107+
JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_NOT_FOUND
108+
|| property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP);
107109
return ECMA_VALUE_TRUE;
108110
}
109111

@@ -419,8 +421,11 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
419421
&ext_property_ref.property_ref,
420422
ECMA_PROPERTY_GET_VALUE | ECMA_PROPERTY_GET_EXT_REFERENCE);
421423

422-
if (current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND || current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
424+
if (!ECMA_PROPERTY_IS_FOUND (current_prop))
423425
{
426+
JERRY_ASSERT (current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND
427+
|| current_prop == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP);
428+
424429
/* 3. */
425430
if (!ecma_op_ordinary_object_is_extensible (object_p))
426431
{

jerry-core/ecma/operations/ecma-objects.c

Lines changed: 90 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -139,49 +139,42 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
139139
{
140140
break;
141141
}
142-
ecma_number_t num = ecma_string_to_number (property_name_p);
143-
bool is_same;
144-
if (num <= 0)
145-
{
146-
is_same = true;
147-
}
148-
else
149-
{
150-
ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num);
151-
is_same = ecma_compare_ecma_strings (property_name_p, num_to_str);
152-
ecma_deref_ecma_string (num_to_str);
153-
}
154142

155-
if (is_same)
143+
uint32_t index = ecma_string_get_array_index (property_name_p);
144+
145+
if (index == ECMA_STRING_NOT_ARRAY_INDEX)
156146
{
157-
ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p);
158-
ecma_value_t value = ecma_get_typedarray_element (&info, num);
147+
JERRY_ASSERT (index == UINT32_MAX);
159148

160-
if (ECMA_IS_VALUE_ERROR (value))
149+
if (!ecma_typedarray_is_element_index (property_name_p))
161150
{
162-
property_ref_p->virtual_value = value;
163-
return ECMA_PROPERTY_TYPE_NOT_FOUND;
151+
break;
164152
}
153+
}
165154

166-
if (!ecma_is_value_undefined (value))
167-
{
168-
if (options & ECMA_PROPERTY_GET_VALUE)
169-
{
170-
property_ref_p->virtual_value = value;
171-
}
172-
else
173-
{
174-
ecma_fast_free_value (value);
175-
}
155+
ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p);
156+
ecma_value_t value = ecma_get_typedarray_element (&info, index);
176157

177-
return ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_PROPERTY_VIRTUAL;
178-
}
179-
else
180-
{
181-
return ECMA_PROPERTY_TYPE_NOT_FOUND;
182-
}
158+
if (ECMA_IS_VALUE_ERROR (value))
159+
{
160+
return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_THROW;
183161
}
184-
break;
162+
163+
if (JERRY_UNLIKELY (ecma_is_value_undefined (value)))
164+
{
165+
return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP;
166+
}
167+
168+
if (options & ECMA_PROPERTY_GET_VALUE)
169+
{
170+
property_ref_p->virtual_value = value;
171+
}
172+
else
173+
{
174+
ecma_fast_free_value (value);
175+
}
176+
177+
return ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_PROPERTY_VIRTUAL;
185178
}
186179
#endif /* JERRY_BUILTIN_TYPEDARRAY */
187180
#if JERRY_MODULE_SYSTEM
@@ -457,48 +450,25 @@ ecma_op_object_has_property (ecma_object_t *object_p, /**< the object */
457450
}
458451
#endif /* JERRY_BUILTIN_PROXY */
459452

460-
#if JERRY_BUILTIN_TYPEDARRAY
461-
if (ecma_object_is_typedarray (object_p) && !ecma_prop_name_is_symbol (property_name_p))
453+
/* 2 - 3. */
454+
ecma_property_t property = ecma_op_object_get_own_property (object_p,
455+
property_name_p,
456+
NULL,
457+
ECMA_PROPERTY_GET_NO_OPTIONS);
458+
459+
if (property != ECMA_PROPERTY_TYPE_NOT_FOUND)
462460
{
463-
ecma_number_t num = ecma_string_to_number (property_name_p);
464-
bool is_same;
465-
if (num <= 0)
466-
{
467-
is_same = true;
468-
}
469-
else
461+
#if JERRY_BUILTIN_TYPEDARRAY
462+
if (JERRY_UNLIKELY (property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_THROW))
470463
{
471-
ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num);
472-
is_same = ecma_compare_ecma_strings (property_name_p, num_to_str);
473-
ecma_deref_ecma_string (num_to_str);
464+
return ECMA_VALUE_ERROR;
474465
}
475-
476-
if (is_same)
477-
{
478-
ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p);
479-
480-
if (ecma_arraybuffer_is_detached (info.array_buffer_p))
481-
{
482-
return ecma_raise_type_error (ECMA_ERR_MSG (ecma_error_arraybuffer_is_detached));
483-
}
484-
485-
if (!ecma_op_is_integer (num)
486-
|| num >= info.length
487-
|| num < 0
488-
|| (ecma_number_is_negative (num) && ecma_number_is_zero (num)))
489-
{
490-
return ECMA_VALUE_FALSE;
491-
}
492-
493-
return ECMA_VALUE_TRUE;
494-
}
495-
}
496466
#endif /* JERRY_BUILTIN_TYPEDARRAY */
497467

498-
/* 2 - 3. */
499-
if (ecma_op_ordinary_object_has_own_property (object_p, property_name_p))
500-
{
501-
return ECMA_VALUE_TRUE;
468+
JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP
469+
|| ECMA_PROPERTY_IS_FOUND (property));
470+
471+
return ecma_make_boolean_value (property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP);
502472
}
503473

504474
jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (object_p);
@@ -604,26 +574,20 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
604574
break;
605575
}
606576

607-
ecma_number_t num = ecma_string_to_number (property_name_p);
608-
bool is_same;
609-
if (num <= 0)
610-
{
611-
is_same = true;
612-
}
613-
else
614-
{
615-
ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num);
616-
is_same = ecma_compare_ecma_strings (property_name_p, num_to_str);
617-
ecma_deref_ecma_string (num_to_str);
618-
}
577+
uint32_t index = ecma_string_get_array_index (property_name_p);
619578

620-
if (is_same)
579+
if (index == ECMA_STRING_NOT_ARRAY_INDEX)
621580
{
622-
ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p);
623-
return ecma_get_typedarray_element (&info, num);
581+
JERRY_ASSERT (index == UINT32_MAX);
582+
583+
if (!ecma_typedarray_is_element_index (property_name_p))
584+
{
585+
break;
586+
}
624587
}
625588

626-
break;
589+
ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p);
590+
return ecma_get_typedarray_element (&info, index);
627591
}
628592
#endif /* JERRY_BUILTIN_TYPEDARRAY */
629593
#if JERRY_MODULE_SYSTEM
@@ -1447,25 +1411,20 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
14471411
break;
14481412
}
14491413

1450-
ecma_number_t num = ecma_string_to_number (property_name_p);
1451-
bool is_same;
1452-
if (num <= 0)
1453-
{
1454-
is_same = true;
1455-
}
1456-
else
1457-
{
1458-
ecma_string_t *num_to_str = ecma_new_ecma_string_from_number (num);
1459-
is_same = ecma_compare_ecma_strings (property_name_p, num_to_str);
1460-
ecma_deref_ecma_string (num_to_str);
1461-
}
1414+
uint32_t index = ecma_string_get_array_index (property_name_p);
14621415

1463-
if (is_same)
1416+
if (index == ECMA_STRING_NOT_ARRAY_INDEX)
14641417
{
1465-
ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p);
1466-
return ecma_set_typedarray_element (&info, value, num);
1418+
JERRY_ASSERT (index == UINT32_MAX);
1419+
1420+
if (!ecma_typedarray_is_element_index (property_name_p))
1421+
{
1422+
break;
1423+
}
14671424
}
1468-
break;
1425+
1426+
ecma_typedarray_info_t info = ecma_typedarray_get_info (object_p);
1427+
return ecma_set_typedarray_element (&info, value, index);
14691428
}
14701429
#endif /* JERRY_BUILTIN_TYPEDARRAY */
14711430
#if JERRY_MODULE_SYSTEM
@@ -1668,8 +1627,7 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
16681627
&property_ref,
16691628
ECMA_PROPERTY_GET_NO_OPTIONS);
16701629

1671-
if (inherited_property != ECMA_PROPERTY_TYPE_NOT_FOUND
1672-
&& inherited_property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
1630+
if (ECMA_PROPERTY_IS_FOUND (inherited_property))
16731631
{
16741632
JERRY_ASSERT (ECMA_PROPERTY_IS_NAMED_PROPERTY (inherited_property));
16751633

@@ -1683,6 +1641,9 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
16831641
create_new_property = ecma_is_property_writable (inherited_property);
16841642
break;
16851643
}
1644+
1645+
JERRY_ASSERT (inherited_property == ECMA_PROPERTY_TYPE_NOT_FOUND
1646+
|| inherited_property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP);
16861647
}
16871648

16881649
#if JERRY_BUILTIN_PROXY
@@ -1962,13 +1923,18 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob
19621923
&property_ref,
19631924
ECMA_PROPERTY_GET_VALUE);
19641925

1965-
if (ECMA_IS_VALUE_ERROR (property_ref.virtual_value))
1926+
if (!ECMA_PROPERTY_IS_FOUND (property))
19661927
{
1967-
return property_ref.virtual_value;
1968-
}
1928+
#if JERRY_BUILTIN_TYPEDARRAY
1929+
if (JERRY_UNLIKELY (property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_THROW))
1930+
{
1931+
return ECMA_VALUE_ERROR;
1932+
}
1933+
#endif /* JERRY_BUILTIN_TYPEDARRAY */
1934+
1935+
JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_NOT_FOUND
1936+
|| property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP);
19691937

1970-
if (property == ECMA_PROPERTY_TYPE_NOT_FOUND || property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP)
1971-
{
19721938
return ECMA_VALUE_FALSE;
19731939
}
19741940

@@ -3488,7 +3454,7 @@ ecma_op_ordinary_object_prevent_extensions (ecma_object_t *object_p) /**< object
34883454
* @return true - if property is found
34893455
* false - otherwise
34903456
*/
3491-
extern inline bool JERRY_ATTR_ALWAYS_INLINE
3457+
extern inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
34923458
ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, /**< the object */
34933459
ecma_string_t *property_name_p) /**< property name */
34943460
{
@@ -3499,7 +3465,18 @@ ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, /**< the obje
34993465
NULL,
35003466
ECMA_PROPERTY_GET_NO_OPTIONS);
35013467

3502-
return property != ECMA_PROPERTY_TYPE_NOT_FOUND && property != ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP;
3468+
#if JERRY_BUILTIN_TYPEDARRAY
3469+
if (JERRY_UNLIKELY (property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_THROW))
3470+
{
3471+
return ECMA_VALUE_ERROR;
3472+
}
3473+
#endif /* JERRY_BUILTIN_TYPEDARRAY */
3474+
3475+
JERRY_ASSERT (ECMA_PROPERTY_IS_FOUND (property)
3476+
|| property == ECMA_PROPERTY_TYPE_NOT_FOUND
3477+
|| property == ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP);
3478+
3479+
return ecma_make_boolean_value (ECMA_PROPERTY_IS_FOUND (property));
35033480
} /* ecma_op_ordinary_object_has_own_property */
35043481

35053482
#if JERRY_BUILTIN_WEAKREF || JERRY_BUILTIN_CONTAINER

jerry-core/ecma/operations/ecma-objects.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ ecma_value_t ecma_raise_readonly_assignment (ecma_string_t *property_name_p, boo
5858

5959
ecma_property_t ecma_op_object_get_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
6060
ecma_property_ref_t *property_ref_p, uint32_t options);
61-
bool ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
61+
ecma_value_t ecma_op_ordinary_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
6262
ecma_value_t ecma_op_object_has_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
6363
ecma_value_t ecma_op_object_find_own (ecma_value_t base_value, ecma_object_t *object_p, ecma_string_t *property_name_p);
6464
ecma_value_t ecma_op_object_find (ecma_object_t *object_p, ecma_string_t *property_name_p);

0 commit comments

Comments
 (0)