From a2350cb88e9a9df613b19507de9ce0cf0d47e185 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Wed, 9 Jul 2014 18:05:19 +0400 Subject: [PATCH] Change parser to stack-only version --- Makefile | 50 ++- src/liballocator/mem-heap.c | 531 ++++++++++++++++++++--------- src/liballocator/mem-heap.h | 25 ++ src/liballocator/mem-poolman.c | 110 +++++- src/liballocator/mem-poolman.h | 29 +- src/libcoreint/interpreter.c | 15 +- src/libcoreint/interpreter.h | 7 +- src/libcoreint/opcode-structures.h | 144 ++++---- src/libcoreint/opcodes.c | 108 +++--- src/libperipherals/actuators.c | 2 +- tests/unit/test_heap.c | 2 + tests/unit/test_poolman.c | 25 +- 12 files changed, 718 insertions(+), 330 deletions(-) diff --git a/Makefile b/Makefile index dc81b69ab..0ab273ff3 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ # limitations under the License. TARGET ?= jerry -CROSS_COMPILE ?= arm-none-eabi- +CROSS_COMPILE ?= OBJ_DIR = obj OUT_DIR = ./out @@ -23,10 +23,12 @@ UNITTESTS_SRC_DIR = ./tests/unit # FIXME: # Place jerry-libc.c, pretty-printer.c to some subdirectory (libruntime?) # and add them to the SOURCES list through wildcard. +# FIXME: +# Add common-io.c and sensors.c SOURCES = \ $(sort \ $(wildcard ./src/jerry-libc.c ./src/pretty-printer.c) \ - $(wildcard ./src/libperipherals/*.c) \ + $(wildcard ./src/libperipherals/actuators.c) \ $(wildcard ./src/libjsparser/*.c) \ $(wildcard ./src/libecmaobjects/*.c) \ $(wildcard ./src/liballocator/*.c) \ @@ -58,48 +60,43 @@ OBJS = \ $(sort \ $(patsubst %.c,./$(OBJ_DIR)/%.o,$(notdir $(MAIN_MODULE_SRC) $(SOURCES)))) -CC = gcc#-4.9 -LD = ld -OBJDUMP = objdump -OBJCOPY = objcopy -SIZE = size -STRIP = strip - -CROSS_CC = $(CROSS_COMPILE)gcc#-4.9 -CROSS_LD = $(CROSS_COMPILE)ld -CROSS_OBJDUMP = $(CROSS_COMPILE)objdump -CROSS_OBJCOPY = $(CROSS_COMPILE)objcopy -CROSS_SIZE = $(CROSS_COMPILE)size +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)ld +OBJDUMP = $(CROSS_COMPILE)objdump +OBJCOPY = $(CROSS_COMPILE)objcopy +SIZE = $(CROSS_COMPILE)size +STRIP = $(CROSS_COMPILE)strip # General flags -CFLAGS ?= $(INCLUDES) -std=c99 -m32 #-fdiagnostics-color=always -#CFLAGS += -Wall -Wextra -Wpedantic -Wlogical-op -Winline -#CFLAGS += -Wformat-nonliteral -Winit-self -Wstack-protector -#CFLAGS += -Wconversion -Wsign-conversion -Wformat-security -#CFLAGS += -Wstrict-prototypes -Wmissing-prototypes +CFLAGS ?= $(INCLUDES) -std=c99 #-fdiagnostics-color=always +CFLAGS += -Wpedantic -Wlogical-op +# CFLAGS += -Wformat-nonliteral -Winit-self -Wstack-protector +# CFLAGS += -Wall -Wextra -Winline +# CFLAGS += -Wconversion -Wsign-conversion -Wformat-security +# CFLAGS += -Wstrict-prototypes -Wmissing-prototypes # Flags for MCU -#CFLAGS += -mlittle-endian -mcpu=cortex-m4 -march=armv7e-m -mthumb -#CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard -#CFLAGS += -ffunction-sections -fdata-sections +MCU_CFLAGS += -mlittle-endian -mcpu=cortex-m4 -march=armv7e-m -mthumb +MCU_CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard +MCU_CFLAGS += -ffunction-sections -fdata-sections DEBUG_OPTIONS = -g3 -O0 -DJERRY_NDEBUG# -fsanitize=address RELEASE_OPTIONS = -Os -Werror -DJERRY_NDEBUG -DEFINES = -DMEM_HEAP_CHUNK_SIZE=256 -DMEM_HEAP_AREA_SIZE=32768 +DEFINES = -DMEM_HEAP_CHUNK_SIZE=256 -DMEM_HEAP_AREA_SIZE=32768 -DMEM_STATS TARGET_HOST = -D__HOST TARGET_MCU = -D__MCU -.PHONY: all debug release clean tests check install +.PHONY: all debug debug.stm32f3 release clean tests check install all: clean debug release check -debug: +debug: clean mkdir -p $(OUT_DIR)/debug.host/ $(CC) $(CFLAGS) $(DEBUG_OPTIONS) $(DEFINES) $(TARGET_HOST) \ $(SOURCES) $(MAIN_MODULE_SRC) -o $(OUT_DIR)/debug.host/$(TARGET) -release: +release: clean mkdir -p $(OUT_DIR)/release.host/ $(CC) $(CFLAGS) $(RELEASE_OPTIONS) $(DEFINES) $(TARGET_HOST) \ $(SOURCES) $(MAIN_MODULE_SRC) -o $(OUT_DIR)/release.host/$(TARGET) @@ -122,6 +119,7 @@ clean: rm -f $(TARGET).map rm -f $(TARGET).hex rm -f $(TARGET).lst + rm -f js.files check: tests @mkdir -p $(OUT_DIR) diff --git a/src/liballocator/mem-heap.c b/src/liballocator/mem-heap.c index 99c060c3d..4a4b26a24 100644 --- a/src/liballocator/mem-heap.c +++ b/src/liballocator/mem-heap.c @@ -64,22 +64,12 @@ typedef enum */ typedef struct mem_BlockHeader_t { - mem_MagicNumOfBlock_t m_MagicNum; /**< magic number - MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK for allocated block - and MEM_MAGIC_NUM_OF_FREE_BLOCK for free block */ + mem_MagicNumOfBlock_t m_MagicNum; /**< magic number - MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK for allocated block + and MEM_MAGIC_NUM_OF_FREE_BLOCK for free block */ struct mem_BlockHeader_t *m_Neighbours[ MEM_DIRECTION_COUNT ]; /**< neighbour blocks */ - size_t m_SizeInChunks; /**< size of block with header in chunks */ + size_t allocated_bytes; /**< allocated area size - for allocated blocks; 0 - for free blocks */ } mem_BlockHeader_t; -/** - * Calculate size in bytes of the block space, that can be used to store data - */ -#define mem_GetHeapBlockDataSpaceSizeInBytes( pBlockHeader) ( MEM_HEAP_CHUNK_SIZE * pBlockHeader->m_SizeInChunks - sizeof(mem_BlockHeader_t) ) - -/** - * Calculate size in chunks of heap block from data space size in bytes - */ -#define mem_GetHeapBlockSizeInChunksFromDataSpaceSizeInBytes( size) ( ( sizeof(mem_BlockHeader_t) + size + MEM_HEAP_CHUNK_SIZE - 1 ) / MEM_HEAP_CHUNK_SIZE ) - /** * Chunk should have enough space for block header */ @@ -95,8 +85,8 @@ JERRY_STATIC_ASSERT( MEM_HEAP_CHUNK_SIZE % MEM_ALIGNMENT == 0 ); */ typedef struct { - uint8_t* m_HeapStart; /**< first address of heap space */ - size_t m_HeapSize; /**< heap space size */ + uint8_t* m_HeapStart; /**< first address of heap space */ + size_t m_HeapSize; /**< heap space size */ mem_BlockHeader_t* m_pFirstBlock; /**< first block of the heap */ mem_BlockHeader_t* m_pLastBlock; /**< last block of the heap */ } mem_HeapState_t; @@ -106,6 +96,10 @@ typedef struct */ mem_HeapState_t mem_Heap; +static inline size_t mem_get_block_chunks_count( const mem_BlockHeader_t *block_header_p); +static inline size_t mem_get_block_data_space_size( const mem_BlockHeader_t *block_header_p); +static inline size_t mem_get_block_chunks_count_from_data_size( size_t block_allocated_size); + static void mem_InitBlockHeader( uint8_t *pFirstChunk, size_t sizeInChunks, mem_BlockState_t blockState, @@ -113,12 +107,80 @@ static void mem_InitBlockHeader( uint8_t *pFirstChunk, mem_BlockHeader_t *pNextBlock); static void mem_CheckHeap( void); +#ifdef MEM_STATS +/** + * Heap's memory usage statistics + */ +static mem_HeapStats_t mem_HeapStats; + +static void mem_HeapStatInit( void); +static void mem_HeapStatAllocBlock( mem_BlockHeader_t *block_header_p); +static void mem_HeapStatFreeBlock( mem_BlockHeader_t *block_header_p); +static void mem_HeapStatFreeBlockSplit( void); +static void mem_HeapStatFreeBlockMerge( void); +#else /* !MEM_STATS */ +# define mem_InitStats() +# define mem_HeapStatAllocBlock( v) +# define mem_HeapStatFreeBlock( v) +# define mem_HeapStatFreeBlockSplit() +# define mem_HeapStatFreeBlockMerge() +#endif /* !MEM_STATS */ + +/** + * get chunk count, used by the block. + * + * @return chunks count + */ +static inline size_t +mem_get_block_chunks_count( const mem_BlockHeader_t *block_header_p) /**< block header */ +{ + JERRY_ASSERT( block_header_p != NULL ); + + const mem_BlockHeader_t *next_block_p = block_header_p->m_Neighbours[ MEM_DIRECTION_NEXT ]; + size_t dist_till_block_end; + + if ( next_block_p == NULL ) + { + dist_till_block_end = (size_t) ( mem_Heap.m_HeapStart + mem_Heap.m_HeapSize - (uint8_t*) block_header_p ); + } else + { + dist_till_block_end = (size_t) ( (uint8_t*) next_block_p - (uint8_t*) block_header_p ); + } + + JERRY_ASSERT( dist_till_block_end <= mem_Heap.m_HeapSize ); + JERRY_ASSERT( dist_till_block_end % MEM_HEAP_CHUNK_SIZE == 0 ); + + return dist_till_block_end / MEM_HEAP_CHUNK_SIZE; +} /* mem_get_block_chunks_count */ + +/** + * Calculate block's data space size + * + * @return size of block area that can be used to store data + */ +static inline size_t +mem_get_block_data_space_size( const mem_BlockHeader_t *block_header_p) /**< block header */ +{ + return mem_get_block_chunks_count( block_header_p) * MEM_HEAP_CHUNK_SIZE - sizeof (mem_BlockHeader_t); +} /* mem_get_block_data_space_size */ + +/** + * Calculate minimum chunks count needed for block with specified size of allocated data area. + * + * @return chunks count + */ +static inline size_t +mem_get_block_chunks_count_from_data_size( size_t block_allocated_size) /**< size of block's allocated area */ +{ + return JERRY_ALIGNUP( sizeof (mem_BlockHeader_t) + block_allocated_size, MEM_HEAP_CHUNK_SIZE) / MEM_HEAP_CHUNK_SIZE; +} /* mem_get_block_chunks_count_from_data_size */ + /** * Startup initialization of heap */ void -mem_HeapInit( uint8_t *heapStart, /**< first address of heap space */ - size_t heapSize) /**< heap space size */ +mem_HeapInit(uint8_t *heapStart, /**< first address of heap space */ + size_t heapSize) /**< heap space size */ { JERRY_ASSERT( heapStart != NULL ); JERRY_ASSERT( heapSize != 0 ); @@ -128,22 +190,24 @@ mem_HeapInit( uint8_t *heapStart, /**< first address of heap space */ mem_Heap.m_HeapStart = heapStart; mem_Heap.m_HeapSize = heapSize; - mem_InitBlockHeader( mem_Heap.m_HeapStart, - heapSize / MEM_HEAP_CHUNK_SIZE, + mem_InitBlockHeader(mem_Heap.m_HeapStart, + 0, MEM_BLOCK_FREE, NULL, NULL); mem_Heap.m_pFirstBlock = (mem_BlockHeader_t*) mem_Heap.m_HeapStart; mem_Heap.m_pLastBlock = mem_Heap.m_pFirstBlock; + + mem_HeapStatInit(); } /* mem_HeapInit */ /** * Initialize block header */ static void -mem_InitBlockHeader( uint8_t *pFirstChunk, /**< address of the first chunk to use for the block */ - size_t sizeInChunks, /**< size of block with header in chunks */ +mem_InitBlockHeader( uint8_t *pFirstChunk, /**< address of the first chunk to use for the block */ + size_t allocated_bytes, /**< size of block's allocated area */ mem_BlockState_t blockState, /**< state of the block (allocated or free) */ mem_BlockHeader_t *pPrevBlock, /**< previous block */ mem_BlockHeader_t *pNextBlock) /**< next block */ @@ -151,17 +215,21 @@ mem_InitBlockHeader( uint8_t *pFirstChunk, /**< address of the fir mem_BlockHeader_t *pBlockHeader = (mem_BlockHeader_t*) pFirstChunk; if ( blockState == MEM_BLOCK_FREE ) - { - pBlockHeader->m_MagicNum = MEM_MAGIC_NUM_OF_FREE_BLOCK; - } else - { - pBlockHeader->m_MagicNum = MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK; - } + { + pBlockHeader->m_MagicNum = MEM_MAGIC_NUM_OF_FREE_BLOCK; - pBlockHeader->m_Neighbours[ MEM_DIRECTION_PREV ] = pPrevBlock; - pBlockHeader->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; - pBlockHeader->m_SizeInChunks = sizeInChunks; -} /* mem_InitFreeBlock */ + JERRY_ASSERT( allocated_bytes == 0 ); + } else + { + pBlockHeader->m_MagicNum = MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK; + } + + pBlockHeader->m_Neighbours[ MEM_DIRECTION_PREV ] = pPrevBlock; + pBlockHeader->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; + pBlockHeader->allocated_bytes = allocated_bytes; + + JERRY_ASSERT( allocated_bytes <= mem_get_block_data_space_size( pBlockHeader) ); +} /* mem_InitBlockHeader */ /** * Allocation of memory region. @@ -177,7 +245,7 @@ mem_InitBlockHeader( uint8_t *pFirstChunk, /**< address of the fir * NULL - if there is not enough memory. */ uint8_t* -mem_HeapAllocBlock( size_t sizeInBytes, /**< size of region to allocate in bytes */ +mem_HeapAllocBlock( size_t sizeInBytes, /**< size of region to allocate in bytes */ mem_HeapAllocTerm_t allocTerm) /**< expected allocation term */ { mem_BlockHeader_t *pBlock; @@ -186,82 +254,86 @@ mem_HeapAllocBlock( size_t sizeInBytes, /**< size of region to allo mem_CheckHeap(); if ( allocTerm == MEM_HEAP_ALLOC_SHORT_TERM ) + { + pBlock = mem_Heap.m_pFirstBlock; + direction = MEM_DIRECTION_NEXT; + } else + { + pBlock = mem_Heap.m_pLastBlock; + direction = MEM_DIRECTION_PREV; + } + + /* searching for appropriate block */ + while ( pBlock != NULL ) + { + if ( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ) { - pBlock = mem_Heap.m_pFirstBlock; - direction = MEM_DIRECTION_NEXT; + if ( mem_get_block_data_space_size( pBlock) >= sizeInBytes ) + { + break; + } } else - { - pBlock = mem_Heap.m_pLastBlock; - direction = MEM_DIRECTION_PREV; - } + { + JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK ); + } - /* searching for appropriate block */ - while ( pBlock != NULL ) - { - if ( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ) - { - if ( mem_GetHeapBlockDataSpaceSizeInBytes( pBlock) >= sizeInBytes ) - { - break; - } - } else - { - JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK ); - } + pBlock = pBlock->m_Neighbours[ direction ]; + } - pBlock = pBlock->m_Neighbours[ direction ]; - } + if ( pBlock == NULL ) + { + /* not enough free space */ + return NULL; + } - if ( pBlock == NULL ) - { - /* not enough free space */ - return NULL; - } + /* appropriate block found, allocating space */ + size_t newBlockSizeInChunks = mem_get_block_chunks_count_from_data_size( sizeInBytes); + size_t foundBlockSizeInChunks = mem_get_block_chunks_count( pBlock); - /* appropriate block found, allocating space */ - size_t newBlockSizeInChunks = mem_GetHeapBlockSizeInChunksFromDataSpaceSizeInBytes( sizeInBytes); - size_t foundBlockSizeInChunks = pBlock->m_SizeInChunks; + JERRY_ASSERT( newBlockSizeInChunks <= foundBlockSizeInChunks ); - JERRY_ASSERT( newBlockSizeInChunks <= foundBlockSizeInChunks ); + mem_BlockHeader_t *pPrevBlock = pBlock->m_Neighbours[ MEM_DIRECTION_PREV ]; + mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; - mem_BlockHeader_t *pPrevBlock = pBlock->m_Neighbours[ MEM_DIRECTION_PREV ]; - mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; + if ( newBlockSizeInChunks < foundBlockSizeInChunks ) + { + mem_HeapStatFreeBlockSplit(); - if ( newBlockSizeInChunks < foundBlockSizeInChunks ) - { - uint8_t *pNewFreeBlockFirstChunk = (uint8_t*) pBlock + newBlockSizeInChunks * MEM_HEAP_CHUNK_SIZE; - mem_InitBlockHeader( pNewFreeBlockFirstChunk, - foundBlockSizeInChunks - newBlockSizeInChunks, - MEM_BLOCK_FREE, - pBlock /* there we will place new allocated block */, - pNextBlock); - - mem_BlockHeader_t *pNewFreeBlock = (mem_BlockHeader_t*) pNewFreeBlockFirstChunk; - - if ( pNextBlock == NULL ) - { - mem_Heap.m_pLastBlock = pNewFreeBlock; - } - - pNextBlock = pNewFreeBlock; - } - - mem_InitBlockHeader( (uint8_t*) pBlock, - newBlockSizeInChunks, - MEM_BLOCK_ALLOCATED, - pPrevBlock, + uint8_t *pNewFreeBlockFirstChunk = (uint8_t*) pBlock + newBlockSizeInChunks * MEM_HEAP_CHUNK_SIZE; + mem_InitBlockHeader(pNewFreeBlockFirstChunk, + 0, + MEM_BLOCK_FREE, + pBlock /* there we will place new allocated block */, pNextBlock); - JERRY_ASSERT( mem_GetHeapBlockDataSpaceSizeInBytes( pBlock) >= sizeInBytes ); + mem_BlockHeader_t *pNewFreeBlock = (mem_BlockHeader_t*) pNewFreeBlockFirstChunk; - mem_CheckHeap(); + if ( pNextBlock == NULL ) + { + mem_Heap.m_pLastBlock = pNewFreeBlock; + } - /* return data space beginning address */ - uint8_t *pDataSpace = (uint8_t*) (pBlock + 1); - JERRY_ASSERT( (uintptr_t) pDataSpace % MEM_ALIGNMENT == 0); + pNextBlock = pNewFreeBlock; + } - return pDataSpace; -} /* mem_Alloc */ + mem_InitBlockHeader((uint8_t*) pBlock, + sizeInBytes, + MEM_BLOCK_ALLOCATED, + pPrevBlock, + pNextBlock); + + mem_HeapStatAllocBlock( pBlock); + + JERRY_ASSERT( mem_get_block_data_space_size( pBlock) >= sizeInBytes ); + + mem_CheckHeap(); + + /* return data space beginning address */ + uint8_t *pDataSpace = (uint8_t*) (pBlock + 1); + JERRY_ASSERT( (uintptr_t) pDataSpace % MEM_ALIGNMENT == 0); + + return pDataSpace; +} /* mem_HeapAllocBlock */ /** * Free the memory block. @@ -279,49 +351,53 @@ mem_HeapFreeBlock( uint8_t *ptr) /**< pointer to beginning of data space of the mem_BlockHeader_t *pPrevBlock = pBlock->m_Neighbours[ MEM_DIRECTION_PREV ]; mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; + mem_HeapStatFreeBlock( pBlock); + /* checking magic nums that are neighbour to data space */ JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK ); if ( pNextBlock != NULL ) - { - JERRY_ASSERT( pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK - || pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ); - } + { + JERRY_ASSERT( pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK + || pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ); + } pBlock->m_MagicNum = MEM_MAGIC_NUM_OF_FREE_BLOCK; if ( pNextBlock != NULL - && pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ) + && pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ) + { + /* merge with the next block */ + mem_HeapStatFreeBlockMerge(); + + pNextBlock = pNextBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; + pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; + if ( pNextBlock != NULL ) { - /* merge with the next block */ - pBlock->m_SizeInChunks += pNextBlock->m_SizeInChunks; - pNextBlock = pNextBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; - pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; - if ( pNextBlock != NULL ) - { - pNextBlock->m_Neighbours[ MEM_DIRECTION_PREV ] = pBlock; - } else - { - mem_Heap.m_pLastBlock = pBlock; - } + pNextBlock->m_Neighbours[ MEM_DIRECTION_PREV ] = pBlock; + } else + { + mem_Heap.m_pLastBlock = pBlock; } + } if ( pPrevBlock != NULL - && pPrevBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ) + && pPrevBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ) + { + /* merge with the previous block */ + mem_HeapStatFreeBlockMerge(); + + pPrevBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; + if ( pNextBlock != NULL ) { - /* merge with the previous block */ - pPrevBlock->m_SizeInChunks += pBlock->m_SizeInChunks; - pPrevBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; - if ( pNextBlock != NULL ) - { - pNextBlock->m_Neighbours[ MEM_DIRECTION_PREV ] = pBlock->m_Neighbours[ MEM_DIRECTION_PREV ]; - } else - { - mem_Heap.m_pLastBlock = pPrevBlock; - } + pNextBlock->m_Neighbours[ MEM_DIRECTION_PREV ] = pBlock->m_Neighbours[ MEM_DIRECTION_PREV ]; + } else + { + mem_Heap.m_pLastBlock = pPrevBlock; } + } mem_CheckHeap(); -} /* mem_Free */ +} /* mem_HeapFreeBlock */ /** * Recommend allocation size based on chunk size. @@ -353,28 +429,52 @@ mem_HeapPrint( bool dumpBlockData) /**< print block with data (true) (void*) mem_Heap.m_pLastBlock); for ( mem_BlockHeader_t *pBlock = mem_Heap.m_pFirstBlock; - pBlock != NULL; - pBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] ) - { - __printf("Block (%p): magic num=0x%08x, size in chunks=%lu, previous block->%p next block->%p\n", - (void*) pBlock, - pBlock->m_MagicNum, - pBlock->m_SizeInChunks, - (void*) pBlock->m_Neighbours[ MEM_DIRECTION_PREV ], - (void*) pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]); + pBlock != NULL; + pBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] ) + { + __printf("Block (%p): magic num=0x%08x, size in chunks=%lu, previous block->%p next block->%p\n", + (void*) pBlock, + pBlock->m_MagicNum, + mem_get_block_chunks_count( pBlock), + (void*) pBlock->m_Neighbours[ MEM_DIRECTION_PREV ], + (void*) pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]); - if ( dumpBlockData ) - { - uint8_t *pBlockData = (uint8_t*) (pBlock + 1); - for ( uint32_t offset = 0; - offset < mem_GetHeapBlockDataSpaceSizeInBytes( pBlock); - offset++ ) - { - __printf("%02x ", pBlockData[ offset ]); - } - __printf("\n"); - } + if ( dumpBlockData ) + { + uint8_t *pBlockData = (uint8_t*) (pBlock + 1); + for ( uint32_t offset = 0; + offset < mem_get_block_data_space_size( pBlock); + offset++ ) + { + __printf("%02x ", pBlockData[ offset ]); + } + __printf("\n"); } + } + +#ifdef MEM_STATS + __printf("Heap stats:\n"); + __printf(" Size = %lu\n" + " Blocks count = %lu\n" + " Allocated blocks count = %lu\n" + " Allocated chunks count = %lu\n" + " Allocated bytes count = %lu\n" + " Waste bytes count = %lu\n" + " Peak allocated blocks count = %lu\n" + " Peak allocated chunks count = %lu\n" + " Peak allocated bytes count = %lu\n" + " Peak waste bytes count = %lu\n", + mem_HeapStats.size, + mem_HeapStats.blocks, + mem_HeapStats.allocated_blocks, + mem_HeapStats.allocated_chunks, + mem_HeapStats.allocated_bytes, + mem_HeapStats.waste_bytes, + mem_HeapStats.peak_allocated_blocks, + mem_HeapStats.peak_allocated_chunks, + mem_HeapStats.peak_allocated_bytes, + mem_HeapStats.peak_waste_bytes); +#endif /* MEM_STATS */ __printf("\n"); } /* mem_PrintHeap */ @@ -389,38 +489,141 @@ mem_CheckHeap( void) JERRY_ASSERT( (uint8_t*) mem_Heap.m_pFirstBlock == mem_Heap.m_HeapStart ); JERRY_ASSERT( mem_Heap.m_HeapSize % MEM_HEAP_CHUNK_SIZE == 0 ); - size_t chunksCount = 0; bool isLastBlockWasMet = false; for ( mem_BlockHeader_t *pBlock = mem_Heap.m_pFirstBlock; - pBlock != NULL; - pBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] ) + pBlock != NULL; + pBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] ) + { + JERRY_ASSERT( pBlock != NULL ); + JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK + || pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK ); + + mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; + if ( pBlock == mem_Heap.m_pLastBlock ) { - JERRY_ASSERT( pBlock != NULL ); - JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK - || pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK ); + isLastBlockWasMet = true; - chunksCount += pBlock->m_SizeInChunks; - - mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; - if ( pBlock == mem_Heap.m_pLastBlock ) - { - isLastBlockWasMet = true; - - JERRY_ASSERT( pNextBlock == NULL ); - JERRY_ASSERT( mem_Heap.m_HeapStart + mem_Heap.m_HeapSize - == (uint8_t*) pBlock + pBlock->m_SizeInChunks * MEM_HEAP_CHUNK_SIZE ); - } else - { - JERRY_ASSERT( pNextBlock != NULL ); - JERRY_ASSERT( (uint8_t*) pNextBlock == (uint8_t*) pBlock + pBlock->m_SizeInChunks * MEM_HEAP_CHUNK_SIZE ); - } + JERRY_ASSERT( pNextBlock == NULL ); + } else + { + JERRY_ASSERT( pNextBlock != NULL ); } + } JERRY_ASSERT( isLastBlockWasMet ); - JERRY_ASSERT( chunksCount == mem_Heap.m_HeapSize / MEM_HEAP_CHUNK_SIZE ); #endif /* !JERRY_NDEBUG */ } /* mem_CheckHeap */ +#ifdef MEM_STATS +/** + * Get heap memory usage statistics + */ +void +mem_HeapGetStats( mem_HeapStats_t *out_heap_stats_p) /**< out: heap stats */ +{ + *out_heap_stats_p = mem_HeapStats; +} /* mem_HeapGetStats */ + +/** + * Initalize heap memory usage statistics account structure + */ +static void +mem_HeapStatInit() +{ + __memset( &mem_HeapStats, 0, sizeof (mem_HeapStats)); + + mem_HeapStats.size = mem_Heap.m_HeapSize; + mem_HeapStats.blocks = 1; +} /* mem_InitStats */ + +/** + * Account block allocation + */ +static void +mem_HeapStatAllocBlock( mem_BlockHeader_t *block_header_p) /**< allocated block */ +{ + JERRY_ASSERT( block_header_p->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK ); + + const size_t chunks = mem_get_block_chunks_count( block_header_p); + const size_t bytes = block_header_p->allocated_bytes; + const size_t waste_bytes = chunks * MEM_HEAP_CHUNK_SIZE - bytes; + + mem_HeapStats.allocated_blocks++; + mem_HeapStats.allocated_chunks += chunks; + mem_HeapStats.allocated_bytes += bytes; + mem_HeapStats.waste_bytes += waste_bytes; + + if ( mem_HeapStats.allocated_blocks > mem_HeapStats.peak_allocated_blocks ) + { + mem_HeapStats.peak_allocated_blocks = mem_HeapStats.allocated_blocks; + } + + if ( mem_HeapStats.allocated_chunks > mem_HeapStats.peak_allocated_chunks ) + { + mem_HeapStats.peak_allocated_chunks = mem_HeapStats.allocated_chunks; + } + + if ( mem_HeapStats.allocated_bytes > mem_HeapStats.peak_allocated_bytes ) + { + mem_HeapStats.peak_allocated_bytes = mem_HeapStats.allocated_bytes; + } + + if ( mem_HeapStats.waste_bytes > mem_HeapStats.peak_waste_bytes ) + { + mem_HeapStats.peak_waste_bytes = mem_HeapStats.waste_bytes; + } + + JERRY_ASSERT( mem_HeapStats.allocated_blocks <= mem_HeapStats.blocks ); + JERRY_ASSERT( mem_HeapStats.allocated_bytes <= mem_HeapStats.size ); + JERRY_ASSERT( mem_HeapStats.allocated_chunks <= mem_HeapStats.size / MEM_HEAP_CHUNK_SIZE ); +} /* mem_HeapStatAllocBlock */ + +/** + * Account block freeing + */ +static void +mem_HeapStatFreeBlock( mem_BlockHeader_t *block_header_p) /**< block to be freed */ +{ + JERRY_ASSERT( block_header_p->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK ); + + const size_t chunks = mem_get_block_chunks_count( block_header_p); + const size_t bytes = block_header_p->allocated_bytes; + const size_t waste_bytes = chunks * MEM_HEAP_CHUNK_SIZE - bytes; + + JERRY_ASSERT( mem_HeapStats.allocated_blocks <= mem_HeapStats.blocks ); + JERRY_ASSERT( mem_HeapStats.allocated_bytes <= mem_HeapStats.size ); + JERRY_ASSERT( mem_HeapStats.allocated_chunks <= mem_HeapStats.size / MEM_HEAP_CHUNK_SIZE ); + + JERRY_ASSERT( mem_HeapStats.allocated_blocks >= 1 ); + JERRY_ASSERT( mem_HeapStats.allocated_chunks >= chunks ); + JERRY_ASSERT( mem_HeapStats.allocated_bytes >= bytes ); + JERRY_ASSERT( mem_HeapStats.waste_bytes >= waste_bytes ); + + mem_HeapStats.allocated_blocks--; + mem_HeapStats.allocated_chunks -= chunks; + mem_HeapStats.allocated_bytes -= bytes; + mem_HeapStats.waste_bytes -= waste_bytes; +} /* mem_HeapStatFreeBlock */ + +/** + * Account free block split + */ +static void +mem_HeapStatFreeBlockSplit( void) +{ + mem_HeapStats.blocks++; +} /* mem_HeapStatFreeBlockSplit */ + +/** + * Account free block merge + */ +static void +mem_HeapStatFreeBlockMerge( void) +{ + mem_HeapStats.blocks--; +} /* mem_HeapStatFreeBlockMerge */ +#endif /* MEM_STATS */ + /** * @} * @} diff --git a/src/liballocator/mem-heap.h b/src/liballocator/mem-heap.h index 4718c0986..0c8ee39bb 100644 --- a/src/liballocator/mem-heap.h +++ b/src/liballocator/mem-heap.h @@ -44,6 +44,31 @@ extern void mem_HeapFreeBlock(uint8_t *ptr); extern size_t mem_HeapRecommendAllocationSize(size_t minimumAllocationSize); extern void mem_HeapPrint(bool dumpBlockData); +#ifdef MEM_STATS +/** + * Heap memory usage statistics + */ +typedef struct { + size_t size; /**< size */ + size_t blocks; /**< blocks count */ + + size_t allocated_chunks; /**< currently allocated chunks */ + size_t peak_allocated_chunks; /**< peak allocated chunks */ + + size_t allocated_blocks; /**< currently allocated blocks */ + size_t peak_allocated_blocks; /**< peak allocated blocks */ + + size_t allocated_bytes; /**< currently allocated bytes */ + size_t peak_allocated_bytes; /**< 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 */ +} mem_HeapStats_t; + +extern void mem_HeapGetStats(mem_HeapStats_t *out_heap_stats_p); +#endif /* MEM_STATS */ + /** * @} * @} diff --git a/src/liballocator/mem-poolman.c b/src/liballocator/mem-poolman.c index 6e2b4fe1e..b8a2d1f8f 100644 --- a/src/liballocator/mem-poolman.c +++ b/src/liballocator/mem-poolman.c @@ -27,6 +27,7 @@ #define JERRY_MEM_POOL_INTERNAL #include "globals.h" +#include "jerry-libc.h" #include "mem-allocator.h" #include "mem-heap.h" #include "mem-pool.h" @@ -52,6 +53,25 @@ mem_PoolState_t mem_PoolForPoolHeaders; */ uint8_t *mem_SpaceForPoolForPoolHeaders; +#ifdef MEM_STATS +/** +* Pools' memory usage statistics + */ +mem_PoolsStats_t mem_PoolsStats; + +static void mem_PoolsStatInit( void); +static void mem_PoolsStatAllocPool( mem_PoolChunkType_t); +static void mem_PoolsStatFreePool( mem_PoolChunkType_t); +static void mem_PoolsStatAllocChunk( mem_PoolChunkType_t); +static void mem_PoolsStatFreeChunk( mem_PoolChunkType_t); +#else /* !MEM_STATS */ +# define mem_PoolsStatsInit() +# define mem_PoolsStatAllocPool() +# define mem_PoolsStatsFreePool() +# define mem_PoolsStatAllocChunk() +# define mem_PoolsStatFreeChunk() +#endif /* !MEM_STATS */ + /** * Initialize pool manager */ @@ -83,6 +103,8 @@ mem_PoolsInit(void) mem_GetChunkSize( chunkType), mem_SpaceForPoolForPoolHeaders, poolSpaceSize); + + mem_PoolsStatInit(); } /* mem_PoolsInit */ /** @@ -138,6 +160,8 @@ mem_PoolsAlloc( mem_PoolChunkType_t chunkType) /**< chunk type */ mem_Pools[ chunkType ] = poolState; mem_FreeChunksNumber[ chunkType ] += poolState->m_FreeChunksNumber; + + mem_PoolsStatAllocPool( chunkType); } /** @@ -159,6 +183,8 @@ mem_PoolsAlloc( mem_PoolChunkType_t chunkType) /**< chunk type */ */ mem_FreeChunksNumber[ chunkType ]--; + mem_PoolsStatAllocChunk( chunkType); + return mem_PoolAllocChunk( poolState); } /* mem_PoolsAlloc */ @@ -189,6 +215,8 @@ mem_PoolsFree( mem_PoolChunkType_t chunkType, /**< the chunk type */ mem_PoolFreeChunk( poolState, pChunk); mem_FreeChunksNumber[ chunkType ]++; + mem_PoolsStatFreeChunk( chunkType); + /** * If all chunks of the pool are free, free the pool itself. */ @@ -207,9 +235,89 @@ mem_PoolsFree( mem_PoolChunkType_t chunkType, /**< the chunk type */ mem_HeapFreeBlock( poolState->m_pPoolStart); mem_PoolFreeChunk( &mem_PoolForPoolHeaders, (uint8_t*) poolState); - } + + mem_PoolsStatFreePool( chunkType); + } } /* mem_PoolsFree */ +#ifdef MEM_STATS +/** + * Get pools memory usage statistics + */ +void +mem_PoolsGetStats( mem_PoolsStats_t *out_pools_stats_p) /**< out: pools' stats */ +{ + JERRY_ASSERT( out_pools_stats_p != NULL ); + + *out_pools_stats_p = mem_PoolsStats; +} /* mem_PoolsGetStats */ + +/** + * Initalize pools' memory usage statistics account structure + */ +static void +mem_PoolsStatInit( void) +{ + __memset( &mem_PoolsStats, 0, sizeof (mem_PoolsStats)); +} /* mem_PoolsStatInit */ + +/** + * Account allocation of a pool + */ +static void +mem_PoolsStatAllocPool( mem_PoolChunkType_t chunkType) /**< chunk type */ +{ + mem_PoolsStats.pools_count[ chunkType ]++; + mem_PoolsStats.free_chunks[ chunkType ] = mem_FreeChunksNumber[ chunkType ]; + + if ( mem_PoolsStats.pools_count[ chunkType ] > mem_PoolsStats.peak_pools_count[ chunkType ] ) + { + mem_PoolsStats.peak_pools_count[ chunkType ] = mem_PoolsStats.pools_count[ chunkType ]; + } +} /* mem_PoolsStatAllocPool */ + +/** + * Account freeing of a pool + */ +static void +mem_PoolsStatFreePool( mem_PoolChunkType_t chunkType) /**< chunk type */ +{ + JERRY_ASSERT( mem_PoolsStats.pools_count[ chunkType ] > 0 ); + + mem_PoolsStats.pools_count[ chunkType ]--; + mem_PoolsStats.free_chunks[ chunkType ] = mem_FreeChunksNumber[ chunkType ]; +} /* mem_PoolsStatFreePool */ + +/** + * Account allocation of chunk in a pool + */ +static void +mem_PoolsStatAllocChunk( mem_PoolChunkType_t chunkType) /**< chunk type */ +{ + JERRY_ASSERT( mem_PoolsStats.free_chunks[ chunkType ] > 0 ); + + mem_PoolsStats.allocated_chunks[ chunkType ]++; + mem_PoolsStats.free_chunks[ chunkType ]--; + + if ( mem_PoolsStats.allocated_chunks[ chunkType ] > mem_PoolsStats.peak_allocated_chunks[ chunkType ] ) + { + mem_PoolsStats.peak_allocated_chunks[ chunkType ] = mem_PoolsStats.allocated_chunks[ chunkType ]; + } +} /* mem_PoolsStatAllocChunk */ + +/** + * Account freeing of chunk in a pool + */ +static void +mem_PoolsStatFreeChunk( mem_PoolChunkType_t chunkType) /**< chunk type */ +{ + JERRY_ASSERT( mem_PoolsStats.allocated_chunks[ chunkType ] > 0 ); + + mem_PoolsStats.allocated_chunks[ chunkType ]--; + mem_PoolsStats.free_chunks[ chunkType ]++; +} /* mem_PoolsStatFreeChunk */ +#endif /* MEM_STATS */ + /** * @} */ diff --git a/src/liballocator/mem-poolman.h b/src/liballocator/mem-poolman.h index 0426712dd..36da10af9 100644 --- a/src/liballocator/mem-poolman.h +++ b/src/liballocator/mem-poolman.h @@ -37,6 +37,7 @@ typedef enum { MEM_POOL_CHUNK_TYPE_8, /**< 8-byte chunk */ MEM_POOL_CHUNK_TYPE_16, /**< 16-byte chunk */ MEM_POOL_CHUNK_TYPE_32, /**< 32-byte chunk */ + MEM_POOL_CHUNK_TYPE_64, /**< 64-byte chunk */ MEM_POOL_CHUNK_TYPE__COUNT /**< count of possible pool chunks' sizes */ } mem_PoolChunkType_t; @@ -47,7 +48,8 @@ typedef enum { ((size) == 8 ? MEM_POOL_CHUNK_TYPE_8 : \ ((size) == 16 ? MEM_POOL_CHUNK_TYPE_16 : \ ((size) == 32 ? MEM_POOL_CHUNK_TYPE_32 : \ - jerry_UnreferencedExpression)))) + ((size) == 64 ? MEM_POOL_CHUNK_TYPE_64 : \ + jerry_UnreferencedExpression))))) /** * Get chunk size from chunk type. @@ -69,6 +71,31 @@ extern void mem_PoolsInit(void); extern uint8_t* mem_PoolsAlloc(mem_PoolChunkType_t chunkType); extern void mem_PoolsFree(mem_PoolChunkType_t chunkType, uint8_t *pChunk); +#ifdef MEM_STATS +/** + * Pools' memory usage statistics + */ +typedef struct +{ + /** pools' count, per type */ + size_t pools_count[ MEM_POOL_CHUNK_TYPE__COUNT ]; + + /** peak pools' count, per type */ + size_t peak_pools_count[ MEM_POOL_CHUNK_TYPE__COUNT ]; + + /** allocated chunks count, per type */ + size_t allocated_chunks[ MEM_POOL_CHUNK_TYPE__COUNT ]; + + /** peak allocated chunks count, per type */ + size_t peak_allocated_chunks[ MEM_POOL_CHUNK_TYPE__COUNT ]; + + /** free chunks count, per type */ + size_t free_chunks[ MEM_POOL_CHUNK_TYPE__COUNT ]; +} mem_PoolsStats_t; + +extern void mem_PoolsGetStats( mem_PoolsStats_t *out_pools_stats_p); +#endif /* MEM_STATS */ + #endif /* JERRY_MEM_POOLMAN_H */ /** diff --git a/src/libcoreint/interpreter.c b/src/libcoreint/interpreter.c index 5eb1a34ef..f497629f8 100644 --- a/src/libcoreint/interpreter.c +++ b/src/libcoreint/interpreter.c @@ -31,13 +31,13 @@ gen_bytecode () wait(500); } - save_op_data (0, getop_loop_inf (1)); - save_op_data (1, getop_call_1 (0, 12)); - save_op_data (2, getop_call_1 (0, 13)); - save_op_data (3, getop_call_1 (0, 14)); - save_op_data (4, getop_call_1 (0, 15)); - save_op_data (5, getop_jmp (0)); */ +// save_op_data (0, getop_loop_inf (1)); +// save_op_data (1, getop_call_1 (0, 12)); +// save_op_data (2, getop_call_1 (0, 13)); +// save_op_data (3, getop_call_1 (0, 14)); +// save_op_data (4, getop_call_1 (0, 15)); +// save_op_data (5, getop_jmp (0)); #ifdef __MCU // It's mandatory to restart app! @@ -49,7 +49,8 @@ void init_int () { #define INIT_OP_FUNC(name) __opfuncs[ name ] = opfunc_##name ; - JERRY_STATIC_ASSERT (sizeof (OPCODE) <= 4); + // FIXME + // JERRY_STATIC_ASSERT (sizeof (OPCODE) <= 4); OP_LIST (INIT_OP_FUNC) } diff --git a/src/libcoreint/interpreter.h b/src/libcoreint/interpreter.h index 620f43549..9e1a993eb 100644 --- a/src/libcoreint/interpreter.h +++ b/src/libcoreint/interpreter.h @@ -23,6 +23,7 @@ #endif #include "opcodes.h" +#include "ecma-globals.h" OPCODE __program[128]; @@ -31,11 +32,13 @@ opfunc __opfuncs[LAST_OP]; struct __int_data { int pos; + ecma_Object_t *pThisBinding; /**< this binding for current context */ + ecma_Object_t *pLexEnv; /**< current lexical environment */ int *root_op_addr; }; -void gen_bytecode (); -void run_int (); +void gen_bytecode (void); +void run_int (void); void run_int_from_pos (struct __int_data *); #endif /* INTERPRETER_H */ diff --git a/src/libcoreint/opcode-structures.h b/src/libcoreint/opcode-structures.h index 3416e012f..76788722a 100644 --- a/src/libcoreint/opcode-structures.h +++ b/src/libcoreint/opcode-structures.h @@ -21,11 +21,11 @@ #define OP_CODE_DECL_VOID(name) \ - struct __op_##name { }; \ - OPCODE getop_##name (); + struct __op_##name { T_IDX __do_not_use; }; \ + OPCODE getop_##name ( void ); #define OP_CODE_DECL(name, type, ... ) \ - OP_DEF (name, type##_DECL( __VA_ARGS__ ) ); \ + OP_DEF (name, type##_DECL( __VA_ARGS__ ) ) \ OPCODE getop_##name ( type ); #define T_IDX_IDX T_IDX, T_IDX @@ -49,112 +49,112 @@ /** L < R */ OP_CODE_DECL (is_less_than, T_IDX_IDX, value_left, - value_right); + value_right) /** L <= R */ OP_CODE_DECL (is_less_or_equal, T_IDX_IDX, value_left, - value_right); + value_right) /** L > R */ OP_CODE_DECL (is_greater_than, T_IDX_IDX, value_left, - value_right); + value_right) /** L >= R */ OP_CODE_DECL (is_greater_or_equal, T_IDX_IDX, value_left, - value_right); + value_right) /** L == R */ OP_CODE_DECL (is_equal_value, T_IDX_IDX, value_left, - value_right); + value_right) /** L != R */ OP_CODE_DECL (is_not_equal_value, T_IDX_IDX, value_left, - value_right); + value_right) /** L === R */ OP_CODE_DECL (is_equal_value_type, T_IDX_IDX, value_left, - value_right); + value_right) /** L !== R */ OP_CODE_DECL (is_not_equal_value_type, T_IDX_IDX, value_left, - value_right); + value_right) /** Instruction tests if BOOLEAN value is TRUE and JMP to DST */ OP_CODE_DECL (is_true_jmp, T_IDX_IDX, value, - opcode); + opcode) /** Instruction tests if BOOLEAN value is FALSE and JMP to DST */ OP_CODE_DECL (is_false_jmp, T_IDX_IDX, value, - opcode); + opcode) /** Unconditional JMP to the specified opcode index */ OP_CODE_DECL (jmp, T_IDX, - opcode_idx); + opcode_idx) /** Unconditional JMP on opcode_count up */ OP_CODE_DECL (jmp_up, T_IDX, - opcode_count); + opcode_count) /** Unconditional JMP on opcode_count down */ OP_CODE_DECL (jmp_down, T_IDX, - opcode_count); + opcode_count) /** dst = L + R */ OP_CODE_DECL (addition, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L - R */ OP_CODE_DECL (substraction, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L / R */ OP_CODE_DECL (division, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L * R */ OP_CODE_DECL (multiplication, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L % R */ OP_CODE_DECL (remainder, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L << R */ OP_CODE_DECL (b_shift_left, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L >> R */ OP_CODE_DECL (b_shift_right, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L >>> R */ OP_CODE_DECL (b_shift_uright, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) // Binary bitwise operators. // Operands is a set of 32 bits @@ -164,19 +164,19 @@ OP_CODE_DECL (b_shift_uright, T_IDX_IDX_IDX, OP_CODE_DECL (b_and, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L | R */ OP_CODE_DECL (b_or, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L ^ R */ OP_CODE_DECL (b_xor, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) // Binary logical operators. // Operands are booleans. @@ -186,13 +186,13 @@ OP_CODE_DECL (b_xor, T_IDX_IDX_IDX, OP_CODE_DECL (logical_and, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) /** dst = L || R */ OP_CODE_DECL (logical_or, T_IDX_IDX_IDX, dst, var_left, - var_right); + var_right) // Assignment operators. // Assign value to LEFT operand based on value of RIGHT operand. @@ -200,133 +200,133 @@ OP_CODE_DECL (logical_or, T_IDX_IDX_IDX, /** L = R */ OP_CODE_DECL (assignment, T_IDX_IDX, value_left, - value_right); + value_right) /** L *= R */ OP_CODE_DECL (assignment_multiplication, T_IDX_IDX, value_left, - value_right); + value_right) /** L /= R */ OP_CODE_DECL (assignment_devision, T_IDX_IDX, value_left, - value_right); + value_right) /** L %= R */ OP_CODE_DECL (assignment_remainder, T_IDX_IDX, value_left, - value_right); + value_right) /** L += R */ OP_CODE_DECL (assignment_addition, T_IDX_IDX, value_left, - value_right); + value_right) /** L -= R */ OP_CODE_DECL (assignment_substruction, T_IDX_IDX, value_left, - value_right); + value_right) /** L <<= R */ OP_CODE_DECL (assignment_shift_left, T_IDX_IDX, value_left, - value_right); + value_right) /** L >>= R */ OP_CODE_DECL (assignment_shift_right, T_IDX_IDX, value_left, - value_right); + value_right) /** L >>>= R */ OP_CODE_DECL (assignment_shift_uright, T_IDX_IDX, value_left, - value_right); + value_right) /** L &= R */ OP_CODE_DECL (assignment_b_and, T_IDX_IDX, value_left, - value_right); + value_right) /** L ^= R */ OP_CODE_DECL (assignment_b_xor, T_IDX_IDX, value_left, - value_right); + value_right) /** L |= R */ OP_CODE_DECL (assignment_b_or, T_IDX_IDX, value_left, - value_right); + value_right) // Functions calls, declarations and argument handling /** name(arg1); */ OP_CODE_DECL (call_1, T_IDX_IDX, name_lit_idx, - arg1_lit_idx); + arg1_lit_idx) /** name(arg1, arg2); */ OP_CODE_DECL (call_2, T_IDX_IDX_IDX, name_lit_idx, arg1_lit_idx, - arg2_lit_idx); + arg2_lit_idx) /** name(arg1, arg2, ... */ OP_CODE_DECL (call_n, T_IDX_IDX_IDX, name_lit_idx, arg1_lit_idx, - arg2_lit_idx); + arg2_lit_idx) /** name(arg1); */ OP_CODE_DECL (func_decl_1, T_IDX_IDX, name_lit_idx, - arg1_lit_idx); + arg1_lit_idx) /** name(arg1, arg2); */ OP_CODE_DECL (func_decl_2, T_IDX_IDX_IDX, name_lit_idx, arg1_lit_idx, - arg2_lit_idx); + arg2_lit_idx) /** name(arg1, arg2, ... */ OP_CODE_DECL (func_decl_n, T_IDX_IDX_IDX, name_lit_idx, arg1_lit_idx, - arg2_lit_idx); + arg2_lit_idx) /** ..., arg1, ... */ OP_CODE_DECL (varg_1, T_IDX, - arg1_lit_idx); + arg1_lit_idx) /** ..., arg1); */ OP_CODE_DECL (varg_1_end, T_IDX, - arg1_lit_idx); + arg1_lit_idx) /** ..., arg1, arg2, ... */ OP_CODE_DECL (varg_2, T_IDX_IDX, arg1_lit_idx, - arg2_lit_idx); + arg2_lit_idx) /** ..., arg1, arg2); */ OP_CODE_DECL (varg_2_end, T_IDX_IDX, arg1_lit_idx, - arg2_lit_idx); + arg2_lit_idx) /** arg1, arg2, arg3, ... */ OP_CODE_DECL (varg_3, T_IDX_IDX_IDX, arg1_lit_idx, arg2_lit_idx, - arg3_lit_idx); + arg3_lit_idx) /** arg1, arg2, arg3); */ OP_CODE_DECL (varg_3_end, T_IDX_IDX_IDX, arg1_lit_idx, arg2_lit_idx, - arg3_lit_idx); + arg3_lit_idx) /** return value; */ OP_CODE_DECL (retval, T_IDX, - ret_value); -OP_CODE_DECL_VOID (ret); + ret_value) +OP_CODE_DECL_VOID (ret) // LOOPS // Lately, all loops should be translated into different JMPs in an optimizer. @@ -334,7 +334,7 @@ OP_CODE_DECL_VOID (ret); /** End of body of infinite loop should be ended with unconditional JMP * to loop_root (ie. next op after loop condition) */ OP_CODE_DECL (loop_inf, T_IDX, - loop_root); + loop_root) /** Numeric loop initialization. * for (start,stop,step) @@ -342,7 +342,7 @@ OP_CODE_DECL (loop_inf, T_IDX, OP_CODE_DECL (loop_init_num, T_IDX_IDX_IDX, start, stop, - step); + step) /** Check loop (condition). * if (loop cond is true) @@ -352,7 +352,7 @@ OP_CODE_DECL (loop_init_num, T_IDX_IDX_IDX, */ OP_CODE_DECL (loop_precond_begin_num, T_IDX_IDX, condition, - after_loop_op); + after_loop_op) /** i++; * Increment iterator on step and JMP to PRECOND @@ -360,43 +360,41 @@ OP_CODE_DECL (loop_precond_begin_num, T_IDX_IDX, OP_CODE_DECL (loop_precond_end_num, T_IDX_IDX_IDX, iterator, step, - precond_begin); + precond_begin) /** do {...} while (cond); * If condition is true, JMP to BODY_ROOT */ OP_CODE_DECL (loop_postcond, T_IDX_IDX, condition, - body_root); + body_root) ///** for vars...in iter, state, ctl */ //OP_CODE_DECL (loop_init, T_IDX_IDX_IDX, -// start_idx, stop_idx, step_idx); +// start_idx, stop_idx, step_idx) ///** loop (condition) */ //OP_CODE_DECL (loop_cond_pre_begin, T_IDX_IDX, -// condition, body_root); +// condition, body_root) ///** i++;*/ //OP_CODE_DECL (loop_cond_pre_end, T_IDX, -// iterator, body_root); +// iterator, body_root) // Property accessors (array, objects, strings) /** Array ops for ILMIR*/ //OP_CODE_DECL (array_copy, T_IDX_IDX, /** L = R */ -// var_left, var_right); +// var_left, var_right) //OP_CODE_DECL (array_set, T_IDX_IDX_IDX, /** array[index] = src */ -// dst, var_left, var_right); +// dst, var_left, var_right) //OP_CODE_DECL (array_get, T_IDX_IDX_IDX, /** dst = array[index] */ -// dst, array, index); +// dst, array, index) //// TODO -// Variable declarations +// Variable declaration +OP_CODE_DECL (decl_var, T_IDX, + variable) + // TODO New constructor - - - - - #endif /* OPCODE_STRUCTURES_H */ - + \ No newline at end of file diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index f5bf62469..884c1b881 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -23,60 +23,60 @@ save_op_data (int pos, OPCODE opdata) __program[pos] = opdata; } -void opfunc_loop_init_num (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_loop_precond_begin_num (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_loop_precond_end_num (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_loop_postcond (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_call_2 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_call_n (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_func_decl_1 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_func_decl_2 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_func_decl_n (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_varg_1 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_varg_1_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_varg_2 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_varg_2_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_varg_3 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_varg_3_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_retval (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_ret (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_multiplication (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_devision (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_remainder (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_addition (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_substruction (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_shift_left (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_shift_right (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_shift_uright (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_b_and (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_b_xor (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_assignment_b_or (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_logical_and (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_logical_or (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_b_and (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_b_or (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_b_xor (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_b_shift_left (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_b_shift_right (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_b_shift_uright (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_addition (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_substraction (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_division (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_multiplication (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_remainder (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_jmp_up (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_jmp_down (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_true_jmp (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_false_jmp (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_less_than (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_less_or_equal (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_greater_than (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_greater_or_equal (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_equal_value (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_not_equal_value (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_equal_value_type (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } -void opfunc_is_not_equal_value_type (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } +void opfunc_loop_init_num (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_loop_precond_begin_num (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_loop_precond_end_num (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_loop_postcond (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_call_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_call_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_func_decl_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_func_decl_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_func_decl_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_varg_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_varg_1_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_varg_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_varg_2_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_varg_3 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_varg_3_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_retval (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_ret (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_multiplication (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_devision (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_remainder (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_addition (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_substruction (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_shift_left (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_shift_right (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_shift_uright (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_b_and (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_b_xor (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_assignment_b_or (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_logical_and (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_logical_or (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_b_and (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_b_or (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_b_xor (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_b_shift_left (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_b_shift_right (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_b_shift_uright (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_addition (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_substraction (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_division (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_multiplication (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_remainder (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_jmp_up (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_jmp_down (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_true_jmp (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_false_jmp (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_less_than (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_less_or_equal (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_greater_than (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_greater_or_equal (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_equal_value (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_not_equal_value (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_equal_value_type (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } +void opfunc_is_not_equal_value_type (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); } void opfunc_loop_inf (OPCODE opdata, struct __int_data *int_data) diff --git a/src/libperipherals/actuators.c b/src/libperipherals/actuators.c index 267120650..1c3472b9b 100644 --- a/src/libperipherals/actuators.c +++ b/src/libperipherals/actuators.c @@ -30,4 +30,4 @@ void led_on(int led_id) void led_off(int led_id) { printf("led_off: %d", led_id); -} \ No newline at end of file +} diff --git a/tests/unit/test_heap.c b/tests/unit/test_heap.c index 862df96fb..f8abfa415 100644 --- a/tests/unit/test_heap.c +++ b/tests/unit/test_heap.c @@ -82,5 +82,7 @@ main( int __unused argc, } } + mem_HeapPrint( false); + return 0; } /* main */ diff --git a/tests/unit/test_poolman.c b/tests/unit/test_poolman.c index 9144ce072..2c11deb7a 100644 --- a/tests/unit/test_poolman.c +++ b/tests/unit/test_poolman.c @@ -36,7 +36,7 @@ const size_t test_heap_size = 8 * 1024; const uint32_t test_iters = 16384; // Subiterations count -const uint32_t test_max_sub_iters = 64; +const uint32_t test_max_sub_iters = 32; int main( int __unused argc, @@ -93,5 +93,28 @@ main( int __unused argc, } } + mem_PoolsStats_t stats; + mem_PoolsGetStats( &stats); + + __printf("Pools stats:\n"); + for(mem_PoolChunkType_t type = 0; + type < MEM_POOL_CHUNK_TYPE__COUNT; + type++) + { + __printf(" Chunk size: %u\n" + " Pools: %lu\n" + " Allocated chunks: %lu\n" + " Free chunks: %lu\n" + " Peak pools: %lu\n" + " Peak allocated chunks: %lu\n", + mem_GetChunkSize( type), + stats.pools_count[ type ], + stats.allocated_chunks[ type ], + stats.free_chunks[ type ], + stats.peak_pools_count[ type ], + stats.peak_allocated_chunks[ type ]); + } + __printf("\n"); + return 0; } /* main */