Example #1
0
static void
interp_mem_stats_opcode_enter (const vm_instr_t *instrs_p,
                               vm_instr_counter_t instr_position,
                               mem_heap_stats_t *out_heap_stats_p,
                               mem_pools_stats_t *out_pools_stats_p)
{
  if (likely (!interp_mem_stats_enabled))
  {
    return;
  }

  const uint32_t indentation = JERRY_MIN (interp_mem_stats_print_indentation,
                                          INTERP_MEM_PRINT_INDENTATION_MAX);

  char indent_prefix[INTERP_MEM_PRINT_INDENTATION_MAX + 2];
  memset (indent_prefix, ' ', sizeof (indent_prefix));
  indent_prefix[indentation] = '|';
  indent_prefix[indentation + 1] = '\0';

  interp_mem_get_stats (out_heap_stats_p,
                        out_pools_stats_p,
                        true, false);

  vm_instr_t instr = vm_get_instr (instrs_p, instr_position);

  printf ("%s-- Opcode: %s (position %u) --\n",
          indent_prefix, __op_names[instr.op_idx], (uint32_t) instr_position);

  interp_mem_stats_print_indentation += INTERP_MEM_PRINT_INDENTATION_STEP;
}
Example #2
0
static void
interp_mem_stats_context_enter (vm_frame_ctx_t *frame_ctx_p,
                                vm_instr_counter_t block_position)
{
  if (likely (!interp_mem_stats_enabled))
  {
    return;
  }

  const uint32_t indentation = JERRY_MIN (interp_mem_stats_print_indentation,
                                          INTERP_MEM_PRINT_INDENTATION_MAX);

  char indent_prefix[INTERP_MEM_PRINT_INDENTATION_MAX + 2];
  memset (indent_prefix, ' ', sizeof (indent_prefix));
  indent_prefix[indentation] = '|';
  indent_prefix[indentation + 1] = '\0';

  frame_ctx_p->context_peak_allocated_heap_bytes = 0;
  frame_ctx_p->context_peak_waste_heap_bytes = 0;
  frame_ctx_p->context_peak_pools_count = 0;
  frame_ctx_p->context_peak_allocated_pool_chunks = 0;

  interp_mem_get_stats (&frame_ctx_p->heap_stats_context_enter,
                        &frame_ctx_p->pools_stats_context_enter,
                        false, false);

  printf ("\n%s--- Beginning interpretation of a block at position %u ---\n"
          "%s Allocated heap bytes:  %5u\n"
          "%s Waste heap bytes:      %5u\n"
          "%s Pools:                 %5u\n"
          "%s Allocated pool chunks: %5u\n\n",
          indent_prefix, (uint32_t) block_position,
          indent_prefix, (uint32_t) frame_ctx_p->heap_stats_context_enter.allocated_bytes,
          indent_prefix, (uint32_t) frame_ctx_p->heap_stats_context_enter.waste_bytes,
          indent_prefix, (uint32_t) frame_ctx_p->pools_stats_context_enter.pools_count,
          indent_prefix, (uint32_t) frame_ctx_p->pools_stats_context_enter.allocated_chunks);
}
Example #3
0
/**
 * Allocation of memory region.
 *
 * See also:
 *          mem_heap_alloc_block
 *
 * @return pointer to allocated memory block - if allocation is successful,
 *         NULL - if there is not enough memory.
 */
