From e191a5cf47eeaf3e36098e49a138885f913c0dd1 Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Fri, 29 Jan 2021 14:45:27 +0100 Subject: [PATCH] Increase the maximum reference count of objects when cpointer 32 is enabled (#4550) JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/ecma/base/ecma-gc.c | 18 ++++++------ jerry-core/ecma/base/ecma-globals.h | 35 ++++++++++++++++++----- jerry-core/ecma/base/ecma-helpers.c | 15 +++++----- jerry-core/ecma/operations/ecma-lex-env.c | 2 +- jerry-core/ecma/operations/ecma-objects.c | 2 +- jerry-core/vm/vm.c | 6 ++-- 6 files changed, 49 insertions(+), 29 deletions(-) diff --git a/jerry-core/ecma/base/ecma-gc.c b/jerry-core/ecma/base/ecma-gc.c index e32f338d7..3e50a17c9 100644 --- a/jerry-core/ecma/base/ecma-gc.c +++ b/jerry-core/ecma/base/ecma-gc.c @@ -91,19 +91,19 @@ ecma_gc_set_object_visited (ecma_object_t *object_p) /**< object */ { JERRY_CONTEXT (ecma_gc_mark_recursion_limit)--; /* Set the reference count of gray object to 0 */ - object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & (ECMA_OBJECT_REF_ONE - 1)); + object_p->type_flags_refs &= (ecma_object_descriptor_t) (ECMA_OBJECT_REF_ONE - 1); ecma_gc_mark (object_p); JERRY_CONTEXT (ecma_gc_mark_recursion_limit)++; } else { /* Set the reference count of the non-marked gray object to 1 */ - object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & ((ECMA_OBJECT_REF_ONE << 1) - 1)); + object_p->type_flags_refs &= (ecma_object_descriptor_t) ((ECMA_OBJECT_REF_ONE << 1) - 1); JERRY_ASSERT (object_p->type_flags_refs >= ECMA_OBJECT_REF_ONE); } #else /* (JERRY_GC_MARK_LIMIT == 0) */ /* Set the reference count of gray object to 0 */ - object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & (ECMA_OBJECT_REF_ONE - 1)); + object_p->type_flags_refs &= (ecma_object_descriptor_t) (ECMA_OBJECT_REF_ONE - 1); #endif /* (JERRY_GC_MARK_LIMIT != 0) */ } } /* ecma_gc_set_object_visited */ @@ -118,7 +118,7 @@ ecma_init_gc_info (ecma_object_t *object_p) /**< object */ JERRY_CONTEXT (ecma_gc_new_objects)++; 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); + object_p->type_flags_refs |= ECMA_OBJECT_REF_ONE; object_p->gc_next_cp = JERRY_CONTEXT (ecma_gc_objects_cp); ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (ecma_gc_objects_cp), object_p); @@ -132,7 +132,7 @@ ecma_ref_object (ecma_object_t *object_p) /**< object */ { if (JERRY_LIKELY (object_p->type_flags_refs < ECMA_OBJECT_MAX_REF)) { - object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs + ECMA_OBJECT_REF_ONE); + object_p->type_flags_refs = (ecma_object_descriptor_t) (object_p->type_flags_refs + ECMA_OBJECT_REF_ONE); } else { @@ -147,7 +147,7 @@ extern inline void JERRY_ATTR_ALWAYS_INLINE ecma_deref_object (ecma_object_t *object_p) /**< object */ { 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); + object_p->type_flags_refs = (ecma_object_descriptor_t) (object_p->type_flags_refs - ECMA_OBJECT_REF_ONE); } /* ecma_deref_object */ /** @@ -1394,9 +1394,7 @@ ecma_gc_free_properties (ecma_object_t *object_p) /**< object */ static void ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */ { - JERRY_ASSERT (object_p != NULL - && !ecma_gc_is_object_visited (object_p) - && ((object_p->type_flags_refs & ECMA_OBJECT_REF_MASK) == ECMA_OBJECT_NON_VISITED)); + JERRY_ASSERT (object_p != NULL && !ecma_gc_is_object_visited (object_p)); JERRY_ASSERT (JERRY_CONTEXT (ecma_gc_objects_number) > 0); JERRY_CONTEXT (ecma_gc_objects_number)--; @@ -1894,7 +1892,7 @@ ecma_gc_run (void) if (obj_iter_p->type_flags_refs >= ECMA_OBJECT_REF_ONE) { /* Set the reference count of non-marked gray object to 0 */ - obj_iter_p->type_flags_refs = (uint16_t) (obj_iter_p->type_flags_refs & (ECMA_OBJECT_REF_ONE - 1)); + obj_iter_p->type_flags_refs &= (ecma_object_descriptor_t) (ECMA_OBJECT_REF_ONE - 1); ecma_gc_mark (obj_iter_p); marked_anything_during_current_iteration = true; } diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 8b8d20984..98d9de036 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -769,7 +769,7 @@ typedef enum #define ECMA_OBJECT_FLAG_EXTENSIBLE 0x20 /** - * Non closure flag for debugger. + * Lexical environments created for non-closure code blocks */ #define ECMA_OBJECT_FLAG_BLOCK ECMA_OBJECT_FLAG_EXTENSIBLE @@ -778,23 +778,44 @@ typedef enum */ #define ECMA_OBJECT_REF_SHIFT 6 +/** + * Value for increasing or decreasing the object reference counter. + */ +#define ECMA_OBJECT_REF_ONE (1u << ECMA_OBJECT_REF_SHIFT) + +#if ENABLED (JERRY_CPOINTER_32_BIT) + +/** + * Bitmask for an ecma-object reference count field + */ +#define ECMA_OBJECT_REF_MASK (((1u << 26) - 1) << ECMA_OBJECT_REF_SHIFT) + +/** + * Type of the descriptor field of an object + */ +typedef uint32_t ecma_object_descriptor_t; + +#else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ + /** * Bitmask for an ecma-object reference count field */ #define ECMA_OBJECT_REF_MASK (((1u << 10) - 1) << ECMA_OBJECT_REF_SHIFT) /** - * Value for increasing or decreasing the object reference counter. + * Type of the descriptor field of an object */ -#define ECMA_OBJECT_REF_ONE (1u << ECMA_OBJECT_REF_SHIFT) +typedef uint16_t ecma_object_descriptor_t; + +#endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ /** * Represents non-visited white object */ -#define ECMA_OBJECT_NON_VISITED (0x3ffu << ECMA_OBJECT_REF_SHIFT) +#define ECMA_OBJECT_NON_VISITED ECMA_OBJECT_REF_MASK /** - * Maximum value of the object reference counter (1022). + * Maximum value of the object reference counter (1022 / 67108862). */ #define ECMA_OBJECT_MAX_REF (ECMA_OBJECT_NON_VISITED - ECMA_OBJECT_REF_ONE) @@ -808,8 +829,8 @@ typedef struct depending on ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV flags : 2 bit : ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV, ECMA_OBJECT_FLAG_EXTENSIBLE or ECMA_OBJECT_FLAG_BLOCK - refs : 10 bit (max 1022) */ - uint16_t type_flags_refs; + refs : 10 / 26 bit (max 1022 / 67108862) */ + ecma_object_descriptor_t type_flags_refs; /** next in the object chain maintained by the garbage collector */ jmem_cpointer_t gc_next_cp; diff --git a/jerry-core/ecma/base/ecma-helpers.c b/jerry-core/ecma/base/ecma-helpers.c index cac1e9a7e..ab6ae4f8e 100644 --- a/jerry-core/ecma/base/ecma-helpers.c +++ b/jerry-core/ecma/base/ecma-helpers.c @@ -52,7 +52,7 @@ JERRY_STATIC_ASSERT (ECMA_OBJECT_FLAG_EXTENSIBLE == (ECMA_OBJECT_FLAG_BUILT_IN_O JERRY_STATIC_ASSERT (ECMA_OBJECT_REF_ONE == (ECMA_OBJECT_FLAG_EXTENSIBLE << 1), ecma_object_ref_one_must_follow_the_extensible_flag); -JERRY_STATIC_ASSERT (((ECMA_OBJECT_MAX_REF + ECMA_OBJECT_REF_ONE) | (ECMA_OBJECT_REF_ONE - 1)) == UINT16_MAX, +JERRY_STATIC_ASSERT ((ECMA_OBJECT_MAX_REF + ECMA_OBJECT_REF_ONE) == ECMA_OBJECT_REF_MASK, ecma_object_max_ref_does_not_fill_the_remaining_bits); JERRY_STATIC_ASSERT (ECMA_PROPERTY_FLAGS_MASK == ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE, @@ -83,7 +83,7 @@ ecma_create_object (ecma_object_t *prototype_object_p, /**< pointer to prototybe new_object_p = ecma_alloc_object (); } - new_object_p->type_flags_refs = (uint16_t) (type | ECMA_OBJECT_FLAG_EXTENSIBLE); + new_object_p->type_flags_refs = (ecma_object_descriptor_t) (type | ECMA_OBJECT_FLAG_EXTENSIBLE); ecma_init_gc_info (new_object_p); @@ -109,8 +109,8 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer { ecma_object_t *new_lexical_environment_p = ecma_alloc_object (); - uint16_t type = ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE; - new_lexical_environment_p->type_flags_refs = type; + new_lexical_environment_p->type_flags_refs = (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV + | ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE); ecma_init_gc_info (new_lexical_environment_p); @@ -148,7 +148,8 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out ecma_object_t *new_lexical_environment_p = ecma_alloc_object (); - new_lexical_environment_p->type_flags_refs = (uint16_t) (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | type); + const ecma_object_descriptor_t lexical_env_flag = ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV; + new_lexical_environment_p->type_flags_refs = (ecma_object_descriptor_t) (type | lexical_env_flag); ecma_init_gc_info (new_lexical_environment_p); @@ -185,7 +186,7 @@ ecma_op_ordinary_object_set_extensible (ecma_object_t *object_p) /**< object */ JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (!ecma_is_lexical_environment (object_p)); - object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_EXTENSIBLE); + object_p->type_flags_refs |= ECMA_OBJECT_FLAG_EXTENSIBLE; } /* ecma_op_ordinary_object_set_extensible */ /** @@ -227,7 +228,7 @@ ecma_set_object_is_builtin (ecma_object_t *object_p) /**< object */ JERRY_ASSERT (!(object_p->type_flags_refs & ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV)); JERRY_ASSERT ((object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK) < ECMA_LEXICAL_ENVIRONMENT_TYPE_START); - object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs | ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV); + object_p->type_flags_refs |= ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV; } /* ecma_set_object_is_builtin */ /** diff --git a/jerry-core/ecma/operations/ecma-lex-env.c b/jerry-core/ecma/operations/ecma-lex-env.c index 5365c5743..0096b23fd 100644 --- a/jerry-core/ecma/operations/ecma-lex-env.c +++ b/jerry-core/ecma/operations/ecma-lex-env.c @@ -81,7 +81,7 @@ ecma_create_global_lexical_block (ecma_object_t *global_object_p) /**< global ob if (real_global_object_p->global_scope_cp == real_global_object_p->global_env_cp) { ecma_object_t *global_scope_p = ecma_create_decl_lex_env (ecma_get_global_environment (global_object_p)); - global_scope_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_BLOCK; + global_scope_p->type_flags_refs |= ECMA_OBJECT_FLAG_BLOCK; ECMA_SET_NON_NULL_POINTER (real_global_object_p->global_scope_cp, global_scope_p); ecma_deref_object (global_scope_p); } diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 2daab2bc4..a678f0f2d 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -3243,7 +3243,7 @@ void JERRY_ATTR_NOINLINE ecma_op_ordinary_object_prevent_extensions (ecma_object_t *object_p) /**< object */ { JERRY_ASSERT (!ECMA_OBJECT_IS_PROXY (object_p)); - object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs & ~ECMA_OBJECT_FLAG_EXTENSIBLE); + object_p->type_flags_refs &= (ecma_object_descriptor_t) ~ECMA_OBJECT_FLAG_EXTENSIBLE; } /* ecma_op_ordinary_object_prevent_extensions */ /** diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index 94359624a..bae3a741e 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -403,7 +403,7 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */ if ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_BLOCK_NEEDED) != 0) { ecma_object_t *lex_block_p = ecma_create_decl_lex_env (lex_env_p); - lex_block_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_BLOCK; + lex_block_p->type_flags_refs |= ECMA_OBJECT_FLAG_BLOCK; ecma_deref_object (lex_env_p); lex_env_p = lex_block_p; @@ -3928,7 +3928,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ #endif /* ENABLED (JERRY_ESNEXT) */ frame_ctx_p->lex_env_p = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p); - frame_ctx_p->lex_env_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_BLOCK; + frame_ctx_p->lex_env_p->type_flags_refs |= ECMA_OBJECT_FLAG_BLOCK; continue; } @@ -3962,7 +3962,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ stack_top_p[-1] = VM_CREATE_CONTEXT_WITH_ENV (VM_CONTEXT_WITH, branch_offset); - with_env_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_BLOCK; + with_env_p->type_flags_refs |= ECMA_OBJECT_FLAG_BLOCK; frame_ctx_p->lex_env_p = with_env_p; continue; }