Repository: jerryscript-project/jerryscript
File: jerry-core/ecma/base/ecma-gc.c (C)

Code before:

  JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_API_AVAILABLE;

  while (native_pointer_p != NULL)
  {
    if (native_pointer_p->info_p != NULL)
    {
      ecma_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb;

      if (free_cb != NULL)
      {
        free_cb (native_pointer_p->data_p);
      }
    }

    ecma_native_pointer_t *next_p = native_pointer_p->next_p;

    jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));

    native_pointer_p = next_p;
  }

  JERRY_CONTEXT (status_flags) |= ECMA_STATUS_API_AVAILABLE;
} /* ecma_gc_free_native_pointer */

/**
 * Free specified 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_ONE);

  bool obj_is_not_lex_env = !ecma_is_lexical_environment (object_p);

  if (obj_is_not_lex_env
      || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
  {
    ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);

    if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
    {
      ecma_property_hashmap_free (object_p);
      prop_iter_p = ecma_get_property_list (object_p);
    }

    while (prop_iter_p != NULL)
    {
      JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));

Review comment (bug):
These are equivalents of the `jerry_make_api_unavailable` and `jerry_make_api_available` static inline functions of jerry.c. But there, they are only called from `jerry_cleanup` and `jerry_init`. Here, they are called on every invocation of `ecma_gc_free_native_pointer`. Wont be that a performance hit?

(Note: that whole flag is strange. It is unconditionally set/cleared by `jerry_init` and `jerry_cleanup` but only checked in debug asserts. Seems like setting/clearing it should also happen in debug builds only. And then the preformance hit question would also go away.)

Code after:

#ifndef JERRY_NDEBUG
  JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_API_AVAILABLE;
#endif /* !JERRY_NDEBUG */

  while (native_pointer_p != NULL)
  {
    if (native_pointer_p->info_p != NULL)
    {
      ecma_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb;

      if (free_cb != NULL)
      {
        free_cb (native_pointer_p->data_p);
      }
    }

    ecma_native_pointer_t *next_p = native_pointer_p->next_p;

    jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));

    native_pointer_p = next_p;
  }

#ifndef JERRY_NDEBUG
  JERRY_CONTEXT (status_flags) |= ECMA_STATUS_API_AVAILABLE;
#endif /* !JERRY_NDEBUG */
} /* ecma_gc_free_native_pointer */

/**
 * Free specified 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_ONE);

  bool obj_is_not_lex_env = !ecma_is_lexical_environment (object_p);

  if (obj_is_not_lex_env
      || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
  {
    ecma_property_header_t *prop_iter_p = ecma_get_property_list (object_p);

    if (prop_iter_p != NULL && prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
    {
      ecma_property_hashmap_free (object_p);
      prop_iter_p = ecma_get_property_list (object_p);
    }