Skip to content

Commit abf81a7

Browse files
author
Zsolt Borbély
committed
[API] Improve the performance of the external magic id search
After this patch, we have to provide external strings ordered by size and lexicographically. We can do this with jerry_parse_and_save_literals() (#1500). JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com
1 parent 0c7d99e commit abf81a7

File tree

3 files changed

+113
-22
lines changed

3 files changed

+113
-22
lines changed

docs/02.API-REFERENCE.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ jerry_cleanup (void);
255255

256256
Registers an external magic string array.
257257

258+
*Note*: The strings in the array must be sorted by size at first, then lexicographically.
259+
258260
**Prototype**
259261

260262
```c
@@ -275,11 +277,12 @@ jerry_register_magic_strings (const jerry_char_ptr_t *ex_str_items_p,
275277
jerry_init (JERRY_INIT_EMPTY);
276278

277279
// must be static, because 'jerry_register_magic_strings' does not copy
280+
// the items must be sorted by size at first, then lexicographically
278281
static const jerry_char_ptr_t magic_string_items[] = {
279282
(const jerry_char_ptr_t) "magicstring1",
280283
(const jerry_char_ptr_t) "magicstring2",
281284
(const jerry_char_ptr_t) "magicstring3"
282-
};
285+
};
283286
uint32_t num_magic_string_items = (uint32_t) (sizeof (magic_string_items) / sizeof (jerry_char_ptr_t));
284287

285288
// must be static, because 'jerry_register_magic_strings' does not copy

jerry-core/lit/lit-magic-strings.c

Lines changed: 107 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,22 @@ lit_magic_strings_ex_set (const lit_utf8_byte_t **ex_str_items, /**< character a
157157
lit_utf8_size_t string_size = lit_zt_utf8_string_size (lit_get_magic_string_ex_utf8 (id));
158158
JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_sizes)[id] == string_size);
159159
JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_sizes)[id] <= LIT_MAGIC_STRING_LENGTH_LIMIT);
160+
161+
/* Check the order of the strings */
162+
if (id > 0)
163+
{
164+
const lit_magic_string_ex_id_t prev_id = id - 1;
165+
const lit_utf8_size_t prev_string_size = lit_get_magic_string_ex_size (prev_id);
166+
JERRY_ASSERT (prev_string_size <= string_size);
167+
168+
if (prev_string_size == string_size)
169+
{
170+
const lit_utf8_byte_t *prev_ex_string_p = lit_get_magic_string_ex_utf8 (prev_id);
171+
const lit_utf8_byte_t *curr_ex_string_p = lit_get_magic_string_ex_utf8 (id);
172+
const int string_compare = memcmp (prev_ex_string_p, curr_ex_string_p, string_size);
173+
JERRY_ASSERT (string_compare < 0);
174+
}
175+
}
160176
}
161177
#endif /* !JERRY_NDEBUG */
162178
} /* lit_magic_strings_ex_set */
@@ -264,22 +280,57 @@ lit_magic_string_ex_id_t
264280
lit_is_ex_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
265281
lit_utf8_size_t string_size) /**< string size in bytes */
266282
{
267-
/* TODO: Improve performance of search */
283+
const uint32_t magic_string_ex_count = lit_get_magic_string_ex_count ();
268284

269-
for (lit_magic_string_ex_id_t id = (lit_magic_string_ex_id_t) 0;
270-
id < JERRY_CONTEXT (lit_magic_string_ex_count);
271-
id = (lit_magic_string_ex_id_t) (id + 1))
285+
if (magic_string_ex_count == 0
286+
|| string_size > lit_get_magic_string_ex_size (magic_string_ex_count - 1))
272287
{
273-
if (string_size == lit_get_magic_string_ex_size (id))
288+
return (lit_magic_string_ex_id_t) magic_string_ex_count;
289+
}
290+
291+
lit_magic_string_ex_id_t first = 0;
292+
lit_magic_string_ex_id_t last = (lit_magic_string_ex_id_t) magic_string_ex_count;
293+
bool found_size_range = false;
294+
295+
while (first < last)
296+
{
297+
const lit_magic_string_ex_id_t middle = (first + last) / 2;
298+
const lit_utf8_byte_t *ext_string_p = lit_get_magic_string_ex_utf8 (middle);
299+
const lit_utf8_size_t ext_string_size = lit_get_magic_string_ex_size (middle);
300+
301+
if (string_size == ext_string_size)
274302
{
275-
if (memcmp (string_p, lit_get_magic_string_ex_utf8 (id), string_size) == 0)
303+
found_size_range = true;
304+
const int string_compare = memcmp (ext_string_p, string_p, string_size);
305+
306+
if (string_compare == 0)
307+
{
308+
return middle;
309+
}
310+
else if (string_compare < 0)
276311
{
277-
return id;
312+
first = middle + 1;
278313
}
314+
else
315+
{
316+
last = middle;
317+
}
318+
}
319+
else if (found_size_range)
320+
{
321+
break;
322+
}
323+
else if (string_size > ext_string_size)
324+
{
325+
first = middle + 1;
326+
}
327+
else
328+
{
329+
last = middle;
279330
}
280331
}
281332

282-
return JERRY_CONTEXT (lit_magic_string_ex_count);
333+
return (lit_magic_string_ex_id_t) magic_string_ex_count;
283334
} /* lit_is_ex_utf8_string_magic */
284335

285336
/**
@@ -294,26 +345,63 @@ lit_is_ex_utf8_string_pair_magic (const lit_utf8_byte_t *string1_p, /**< first u
294345
const lit_utf8_byte_t *string2_p, /**< second utf-8 string */
295346
lit_utf8_size_t string2_size) /**< second string size in bytes */
296347
{
297-
/* TODO: Improve performance of search */
298-
lit_utf8_size_t total_string_size = string1_size + string2_size;
348+
const uint32_t magic_string_ex_count = lit_get_magic_string_ex_count ();
349+
const lit_utf8_size_t total_string_size = string1_size + string2_size;
299350

300-
for (lit_magic_string_ex_id_t id = (lit_magic_string_ex_id_t) 0;
301-
id < JERRY_CONTEXT (lit_magic_string_ex_count);
302-
id = (lit_magic_string_ex_id_t) (id + 1))
351+
if (magic_string_ex_count == 0
352+
|| total_string_size > lit_get_magic_string_ex_size (magic_string_ex_count - 1))
353+
{
354+
return (lit_magic_string_ex_id_t) magic_string_ex_count;
355+
}
356+
357+
lit_magic_string_ex_id_t first = 0;
358+
lit_magic_string_ex_id_t last = (lit_magic_string_ex_id_t) magic_string_ex_count;
359+
bool found_size_range = false;
360+
361+
while (first < last)
303362
{
304-
if (total_string_size == lit_get_magic_string_ex_size (id))
363+
const lit_magic_string_ex_id_t middle = (first + last) / 2;
364+
const lit_utf8_byte_t *ext_string_p = lit_get_magic_string_ex_utf8 (middle);
365+
const lit_utf8_size_t ext_string_size = lit_get_magic_string_ex_size (middle);
366+
367+
if (total_string_size == ext_string_size)
305368
{
306-
const lit_utf8_byte_t *ex_magic_string_p = lit_get_magic_string_ex_utf8 (id);
369+
found_size_range = true;
370+
int string_compare = memcmp (ext_string_p, string1_p, string1_size);
371+
372+
if (string_compare == 0)
373+
{
374+
string_compare = memcmp (ext_string_p + string1_size, string2_p, string2_size);
375+
}
307376

308-
if (memcmp (string1_p, ex_magic_string_p, string1_size) == 0
309-
&& memcmp (string2_p, ex_magic_string_p + string1_size, string2_size) == 0)
377+
if (string_compare == 0)
310378
{
311-
return id;
379+
return middle;
312380
}
381+
else if (string_compare < 0)
382+
{
383+
first = middle + 1;
384+
}
385+
else
386+
{
387+
last = middle;
388+
}
389+
}
390+
else if (found_size_range)
391+
{
392+
break;
393+
}
394+
else if (total_string_size > ext_string_size)
395+
{
396+
first = middle + 1;
397+
}
398+
else
399+
{
400+
last = middle;
313401
}
314402
}
315403

316-
return JERRY_CONTEXT (lit_magic_string_ex_count);
404+
return (lit_magic_string_ex_id_t) magic_string_ex_count;
317405
} /* lit_is_ex_utf8_string_pair_magic */
318406

319407
/**

tests/unit/test-api.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ handler_construct (const jerry_value_t func_obj_val, /**< function object */
150150
*/
151151
#define JERRY_MAGIC_STRING_ITEMS \
152152
JERRY_MAGIC_STRING_DEF (GLOBAL, global) \
153-
JERRY_MAGIC_STRING_DEF (CONSOLE, console) \
154-
JERRY_MAGIC_STRING_DEF (GREEK_ZERO_SIGN, \xed\xa0\x80\xed\xb6\x8a)
153+
JERRY_MAGIC_STRING_DEF (GREEK_ZERO_SIGN, \xed\xa0\x80\xed\xb6\x8a) \
154+
JERRY_MAGIC_STRING_DEF (CONSOLE, console)
155155

156156
#define JERRY_MAGIC_STRING_DEF(NAME, STRING) \
157157
static const char jerry_magic_string_ex_ ## NAME[] = # STRING;

0 commit comments

Comments
 (0)