diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index bc62a35a3c..51f19eae0d 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -24,6 +24,7 @@ #include "ecma-helpers.h" #include "ecma-lcache.h" #include "ecma-property-hashmap.h" +#include "jcontext.h" #include "jrt.h" #include "jrt-libc-includes.h" #include "jrt-bit-fields.h" @@ -44,44 +45,15 @@ */ /** - * An object's GC color + * Current state of an object's visited flag that + * indicates whether the object is in visited state: * - * Tri-color marking: - * WHITE_GRAY, unvisited -> WHITE // not referenced by a live object or the reference not found yet - * WHITE_GRAY, visited -> GRAY // referenced by some live object - * BLACK -> BLACK // all referenced objects are gray or black - */ -typedef enum -{ - ECMA_GC_COLOR_WHITE_GRAY, /**< white or gray */ - ECMA_GC_COLOR_BLACK, /**< black */ - ECMA_GC_COLOR__COUNT /**< number of colors */ -} ecma_gc_color_t; - -/** - * List of marked (visited during current GC session) and umarked objects - */ -static ecma_object_t *ecma_gc_objects_lists[ECMA_GC_COLOR__COUNT]; - -/** - * Current state of an object's visited flag that indicates whether the object is in visited state: * visited_field | visited_flip_flag | real_value * false | false | false * false | true | true * true | false | true * true | true | false */ -static bool ecma_gc_visited_flip_flag = false; - -/** - * Number of currently allocated objects - */ -static size_t ecma_gc_objects_number = 0; - -/** - * Number of newly allocated objects since last GC session - */ -static size_t ecma_gc_new_objects_since_last_gc = 0; static void ecma_gc_mark (ecma_object_t *object_p); static void ecma_gc_sweep (ecma_object_t *object_p); @@ -119,7 +91,7 @@ ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */ bool flag_value = (object_p->type_flags_refs & ECMA_OBJECT_FLAG_GC_VISITED) != 0; - return flag_value != ecma_gc_visited_flip_flag; + return flag_value != JERRY_CONTEXT (ecma_gc_visited_flip_flag); } /* ecma_gc_is_object_visited */ /** @@ -131,7 +103,7 @@ ecma_gc_set_object_visited (ecma_object_t *object_p, /**< object */ { JERRY_ASSERT (object_p != NULL); - if (is_visited != ecma_gc_visited_flip_flag) + if (is_visited != JERRY_CONTEXT (ecma_gc_visited_flip_flag)) { object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_GC_VISITED); } @@ -147,16 +119,16 @@ ecma_gc_set_object_visited (ecma_object_t *object_p, /**< object */ inline void ecma_init_gc_info (ecma_object_t *object_p) /**< object */ { - ecma_gc_objects_number++; - ecma_gc_new_objects_since_last_gc++; + JERRY_CONTEXT (ecma_gc_objects_number)++; + JERRY_CONTEXT (ecma_gc_new_objects)++; - JERRY_ASSERT (ecma_gc_new_objects_since_last_gc <= ecma_gc_objects_number); + JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_new_objects) <= JERRY_CONTEXT (ecma_gc_objects_number)); JERRY_ASSERT (object_p->type_flags_refs < ECMA_OBJECT_REF_ONE); object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_REF_ONE); - ecma_gc_set_object_next (object_p, ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY]); - ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY] = object_p; + ecma_gc_set_object_next (object_p, JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY]); + JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY] = object_p; /* Should be set to false at the beginning of garbage collection */ ecma_gc_set_object_visited (object_p, false); @@ -194,11 +166,11 @@ ecma_deref_object (ecma_object_t *object_p) /**< object */ void ecma_gc_init (void) { - ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY] = NULL; - ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK] = NULL; - ecma_gc_visited_flip_flag = false; - ecma_gc_objects_number = 0; - ecma_gc_new_objects_since_last_gc = 0; + JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY] = NULL; + JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK] = NULL; + JERRY_CONTEXT (ecma_gc_visited_flip_flag) = false; + JERRY_CONTEXT (ecma_gc_objects_number) = 0; + JERRY_CONTEXT (ecma_gc_new_objects) = 0; } /* ecma_gc_init */ /** @@ -474,8 +446,8 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */ } } - JERRY_ASSERT (ecma_gc_objects_number > 0); - ecma_gc_objects_number--; + JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_objects_number) > 0); + JERRY_CONTEXT (ecma_gc_objects_number)--; if (!ecma_is_lexical_environment (object_p)) { @@ -508,12 +480,12 @@ ecma_gc_sweep (ecma_object_t *object_p) /**< object to free */ void ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */ { - ecma_gc_new_objects_since_last_gc = 0; + JERRY_CONTEXT (ecma_gc_new_objects) = 0; - JERRY_ASSERT (ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK] == NULL); + JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK] == NULL); /* if some object is referenced from stack or globals (i.e. it is root), mark it */ - for (ecma_object_t *obj_iter_p = ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY]; + for (ecma_object_t *obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY]; obj_iter_p != NULL; obj_iter_p = ecma_gc_get_object_next (obj_iter_p)) { @@ -531,17 +503,18 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */ { marked_anything_during_current_iteration = false; - for (ecma_object_t *obj_iter_p = ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY], *obj_prev_p = NULL, *obj_next_p; - obj_iter_p != NULL; - obj_iter_p = obj_next_p) + ecma_object_t *obj_prev_p = NULL; + ecma_object_t *obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY]; + + while (obj_iter_p != NULL) { - obj_next_p = ecma_gc_get_object_next (obj_iter_p); + ecma_object_t *obj_next_p = ecma_gc_get_object_next (obj_iter_p); if (ecma_gc_is_object_visited (obj_iter_p)) { /* Moving the object to list of marked objects */ - ecma_gc_set_object_next (obj_iter_p, ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK]); - ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK] = obj_iter_p; + ecma_gc_set_object_next (obj_iter_p, JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK]); + JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK] = obj_iter_p; if (likely (obj_prev_p != NULL)) { @@ -551,7 +524,7 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */ } else { - ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY] = obj_next_p; + JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY] = obj_next_p; } ecma_gc_mark (obj_iter_p); @@ -561,47 +534,52 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */ { obj_prev_p = obj_iter_p; } + + obj_iter_p = obj_next_p; } } while (marked_anything_during_current_iteration); /* Sweeping objects that are currently unmarked */ - for (ecma_object_t *obj_iter_p = ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY], *obj_next_p; - obj_iter_p != NULL; - obj_iter_p = obj_next_p) + ecma_object_t *obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_WHITE_GRAY]; + + while (obj_iter_p != NULL) { - obj_next_p = ecma_gc_get_object_next (obj_iter_p); + ecma_object_t *obj_next_p = ecma_gc_get_object_next (obj_iter_p); JERRY_ASSERT (!ecma_gc_is_object_visited (obj_iter_p)); ecma_gc_sweep (obj_iter_p); + obj_iter_p = obj_next_p; } if (severity == JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH) { /* Remove the property hashmap of BLACK objects */ - for (ecma_object_t *obj_iter_p = ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK], *obj_next_p; - obj_iter_p != NULL; - obj_iter_p = obj_next_p) - { - obj_next_p = ecma_gc_get_object_next (obj_iter_p); + obj_iter_p = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK]; + while (obj_iter_p != NULL) + { JERRY_ASSERT (ecma_gc_is_object_visited (obj_iter_p)); ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_iter_p); + if (prop_iter_p != NULL && ECMA_PROPERTY_GET_TYPE (prop_iter_p->types + 0) == ECMA_PROPERTY_TYPE_HASHMAP) { ecma_property_hashmap_free (obj_iter_p); } + + obj_iter_p = ecma_gc_get_object_next (obj_iter_p); } } /* Unmarking all objects */ - ecma_gc_objects_lists[ECMA_GC_COLOR_WHITE_GRAY] = ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK]; - ecma_gc_objects_lists[ECMA_GC_COLOR_BLACK] = NULL; + ecma_object_t *black_objects = JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK]; + JERRY_CONTEXT (ecma_gc_objects_lists)[ECMA_GC_COLOR_WHITE_GRAY] = black_objects; + JERRY_CONTEXT (ecma_gc_objects_lists) [ECMA_GC_COLOR_BLACK] = NULL; - ecma_gc_visited_flip_flag = !ecma_gc_visited_flip_flag; + JERRY_CONTEXT (ecma_gc_visited_flip_flag) = !JERRY_CONTEXT (ecma_gc_visited_flip_flag); #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN /* Free RegExp bytecodes stored in cache */ @@ -621,7 +599,9 @@ ecma_free_unused_memory (jmem_free_unused_memory_severity_t severity) /**< sever * If there is enough newly allocated objects since last GC, probably it is worthwhile to start GC now. * Otherwise, probability to free sufficient space is considered to be low. */ - if (ecma_gc_new_objects_since_last_gc * CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC > ecma_gc_objects_number) + size_t new_objects_share = CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC; + + if (JERRY_CONTEXT (ecma_gc_new_objects) * new_objects_share > JERRY_CONTEXT (ecma_gc_objects_number)) { ecma_gc_run (severity); } diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 660c3f235f..be9fc4a257 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -911,6 +911,64 @@ typedef struct * If regexp, the other flags must be RE_FLAG... */ } ecma_compiled_code_t; +/** + * An object's GC color + * + * Tri-color marking: + * WHITE_GRAY, unvisited -> WHITE // not referenced by a live object or the reference not found yet + * WHITE_GRAY, visited -> GRAY // referenced by some live object + * BLACK -> BLACK // all referenced objects are gray or black + */ +typedef enum +{ + ECMA_GC_COLOR_WHITE_GRAY, /**< white or gray */ + ECMA_GC_COLOR_BLACK, /**< black */ + ECMA_GC_COLOR__COUNT /**< number of colors */ +} ecma_gc_color_t; + +/** + * Number of values in a literal storage item + */ +#define ECMA_LIT_STORAGE_VALUE_COUNT 3 + +/** + * Literal storage item + */ +typedef struct +{ + jmem_cpointer_t next_cp; /**< cpointer ot next item */ + jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */ +} ecma_lit_storage_item_t; + +#ifndef CONFIG_ECMA_LCACHE_DISABLE + +/** + * Entry of LCache hash table + */ +typedef struct +{ + /** Pointer to a property of the object */ + ecma_property_t *prop_p; + + /** Compressed pointer to object (ECMA_NULL_POINTER marks record empty) */ + jmem_cpointer_t object_cp; + + /** Compressed pointer to property's name */ + jmem_cpointer_t prop_name_cp; +} ecma_lcache_hash_entry_t; + +/** + * Number of rows in LCache's hash table + */ +#define ECMA_LCACHE_HASH_ROWS_COUNT 128 + +/** + * Number of entries in a row of LCache's hash table + */ +#define ECMA_LCACHE_HASH_ROW_LENGTH 2 + +#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ + /** * @} * @} diff --git a/jerry-core/ecma/base/ecma-init-finalize.c b/jerry-core/ecma/base/ecma-init-finalize.c index fbddf251bd..847f64845e 100644 --- a/jerry-core/ecma/base/ecma-init-finalize.c +++ b/jerry-core/ecma/base/ecma-init-finalize.c @@ -39,7 +39,7 @@ ecma_init (void) ecma_init_builtins (); ecma_lcache_init (); ecma_init_lit_storage (); - ecma_init_environment (); + ecma_init_global_lex_env (); jmem_register_free_unused_memory_callback (ecma_free_unused_memory); } /* ecma_init */ @@ -52,7 +52,7 @@ ecma_finalize (void) { jmem_unregister_free_unused_memory_callback (ecma_free_unused_memory); - ecma_finalize_environment (); + ecma_finalize_global_lex_env (); ecma_finalize_builtins (); ecma_gc_run (JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW); ecma_finalize_lit_storage (); diff --git a/jerry-core/ecma/base/ecma-lcache.c b/jerry-core/ecma/base/ecma-lcache.c index eb8e01bf60..fb0185564e 100644 --- a/jerry-core/ecma/base/ecma-lcache.c +++ b/jerry-core/ecma/base/ecma-lcache.c @@ -18,7 +18,7 @@ #include "ecma-globals.h" #include "ecma-helpers.h" #include "ecma-lcache.h" -#include "jrt-libc-includes.h" +#include "jcontext.h" /** \addtogroup ecma ECMA * @{ @@ -28,41 +28,12 @@ */ #ifndef CONFIG_ECMA_LCACHE_DISABLE -/** - * Entry of LCache hash table - */ -typedef struct -{ - /** Pointer to a property of the object */ - ecma_property_t *prop_p; - - /** Compressed pointer to object (ECMA_NULL_POINTER marks record empty) */ - jmem_cpointer_t object_cp; - - /** Compressed pointer to property's name */ - jmem_cpointer_t prop_name_cp; -} ecma_lcache_hash_entry_t; - -/** - * Number of rows in LCache's hash table - */ -#define ECMA_LCACHE_HASH_ROWS_COUNT 128 - -/** - * Number of entries in a row of LCache's hash table - */ -#define ECMA_LCACHE_HASH_ROW_LENGTH 2 - /** * Mask for hash bits */ #define ECMA_LCACHE_HASH_MASK (ECMA_LCACHE_HASH_ROWS_COUNT - 1) -/** - * LCache's hash table - */ -static ecma_lcache_hash_entry_t ecma_lcache_hash_table[ ECMA_LCACHE_HASH_ROWS_COUNT ][ ECMA_LCACHE_HASH_ROW_LENGTH ]; #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ /** @@ -72,7 +43,7 @@ void ecma_lcache_init (void) { #ifndef CONFIG_ECMA_LCACHE_DISABLE - memset (ecma_lcache_hash_table, 0, sizeof (ecma_lcache_hash_table)); + memset (JERRY_HASH_TABLE_CONTEXT (table), 0, sizeof (jerry_hash_table_t)); #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ } /* ecma_lcache_init */ @@ -98,13 +69,13 @@ ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to i * @return row index */ static inline size_t __attr_always_inline___ -ecma_lcache_row_idx (jmem_cpointer_t object_cp, /**< compressed pointer to object */ - const ecma_string_t *prop_name_p) /**< proeprty name */ +ecma_lcache_row_index (jmem_cpointer_t object_cp, /**< compressed pointer to object */ + const ecma_string_t *prop_name_p) /**< proeprty name */ { /* Randomize the hash of the property name with the object pointer using a xor operation, * so properties of different objects with the same name can be cached effectively. */ return (size_t) ((ecma_string_hash (prop_name_p) ^ object_cp) & ECMA_LCACHE_HASH_MASK); -} /* ecma_lcache_row_idx */ +} /* ecma_lcache_row_index */ #endif /* !CONFIG_ECMA_LCACHE_DISABLE */ /** @@ -126,7 +97,8 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */ ECMA_SET_NON_NULL_POINTER (object_cp, object_p); - ecma_lcache_hash_entry_t *entries_p = ecma_lcache_hash_table[ecma_lcache_row_idx (object_cp, prop_name_p)]; + size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p); + ecma_lcache_hash_entry_t *entries_p = JERRY_HASH_TABLE_CONTEXT (table)[row_index]; int32_t entry_index; for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++) @@ -177,7 +149,8 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */ jmem_cpointer_t object_cp; ECMA_SET_NON_NULL_POINTER (object_cp, object_p); - ecma_lcache_hash_entry_t *entry_p = ecma_lcache_hash_table[ecma_lcache_row_idx (object_cp, prop_name_p)]; + size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p); + ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index]; ecma_lcache_hash_entry_t *entry_end_p = entry_p + ECMA_LCACHE_HASH_ROW_LENGTH; ecma_string_container_t prop_container = ECMA_STRING_GET_CONTAINER (prop_name_p); @@ -230,7 +203,8 @@ ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */ jmem_cpointer_t object_cp; ECMA_SET_NON_NULL_POINTER (object_cp, object_p); - ecma_lcache_hash_entry_t *entry_p = ecma_lcache_hash_table[ecma_lcache_row_idx (object_cp, prop_name_p)]; + size_t row_index = ecma_lcache_row_index (object_cp, prop_name_p); + ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index]; for (uint32_t entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++) { diff --git a/jerry-core/ecma/base/ecma-literal-storage.c b/jerry-core/ecma/base/ecma-literal-storage.c index dd65c59ab8..c6f5c19958 100644 --- a/jerry-core/ecma/base/ecma-literal-storage.c +++ b/jerry-core/ecma/base/ecma-literal-storage.c @@ -16,6 +16,7 @@ #include "ecma-literal-storage.h" #include "ecma-helpers.h" +#include "jcontext.h" /** \addtogroup ecma ECMA * @{ @@ -24,34 +25,17 @@ * @{ */ -/** - * Number of values in a literal storage item - */ -#define ECMA_LIT_STORAGE_VALUE_COUNT 3 - -/** - * Literal storage item - */ -typedef struct -{ - jmem_cpointer_t next_cp; /**< cpointer ot next item */ - jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */ -} ecma_lit_storage_item_t; - JERRY_STATIC_ASSERT (sizeof (ecma_lit_storage_item_t) <= sizeof (uint64_t), size_of_ecma_lit_storage_item_t_must_be_less_than_or_equal_to_8_bytes); -static ecma_lit_storage_item_t *string_list_first_p; -static ecma_lit_storage_item_t *number_list_first_p; - /** * Initialize literal storage */ void ecma_init_lit_storage (void) { - string_list_first_p = NULL; - number_list_first_p = NULL; + JERRY_CONTEXT (string_list_first_p) = NULL; + JERRY_CONTEXT (number_list_first_p) = NULL; } /* ecma_init_lit_storage */ /** @@ -86,8 +70,8 @@ ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list void ecma_finalize_lit_storage (void) { - ecma_free_string_list (string_list_first_p); - ecma_free_string_list (number_list_first_p); + ecma_free_string_list (JERRY_CONTEXT (string_list_first_p)); + ecma_free_string_list (JERRY_CONTEXT (number_list_first_p)); } /* ecma_finalize_lit_storage */ /** @@ -101,7 +85,7 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string { ecma_string_t *string_p = ecma_new_ecma_string_from_utf8 (chars_p, size); - ecma_lit_storage_item_t *string_list_p = string_list_first_p; + ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p); jmem_cpointer_t *empty_cpointer_p = NULL; while (string_list_p != NULL) @@ -149,8 +133,8 @@ ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string new_item_p->values[i] = JMEM_CP_NULL; } - JMEM_CP_SET_POINTER (new_item_p->next_cp, string_list_first_p); - string_list_first_p = new_item_p; + JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (string_list_first_p)); + JERRY_CONTEXT (string_list_first_p) = new_item_p; return result; } /* ecma_find_or_create_literal_string */ @@ -165,7 +149,7 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be { ecma_value_t num = ecma_make_number_value (number_arg); - ecma_lit_storage_item_t *number_list_p = number_list_first_p; + ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p); jmem_cpointer_t *empty_cpointer_p = NULL; while (number_list_p != NULL) @@ -229,8 +213,8 @@ ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be new_item_p->values[i] = JMEM_CP_NULL; } - JMEM_CP_SET_POINTER (new_item_p->next_cp, number_list_first_p); - number_list_first_p = new_item_p; + JMEM_CP_SET_POINTER (new_item_p->next_cp, JERRY_CONTEXT (number_list_first_p)); + JERRY_CONTEXT (number_list_first_p) = new_item_p; return result; } /* ecma_find_or_create_literal_number */ @@ -268,7 +252,7 @@ ecma_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot b uint32_t number_count = 0; uint32_t lit_table_size = 2 * sizeof (uint32_t); - ecma_lit_storage_item_t *string_list_p = string_list_first_p; + ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p); while (string_list_p != NULL) { @@ -288,7 +272,7 @@ ecma_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot b string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp); } - ecma_lit_storage_item_t *number_list_p = number_list_first_p; + ecma_lit_storage_item_t *number_list_p = JERRY_CONTEXT (number_list_first_p); while (number_list_p != NULL) { @@ -338,7 +322,7 @@ ecma_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot b ((uint32_t *) buffer_p)[1] = number_count; buffer_p += 2 * sizeof (uint32_t); - string_list_p = string_list_first_p; + string_list_p = JERRY_CONTEXT (string_list_first_p); while (string_list_p != NULL) { @@ -369,7 +353,7 @@ ecma_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot b string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp); } - number_list_p = number_list_first_p; + number_list_p = JERRY_CONTEXT (number_list_first_p); while (number_list_p != NULL) { diff --git a/jerry-core/ecma/operations/ecma-lex-env.c b/jerry-core/ecma/operations/ecma-lex-env.c index 0a9130442f..d07488cb68 100644 --- a/jerry-core/ecma/operations/ecma-lex-env.c +++ b/jerry-core/ecma/operations/ecma-lex-env.c @@ -22,7 +22,7 @@ #include "ecma-helpers.h" #include "ecma-lex-env.h" #include "ecma-objects.h" -#include "jrt.h" +#include "jcontext.h" /** \addtogroup ecma ECMA * @{ @@ -34,39 +34,32 @@ * @{ */ -/** - * Global lexical environment - * - * See also: ECMA-262 v5, 10.2.3 - */ -ecma_object_t *ecma_global_lex_env_p = NULL; - /** * Initialize Global environment */ void -ecma_init_environment (void) +ecma_init_global_lex_env (void) { #ifdef CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE - ecma_global_lex_env_p = ecma_create_decl_lex_env (NULL); + JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_decl_lex_env (NULL); #else /* !CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE */ ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL); - ecma_global_lex_env_p = ecma_create_object_lex_env (NULL, glob_obj_p, false); + JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_object_lex_env (NULL, glob_obj_p, false); ecma_deref_object (glob_obj_p); #endif /* CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE */ -} /* ecma_init_environment */ +} /* ecma_init_global_lex_env */ /** * Finalize Global environment */ void -ecma_finalize_environment (void) +ecma_finalize_global_lex_env (void) { - ecma_deref_object (ecma_global_lex_env_p); - ecma_global_lex_env_p = NULL; -} /* ecma_finalize_environment */ + ecma_deref_object (JERRY_CONTEXT (ecma_global_lex_env_p)); + JERRY_CONTEXT (ecma_global_lex_env_p) = NULL; +} /* ecma_finalize_global_lex_env */ /** * Get reference to Global lexical environment @@ -77,7 +70,7 @@ ecma_finalize_environment (void) ecma_object_t * ecma_get_global_environment (void) { - return ecma_global_lex_env_p; + return JERRY_CONTEXT (ecma_global_lex_env_p); } /* ecma_get_global_environment */ /** diff --git a/jerry-core/ecma/operations/ecma-lex-env.h b/jerry-core/ecma/operations/ecma-lex-env.h index 2615a3d97e..7f0ef1de27 100644 --- a/jerry-core/ecma/operations/ecma-lex-env.h +++ b/jerry-core/ecma/operations/ecma-lex-env.h @@ -30,8 +30,8 @@ * @{ */ -extern void ecma_init_environment (void); -extern void ecma_finalize_environment (void); +extern void ecma_init_global_lex_env (void); +extern void ecma_finalize_global_lex_env (void); extern ecma_object_t *ecma_get_global_environment (void); /** diff --git a/jerry-core/jcontext/jcontext.c b/jerry-core/jcontext/jcontext.c index 8186a39427..38c6878edb 100644 --- a/jerry-core/jcontext/jcontext.c +++ b/jerry-core/jcontext/jcontext.c @@ -42,6 +42,15 @@ jerry_context_t jerry_global_context; */ jmem_heap_t jerry_global_heap __attribute__ ((aligned (JMEM_ALIGNMENT))) JERRY_GLOBAL_HEAP_SECTION; +#ifndef CONFIG_ECMA_LCACHE_DISABLE + +/** + * Global hash table. + */ +jerry_hash_table_t jerry_global_hash_table; + +#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ + /** * @} * @} diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h index 4a918a7eb7..4eca947df8 100644 --- a/jerry-core/jcontext/jcontext.h +++ b/jerry-core/jcontext/jcontext.h @@ -21,6 +21,7 @@ #define JCONTEXT_H #include "jrt.h" +#include "ecma-globals.h" #include "jmem-allocator.h" #include "jmem-config.h" @@ -31,6 +32,47 @@ * @{ */ +/** + * JerryScript context + * + * The purpose of this header is storing + * all global variables for Jerry + */ +typedef struct +{ + /** + * Memory manager part. + */ + size_t jmem_heap_allocated_size; /**< size of allocated regions */ + size_t jmem_heap_limit; /**< current limit of heap usage, that is upon being reached, + * causes call of "try give memory back" callbacks */ + jmem_heap_free_t *jmem_heap_list_skip_p; /**< This is used to speed up deallocation. */ + jmem_pools_chunk_t *jmem_free_chunk_p; /**< list of free pool chunks */ + jmem_free_unused_memory_callback_t jmem_free_unused_memory_callback; /**< Callback for freeing up memory. */ + +#ifdef JMEM_STATS + jmem_heap_stats_t jmem_heap_stats; /**< heap's memory usage statistics */ + jmem_pools_stats_t jmem_pools_stats; /**< pools' memory usage statistics */ +#endif /* MEM_STATS */ + +#ifdef JERRY_VALGRIND_FREYA + bool valgrind_freya_mempool_request; /**< Tells whether a pool manager + * allocator request is in progress */ +#endif /* JERRY_VALGRIND_FREYA */ + + /** + * Ecma part. + */ + ecma_object_t *ecma_gc_objects_lists[ECMA_GC_COLOR__COUNT]; /**< List of marked (visited during + * current GC session) and umarked objects */ + bool ecma_gc_visited_flip_flag; /**< current state of an object's visited flag */ + size_t ecma_gc_objects_number; /**< number of currently allocated objects */ + size_t ecma_gc_new_objects; /**< number of newly allocated objects since last GC session */ + ecma_lit_storage_item_t *string_list_first_p; /**< first item of the literal string list */ + ecma_lit_storage_item_t *number_list_first_p; /**< first item of the literal number list */ + ecma_object_t *ecma_global_lex_env_p; /**< global lexical environment */ +} jerry_context_t; + /** * Calculate heap area size, leaving space for a pointer to the free list */ @@ -54,45 +96,40 @@ typedef struct uint8_t area[JMEM_HEAP_AREA_SIZE]; /**< heap area */ } jmem_heap_t; +#ifndef CONFIG_ECMA_LCACHE_DISABLE + /** - * JerryScript context - * - * The purpose of this header is storing - * all global variables for Jerry + * JerryScript global hash table for caching the last access of properties. */ typedef struct { /** - * Memory manager part. + * Hash table */ - size_t jmem_heap_allocated_size; /**< size of allocated regions */ - size_t jmem_heap_limit; /**< current limit of heap usage, that is upon being reached, - * causes call of "try give memory back" callbacks */ - jmem_heap_free_t *jmem_heap_list_skip_p; /**< This is used to speed up deallocation. */ - jmem_pools_chunk_t *jmem_free_chunk_p; /**< list of free pool chunks */ - jmem_free_unused_memory_callback_t jmem_free_unused_memory_callback; /**< Callback for freeing up memory. */ - -#ifdef JMEM_STATS - jmem_heap_stats_t jmem_heap_stats; /**< heap's memory usage statistics */ - jmem_pools_stats_t jmem_pools_stats; /**< pools' memory usage statistics */ -#endif /* MEM_STATS */ + ecma_lcache_hash_entry_t table[ECMA_LCACHE_HASH_ROWS_COUNT][ECMA_LCACHE_HASH_ROW_LENGTH]; +} jerry_hash_table_t; -#ifdef JERRY_VALGRIND_FREYA - bool valgrind_freya_mempool_request; /**< Tells whether a pool manager - * allocator request is in progress */ -#endif /* JERRY_VALGRIND_FREYA */ -} jerry_context_t; +#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ /** - * Jerry global context. + * Global context. */ extern jerry_context_t jerry_global_context; /** - * Jerry global heap. + * Global heap. */ extern jmem_heap_t jerry_global_heap; +#ifndef CONFIG_ECMA_LCACHE_DISABLE + +/** + * Global hash table. + */ +extern jerry_hash_table_t jerry_global_hash_table; + +#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ + /** * Provides a reference to a field in the current context. */ @@ -103,6 +140,15 @@ extern jmem_heap_t jerry_global_heap; */ #define JERRY_HEAP_CONTEXT(field) (jerry_global_heap.field) +#ifndef CONFIG_ECMA_LCACHE_DISABLE + +/** + * Provides a reference to the global hash table. + */ +#define JERRY_HASH_TABLE_CONTEXT(field) (jerry_global_hash_table.field) + +#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ + /** * @} * @}