static
void* mem_heap_alloc_block_internal (size_t size_in_bytes, /**< size of region to allocate in bytes */
                                     mem_block_length_type_t length_type, /**< length type of the block
                                                                           *   (one-chunked or general) */
                                     mem_heap_alloc_term_t alloc_term) /**< expected allocation term */
{
  mem_block_header_t *block_p;
  mem_direction_t direction;

  JERRY_ASSERT (size_in_bytes != 0);
  JERRY_ASSERT (length_type != mem_block_length_type_t::ONE_CHUNKED
                || size_in_bytes == mem_heap_get_chunked_block_data_size ());

  mem_check_heap ();

  if (alloc_term == MEM_HEAP_ALLOC_LONG_TERM)
  {
    block_p = mem_heap.first_block_p;
    direction = MEM_DIRECTION_NEXT;
  }
  else
  {
    JERRY_ASSERT (alloc_term == MEM_HEAP_ALLOC_SHORT_TERM);

    block_p = mem_heap.last_block_p;
    direction = MEM_DIRECTION_PREV;
  }

  /* searching for appropriate block */
  while (block_p != NULL)
  {
    VALGRIND_DEFINED_STRUCT (block_p);

    if (mem_is_block_free (block_p))
    {
      if (mem_get_block_data_space_size (block_p) >= size_in_bytes)
      {
        break;
      }
    }
    else
    {
      JERRY_ASSERT (!mem_is_block_free (block_p));
    }

    mem_block_header_t *next_block_p = mem_get_next_block_by_direction (block_p, direction);

    VALGRIND_NOACCESS_STRUCT (block_p);

    block_p = next_block_p;
  }

  if (block_p == NULL)
  {
    /* not enough free space */
    return NULL;
  }

  /* appropriate block found, allocating space */
  size_t new_block_size_in_chunks = mem_get_block_chunks_count_from_data_size (size_in_bytes);
  size_t found_block_size_in_chunks = mem_get_block_chunks_count (block_p);

  JERRY_ASSERT (new_block_size_in_chunks <= found_block_size_in_chunks);

  mem_heap.allocated_chunks += new_block_size_in_chunks;

  JERRY_ASSERT (mem_heap.allocated_chunks * MEM_HEAP_CHUNK_SIZE <= mem_heap.heap_size);

  if (mem_heap.allocated_chunks * MEM_HEAP_CHUNK_SIZE >= mem_heap.limit)
  {
    mem_heap.limit = JERRY_MIN (mem_heap.heap_size,
                                JERRY_MAX (mem_heap.limit + CONFIG_MEM_HEAP_DESIRED_LIMIT,
                                           mem_heap.allocated_chunks * MEM_HEAP_CHUNK_SIZE));
    JERRY_ASSERT (mem_heap.limit >= mem_heap.allocated_chunks * MEM_HEAP_CHUNK_SIZE);
  }

  mem_block_header_t *prev_block_p = mem_get_next_block_by_direction (block_p, MEM_DIRECTION_PREV);
  mem_block_header_t *next_block_p = mem_get_next_block_by_direction (block_p, MEM_DIRECTION_NEXT);

  if (new_block_size_in_chunks < found_block_size_in_chunks)
  {
    MEM_HEAP_STAT_FREE_BLOCK_SPLIT ();

    if (direction == MEM_DIRECTION_PREV)
    {
      prev_block_p = block_p;
      uint8_t *block_end_p = (uint8_t*) block_p + found_block_size_in_chunks * MEM_HEAP_CHUNK_SIZE;
      block_p = (mem_block_header_t*) (block_end_p - new_block_size_in_chunks * MEM_HEAP_CHUNK_SIZE);

      VALGRIND_DEFINED_STRUCT (prev_block_p);

      mem_set_block_next (prev_block_p, block_p);

      VALGRIND_NOACCESS_STRUCT (prev_block_p);

      if (next_block_p == NULL)
      {
        mem_heap.last_block_p = block_p;
      }
      else
      {
        VALGRIND_DEFINED_STRUCT (next_block_p);

        mem_set_block_prev (next_block_p, block_p);

        VALGRIND_NOACCESS_STRUCT (next_block_p);
      }
    }
    else
    {
      uint8_t *new_free_block_first_chunk_p = (uint8_t*) block_p + new_block_size_in_chunks * MEM_HEAP_CHUNK_SIZE;
      mem_init_block_header (new_free_block_first_chunk_p,
                             0,
                             MEM_BLOCK_FREE,
                             mem_block_length_type_t::GENERAL,
                             block_p,
                             next_block_p);

      mem_block_header_t *new_free_block_p = (mem_block_header_t*) new_free_block_first_chunk_p;

      if (next_block_p == NULL)
      {
        mem_heap.last_block_p = new_free_block_p;
      }
      else
      {
        VALGRIND_DEFINED_STRUCT (next_block_p);

        mem_block_header_t* new_free_block_p = (mem_block_header_t*) new_free_block_first_chunk_p;
        mem_set_block_prev (next_block_p, new_free_block_p);

        VALGRIND_NOACCESS_STRUCT (next_block_p);
      }

      next_block_p = new_free_block_p;
    }
  }

  mem_init_block_header ((uint8_t*) block_p,
                         size_in_bytes,
                         MEM_BLOCK_ALLOCATED,
                         length_type,
                         prev_block_p,
                         next_block_p);

  VALGRIND_DEFINED_STRUCT (block_p);

  MEM_HEAP_STAT_ALLOC_BLOCK (block_p);

  JERRY_ASSERT (mem_get_block_data_space_size (block_p) >= size_in_bytes);

  VALGRIND_NOACCESS_STRUCT (block_p);

  /* return data space beginning address */
  uint8_t *data_space_p = (uint8_t*) (block_p + 1);
  JERRY_ASSERT ((uintptr_t) data_space_p % MEM_ALIGNMENT == 0);

  VALGRIND_UNDEFINED_SPACE (data_space_p, size_in_bytes);

  mem_check_heap ();

  return data_space_p;
} /* mem_heap_alloc_block_internal */
/**
 * Helper for stringifying numbers
 *
 * @return the length of the generated string representation
 */
