Statistics of memory usage during interpretation.
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "globals.h"
|
||||
#include "mem-config.h"
|
||||
#include "mem-heap.h"
|
||||
#include "mem-poolman.h"
|
||||
|
||||
/**
|
||||
* Representation of NULL value for compressed pointers
|
||||
|
||||
@@ -807,6 +807,18 @@ mem_heap_get_stats (mem_heap_stats_t *out_heap_stats_p) /**< out: heap stats */
|
||||
*out_heap_stats_p = mem_heap_stats;
|
||||
} /* mem_heap_get_stats */
|
||||
|
||||
/**
|
||||
* Reset peak values in memory usage statistics
|
||||
*/
|
||||
void
|
||||
mem_heap_stats_reset_peak (void)
|
||||
{
|
||||
mem_heap_stats.peak_allocated_chunks = mem_heap_stats.allocated_chunks;
|
||||
mem_heap_stats.peak_allocated_blocks = mem_heap_stats.allocated_blocks;
|
||||
mem_heap_stats.peak_allocated_bytes = mem_heap_stats.allocated_bytes;
|
||||
mem_heap_stats.peak_waste_bytes = mem_heap_stats.waste_bytes;
|
||||
} /* mem_heap_stats_reset_peak */
|
||||
|
||||
/**
|
||||
* Initalize heap memory usage statistics account structure
|
||||
*/
|
||||
@@ -840,21 +852,37 @@ mem_heap_stat_alloc_block (mem_block_header_t *block_header_p) /**< allocated bl
|
||||
{
|
||||
mem_heap_stats.peak_allocated_blocks = mem_heap_stats.allocated_blocks;
|
||||
}
|
||||
if (mem_heap_stats.allocated_blocks > mem_heap_stats.global_peak_allocated_blocks)
|
||||
{
|
||||
mem_heap_stats.global_peak_allocated_blocks = mem_heap_stats.allocated_blocks;
|
||||
}
|
||||
|
||||
if (mem_heap_stats.allocated_chunks > mem_heap_stats.peak_allocated_chunks)
|
||||
{
|
||||
mem_heap_stats.peak_allocated_chunks = mem_heap_stats.allocated_chunks;
|
||||
}
|
||||
if (mem_heap_stats.allocated_chunks > mem_heap_stats.global_peak_allocated_chunks)
|
||||
{
|
||||
mem_heap_stats.global_peak_allocated_chunks = mem_heap_stats.allocated_chunks;
|
||||
}
|
||||
|
||||
if (mem_heap_stats.allocated_bytes > mem_heap_stats.peak_allocated_bytes)
|
||||
{
|
||||
mem_heap_stats.peak_allocated_bytes = mem_heap_stats.allocated_bytes;
|
||||
}
|
||||
if (mem_heap_stats.allocated_bytes > mem_heap_stats.global_peak_allocated_bytes)
|
||||
{
|
||||
mem_heap_stats.global_peak_allocated_bytes = mem_heap_stats.allocated_bytes;
|
||||
}
|
||||
|
||||
if (mem_heap_stats.waste_bytes > mem_heap_stats.peak_waste_bytes)
|
||||
{
|
||||
mem_heap_stats.peak_waste_bytes = mem_heap_stats.waste_bytes;
|
||||
}
|
||||
if (mem_heap_stats.waste_bytes > mem_heap_stats.global_peak_waste_bytes)
|
||||
{
|
||||
mem_heap_stats.global_peak_waste_bytes = mem_heap_stats.waste_bytes;
|
||||
}
|
||||
|
||||
JERRY_ASSERT(mem_heap_stats.allocated_blocks <= mem_heap_stats.blocks);
|
||||
JERRY_ASSERT(mem_heap_stats.allocated_bytes <= mem_heap_stats.size);
|
||||
|
||||
@@ -57,19 +57,24 @@ typedef struct
|
||||
|
||||
size_t allocated_chunks; /**< currently allocated chunks */
|
||||
size_t peak_allocated_chunks; /**< peak allocated chunks */
|
||||
size_t global_peak_allocated_chunks; /**< non-resettable peak allocated chunks */
|
||||
|
||||
size_t allocated_blocks; /**< currently allocated blocks */
|
||||
size_t peak_allocated_blocks; /**< peak allocated blocks */
|
||||
size_t global_peak_allocated_blocks; /**< non-resettable peak allocated blocks */
|
||||
|
||||
size_t allocated_bytes; /**< currently allocated bytes */
|
||||
size_t peak_allocated_bytes; /**< peak allocated bytes */
|
||||
size_t global_peak_allocated_bytes; /**< non-resettable peak allocated bytes */
|
||||
|
||||
size_t waste_bytes; /**< bytes waste due to blocks filled partially
|
||||
and due to block headers */
|
||||
size_t peak_waste_bytes; /**< peak bytes waste */
|
||||
size_t global_peak_waste_bytes; /**< non-resettable peak bytes waste */
|
||||
} mem_heap_stats_t;
|
||||
|
||||
extern void mem_heap_get_stats (mem_heap_stats_t *out_heap_stats_p);
|
||||
extern void mem_heap_stats_reset_peak (void);
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
/**
|
||||
|
||||
@@ -225,6 +225,16 @@ mem_pools_get_stats (mem_pools_stats_t *out_pools_stats_p) /**< out: pools' stat
|
||||
*out_pools_stats_p = mem_pools_stats;
|
||||
} /* mem_pools_get_stats */
|
||||
|
||||
/**
|
||||
* Reset peak values in memory usage statistics
|
||||
*/
|
||||
void
|
||||
mem_pools_stats_reset_peak (void)
|
||||
{
|
||||
mem_pools_stats.peak_pools_count = mem_pools_stats.pools_count;
|
||||
mem_pools_stats.peak_allocated_chunks = mem_pools_stats.allocated_chunks;
|
||||
} /* mem_pools_stats_reset_peak */
|
||||
|
||||
/**
|
||||
* Initalize pools' memory usage statistics account structure
|
||||
*/
|
||||
@@ -247,6 +257,10 @@ mem_pools_stat_alloc_pool (void)
|
||||
{
|
||||
mem_pools_stats.peak_pools_count = mem_pools_stats.pools_count;
|
||||
}
|
||||
if (mem_pools_stats.pools_count > mem_pools_stats.global_peak_pools_count)
|
||||
{
|
||||
mem_pools_stats.global_peak_pools_count = mem_pools_stats.pools_count;
|
||||
}
|
||||
} /* mem_pools_stat_alloc_pool */
|
||||
|
||||
/**
|
||||
@@ -276,6 +290,10 @@ mem_pools_stat_alloc_chunk (void)
|
||||
{
|
||||
mem_pools_stats.peak_allocated_chunks = mem_pools_stats.allocated_chunks;
|
||||
}
|
||||
if (mem_pools_stats.allocated_chunks > mem_pools_stats.global_peak_allocated_chunks)
|
||||
{
|
||||
mem_pools_stats.global_peak_allocated_chunks = mem_pools_stats.allocated_chunks;
|
||||
}
|
||||
} /* mem_pools_stat_alloc_chunk */
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,17 +46,24 @@ typedef struct
|
||||
/** peak pools' count */
|
||||
size_t peak_pools_count;
|
||||
|
||||
/** non-resettable peak pools' count */
|
||||
size_t global_peak_pools_count;
|
||||
|
||||
/** allocated chunks count */
|
||||
size_t allocated_chunks;
|
||||
|
||||
/** peak allocated chunks count */
|
||||
size_t peak_allocated_chunks;
|
||||
|
||||
/** non-resettable peak allocated chunks count */
|
||||
size_t global_peak_allocated_chunks;
|
||||
|
||||
/** free chunks count */
|
||||
size_t free_chunks;
|
||||
} mem_pools_stats_t;
|
||||
|
||||
extern void mem_pools_get_stats (mem_pools_stats_t *out_pools_stats_p);
|
||||
extern void mem_pools_stats_reset_peak (void);
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
#endif /* JERRY_MEM_POOLMAN_H */
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "globals.h"
|
||||
#include "interpreter.h"
|
||||
#include "jerry-libc.h"
|
||||
#include "mem-allocator.h"
|
||||
|
||||
#define __INIT_OP_FUNC(name, arg1, arg2, arg3) [ __op__idx_##name ] = opfunc_##name,
|
||||
static const opfunc __opfuncs[LAST_OP] =
|
||||
@@ -34,12 +35,294 @@ JERRY_STATIC_ASSERT (sizeof (opcode_t) <= 4);
|
||||
|
||||
const opcode_t *__program = NULL;
|
||||
|
||||
#ifdef MEM_STATS
|
||||
#define __OP_FUNC_NAME(name, arg1, arg2, arg3) #name,
|
||||
static const char *__op_names[LAST_OP] =
|
||||
{
|
||||
OP_LIST (OP_FUNC_NAME)
|
||||
};
|
||||
#undef __OP_FUNC_NAME
|
||||
|
||||
static uint32_t interp_mem_stats_print_indentation = 0;
|
||||
static bool interp_mem_stats_enabled = false;
|
||||
|
||||
static void
|
||||
interp_mem_stats_print_legend (void)
|
||||
{
|
||||
if (likely (!interp_mem_stats_enabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
__printf ("----- Legend of memory usage trace during interpretation -----\n\n"
|
||||
"\tEntering block = beginning execution of initial (global) scope or function.\n\n"
|
||||
"\tInformation on each value is formatted as following: (p -> n ( [+-]c, local l, peak g), where:\n"
|
||||
"\t p - value just before starting of item's execution;\n"
|
||||
"\t n - value just after end of item's execution;\n"
|
||||
"\t [+-c] - difference between n and p;\n"
|
||||
"\t l - temporary usage of memory during item's execution;\n"
|
||||
"\t g - global peak of the value during program's execution.\n\n"
|
||||
"\tChunks are items allocated in a pool."
|
||||
" If there is no pool with a free chunk upon chunk allocation request,\n"
|
||||
"\tthen new pool is allocated on the heap (that causes increase of number of allocated heap bytes).\n\n");
|
||||
}
|
||||
|
||||
static void
|
||||
interp_mem_get_stats (mem_heap_stats_t *out_heap_stats_p,
|
||||
mem_pools_stats_t *out_pool_stats_p,
|
||||
bool reset_peak_before,
|
||||
bool reset_peak_after)
|
||||
{
|
||||
if (likely (!interp_mem_stats_enabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ecma_gc_run (ECMA_GC_GEN_2);
|
||||
|
||||
if (reset_peak_before)
|
||||
{
|
||||
mem_heap_stats_reset_peak ();
|
||||
mem_pools_stats_reset_peak ();
|
||||
}
|
||||
|
||||
mem_heap_get_stats (out_heap_stats_p);
|
||||
mem_pools_get_stats (out_pool_stats_p);
|
||||
|
||||
if (reset_peak_after)
|
||||
{
|
||||
mem_heap_stats_reset_peak ();
|
||||
mem_pools_stats_reset_peak ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
interp_mem_stats_context_enter (int_data_t *int_data_p,
|
||||
opcode_counter_t block_position)
|
||||
{
|
||||
if (likely (!interp_mem_stats_enabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char indent_prefix[interp_mem_stats_print_indentation + 2];
|
||||
__memset (indent_prefix, ' ', sizeof (indent_prefix));
|
||||
indent_prefix [interp_mem_stats_print_indentation] = '|';
|
||||
indent_prefix [interp_mem_stats_print_indentation + 1] = '\0';
|
||||
|
||||
int_data_p->context_peak_allocated_heap_bytes = 0;
|
||||
int_data_p->context_peak_waste_heap_bytes = 0;
|
||||
int_data_p->context_peak_pools_count = 0;
|
||||
int_data_p->context_peak_allocated_pool_chunks = 0;
|
||||
|
||||
interp_mem_get_stats (&int_data_p->heap_stats_context_enter,
|
||||
&int_data_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, int_data_p->heap_stats_context_enter.allocated_bytes,
|
||||
indent_prefix, int_data_p->heap_stats_context_enter.waste_bytes,
|
||||
indent_prefix, int_data_p->pools_stats_context_enter.pools_count,
|
||||
indent_prefix, int_data_p->pools_stats_context_enter.allocated_chunks);
|
||||
}
|
||||
|
||||
static void
|
||||
interp_mem_stats_context_exit (int_data_t *int_data_p,
|
||||
opcode_counter_t block_position)
|
||||
{
|
||||
if (likely (!interp_mem_stats_enabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char indent_prefix[interp_mem_stats_print_indentation + 2];
|
||||
__memset (indent_prefix, ' ', sizeof (indent_prefix));
|
||||
indent_prefix [interp_mem_stats_print_indentation] = '|';
|
||||
indent_prefix [interp_mem_stats_print_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);
|
||||
|
||||
int_data_p->context_peak_allocated_heap_bytes -= JERRY_MAX (int_data_p->heap_stats_context_enter.allocated_bytes,
|
||||
heap_stats_context_exit.allocated_bytes);
|
||||
int_data_p->context_peak_waste_heap_bytes -= JERRY_MAX (int_data_p->heap_stats_context_enter.waste_bytes,
|
||||
heap_stats_context_exit.waste_bytes);
|
||||
int_data_p->context_peak_pools_count -= JERRY_MAX (int_data_p->pools_stats_context_enter.pools_count,
|
||||
pools_stats_context_exit.pools_count);
|
||||
int_data_p->context_peak_allocated_pool_chunks -= JERRY_MAX (int_data_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,
|
||||
int_data_p->heap_stats_context_enter.allocated_bytes,
|
||||
heap_stats_context_exit.allocated_bytes,
|
||||
heap_stats_context_exit.allocated_bytes - int_data_p->heap_stats_context_enter.allocated_bytes,
|
||||
int_data_p->context_peak_allocated_heap_bytes,
|
||||
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,
|
||||
int_data_p->heap_stats_context_enter.waste_bytes,
|
||||
heap_stats_context_exit.waste_bytes,
|
||||
heap_stats_context_exit.waste_bytes - int_data_p->heap_stats_context_enter.waste_bytes,
|
||||
int_data_p->context_peak_waste_heap_bytes,
|
||||
heap_stats_context_exit.global_peak_waste_bytes);
|
||||
|
||||
__printf ("%sPools count in the context: %5u -> %5u (%+5d, local %5u, peak %5u)\n",
|
||||
indent_prefix,
|
||||
int_data_p->pools_stats_context_enter.pools_count,
|
||||
pools_stats_context_exit.pools_count,
|
||||
pools_stats_context_exit.pools_count - int_data_p->pools_stats_context_enter.pools_count,
|
||||
int_data_p->context_peak_pools_count,
|
||||
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,
|
||||
int_data_p->pools_stats_context_enter.allocated_chunks,
|
||||
pools_stats_context_exit.allocated_chunks,
|
||||
pools_stats_context_exit.allocated_chunks - int_data_p->pools_stats_context_enter.allocated_chunks,
|
||||
int_data_p->context_peak_allocated_pool_chunks,
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
interp_mem_stats_opcode_enter (opcode_counter_t opcode_position,
|
||||
mem_heap_stats_t *out_heap_stats_p,
|
||||
mem_pools_stats_t *out_pools_stats_p)
|
||||
{
|
||||
if (likely (!interp_mem_stats_enabled))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char indent_prefix[interp_mem_stats_print_indentation + 2];
|
||||
__memset (indent_prefix, ' ', sizeof (indent_prefix));
|
||||
indent_prefix [interp_mem_stats_print_indentation] = '|';
|
||||
indent_prefix [interp_mem_stats_print_indentation + 1] = '\0';
|
||||
|
||||
interp_mem_get_stats (out_heap_stats_p,
|
||||
out_pools_stats_p,
|
||||
true, false);
|
||||
|
||||
opcode_t opcode = read_opcode (opcode_position);
|
||||
|
||||
__printf ("%s-- Opcode: %s (position %u) --\n",
|
||||
indent_prefix, __op_names [opcode.op_idx], (uint32_t) opcode_position);
|
||||
|
||||
interp_mem_stats_print_indentation += 5;
|
||||
}
|
||||
|
||||
static void
|
||||
interp_mem_stats_opcode_exit (int_data_t *int_data_p,
|
||||
opcode_counter_t opcode_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 -= 5;
|
||||
|
||||
char indent_prefix[interp_mem_stats_print_indentation + 2];
|
||||
__memset (indent_prefix, ' ', sizeof (indent_prefix));
|
||||
indent_prefix [interp_mem_stats_print_indentation] = '|';
|
||||
indent_prefix [interp_mem_stats_print_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);
|
||||
|
||||
int_data_p->context_peak_allocated_heap_bytes = JERRY_MAX (int_data_p->context_peak_allocated_heap_bytes,
|
||||
heap_stats_after.allocated_bytes);
|
||||
int_data_p->context_peak_waste_heap_bytes = JERRY_MAX (int_data_p->context_peak_waste_heap_bytes,
|
||||
heap_stats_after.waste_bytes);
|
||||
int_data_p->context_peak_pools_count = JERRY_MAX (int_data_p->context_peak_pools_count,
|
||||
pools_stats_after.pools_count);
|
||||
int_data_p->context_peak_allocated_pool_chunks = JERRY_MAX (int_data_p->context_peak_allocated_pool_chunks,
|
||||
pools_stats_after.allocated_chunks);
|
||||
|
||||
opcode_t opcode = read_opcode (opcode_position);
|
||||
|
||||
__printf ("%s Allocated heap bytes: %5u -> %5u (%+5d, local %5u, peak %5u)\n",
|
||||
indent_prefix,
|
||||
heap_stats_before_p->allocated_bytes,
|
||||
heap_stats_after.allocated_bytes,
|
||||
heap_stats_after.allocated_bytes - heap_stats_before_p->allocated_bytes,
|
||||
heap_stats_after.peak_allocated_bytes - JERRY_MAX (heap_stats_before_p->allocated_bytes,
|
||||
heap_stats_after.allocated_bytes),
|
||||
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,
|
||||
heap_stats_before_p->waste_bytes,
|
||||
heap_stats_after.waste_bytes,
|
||||
heap_stats_after.waste_bytes - heap_stats_before_p->waste_bytes,
|
||||
heap_stats_after.peak_waste_bytes - JERRY_MAX (heap_stats_before_p->waste_bytes,
|
||||
heap_stats_after.waste_bytes),
|
||||
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,
|
||||
pools_stats_before_p->pools_count,
|
||||
pools_stats_after.pools_count,
|
||||
pools_stats_after.pools_count - pools_stats_before_p->pools_count,
|
||||
pools_stats_after.peak_pools_count - JERRY_MAX (pools_stats_before_p->pools_count,
|
||||
pools_stats_after.pools_count),
|
||||
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,
|
||||
pools_stats_before_p->allocated_chunks,
|
||||
pools_stats_after.allocated_chunks,
|
||||
pools_stats_after.allocated_chunks - pools_stats_before_p->allocated_chunks,
|
||||
pools_stats_after.peak_allocated_chunks - JERRY_MAX (pools_stats_before_p->allocated_chunks,
|
||||
pools_stats_after.allocated_chunks),
|
||||
pools_stats_after.global_peak_allocated_chunks);
|
||||
}
|
||||
|
||||
__printf ("%s-- End of execution of opcode %s (position %u) --\n\n",
|
||||
indent_prefix, __op_names [opcode.op_idx], opcode_position);
|
||||
}
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
/**
|
||||
* Initialize interpreter.
|
||||
*/
|
||||
void
|
||||
init_int (const opcode_t *program_p) /**< pointer to byte-code program */
|
||||
init_int (const opcode_t *program_p, /**< pointer to byte-code program */
|
||||
bool dump_mem_stats) /** dump per-opcode memory usage change statistics */
|
||||
{
|
||||
#ifdef MEM_STATS
|
||||
interp_mem_stats_enabled = dump_mem_stats;
|
||||
#else /* MEM_STATS */
|
||||
JERRY_ASSERT (!dump_mem_stats);
|
||||
#endif /* !MEM_STATS */
|
||||
|
||||
JERRY_ASSERT (__program == NULL);
|
||||
|
||||
__program = program_p;
|
||||
@@ -50,6 +333,10 @@ run_int (void)
|
||||
{
|
||||
JERRY_ASSERT (__program != NULL);
|
||||
|
||||
#ifdef MEM_STATS
|
||||
interp_mem_stats_print_legend ();
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
bool is_strict = false;
|
||||
opcode_counter_t start_pos = 0;
|
||||
|
||||
@@ -108,15 +395,39 @@ run_int (void)
|
||||
ecma_completion_value_t
|
||||
run_int_loop (int_data_t *int_data)
|
||||
{
|
||||
ecma_completion_value_t completion;
|
||||
|
||||
#ifdef MEM_STATS
|
||||
mem_heap_stats_t heap_stats_before;
|
||||
mem_pools_stats_t pools_stats_before;
|
||||
|
||||
__memset (&heap_stats_before, 0, sizeof (heap_stats_before));
|
||||
__memset (&pools_stats_before, 0, sizeof (pools_stats_before));
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
while (true)
|
||||
{
|
||||
ecma_completion_value_t completion;
|
||||
|
||||
do
|
||||
{
|
||||
const opcode_t *curr = &__program[int_data->pos];
|
||||
|
||||
#ifdef MEM_STATS
|
||||
const opcode_counter_t opcode_pos = int_data->pos;
|
||||
|
||||
interp_mem_stats_opcode_enter (opcode_pos,
|
||||
&heap_stats_before,
|
||||
&pools_stats_before);
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
completion = __opfuncs[curr->op_idx] (*curr, int_data);
|
||||
|
||||
#ifdef MEM_STATS
|
||||
interp_mem_stats_opcode_exit (int_data,
|
||||
opcode_pos,
|
||||
&heap_stats_before,
|
||||
&pools_stats_before);
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
JERRY_ASSERT (!ecma_is_completion_value_normal (completion)
|
||||
|| ecma_is_completion_value_empty (completion));
|
||||
}
|
||||
@@ -173,6 +484,10 @@ run_int_from_pos (opcode_counter_t start_pos,
|
||||
int_data.max_reg_num = max_reg_num;
|
||||
int_data.regs_p = regs;
|
||||
|
||||
#ifdef MEM_STATS
|
||||
interp_mem_stats_context_enter (&int_data, start_pos);
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
completion = run_int_loop (&int_data);
|
||||
|
||||
for (uint32_t reg_index = 0;
|
||||
@@ -182,6 +497,10 @@ run_int_from_pos (opcode_counter_t start_pos,
|
||||
ecma_free_value (regs[ reg_index ], true);
|
||||
}
|
||||
|
||||
#ifdef MEM_STATS
|
||||
interp_mem_stats_context_exit (&int_data, start_pos);
|
||||
#endif /* MEM_STATS */
|
||||
|
||||
return completion;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "globals.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
void init_int (const opcode_t* program_p);
|
||||
void init_int (const opcode_t* program_p, bool dump_mem_stats);
|
||||
bool run_int (void);
|
||||
ecma_completion_value_t run_int_loop (int_data_t *int_data);
|
||||
ecma_completion_value_t run_int_from_pos (opcode_counter_t start_pos,
|
||||
|
||||
@@ -77,6 +77,16 @@ typedef struct
|
||||
idx_t min_reg_num; /**< minimum idx used for register identification */
|
||||
idx_t max_reg_num; /**< maximum idx used for register identification */
|
||||
ecma_value_t *regs_p; /**< register variables */
|
||||
|
||||
#ifdef MEM_STATS
|
||||
size_t context_peak_allocated_heap_bytes;
|
||||
size_t context_peak_waste_heap_bytes;
|
||||
size_t context_peak_pools_count;
|
||||
size_t context_peak_allocated_pool_chunks;
|
||||
|
||||
mem_heap_stats_t heap_stats_context_enter;
|
||||
mem_pools_stats_t pools_stats_context_enter;
|
||||
#endif /* MEM_STATS */
|
||||
} int_data_t;
|
||||
|
||||
opcode_counter_t calc_opcode_counter_from_idx_idx (const idx_t oc_idx_1, const idx_t oc_idx_2);
|
||||
|
||||
+7
-1
@@ -85,7 +85,7 @@ jerry_run (const char *script_source, size_t script_source_size,
|
||||
return true;
|
||||
}
|
||||
|
||||
init_int (opcodes);
|
||||
init_int (opcodes, is_show_mem_stats);
|
||||
|
||||
bool is_success = run_int ();
|
||||
|
||||
@@ -184,7 +184,13 @@ main (int argc __unused,
|
||||
}
|
||||
if (!__strcmp ("--mem-stats", argv[i]))
|
||||
{
|
||||
#ifdef MEM_STATS
|
||||
print_mem_stats = true;
|
||||
#else /* MEM_STATS */
|
||||
__printf ("Ignoring --mem-stats because of '!MEM_STATS' build configuration.\n");
|
||||
|
||||
print_mem_stats = false;
|
||||
#endif /* !MEM_STATS */
|
||||
}
|
||||
else if (!__strcmp ("--parse-only", argv[i]))
|
||||
{
|
||||
|
||||
@@ -44,7 +44,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 4);
|
||||
serializer_dump_nums( nums, 3, offset, 4);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 7);
|
||||
serializer_dump_nums( nums, 1, offset, 7);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
return run_int() ? 0
|
||||
: 1;
|
||||
|
||||
@@ -44,7 +44,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 3);
|
||||
serializer_dump_nums( nums, 1, offset, 3);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool is_ok = run_int();
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ main( int __unused argc,
|
||||
uint16_t offset = serializer_dump_strings( strings, 2);
|
||||
serializer_dump_nums( nums, 1, offset, 2);
|
||||
|
||||
init_int( test_program);
|
||||
init_int( test_program, false);
|
||||
|
||||
bool status = run_int();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user