Skip to content

Commit 7ab6225

Browse files
committed
Refactor ECMA builtin template
Avoid sorting the array of property magic string IDs and make it const, thus ensuring that it gets placed in .rodata. Replace the binary search in the array (which would not work anymore because of unsortendness) with function that returns the index of the looked-after magic string ID using a switch-based logic (we rely on compiler optimization to generate optimal code from that switch). Extras: * Getting rid of the superfluous macro argument from routine names. * Fixing the list of undef'd macros * Fixing builtin-related comments JerryScript-DCO-1.0-Signed-off-by: Akos Kiss [email protected]
1 parent a0bedaa commit 7ab6225

File tree

4 files changed

+115
-138
lines changed

4 files changed

+115
-138
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h

Lines changed: 111 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
1+
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
2+
* Copyright 2016 University of Szeged
23
*
34
* Licensed under the Apache License, Version 2.0 (the "License");
45
* you may not use this file except in compliance with the License.
@@ -27,14 +28,14 @@
2728
#define PASTE_(x, y) PASTE__ (x, y)
2829
#define PASTE(x, y) PASTE_ (x, y)
2930

30-
#define SORT_PROPERTY_NAMES_ROUTINE_NAME(builtin_underscored_id) \
31-
PASTE (PASTE (ecma_builtin_, builtin_underscored_id), _sort_property_names)
32-
#define TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME(builtin_underscored_id) \
33-
PASTE (PASTE (ecma_builtin_, builtin_underscored_id), _try_to_instantiate_property)
34-
#define LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME(builtin_underscored_id) \
35-
PASTE (PASTE (ecma_builtin_, builtin_underscored_id), _list_lazy_property_names)
36-
#define DISPATCH_ROUTINE_ROUTINE_NAME(builtin_underscored_id) \
37-
PASTE (PASTE (ecma_builtin_, builtin_underscored_id), _dispatch_routine)
31+
#define FIND_PROPERTY_INDEX_ROUTINE_NAME \
32+
PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _find_property_index)
33+
#define TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME \
34+
PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _try_to_instantiate_property)
35+
#define LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME \
36+
PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _list_lazy_property_names)
37+
#define DISPATCH_ROUTINE_ROUTINE_NAME \
38+
PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _dispatch_routine)
3839

3940
#define ROUTINE_ARG(n) , ecma_value_t arg ## n
4041
#define ROUTINE_ARG_LIST_0 ecma_value_t this_arg
@@ -56,7 +57,7 @@
5657
#define ECMA_BUILTIN_PROPERTY_NAMES \
5758
PASTE (PASTE (ecma_builtin_property_names, _), BUILTIN_UNDERSCORED_ID)
5859

59-
static lit_magic_string_id_t ECMA_BUILTIN_PROPERTY_NAMES[] =
60+
static const lit_magic_string_id_t ECMA_BUILTIN_PROPERTY_NAMES[] =
6061
{
6162
#define SIMPLE_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) name,
6263
#define NUMBER_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) name,
@@ -67,34 +68,79 @@ static lit_magic_string_id_t ECMA_BUILTIN_PROPERTY_NAMES[] =
6768
#include BUILTIN_INC_HEADER_NAME
6869
};
6970