static lit_utf8_size_t
ecma_builtin_number_prototype_helper_to_string (lit_utf8_byte_t *digits_p, /**< number as string in decimal form */
                                                lit_utf8_size_t num_digits, /**< length of the string representation */
                                                int32_t exponent, /**< decimal exponent */
                                                lit_utf8_byte_t *to_digits_p, /**< [out] buffer to write */
                                                lit_utf8_size_t to_num_digits) /**< requested number of digits */
{
  lit_utf8_byte_t *p = to_digits_p;

  if (exponent <= 0)
  {
    /* Add zero to the integer part. */
    *p++ = '0';
    to_num_digits--;

    if (to_num_digits > 0)
    {
      *p++ = '.';

      /* Add leading zeros to the fraction part. */
      for (int i = 0; i < -exponent && to_num_digits > 0; i++)
      {
        *p++ = '0';
        to_num_digits--;
      }
    }
  }
  else
  {
    /* Add significant digits of the integer part. */
    lit_utf8_size_t to_copy = JERRY_MIN (num_digits, to_num_digits);
    to_copy = JERRY_MIN (to_copy, (lit_utf8_size_t) exponent);
    memmove (p, digits_p, (size_t) to_copy);
    p += to_copy;
    to_num_digits -= to_copy;
    digits_p += to_copy;
    num_digits -= to_copy;
    exponent -= (int32_t) to_copy;

    /* Add zeros before decimal point. */
    while (exponent > 0 && to_num_digits > 0)
    {
      JERRY_ASSERT (num_digits == 0);
      *p++ = '0';
      to_num_digits--;
      exponent--;
    }

    if (to_num_digits > 0)
    {
      *p++ = '.';
    }
  }

  if (to_num_digits > 0)
  {
    /* Add significant digits of the fraction part. */
    lit_utf8_size_t to_copy = JERRY_MIN (num_digits, to_num_digits);
    memmove (p, digits_p, (size_t) to_copy);
    p += to_copy;
    to_num_digits -= to_copy;

    /* Add trailing zeros. */
    while (to_num_digits > 0)
    {
      *p++ = '0';
      to_num_digits--;
    }
  }

  return (lit_utf8_size_t) (p - to_digits_p);
} /* ecma_builtin_number_prototype_helper_to_string */
Example #5
0
static void
interp_mem_stats_opcode_exit (vm_frame_ctx_t *frame_ctx_p,
                              vm_instr_counter_t instr_position,
                              mem_heap_stats_t *heap_stats_before_p,
                              mem_pools_stats_t *pools_stats_before_p)
{
  if (likely (!interp_mem_stats_enabled))
  {
    return;
  }

  interp_mem_stats_print_indentation -= INTERP_MEM_PRINT_INDENTATION_STEP;

  const uint32_t indentation = JERRY_MIN (interp_mem_stats_print_indentation,
                                          INTERP_MEM_PRINT_INDENTATION_MAX);

  char indent_prefix[INTERP_MEM_PRINT_INDENTATION_MAX + 2];
  memset (indent_prefix, ' ', sizeof (indent_prefix));
  indent_prefix[indentation] = '|';
  indent_prefix[indentation + 1] = '\0';

  mem_heap_stats_t heap_stats_after;
  mem_pools_stats_t pools_stats_after;

  interp_mem_get_stats (&heap_stats_after,
                        &pools_stats_after,
                        false, true);

  frame_ctx_p->context_peak_allocated_heap_bytes = JERRY_MAX (frame_ctx_p->context_peak_allocated_heap_bytes,
                                                             heap_stats_after.allocated_bytes);
  frame_ctx_p->context_peak_waste_heap_bytes = JERRY_MAX (frame_ctx_p->context_peak_waste_heap_bytes,
                                                         heap_stats_after.waste_bytes);
  frame_ctx_p->context_peak_pools_count = JERRY_MAX (frame_ctx_p->context_peak_pools_count,
                                                    pools_stats_after.pools_count);
  frame_ctx_p->context_peak_allocated_pool_chunks = JERRY_MAX (frame_ctx_p->context_peak_allocated_pool_chunks,
                                                              pools_stats_after.allocated_chunks);

  vm_instr_t instr = vm_get_instr (frame_ctx_p->instrs_p, instr_position);

  printf ("%s Allocated heap bytes:  %5u -> %5u (%+5d, local %5u, peak %5u)\n",
          indent_prefix,
          (uint32_t) heap_stats_before_p->allocated_bytes,
          (uint32_t) heap_stats_after.allocated_bytes,
          (uint32_t) (heap_stats_after.allocated_bytes - heap_stats_before_p->allocated_bytes),
          (uint32_t) (heap_stats_after.peak_allocated_bytes - JERRY_MAX (heap_stats_before_p->allocated_bytes,
                                                                         heap_stats_after.allocated_bytes)),
          (uint32_t) heap_stats_after.global_peak_allocated_bytes);

  if (heap_stats_before_p->waste_bytes != heap_stats_after.waste_bytes)
  {
    printf ("%s Waste heap bytes:      %5u -> %5u (%+5d, local %5u, peak %5u)\n",
            indent_prefix,
            (uint32_t) heap_stats_before_p->waste_bytes,
            (uint32_t) heap_stats_after.waste_bytes,
            (uint32_t) (heap_stats_after.waste_bytes - heap_stats_before_p->waste_bytes),
            (uint32_t) (heap_stats_after.peak_waste_bytes - JERRY_MAX (heap_stats_before_p->waste_bytes,
                                                                       heap_stats_after.waste_bytes)),
            (uint32_t) heap_stats_after.global_peak_waste_bytes);
  }

  if (pools_stats_before_p->pools_count != pools_stats_after.pools_count)
  {
    printf ("%s Pools:                 %5u -> %5u (%+5d, local %5u, peak %5u)\n",
            indent_prefix,
            (uint32_t) pools_stats_before_p->pools_count,
            (uint32_t) pools_stats_after.pools_count,
            (uint32_t) (pools_stats_after.pools_count - pools_stats_before_p->pools_count),
            (uint32_t) (pools_stats_after.peak_pools_count - JERRY_MAX (pools_stats_before_p->pools_count,
                                                                        pools_stats_after.pools_count)),
            (uint32_t) pools_stats_after.global_peak_pools_count);
  }

  if (pools_stats_before_p->allocated_chunks != pools_stats_after.allocated_chunks)
  {
    printf ("%s Allocated pool chunks: %5u -> %5u (%+5d, local %5u, peak %5u)\n",
            indent_prefix,
            (uint32_t) pools_stats_before_p->allocated_chunks,
            (uint32_t) pools_stats_after.allocated_chunks,
            (uint32_t) (pools_stats_after.allocated_chunks - pools_stats_before_p->allocated_chunks),
            (uint32_t) (pools_stats_after.peak_allocated_chunks - JERRY_MAX (pools_stats_before_p->allocated_chunks,
                                                                             pools_stats_after.allocated_chunks)),
            (uint32_t) pools_stats_after.global_peak_allocated_chunks);
  }

  printf ("%s-- End of execution of opcode %s (position %u) --\n\n",
          indent_prefix, __op_names[instr.op_idx], instr_position);
}
Example #6
0
static void
interp_mem_stats_context_exit (vm_frame_ctx_t *frame_ctx_p,
                               vm_instr_counter_t block_position)
{
  if (likely (!interp_mem_stats_enabled))
  {
    return;
  }

  const uint32_t indentation = JERRY_MIN (interp_mem_stats_print_indentation,
                                          INTERP_MEM_PRINT_INDENTATION_MAX);

  char indent_prefix[INTERP_MEM_PRINT_INDENTATION_MAX + 2];
  memset (indent_prefix, ' ', sizeof (indent_prefix));
  indent_prefix[indentation] = '|';
  indent_prefix[indentation + 1] = '\0';

  mem_heap_stats_t heap_stats_context_exit;
  mem_pools_stats_t pools_stats_context_exit;

  interp_mem_get_stats (&heap_stats_context_exit,
                        &pools_stats_context_exit,
                        false, true);

  frame_ctx_p->context_peak_allocated_heap_bytes -= JERRY_MAX (frame_ctx_p->heap_stats_context_enter.allocated_bytes,
                                                              heap_stats_context_exit.allocated_bytes);
  frame_ctx_p->context_peak_waste_heap_bytes -= JERRY_MAX (frame_ctx_p->heap_stats_context_enter.waste_bytes,
                                                          heap_stats_context_exit.waste_bytes);
  frame_ctx_p->context_peak_pools_count -= JERRY_MAX (frame_ctx_p->pools_stats_context_enter.pools_count,
                                                     pools_stats_context_exit.pools_count);
  frame_ctx_p->context_peak_allocated_pool_chunks -= JERRY_MAX (frame_ctx_p->pools_stats_context_enter.allocated_chunks,
                                                               pools_stats_context_exit.allocated_chunks);

  printf ("%sAllocated heap bytes in the context:  %5u -> %5u (%+5d, local %5u, peak %5u)\n",
          indent_prefix,
          (uint32_t) frame_ctx_p->heap_stats_context_enter.allocated_bytes,
          (uint32_t) heap_stats_context_exit.allocated_bytes,
          (uint32_t) (heap_stats_context_exit.allocated_bytes - frame_ctx_p->heap_stats_context_enter.allocated_bytes),
          (uint32_t) frame_ctx_p->context_peak_allocated_heap_bytes,
          (uint32_t) heap_stats_context_exit.global_peak_allocated_bytes);

  printf ("%sWaste heap bytes in the context:      %5u -> %5u (%+5d, local %5u, peak %5u)\n",
          indent_prefix,
          (uint32_t) frame_ctx_p->heap_stats_context_enter.waste_bytes,
          (uint32_t) heap_stats_context_exit.waste_bytes,
          (uint32_t) (heap_stats_context_exit.waste_bytes - frame_ctx_p->heap_stats_context_enter.waste_bytes),
          (uint32_t) frame_ctx_p->context_peak_waste_heap_bytes,
          (uint32_t) heap_stats_context_exit.global_peak_waste_bytes);

  printf ("%sPools count in the context:           %5u -> %5u (%+5d, local %5u, peak %5u)\n",
          indent_prefix,
          (uint32_t) frame_ctx_p->pools_stats_context_enter.pools_count,
          (uint32_t) pools_stats_context_exit.pools_count,
          (uint32_t) (pools_stats_context_exit.pools_count - frame_ctx_p->pools_stats_context_enter.pools_count),
          (uint32_t) frame_ctx_p->context_peak_pools_count,
          (uint32_t) pools_stats_context_exit.global_peak_pools_count);

  printf ("%sAllocated pool chunks in the context: %5u -> %5u (%+5d, local %5u, peak %5u)\n",
          indent_prefix,
          (uint32_t) frame_ctx_p->pools_stats_context_enter.allocated_chunks,
          (uint32_t) pools_stats_context_exit.allocated_chunks,
          (uint32_t) (pools_stats_context_exit.allocated_chunks -
                      frame_ctx_p->pools_stats_context_enter.allocated_chunks),
          (uint32_t) frame_ctx_p->context_peak_allocated_pool_chunks,
          (uint32_t) pools_stats_context_exit.global_peak_allocated_chunks);

  printf ("\n%s--- End of interpretation of a block at position %u ---\n\n",
          indent_prefix, (uint32_t) block_position);
}