diff --git a/jerry-core/CMakeLists.txt b/jerry-core/CMakeLists.txt index aa58a3d0fa..d1ecac54da 100644 --- a/jerry-core/CMakeLists.txt +++ b/jerry-core/CMakeLists.txt @@ -40,6 +40,7 @@ set(JERRY_SYSTEM_ALLOCATOR OFF CACHE BOOL "Enable system all set(JERRY_VALGRIND OFF CACHE BOOL "Enable Valgrind support?") set(JERRY_VM_HALT OFF CACHE BOOL "Enable VM execution stop callback?") set(JERRY_VM_THROW OFF CACHE BOOL "Enable VM throw callback?") +set(JERRY_LIT_HASHMAP OFF CACHE BOOL "Enable literal hashmap storage?") set(JERRY_GLOBAL_HEAP_SIZE "(512)" CACHE STRING "Size of memory heap, in kilobytes") set(JERRY_GC_LIMIT "(0)" CACHE STRING "Heap usage limit to trigger garbage collection") set(JERRY_STACK_LIMIT "(0)" CACHE STRING "Maximum stack usage size, in kilobytes") @@ -304,6 +305,7 @@ set(SOURCE_CORE_FILES lit/lit-char-helpers.c lit/lit-magic-strings.c lit/lit-strings.c + lit/lit-hashmap.c parser/js/byte-code.c parser/js/common.c parser/js/js-lexer.c @@ -498,6 +500,8 @@ if(ENABLE_AMALGAM) lit/lit-unicode-folding.inc.h lit/lit-unicode-ranges-sup.inc.h lit/lit-unicode-ranges.inc.h + lit/lit-hashmap-impl.h + lit/lit-hashmap.h vm/opcodes.h vm/vm-defines.h vm/vm-stack.h diff --git a/jerry-core/config.h b/jerry-core/config.h index 002f49e3ca..55eb144baf 100644 --- a/jerry-core/config.h +++ b/jerry-core/config.h @@ -466,6 +466,13 @@ * Advanced section configurations. */ +/** + * The JERRY_LIT_HASHMAP uses an hashmap for faster literal storage. + */ +#ifndef JERRY_LIT_HASHMAP +#define JERRY_LIT_HASHMAP 0 +#endif /* !defined (JERRY_LIT_HASHMAP) */ + /** * Allow configuring attributes on a few constant data inside the engine. * diff --git a/jerry-core/ecma/base/ecma-literal-storage.c b/jerry-core/ecma/base/ecma-literal-storage.c index db086a51be..6f845b2219 100644 --- a/jerry-core/ecma/base/ecma-literal-storage.c +++ b/jerry-core/ecma/base/ecma-literal-storage.c @@ -153,23 +153,68 @@ ecma_finalize_lit_storage (void) } /* ecma_finalize_lit_storage */ /** - * Find or create a literal string. + * Create a new literal string slot "pool". * - * @return ecma_string_t compressed pointer + * @return jmem_cpointer_t slot pointer */ -ecma_value_t -ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string to be searched */ - lit_utf8_size_t size, /**< size of the string */ - bool is_ascii) /**< encode of the string */ + +static jmem_cpointer_t * +ecma_allocate_new_string_slot (void) { - ecma_string_t *string_p = - (is_ascii ? ecma_new_ecma_string_from_ascii (chars_p, size) : ecma_new_ecma_string_from_utf8 (chars_p, size)); + ecma_lit_storage_item_t *new_item_p; + new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t)); - if (ECMA_IS_DIRECT_STRING (string_p)) + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) { - return ecma_make_string_value (string_p); + new_item_p->values[i] = JMEM_CP_NULL; + } + + new_item_p->next_cp = JERRY_CONTEXT (string_list_first_cp); + JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (string_list_first_cp), new_item_p); + + return new_item_p->values + 0; +} /* ecma_allocate_new_string_slot */ + +#if JERRY_LIT_HASHMAP +/** + * Find an empty a literal string slot. + * + * @return jmem_cpointer_t slot pointer + */ + +static jmem_cpointer_t * +ecma_find_empty_literal_string_slot (void) +{ + jmem_cpointer_t string_list_cp = JERRY_CONTEXT (string_list_first_cp); + + while (string_list_cp != JMEM_CP_NULL) + { + ecma_lit_storage_item_t *string_list_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_lit_storage_item_t, string_list_cp); + + for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) + { + if (string_list_p->values[i] == JMEM_CP_NULL) + { + return string_list_p->values + i; + } + } + string_list_cp = string_list_p->next_cp; } + return ecma_allocate_new_string_slot (); +} /* ecma_find_empty_literal_string_slot */ +#endif /* JERRY_LIT_HASHMAP */ + +/** + * Find an empty or similar a literal string slot. + * + * @return jmem_cpointer_t slot pointer + */ + +#if !JERRY_LIT_HASHMAP +static jmem_cpointer_t * +ecma_find_empty_or_same_literal_string_slot (ecma_string_t *string_p /**< string to be searched */) +{ jmem_cpointer_t string_list_cp = JERRY_CONTEXT (string_list_first_cp); jmem_cpointer_t *empty_cpointer_p = NULL; @@ -189,12 +234,9 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string else { ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, string_list_p->values[i]); - if (ecma_compare_ecma_strings (string_p, value_p)) { - /* Return with string if found in the list. */ - ecma_deref_ecma_string (string_p); - return ecma_make_string_value (value_p); + return string_list_p->values + i; } } } @@ -202,29 +244,66 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string string_list_cp = string_list_p->next_cp; } - ECMA_SET_STRING_AS_STATIC (string_p); - jmem_cpointer_t result; - JMEM_CP_SET_NON_NULL_POINTER (result, string_p); - if (empty_cpointer_p != NULL) { - *empty_cpointer_p = result; - return ecma_make_string_value (string_p); + return empty_cpointer_p; } - ecma_lit_storage_item_t *new_item_p; - new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc (sizeof (ecma_lit_storage_item_t)); + return ecma_allocate_new_string_slot (); +} /* ecma_find_empty_or_same_literal_string_slot */ +#endif /* !JERRY_LIT_HASHMAP */ - new_item_p->values[0] = result; - for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++) +/** + * Find or create a literal string. + * + * @return ecma_string_t compressed pointer + */ + +ecma_value_t +ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string to be searched */ + lit_utf8_size_t size, /**< size of the string */ + bool is_ascii) /**< encode of the string */ +{ + ecma_string_t *string_p = + (is_ascii ? ecma_new_ecma_string_from_ascii (chars_p, size) : ecma_new_ecma_string_from_utf8 (chars_p, size)); + + if (ECMA_IS_DIRECT_STRING (string_p)) { - new_item_p->values[i] = JMEM_CP_NULL; + return ecma_make_string_value (string_p); } - new_item_p->next_cp = JERRY_CONTEXT (string_list_first_cp); - JMEM_CP_SET_NON_NULL_POINTER (JERRY_CONTEXT (string_list_first_cp), new_item_p); +#if JERRY_LIT_HASHMAP + const ecma_string_t *hashmap_entry = hashmap_get (JERRY_CONTEXT (string_hashmap), string_p); + if (hashmap_entry != NULL) + { + ecma_deref_ecma_string (string_p); + return ecma_make_string_value (hashmap_entry); + } + // Since the string is not found, just find an empty slot + jmem_cpointer_t *slot = ecma_find_empty_literal_string_slot (); +#else /* JERRY_LIT_HASHMAP */ + jmem_cpointer_t *slot = ecma_find_empty_or_same_literal_string_slot (string_p); + if (*slot != JMEM_CP_NULL) + { + // The string has been found + ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, *slot); + ecma_deref_ecma_string (string_p); + return ecma_make_string_value (value_p); + } +#endif /* JERRY_LIT_HASHMAP */ + + // String has not been found... + ECMA_SET_STRING_AS_STATIC (string_p); + jmem_cpointer_t result; + JMEM_CP_SET_NON_NULL_POINTER (result, string_p); + *slot = result; + +#if JERRY_LIT_HASHMAP + hashmap_put (JERRY_CONTEXT (string_hashmap), string_p); +#endif /* JERRY_LIT_HASHMAP */ return ecma_make_string_value (string_p); + } /* ecma_find_or_create_literal_string */ /** diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h index 397863a72f..063a331bc1 100644 --- a/jerry-core/jcontext/jcontext.h +++ b/jerry-core/jcontext/jcontext.h @@ -28,6 +28,7 @@ #include "debugger.h" #include "jmem.h" #include "js-parser-internal.h" +#include "lit-hashmap.h" #include "re-bytecode.h" #include "vm-defines.h" @@ -138,6 +139,10 @@ struct jerry_context_t #endif /* JERRY_BUILTIN_BIGINT */ jmem_cpointer_t global_symbols_cp[ECMA_BUILTIN_GLOBAL_SYMBOL_COUNT]; /**< global symbols */ +#if JERRY_LIT_HASHMAP + hashmap_t string_hashmap; +#endif /* JERRY_LIT_HASHMAP */ + #if JERRY_MODULE_SYSTEM ecma_module_t *module_current_p; /**< current module context */ jerry_module_state_changed_cb_t module_state_changed_callback_p; /**< callback which is called after the diff --git a/jerry-core/jmem/jmem-heap.c b/jerry-core/jmem/jmem-heap.c index fa83605cff..4b9bc3d6f7 100644 --- a/jerry-core/jmem/jmem-heap.c +++ b/jerry-core/jmem/jmem-heap.c @@ -23,6 +23,7 @@ #include "jmem.h" #include "jrt-bit-fields.h" #include "jrt-libc-includes.h" +#include "lit-hashmap.h" #define JMEM_ALLOCATOR_INTERNAL #include "jmem-allocator-internal.h" @@ -103,6 +104,11 @@ jmem_heap_init (void) JMEM_VALGRIND_NOACCESS_SPACE (JERRY_HEAP_CONTEXT (area), JMEM_HEAP_AREA_SIZE); #endif /* !JERRY_SYSTEM_ALLOCATOR */ + +#if JERRY_LIT_HASHMAP + hashmap_init (&JERRY_CONTEXT (string_hashmap)); +#endif /* JERRY_LIT_HASHMAP */ + JMEM_HEAP_STAT_INIT (); } /* jmem_heap_init */ @@ -112,6 +118,10 @@ jmem_heap_init (void) void jmem_heap_finalize (void) { +#if JERRY_LIT_HASHMAP + hashmap_destroy (&JERRY_CONTEXT (string_hashmap)); +#endif /* JERRY_LIT_HASHMAP */ + JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_allocated_size) == 0); #if !JERRY_SYSTEM_ALLOCATOR JMEM_VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), JMEM_HEAP_SIZE); diff --git a/jerry-core/lit/lit-hashmap-impl.h b/jerry-core/lit/lit-hashmap-impl.h new file mode 100644 index 0000000000..ddfc7cce94 --- /dev/null +++ b/jerry-core/lit/lit-hashmap-impl.h @@ -0,0 +1,202 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * The lit-hashmap library is based on the public domain software + * available from https://github.com/sheredom/hashmap.h + */ + +#include +#include + +#include "ecma-globals.h" +#include "ecma-helpers.h" + +/* ------------------------------------------------------------------------------------------------ */ +// Configuration + +#define HASHMAP_LINEAR_PROBE_LENGTH ((size_t) 8) + +/* ------------------------------------------------------------------------------------------------ */ + +#define HASHMAP_CAST(type, x) ((type) (x)) +#define HASHMAP_PTR_CAST(type, x) ((type) (x)) +#define HASHMAP_NULL 0 + +#define HASHMAP_IMPL_INLINE __attribute__ ((always_inline)) inline + +/* ------------------------------------------------------------------------------------------------ */ + +/** + * HashMap object, internal representation + */ +typedef struct +{ + size_t log2_capacity; /**< hashmap capacity */ + uint32_t used_entries; /**< hashmap size*/ + size_t array_size; /**< allocated size */ + const ecma_string_t **literals; /**< element array */ +} hashmap_impl; + +/** + * HashMap iterator object, internal representation + */ +typedef struct +{ + hashmap_impl *hmap; /**< pointer to the hashmap */ + uint32_t index; /**< iterator start index */ + uint32_t slot; /**< iterator slot, from 0 to HASHMAP_LINEAR_PROBE_LENGTH */ + lit_string_hash_t key; /**< key beeing looked for */ +} hashmap_impl_iter; + +/* ------------------------------------------------------------------------------------------------ */ + +void hashmap_impl_rehash (hashmap_impl *const hashmap); + +/* ------------------------------------------------------------------------------------------------ */ + +HASHMAP_IMPL_INLINE size_t +hashmap_impl_log2 (size_t v) +{ + int n = 31 - __builtin_clz ((uint32_t) v); + return (size_t) n; +} /* hashmap_round_log2 */ + +HASHMAP_IMPL_INLINE uint32_t +hashmap_impl_lithash_to_index (const hashmap_impl *const m, lit_string_hash_t hash) +{ + uint32_t v = (hash * 2654435769u) >> (32u - m->log2_capacity); + return v; +} /* hashmap_hash_to_index */ + +/* ------------------------------------------------------------------------------------------------ */ + +HASHMAP_IMPL_INLINE void +hashmap_impl_init (size_t initial_capacity, hashmap_impl *hashmap) +{ + initial_capacity = ((size_t) 1) << hashmap_impl_log2 (initial_capacity); + size_t array_size = (initial_capacity + HASHMAP_LINEAR_PROBE_LENGTH); + + hashmap->literals = jmem_heap_alloc_block (array_size * sizeof (const ecma_string_t *)); + memset (hashmap->literals, 0, array_size * sizeof (const ecma_string_t *)); + hashmap->log2_capacity = hashmap_impl_log2 (initial_capacity); + hashmap->used_entries = 0; +} /* hashmap_new */ + +/* ------------------------------------------------------------------------------------------------ */ + +HASHMAP_IMPL_INLINE int +hashmap_impl_find_empty_slot (const hashmap_impl *const hashmap, const lit_string_hash_t key, uint32_t *const out_index) +{ + uint32_t start_index = hashmap_impl_lithash_to_index (hashmap, key); + + for (uint32_t offset = 0; offset < HASHMAP_LINEAR_PROBE_LENGTH; offset++) + { + const uint32_t index = start_index + offset; + + if (hashmap->literals[index] == NULL) + { + *out_index = index; + return 1; + } + } + + return 0; +} /* hashmap_impl_find_empty_slot */ + +/* ------------------------------------------------------------------------------------------------ */ + +HASHMAP_IMPL_INLINE void +hashmap_impl_insert (hashmap_impl *hashmap, const ecma_string_t *literal) +{ + /* Find a place to put our value. */ + uint32_t index; + uint32_t lithash = literal->u.hash; + while (!hashmap_impl_find_empty_slot (hashmap, lithash, &index)) + { + hashmap_impl_rehash (hashmap); + } + + hashmap->literals[index] = literal; + hashmap->used_entries++; +} /* hashmap_impl_insert */ + +/* ------------------------------------------------------------------------------------------------ */ + +HASHMAP_IMPL_INLINE hashmap_impl_iter +hashmap_impl_find (hashmap_impl *hashmap, lit_string_hash_t key) +{ + uint32_t start_index = hashmap_impl_lithash_to_index (hashmap, key); + return (hashmap_impl_iter){ + .hmap = hashmap, + .index = start_index, + .slot = 0, + .key = key, + }; +} /* hashmap_impl_find */ + +HASHMAP_IMPL_INLINE const ecma_string_t * +hashmap_impl_iter_get (hashmap_impl_iter *iter) +{ + const ecma_string_t **literals = iter->hmap->literals; + while (iter->slot < HASHMAP_LINEAR_PROBE_LENGTH) + { + uint32_t index = iter->index + iter->slot; + const ecma_string_t *literal = literals[index]; + if (literal && literal->u.hash == iter->key) + { + return literals[index]; + } + + iter->slot++; + } + return NULL; +} /* hashmap_impl_iter_get */ + +HASHMAP_IMPL_INLINE const ecma_string_t * +hashmap_impl_iter_next (hashmap_impl_iter *iter) +{ + iter->slot++; + return hashmap_impl_iter_get (iter); +} /* hashmap_impl_iter_next */ + +HASHMAP_IMPL_INLINE void +hashmap_impl_destroy (hashmap_impl *hashmap) +{ + size_t l = ((size_t) (1 << hashmap->log2_capacity)) + HASHMAP_LINEAR_PROBE_LENGTH; + jmem_heap_free_block (hashmap->literals, l * sizeof (const ecma_string_t *)); +} /* hashmap_impl_destroy */ + +/* ------------------------------------------------------------------------------------------------ */ + +void +hashmap_impl_rehash (hashmap_impl *const hashmap) +{ + size_t clen = ((size_t) (1 << hashmap->log2_capacity)) + HASHMAP_LINEAR_PROBE_LENGTH; + + hashmap_impl new_hashmap; + hashmap_impl_init (clen * 2, &new_hashmap); + + size_t l = clen + HASHMAP_LINEAR_PROBE_LENGTH; + for (size_t i = 0; i < l; i++) + { + const ecma_string_t *p = hashmap->literals[i]; + if (!p) + continue; + hashmap_impl_insert (&new_hashmap, p); + } + + jmem_heap_free_block (hashmap->literals, l * sizeof (const ecma_string_t *)); + + memcpy (hashmap, &new_hashmap, sizeof (hashmap_impl)); +} /* hashmap_impl_rehash */ diff --git a/jerry-core/lit/lit-hashmap.c b/jerry-core/lit/lit-hashmap.c new file mode 100644 index 0000000000..1729a4d539 --- /dev/null +++ b/jerry-core/lit/lit-hashmap.c @@ -0,0 +1,76 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * The lit-hashmap library is based on the public domain software + * available from https://github.com/sheredom/hashmap.h + */ + +#include "lit-hashmap.h" + +#include +#include + +#include "ecma-globals.h" + +#if JERRY_LIT_HASHMAP + +#include "lit-hashmap-impl.h" +#include "lit-hashmap.h" + +struct hashmap_s +{ + hashmap_impl map; +}; + +void +hashmap_init (hashmap_t *map) +{ + struct hashmap_s *hashmap = jmem_heap_alloc_block (sizeof (struct hashmap_s)); + hashmap_impl_init (8, &(hashmap->map)); + (*map) = hashmap; +} /* hashmap_init */ + +void +hashmap_put (hashmap_t hashmap, const ecma_string_t *const literal) +{ + hashmap_impl_insert (&hashmap->map, literal); +} /* hashmap_put */ + +const ecma_string_t * +hashmap_get (hashmap_t hashmap, const ecma_string_t *const literal) +{ + hashmap_impl_iter it = hashmap_impl_find (&hashmap->map, literal->u.hash); + + for (const ecma_string_t *p = hashmap_impl_iter_get (&it); p != NULL; p = hashmap_impl_iter_next (&it)) + { + if (ecma_compare_ecma_strings (p, literal)) + { + return p; + } + } + return NULL; +} /* hashmap_get */ + +void +hashmap_destroy (hashmap_t *hashmap) +{ + if (*hashmap) + { + hashmap_impl_destroy (&((*hashmap)->map)); + jmem_heap_free_block (&((*hashmap)->map), sizeof (struct hashmap_s)); + *hashmap = (hashmap_t) 0; + } +} /* hashmap_destroy */ + +#endif /* JERRY_LIT_HASHMAP */ diff --git a/jerry-core/lit/lit-hashmap.h b/jerry-core/lit/lit-hashmap.h new file mode 100644 index 0000000000..3a008e20ea --- /dev/null +++ b/jerry-core/lit/lit-hashmap.h @@ -0,0 +1,38 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + The lit-hashmap library is based on the public domain software + available from https://github.com/sheredom/hashmap.h +*/ + +#ifndef LIT_HASHMAP_H +#define LIT_HASHMAP_H + +#include +#include +#include + +#include "ecma-globals.h" + +typedef struct hashmap_s *hashmap_t; + +void hashmap_init (hashmap_t *); +void hashmap_put (hashmap_t hashmap, const ecma_string_t *const key); +const ecma_string_t *hashmap_get (hashmap_t hashmap, const ecma_string_t *const key); +void hashmap_remove (hashmap_t hashmap, const ecma_string_t *const key); +void hashmap_destroy (hashmap_t *hashmap); + +#endif // LIT_HASHMAP_H diff --git a/tools/build.py b/tools/build.py index 137c32b48f..7245ac8e98 100755 --- a/tools/build.py +++ b/tools/build.py @@ -158,6 +158,8 @@ def devhelp(helpstring): help='enable VM execution stop callback (%(choices)s)') coregrp.add_argument('--vm-throw', metavar='X', choices=['ON', 'OFF'], type=str.upper, help='enable VM throw callback (%(choices)s)') + coregrp.add_argument('--lit-hashmap', metavar='X', choices=['ON', 'OFF'], type=str.upper, + help='Enable literal hashmap storage (%(choices)s)') maingrp = parser.add_argument_group('jerry-main options') maingrp.add_argument('--link-map', metavar='X', choices=['ON', 'OFF'], type=str.upper, @@ -227,6 +229,7 @@ def build_options_append(cmakeopt, cliarg): build_options_append('JERRY_VALGRIND', arguments.valgrind) build_options_append('JERRY_VM_HALT', arguments.vm_exec_stop) build_options_append('JERRY_VM_THROW', arguments.vm_throw) + build_options_append('JERRY_LIT_HASHMAP', arguments.lit_hashmap) if arguments.gc_mark_limit is not None: build_options.append(f'-DJERRY_GC_MARK_LIMIT={arguments.gc_mark_limit}') diff --git a/tools/run-tests.py b/tools/run-tests.py index 64bc1ed827..f1a76fae47 100755 --- a/tools/run-tests.py +++ b/tools/run-tests.py @@ -77,6 +77,9 @@ def skip_if(condition, desc): Options('jerry_tests-external_context', OPTIONS_COMMON + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT + ['--external-context=on']), + Options('jerry_tests-lit-hashmap', + OPTIONS_COMMON + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT + + ['--lit-hashmap=on']), ] # Test options for test262 @@ -139,6 +142,8 @@ def skip_if(condition, desc): ['--compile-flag=-DJERRY_MODULE_SYSTEM=0', '--lto=off']), Options('buildoption_test-builtin-proxy-off', ['--compile-flag=-DJERRY_BUILTIN_PROXY=0']), + Options('buildoption_test-literal-hashmap-on', + ['--compile-flag=-DJERRY_LIT_HASHMAP=1']), ] def get_arguments():