71+
#define ECMA_BUILTIN_PROPERTY_NAME_INDEX(name) \
72+
PASTE (PASTE (PASTE (PASTE (ecma_builtin_property_names, _), BUILTIN_UNDERSCORED_ID), _), name)
73+
74+
enum
75+
{
76+
#define SIMPLE_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
77+
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
78+
#define NUMBER_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
79+
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
80+
#define STRING_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
81+
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
82+
#define CP_UNIMPLEMENTED_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
83+
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
84+
#define OBJECT_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
85+
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
86+
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
87+
ECMA_BUILTIN_PROPERTY_NAME_INDEX(name),
88+
#include BUILTIN_INC_HEADER_NAME
89+
};
90+
7091
/**
71-
* Sort builtin's property names array
92+
* Return the index of a magic string ID in the ECMA_BUILTIN_PROPERTY_NAMES
93+
* array, or -1 if not found.
94+
*
95+
* Note: we trust the compiler to find the optimal (most performance and/or
96+
* memory effective) way of implementing the switch construct of this function
97+
* in binary code (e.g., jump tables for large consecutive cases, binary search
98+
* for non-consecutive cases, some simple conditional branches for low number of
99+
* cases, etc. -- the worst case is a linear sequence of comparisons, but even
100+
* that's not that bad, since we cannot have more than 64 IDs in the array).
72101
*/
73-
void
74-
SORT_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (void)
102+
static int32_t
103+
FIND_PROPERTY_INDEX_ROUTINE_NAME (lit_magic_string_id_t id) /**< magic string id */
75104
{
76-
bool swapped;
77-
78-
do
105+
switch (id)
79106
{
80-
swapped = false;
81-
82-
for (ecma_length_t i = 1;
83-
i < (sizeof (ECMA_BUILTIN_PROPERTY_NAMES) / sizeof (ECMA_BUILTIN_PROPERTY_NAMES[0]));
84-
i++)
107+
#define SIMPLE_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
108+
case name: \
109+
{ \
110+
return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \
111+
}
112+
#define NUMBER_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
113+
case name: \
114+
{ \
115+
return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \
116+
}
117+
#define STRING_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
118+
case name: \
119+
{ \
120+
return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \
121+
}
122+
#define CP_UNIMPLEMENTED_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
123+
case name: \
124+
{ \
125+
return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \
126+
}
127+
#define OBJECT_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \
128+
case name: \
129+
{ \
130+
return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \
131+
}
132+
#define ROUTINE(name, c_function_name, args_number, length_prop_value) \
133+
case name: \
134+
{ \
135+
return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \
136+
}
137+
#include BUILTIN_INC_HEADER_NAME
138+
default:
85139
{
86-
if (ECMA_BUILTIN_PROPERTY_NAMES[i] < ECMA_BUILTIN_PROPERTY_NAMES[i - 1])
87-
{
88-
lit_magic_string_id_t id_temp = ECMA_BUILTIN_PROPERTY_NAMES[i - 1];
89-
ECMA_BUILTIN_PROPERTY_NAMES[i - 1] = ECMA_BUILTIN_PROPERTY_NAMES[i];
90-
ECMA_BUILTIN_PROPERTY_NAMES[i] = id_temp;
91-
92-
swapped = true;
93-
}
140+
return -1;
94141
}
95142
}
96-
while (swapped);
97-
} /* SORT_PROPERTY_NAMES_ROUTINE_NAME */
143+
} /* FIND_PROPERTY_INDEX_ROUTINE_NAME */
98144

99145
/**
100146
* If the property's name is one of built-in properties of the built-in object
@@ -105,8 +151,8 @@ SORT_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (void)
105151
* NULL - otherwise.
106152
*/
107153
ecma_property_t *
108-
TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t *obj_p, /**< object */
109-
ecma_string_t *prop_name_p) /**< property's name */
154+
TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (ecma_object_t *obj_p, /**< object */
155+
ecma_string_t *prop_name_p) /**< property's name */
110156
{
111157
#define OBJECT_ID(builtin_id) const ecma_builtin_id_t builtin_object_id = builtin_id;
112158
#include BUILTIN_INC_HEADER_NAME
@@ -121,12 +167,7 @@ TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t
121167
return NULL;
122168
}
123169

124-
const ecma_length_t property_numbers = (ecma_length_t) (sizeof (ECMA_BUILTIN_PROPERTY_NAMES) /
125-
sizeof (ECMA_BUILTIN_PROPERTY_NAMES[0]));
126-
int32_t index;
127-
index = ecma_builtin_bin_search_for_magic_string_id_in_array (ECMA_BUILTIN_PROPERTY_NAMES,
128-
property_numbers,
129-
id);
170+
int32_t index = FIND_PROPERTY_INDEX_ROUTINE_NAME (id);
130171

131172
if (index == -1)
132173
{
@@ -284,21 +325,21 @@ TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t
284325
* @return string values collection
285326
*/
286327
void
287-
LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t *object_p, /**< a built-in object */
288-
/** true - list enumerable properties
289-
* into main collection,
290-
* and non-enumerable to
291-
* collection of 'skipped
292-
* non-enumerable'
293-
* properties,
294-
* false - list all properties into
295-
* main collection.
296-
*/
297-
bool separate_enumerable,
298-
/** 'main' collection */
299-
ecma_collection_header_t *main_collection_p,
300-
/** skipped 'non-enumerable' collection */
301-
ecma_collection_header_t *non_enum_collection_p)
328+
LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (ecma_object_t *object_p, /**< a built-in object */
329+
/** true - list enumerable properties
330+
* into main collection,
331+
* and non-enumerable to
332+
* collection of 'skipped
333+
* non-enumerable'
334+
* properties,
335+
* false - list all properties into
336+
* main collection.
337+
*/
338+
bool separate_enumerable,
339+
/** 'main' collection */
340+
ecma_collection_header_t *main_collection_p,
341+
/** skipped 'non-enumerable' collection */
342+
ecma_collection_header_t *non_enum_collection_p)
302343
{
303344
ecma_collection_header_t *for_enumerable_p = main_collection_p;
304345
(void) for_enumerable_p;
@@ -313,16 +354,11 @@ LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t *o
313354
const ecma_length_t properties_number = (ecma_length_t) (sizeof (ECMA_BUILTIN_PROPERTY_NAMES) /
314355
sizeof (ECMA_BUILTIN_PROPERTY_NAMES[0]));
315356

316-
for (ecma_length_t i = 0;
317-
i < properties_number;
318-
i++)
357+
for (ecma_length_t index = 0;
358+
index < properties_number;
359+
index++)
319360
{
320-
lit_magic_string_id_t name = ECMA_BUILTIN_PROPERTY_NAMES[i];
321-
322-
int32_t index;
323-
index = ecma_builtin_bin_search_for_magic_string_id_in_array (ECMA_BUILTIN_PROPERTY_NAMES,
324-
properties_number,
325-
name);
361+
lit_magic_string_id_t name = ECMA_BUILTIN_PROPERTY_NAMES[index];
326362

327363
uint32_t bit;
328364
ecma_internal_property_id_t mask_prop_id;
@@ -398,14 +434,14 @@ LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t *o
398434
* Returned value must be freed with ecma_free_value.
399435
*/
400436
ecma_value_t
401-
DISPATCH_ROUTINE_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (uint16_t builtin_routine_id, /**< built-in wide routine
402-
identifier */
403-
ecma_value_t this_arg_value, /**< 'this' argument
404-
value */
405-
const ecma_value_t arguments_list[], /**< list of arguments
406-
passed to routine */
407-
ecma_length_t arguments_number) /**< length of
408-
arguments' list */
437+
DISPATCH_ROUTINE_ROUTINE_NAME (uint16_t builtin_routine_id, /**< built-in wide routine
438+
identifier */
439+
ecma_value_t this_arg_value, /**< 'this' argument
440+
value */
441+
const ecma_value_t arguments_list[], /**< list of arguments
442+
passed to routine */
443+
ecma_length_t arguments_number) /**< length of
444+
arguments' list */
409445
{
410446
/* the arguments may be unused for some built-ins */
411447
(void) this_arg_value;
@@ -444,10 +480,11 @@ DISPATCH_ROUTINE_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (uint16_t builtin_routine
444480
#undef PASTE__
445481
#undef PASTE_
446482
#undef PASTE
447-
#undef SORT_PROPERTY_NAMES_ROUTINE_NAME
448-
#undef DISPATCH_ROUTINE_ROUTINE_NAME
483+
#undef FIND_PROPERTY_INDEX_ROUTINE_NAME
449484
#undef TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME
485+
#undef LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME
486+
#undef DISPATCH_ROUTINE_ROUTINE_NAME
450487
#undef BUILTIN_UNDERSCORED_ID
451488
#undef BUILTIN_INC_HEADER_NAME
452489
#undef ECMA_BUILTIN_PROPERTY_NAMES
453-
490+
#undef ECMA_BUILTIN_PROPERTY_NAME_INDEX

jerry-core/ecma/builtin-objects/ecma-builtins-internal.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
1+
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -60,9 +60,6 @@
6060
/* ecma-builtins.c */
6161
extern ecma_object_t *
6262
ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t, uint16_t, uint8_t);
63-
extern int32_t
64-
ecma_builtin_bin_search_for_magic_string_id_in_array (const lit_magic_string_id_t[],
65-
ecma_length_t, lit_magic_string_id_t);
6663

6764
#define BUILTIN(builtin_id, \
6865
object_type, \
@@ -88,9 +85,7 @@ extern void \
8885
ecma_builtin_ ## lowercase_name ## _list_lazy_property_names (ecma_object_t *, \
8986
bool, \
9087
ecma_collection_header_t *, \
91-
ecma_collection_header_t *); \
92-
extern void \
93-
ecma_builtin_ ## lowercase_name ## _sort_property_names (void);
88+
ecma_collection_header_t *);
9489
#include "ecma-builtins.inc.h"
9590

9691
#endif /* !ECMA_BUILTINS_INTERNAL_H */

jerry-core/ecma/builtin-objects/ecma-builtins.c

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,6 @@ ecma_instantiate_builtin (ecma_builtin_id_t id) /**< built-in id */
219219
case builtin_id: \
220220
{ \
221221
JERRY_ASSERT (ecma_builtin_objects[builtin_id] == NULL); \
222-
if (is_static) \
223-
{ \
224-
ecma_builtin_ ## lowercase_name ## _sort_property_names (); \
225-
} \
226222
\
227223
ecma_object_t *prototype_obj_p; \
228224
if (object_prototype_builtin_id == ECMA_BUILTIN_ID__COUNT) \
@@ -701,57 +697,6 @@ ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, /**< built-i
701697
JERRY_UNREACHABLE ();
702698
} /* ecma_builtin_dispatch_routine */
703699

704-
/**
705-
* Binary search for magic string identifier in array.
706-
*
707-
* Warning:
708-
* array should be sorted in ascending order
709-
*
710-
* @return index of identifier, if it is contained in array,
711-
* -1 - otherwise.
712-
*/
713-
int32_t
714-
ecma_builtin_bin_search_for_magic_string_id_in_array (const lit_magic_string_id_t ids[], /**< array to search in */
715-
ecma_length_t array_length, /**< number of elements
716-
in the array */
717-
lit_magic_string_id_t key) /**< value to search for */
718-
{
719-
#ifndef JERRY_NDEBUG
720-
/* For binary search the values should be sorted */
721-
for (ecma_length_t id_index = 1;
722-
id_index < array_length;
723-
id_index++)
724-
{
725-
JERRY_ASSERT (ids[id_index - 1] < ids[id_index]);
726-
}
727-
#endif /* !JERRY_NDEBUG */
728-
729-
int32_t min = 0;
730-
int32_t max = (int32_t) array_length - 1;
731-
732-
while (min <= max)
733-
{
734-
int32_t mid = (min + max) / 2;
735-
736-
if (ids[mid] == key)
737-
{
738-
return (int32_t) mid;
739-
}
740-
else if (ids[mid] > key)
741-
{
742-
max = mid - 1;
743-
}
744-
else
745-
{
746-
JERRY_ASSERT (ids[mid] < key);
747-
748-
min = mid + 1;
749-
}
750-
}
751-
752-
return -1;
753-
} /* ecma_builtin_bin_search_for_magic_string_id_in_array */
754-
755700
/**
756701
* @}
757702
* @}

jerry-core/ecma/builtin-objects/ecma-builtins.inc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
1+
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
1414
*/
1515

1616
/* Description of built-in objects
17-
in format (ECMA_BUILTIN_ID_id, object_type, class_magic_string_id, prototype_id, is_extensible, underscored_id) */
17+
in format (ECMA_BUILTIN_ID_id, object_type, prototype_id, is_extensible, is_static, underscored_id) */
1818

1919
/* The Object.prototype object (15.2.4) */
2020
BUILTIN (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,

0 commit comments

Comments
 (0)