Change parser to stack-only version

This commit is contained in:
Ilmir Usmanov
2014-07-09 18:05:19 +04:00
parent f46d5b440c
commit a2350cb88e
12 changed files with 718 additions and 330 deletions
+24 -26
View File
@@ -13,7 +13,7 @@
# limitations under the License. # limitations under the License.
TARGET ?= jerry TARGET ?= jerry
CROSS_COMPILE ?= arm-none-eabi- CROSS_COMPILE ?=
OBJ_DIR = obj OBJ_DIR = obj
OUT_DIR = ./out OUT_DIR = ./out
@@ -23,10 +23,12 @@ UNITTESTS_SRC_DIR = ./tests/unit
# FIXME: # FIXME:
# Place jerry-libc.c, pretty-printer.c to some subdirectory (libruntime?) # Place jerry-libc.c, pretty-printer.c to some subdirectory (libruntime?)
# and add them to the SOURCES list through wildcard. # and add them to the SOURCES list through wildcard.
# FIXME:
# Add common-io.c and sensors.c
SOURCES = \ SOURCES = \
$(sort \ $(sort \
$(wildcard ./src/jerry-libc.c ./src/pretty-printer.c) \ $(wildcard ./src/jerry-libc.c ./src/pretty-printer.c) \
$(wildcard ./src/libperipherals/*.c) \ $(wildcard ./src/libperipherals/actuators.c) \
$(wildcard ./src/libjsparser/*.c) \ $(wildcard ./src/libjsparser/*.c) \
$(wildcard ./src/libecmaobjects/*.c) \ $(wildcard ./src/libecmaobjects/*.c) \
$(wildcard ./src/liballocator/*.c) \ $(wildcard ./src/liballocator/*.c) \
@@ -58,48 +60,43 @@ OBJS = \
$(sort \ $(sort \
$(patsubst %.c,./$(OBJ_DIR)/%.o,$(notdir $(MAIN_MODULE_SRC) $(SOURCES)))) $(patsubst %.c,./$(OBJ_DIR)/%.o,$(notdir $(MAIN_MODULE_SRC) $(SOURCES))))
CC = gcc#-4.9 CC = $(CROSS_COMPILE)gcc
LD = ld LD = $(CROSS_COMPILE)ld
OBJDUMP = objdump OBJDUMP = $(CROSS_COMPILE)objdump
OBJCOPY = objcopy OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = size SIZE = $(CROSS_COMPILE)size
STRIP = strip STRIP = $(CROSS_COMPILE)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
# General flags # General flags
CFLAGS ?= $(INCLUDES) -std=c99 -m32 #-fdiagnostics-color=always CFLAGS ?= $(INCLUDES) -std=c99 #-fdiagnostics-color=always
#CFLAGS += -Wall -Wextra -Wpedantic -Wlogical-op -Winline CFLAGS += -Wpedantic -Wlogical-op
#CFLAGS += -Wformat-nonliteral -Winit-self -Wstack-protector # CFLAGS += -Wformat-nonliteral -Winit-self -Wstack-protector
#CFLAGS += -Wconversion -Wsign-conversion -Wformat-security # CFLAGS += -Wall -Wextra -Winline
#CFLAGS += -Wstrict-prototypes -Wmissing-prototypes # CFLAGS += -Wconversion -Wsign-conversion -Wformat-security
# CFLAGS += -Wstrict-prototypes -Wmissing-prototypes
# Flags for MCU # Flags for MCU
#CFLAGS += -mlittle-endian -mcpu=cortex-m4 -march=armv7e-m -mthumb MCU_CFLAGS += -mlittle-endian -mcpu=cortex-m4 -march=armv7e-m -mthumb
#CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard MCU_CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard
#CFLAGS += -ffunction-sections -fdata-sections MCU_CFLAGS += -ffunction-sections -fdata-sections
DEBUG_OPTIONS = -g3 -O0 -DJERRY_NDEBUG# -fsanitize=address DEBUG_OPTIONS = -g3 -O0 -DJERRY_NDEBUG# -fsanitize=address
RELEASE_OPTIONS = -Os -Werror -DJERRY_NDEBUG 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_HOST = -D__HOST
TARGET_MCU = -D__MCU 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 all: clean debug release check
debug: debug: clean
mkdir -p $(OUT_DIR)/debug.host/ mkdir -p $(OUT_DIR)/debug.host/
$(CC) $(CFLAGS) $(DEBUG_OPTIONS) $(DEFINES) $(TARGET_HOST) \ $(CC) $(CFLAGS) $(DEBUG_OPTIONS) $(DEFINES) $(TARGET_HOST) \
$(SOURCES) $(MAIN_MODULE_SRC) -o $(OUT_DIR)/debug.host/$(TARGET) $(SOURCES) $(MAIN_MODULE_SRC) -o $(OUT_DIR)/debug.host/$(TARGET)
release: release: clean
mkdir -p $(OUT_DIR)/release.host/ mkdir -p $(OUT_DIR)/release.host/
$(CC) $(CFLAGS) $(RELEASE_OPTIONS) $(DEFINES) $(TARGET_HOST) \ $(CC) $(CFLAGS) $(RELEASE_OPTIONS) $(DEFINES) $(TARGET_HOST) \
$(SOURCES) $(MAIN_MODULE_SRC) -o $(OUT_DIR)/release.host/$(TARGET) $(SOURCES) $(MAIN_MODULE_SRC) -o $(OUT_DIR)/release.host/$(TARGET)
@@ -122,6 +119,7 @@ clean:
rm -f $(TARGET).map rm -f $(TARGET).map
rm -f $(TARGET).hex rm -f $(TARGET).hex
rm -f $(TARGET).lst rm -f $(TARGET).lst
rm -f js.files
check: tests check: tests
@mkdir -p $(OUT_DIR) @mkdir -p $(OUT_DIR)
+367 -164
View File
@@ -64,22 +64,12 @@ typedef enum
*/ */
typedef struct mem_BlockHeader_t typedef struct mem_BlockHeader_t
{ {
mem_MagicNumOfBlock_t m_MagicNum; /**< magic number - MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK for allocated 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 */ and MEM_MAGIC_NUM_OF_FREE_BLOCK for free block */
struct mem_BlockHeader_t *m_Neighbours[ MEM_DIRECTION_COUNT ]; /**< neighbour blocks */ 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; } 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 * Chunk should have enough space for block header
*/ */
@@ -95,8 +85,8 @@ JERRY_STATIC_ASSERT( MEM_HEAP_CHUNK_SIZE % MEM_ALIGNMENT == 0 );
*/ */
typedef struct typedef struct
{ {
uint8_t* m_HeapStart; /**< first address of heap space */ uint8_t* m_HeapStart; /**< first address of heap space */
size_t m_HeapSize; /**< heap space size */ size_t m_HeapSize; /**< heap space size */
mem_BlockHeader_t* m_pFirstBlock; /**< first block of the heap */ mem_BlockHeader_t* m_pFirstBlock; /**< first block of the heap */
mem_BlockHeader_t* m_pLastBlock; /**< last block of the heap */ mem_BlockHeader_t* m_pLastBlock; /**< last block of the heap */
} mem_HeapState_t; } mem_HeapState_t;
@@ -106,6 +96,10 @@ typedef struct
*/ */
mem_HeapState_t mem_Heap; 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, static void mem_InitBlockHeader( uint8_t *pFirstChunk,
size_t sizeInChunks, size_t sizeInChunks,
mem_BlockState_t blockState, mem_BlockState_t blockState,
@@ -113,12 +107,80 @@ static void mem_InitBlockHeader( uint8_t *pFirstChunk,
mem_BlockHeader_t *pNextBlock); mem_BlockHeader_t *pNextBlock);
static void mem_CheckHeap( void); 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 * Startup initialization of heap
*/ */
void void
mem_HeapInit( uint8_t *heapStart, /**< first address of heap space */ mem_HeapInit(uint8_t *heapStart, /**< first address of heap space */
size_t heapSize) /**< heap space size */ size_t heapSize) /**< heap space size */
{ {
JERRY_ASSERT( heapStart != NULL ); JERRY_ASSERT( heapStart != NULL );
JERRY_ASSERT( heapSize != 0 ); 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_HeapStart = heapStart;
mem_Heap.m_HeapSize = heapSize; mem_Heap.m_HeapSize = heapSize;
mem_InitBlockHeader( mem_Heap.m_HeapStart, mem_InitBlockHeader(mem_Heap.m_HeapStart,
heapSize / MEM_HEAP_CHUNK_SIZE, 0,
MEM_BLOCK_FREE, MEM_BLOCK_FREE,
NULL, NULL,
NULL); NULL);
mem_Heap.m_pFirstBlock = (mem_BlockHeader_t*) mem_Heap.m_HeapStart; mem_Heap.m_pFirstBlock = (mem_BlockHeader_t*) mem_Heap.m_HeapStart;
mem_Heap.m_pLastBlock = mem_Heap.m_pFirstBlock; mem_Heap.m_pLastBlock = mem_Heap.m_pFirstBlock;
mem_HeapStatInit();
} /* mem_HeapInit */ } /* mem_HeapInit */
/** /**
* Initialize block header * Initialize block header
*/ */
static void static void
mem_InitBlockHeader( uint8_t *pFirstChunk, /**< address of the first chunk to use for the block */ 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 */ size_t allocated_bytes, /**< size of block's allocated area */
mem_BlockState_t blockState, /**< state of the block (allocated or free) */ mem_BlockState_t blockState, /**< state of the block (allocated or free) */
mem_BlockHeader_t *pPrevBlock, /**< previous block */ mem_BlockHeader_t *pPrevBlock, /**< previous block */
mem_BlockHeader_t *pNextBlock) /**< next 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; mem_BlockHeader_t *pBlockHeader = (mem_BlockHeader_t*) pFirstChunk;
if ( blockState == MEM_BLOCK_FREE ) if ( blockState == MEM_BLOCK_FREE )
{ {
pBlockHeader->m_MagicNum = MEM_MAGIC_NUM_OF_FREE_BLOCK; pBlockHeader->m_MagicNum = MEM_MAGIC_NUM_OF_FREE_BLOCK;
} else
{
pBlockHeader->m_MagicNum = MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK;
}
pBlockHeader->m_Neighbours[ MEM_DIRECTION_PREV ] = pPrevBlock; JERRY_ASSERT( allocated_bytes == 0 );
pBlockHeader->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; } else
pBlockHeader->m_SizeInChunks = sizeInChunks; {
} /* mem_InitFreeBlock */ 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. * Allocation of memory region.
@@ -177,7 +245,7 @@ mem_InitBlockHeader( uint8_t *pFirstChunk, /**< address of the fir
* NULL - if there is not enough memory. * NULL - if there is not enough memory.
*/ */
uint8_t* 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_HeapAllocTerm_t allocTerm) /**< expected allocation term */
{ {
mem_BlockHeader_t *pBlock; mem_BlockHeader_t *pBlock;
@@ -186,82 +254,86 @@ mem_HeapAllocBlock( size_t sizeInBytes, /**< size of region to allo
mem_CheckHeap(); mem_CheckHeap();
if ( allocTerm == MEM_HEAP_ALLOC_SHORT_TERM ) 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; if ( mem_get_block_data_space_size( pBlock) >= sizeInBytes )
direction = MEM_DIRECTION_NEXT; {
break;
}
} else } else
{ {
pBlock = mem_Heap.m_pLastBlock; JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK );
direction = MEM_DIRECTION_PREV; }
}
/* searching for appropriate block */ pBlock = pBlock->m_Neighbours[ direction ];
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 ]; if ( pBlock == NULL )
} {
/* not enough free space */
return NULL;
}
if ( pBlock == NULL ) /* appropriate block found, allocating space */
{ size_t newBlockSizeInChunks = mem_get_block_chunks_count_from_data_size( sizeInBytes);
/* not enough free space */ size_t foundBlockSizeInChunks = mem_get_block_chunks_count( pBlock);
return NULL;
}
/* appropriate block found, allocating space */ JERRY_ASSERT( newBlockSizeInChunks <= foundBlockSizeInChunks );
size_t newBlockSizeInChunks = mem_GetHeapBlockSizeInChunksFromDataSpaceSizeInBytes( sizeInBytes);
size_t foundBlockSizeInChunks = pBlock->m_SizeInChunks;
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 ]; if ( newBlockSizeInChunks < foundBlockSizeInChunks )
mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; {
mem_HeapStatFreeBlockSplit();
if ( newBlockSizeInChunks < foundBlockSizeInChunks ) uint8_t *pNewFreeBlockFirstChunk = (uint8_t*) pBlock + newBlockSizeInChunks * MEM_HEAP_CHUNK_SIZE;
{ mem_InitBlockHeader(pNewFreeBlockFirstChunk,
uint8_t *pNewFreeBlockFirstChunk = (uint8_t*) pBlock + newBlockSizeInChunks * MEM_HEAP_CHUNK_SIZE; 0,
mem_InitBlockHeader( pNewFreeBlockFirstChunk, MEM_BLOCK_FREE,
foundBlockSizeInChunks - newBlockSizeInChunks, pBlock /* there we will place new allocated block */,
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,
pNextBlock); 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 */ pNextBlock = pNewFreeBlock;
uint8_t *pDataSpace = (uint8_t*) (pBlock + 1); }
JERRY_ASSERT( (uintptr_t) pDataSpace % MEM_ALIGNMENT == 0);
return pDataSpace; mem_InitBlockHeader((uint8_t*) pBlock,
} /* mem_Alloc */ 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. * 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 *pPrevBlock = pBlock->m_Neighbours[ MEM_DIRECTION_PREV ];
mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ];
mem_HeapStatFreeBlock( pBlock);
/* checking magic nums that are neighbour to data space */ /* checking magic nums that are neighbour to data space */
JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK ); JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK );
if ( pNextBlock != NULL ) if ( pNextBlock != NULL )
{ {
JERRY_ASSERT( pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK JERRY_ASSERT( pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK
|| pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK ); || pNextBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK );
} }
pBlock->m_MagicNum = MEM_MAGIC_NUM_OF_FREE_BLOCK; pBlock->m_MagicNum = MEM_MAGIC_NUM_OF_FREE_BLOCK;
if ( pNextBlock != NULL 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 */ pNextBlock->m_Neighbours[ MEM_DIRECTION_PREV ] = pBlock;
pBlock->m_SizeInChunks += pNextBlock->m_SizeInChunks; } else
pNextBlock = pNextBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; {
pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; mem_Heap.m_pLastBlock = pBlock;
if ( pNextBlock != NULL )
{
pNextBlock->m_Neighbours[ MEM_DIRECTION_PREV ] = pBlock;
} else
{
mem_Heap.m_pLastBlock = pBlock;
}
} }
}
if ( pPrevBlock != NULL 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 */ pNextBlock->m_Neighbours[ MEM_DIRECTION_PREV ] = pBlock->m_Neighbours[ MEM_DIRECTION_PREV ];
pPrevBlock->m_SizeInChunks += pBlock->m_SizeInChunks; } else
pPrevBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] = pNextBlock; {
if ( pNextBlock != NULL ) 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_CheckHeap();
} /* mem_Free */ } /* mem_HeapFreeBlock */
/** /**
* Recommend allocation size based on chunk size. * 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); (void*) mem_Heap.m_pLastBlock);
for ( mem_BlockHeader_t *pBlock = mem_Heap.m_pFirstBlock; for ( mem_BlockHeader_t *pBlock = mem_Heap.m_pFirstBlock;
pBlock != NULL; pBlock != NULL;
pBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] ) 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", __printf("Block (%p): magic num=0x%08x, size in chunks=%lu, previous block->%p next block->%p\n",
(void*) pBlock, (void*) pBlock,
pBlock->m_MagicNum, pBlock->m_MagicNum,
pBlock->m_SizeInChunks, mem_get_block_chunks_count( pBlock),
(void*) pBlock->m_Neighbours[ MEM_DIRECTION_PREV ], (void*) pBlock->m_Neighbours[ MEM_DIRECTION_PREV ],
(void*) pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]); (void*) pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]);
if ( dumpBlockData ) if ( dumpBlockData )
{ {
uint8_t *pBlockData = (uint8_t*) (pBlock + 1); uint8_t *pBlockData = (uint8_t*) (pBlock + 1);
for ( uint32_t offset = 0; for ( uint32_t offset = 0;
offset < mem_GetHeapBlockDataSpaceSizeInBytes( pBlock); offset < mem_get_block_data_space_size( pBlock);
offset++ ) offset++ )
{ {
__printf("%02x ", pBlockData[ offset ]); __printf("%02x ", pBlockData[ offset ]);
} }
__printf("\n"); __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"); __printf("\n");
} /* mem_PrintHeap */ } /* mem_PrintHeap */
@@ -389,38 +489,141 @@ mem_CheckHeap( void)
JERRY_ASSERT( (uint8_t*) mem_Heap.m_pFirstBlock == mem_Heap.m_HeapStart ); JERRY_ASSERT( (uint8_t*) mem_Heap.m_pFirstBlock == mem_Heap.m_HeapStart );
JERRY_ASSERT( mem_Heap.m_HeapSize % MEM_HEAP_CHUNK_SIZE == 0 ); JERRY_ASSERT( mem_Heap.m_HeapSize % MEM_HEAP_CHUNK_SIZE == 0 );
size_t chunksCount = 0;
bool isLastBlockWasMet = false; bool isLastBlockWasMet = false;
for ( mem_BlockHeader_t *pBlock = mem_Heap.m_pFirstBlock; for ( mem_BlockHeader_t *pBlock = mem_Heap.m_pFirstBlock;
pBlock != NULL; pBlock != NULL;
pBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ] ) 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 ); isLastBlockWasMet = true;
JERRY_ASSERT( pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_FREE_BLOCK
|| pBlock->m_MagicNum == MEM_MAGIC_NUM_OF_ALLOCATED_BLOCK );
chunksCount += pBlock->m_SizeInChunks; JERRY_ASSERT( pNextBlock == NULL );
} else
mem_BlockHeader_t *pNextBlock = pBlock->m_Neighbours[ MEM_DIRECTION_NEXT ]; {
if ( pBlock == mem_Heap.m_pLastBlock ) JERRY_ASSERT( pNextBlock != NULL );
{
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( isLastBlockWasMet ); JERRY_ASSERT( isLastBlockWasMet );
JERRY_ASSERT( chunksCount == mem_Heap.m_HeapSize / MEM_HEAP_CHUNK_SIZE );
#endif /* !JERRY_NDEBUG */ #endif /* !JERRY_NDEBUG */
} /* mem_CheckHeap */ } /* 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 */
/** /**
* @} * @}
* @} * @}
+25
View File
@@ -44,6 +44,31 @@ extern void mem_HeapFreeBlock(uint8_t *ptr);
extern size_t mem_HeapRecommendAllocationSize(size_t minimumAllocationSize); extern size_t mem_HeapRecommendAllocationSize(size_t minimumAllocationSize);
extern void mem_HeapPrint(bool dumpBlockData); 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 */
/** /**
* @} * @}
* @} * @}
+109 -1
View File
@@ -27,6 +27,7 @@
#define JERRY_MEM_POOL_INTERNAL #define JERRY_MEM_POOL_INTERNAL
#include "globals.h" #include "globals.h"
#include "jerry-libc.h"
#include "mem-allocator.h" #include "mem-allocator.h"
#include "mem-heap.h" #include "mem-heap.h"
#include "mem-pool.h" #include "mem-pool.h"
@@ -52,6 +53,25 @@ mem_PoolState_t mem_PoolForPoolHeaders;
*/ */
uint8_t *mem_SpaceForPoolForPoolHeaders; 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 * Initialize pool manager
*/ */
@@ -83,6 +103,8 @@ mem_PoolsInit(void)
mem_GetChunkSize( chunkType), mem_GetChunkSize( chunkType),
mem_SpaceForPoolForPoolHeaders, mem_SpaceForPoolForPoolHeaders,
poolSpaceSize); poolSpaceSize);
mem_PoolsStatInit();
} /* mem_PoolsInit */ } /* mem_PoolsInit */
/** /**
@@ -138,6 +160,8 @@ mem_PoolsAlloc( mem_PoolChunkType_t chunkType) /**< chunk type */
mem_Pools[ chunkType ] = poolState; mem_Pools[ chunkType ] = poolState;
mem_FreeChunksNumber[ chunkType ] += poolState->m_FreeChunksNumber; 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_FreeChunksNumber[ chunkType ]--;
mem_PoolsStatAllocChunk( chunkType);
return mem_PoolAllocChunk( poolState); return mem_PoolAllocChunk( poolState);
} /* mem_PoolsAlloc */ } /* mem_PoolsAlloc */
@@ -189,6 +215,8 @@ mem_PoolsFree( mem_PoolChunkType_t chunkType, /**< the chunk type */
mem_PoolFreeChunk( poolState, pChunk); mem_PoolFreeChunk( poolState, pChunk);
mem_FreeChunksNumber[ chunkType ]++; mem_FreeChunksNumber[ chunkType ]++;
mem_PoolsStatFreeChunk( chunkType);
/** /**
* If all chunks of the pool are free, free the pool itself. * 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_HeapFreeBlock( poolState->m_pPoolStart);
mem_PoolFreeChunk( &mem_PoolForPoolHeaders, (uint8_t*) poolState); mem_PoolFreeChunk( &mem_PoolForPoolHeaders, (uint8_t*) poolState);
}
mem_PoolsStatFreePool( chunkType);
}
} /* mem_PoolsFree */ } /* 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 */
/** /**
* @} * @}
*/ */
+28 -1
View File
@@ -37,6 +37,7 @@ typedef enum {
MEM_POOL_CHUNK_TYPE_8, /**< 8-byte chunk */ MEM_POOL_CHUNK_TYPE_8, /**< 8-byte chunk */
MEM_POOL_CHUNK_TYPE_16, /**< 16-byte chunk */ MEM_POOL_CHUNK_TYPE_16, /**< 16-byte chunk */
MEM_POOL_CHUNK_TYPE_32, /**< 32-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_POOL_CHUNK_TYPE__COUNT /**< count of possible pool chunks' sizes */
} mem_PoolChunkType_t; } mem_PoolChunkType_t;
@@ -47,7 +48,8 @@ typedef enum {
((size) == 8 ? MEM_POOL_CHUNK_TYPE_8 : \ ((size) == 8 ? MEM_POOL_CHUNK_TYPE_8 : \
((size) == 16 ? MEM_POOL_CHUNK_TYPE_16 : \ ((size) == 16 ? MEM_POOL_CHUNK_TYPE_16 : \
((size) == 32 ? MEM_POOL_CHUNK_TYPE_32 : \ ((size) == 32 ? MEM_POOL_CHUNK_TYPE_32 : \
jerry_UnreferencedExpression)))) ((size) == 64 ? MEM_POOL_CHUNK_TYPE_64 : \
jerry_UnreferencedExpression)))))
/** /**
* Get chunk size from chunk type. * 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 uint8_t* mem_PoolsAlloc(mem_PoolChunkType_t chunkType);
extern void mem_PoolsFree(mem_PoolChunkType_t chunkType, uint8_t *pChunk); 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 */ #endif /* JERRY_MEM_POOLMAN_H */
/** /**
+8 -7
View File
@@ -31,13 +31,13 @@ gen_bytecode ()
wait(500); 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 #ifdef __MCU
// It's mandatory to restart app! // It's mandatory to restart app!
@@ -49,7 +49,8 @@ void
init_int () init_int ()
{ {
#define INIT_OP_FUNC(name) __opfuncs[ name ] = opfunc_##name ; #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) OP_LIST (INIT_OP_FUNC)
} }
+5 -2
View File
@@ -23,6 +23,7 @@
#endif #endif
#include "opcodes.h" #include "opcodes.h"
#include "ecma-globals.h"
OPCODE __program[128]; OPCODE __program[128];
@@ -31,11 +32,13 @@ opfunc __opfuncs[LAST_OP];
struct __int_data struct __int_data
{ {
int pos; int pos;
ecma_Object_t *pThisBinding; /**< this binding for current context */
ecma_Object_t *pLexEnv; /**< current lexical environment */
int *root_op_addr; int *root_op_addr;
}; };
void gen_bytecode (); void gen_bytecode (void);
void run_int (); void run_int (void);
void run_int_from_pos (struct __int_data *); void run_int_from_pos (struct __int_data *);
#endif /* INTERPRETER_H */ #endif /* INTERPRETER_H */
+71 -73
View File
@@ -21,11 +21,11 @@
#define OP_CODE_DECL_VOID(name) \ #define OP_CODE_DECL_VOID(name) \
struct __op_##name { }; \ struct __op_##name { T_IDX __do_not_use; }; \
OPCODE getop_##name (); OPCODE getop_##name ( void );
#define OP_CODE_DECL(name, type, ... ) \ #define OP_CODE_DECL(name, type, ... ) \
OP_DEF (name, type##_DECL( __VA_ARGS__ ) ); \ OP_DEF (name, type##_DECL( __VA_ARGS__ ) ) \
OPCODE getop_##name ( type ); OPCODE getop_##name ( type );
#define T_IDX_IDX T_IDX, T_IDX #define T_IDX_IDX T_IDX, T_IDX
@@ -49,112 +49,112 @@
/** L < R */ /** L < R */
OP_CODE_DECL (is_less_than, T_IDX_IDX, OP_CODE_DECL (is_less_than, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L <= R */ /** L <= R */
OP_CODE_DECL (is_less_or_equal, T_IDX_IDX, OP_CODE_DECL (is_less_or_equal, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L > R */ /** L > R */
OP_CODE_DECL (is_greater_than, T_IDX_IDX, OP_CODE_DECL (is_greater_than, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L >= R */ /** L >= R */
OP_CODE_DECL (is_greater_or_equal, T_IDX_IDX, OP_CODE_DECL (is_greater_or_equal, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L == R */ /** L == R */
OP_CODE_DECL (is_equal_value, T_IDX_IDX, OP_CODE_DECL (is_equal_value, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L != R */ /** L != R */
OP_CODE_DECL (is_not_equal_value, T_IDX_IDX, OP_CODE_DECL (is_not_equal_value, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L === R */ /** L === R */
OP_CODE_DECL (is_equal_value_type, T_IDX_IDX, OP_CODE_DECL (is_equal_value_type, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L !== R */ /** L !== R */
OP_CODE_DECL (is_not_equal_value_type, T_IDX_IDX, OP_CODE_DECL (is_not_equal_value_type, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** Instruction tests if BOOLEAN value is TRUE and JMP to DST */ /** Instruction tests if BOOLEAN value is TRUE and JMP to DST */
OP_CODE_DECL (is_true_jmp, T_IDX_IDX, OP_CODE_DECL (is_true_jmp, T_IDX_IDX,
value, value,
opcode); opcode)
/** Instruction tests if BOOLEAN value is FALSE and JMP to DST */ /** Instruction tests if BOOLEAN value is FALSE and JMP to DST */
OP_CODE_DECL (is_false_jmp, T_IDX_IDX, OP_CODE_DECL (is_false_jmp, T_IDX_IDX,
value, value,
opcode); opcode)
/** Unconditional JMP to the specified opcode index */ /** Unconditional JMP to the specified opcode index */
OP_CODE_DECL (jmp, T_IDX, OP_CODE_DECL (jmp, T_IDX,
opcode_idx); opcode_idx)
/** Unconditional JMP on opcode_count up */ /** Unconditional JMP on opcode_count up */
OP_CODE_DECL (jmp_up, T_IDX, OP_CODE_DECL (jmp_up, T_IDX,
opcode_count); opcode_count)
/** Unconditional JMP on opcode_count down */ /** Unconditional JMP on opcode_count down */
OP_CODE_DECL (jmp_down, T_IDX, OP_CODE_DECL (jmp_down, T_IDX,
opcode_count); opcode_count)
/** dst = L + R */ /** dst = L + R */
OP_CODE_DECL (addition, T_IDX_IDX_IDX, OP_CODE_DECL (addition, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L - R */ /** dst = L - R */
OP_CODE_DECL (substraction, T_IDX_IDX_IDX, OP_CODE_DECL (substraction, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L / R */ /** dst = L / R */
OP_CODE_DECL (division, T_IDX_IDX_IDX, OP_CODE_DECL (division, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L * R */ /** dst = L * R */
OP_CODE_DECL (multiplication, T_IDX_IDX_IDX, OP_CODE_DECL (multiplication, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L % R */ /** dst = L % R */
OP_CODE_DECL (remainder, T_IDX_IDX_IDX, OP_CODE_DECL (remainder, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L << R */ /** dst = L << R */
OP_CODE_DECL (b_shift_left, T_IDX_IDX_IDX, OP_CODE_DECL (b_shift_left, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L >> R */ /** dst = L >> R */
OP_CODE_DECL (b_shift_right, T_IDX_IDX_IDX, OP_CODE_DECL (b_shift_right, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L >>> R */ /** dst = L >>> R */
OP_CODE_DECL (b_shift_uright, T_IDX_IDX_IDX, OP_CODE_DECL (b_shift_uright, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
// Binary bitwise operators. // Binary bitwise operators.
// Operands is a set of 32 bits // 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, OP_CODE_DECL (b_and, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L | R */ /** dst = L | R */
OP_CODE_DECL (b_or, T_IDX_IDX_IDX, OP_CODE_DECL (b_or, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L ^ R */ /** dst = L ^ R */
OP_CODE_DECL (b_xor, T_IDX_IDX_IDX, OP_CODE_DECL (b_xor, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
// Binary logical operators. // Binary logical operators.
// Operands are booleans. // 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, OP_CODE_DECL (logical_and, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
/** dst = L || R */ /** dst = L || R */
OP_CODE_DECL (logical_or, T_IDX_IDX_IDX, OP_CODE_DECL (logical_or, T_IDX_IDX_IDX,
dst, dst,
var_left, var_left,
var_right); var_right)
// Assignment operators. // Assignment operators.
// Assign value to LEFT operand based on value of RIGHT operand. // 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 */ /** L = R */
OP_CODE_DECL (assignment, T_IDX_IDX, OP_CODE_DECL (assignment, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L *= R */ /** L *= R */
OP_CODE_DECL (assignment_multiplication, T_IDX_IDX, OP_CODE_DECL (assignment_multiplication, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L /= R */ /** L /= R */
OP_CODE_DECL (assignment_devision, T_IDX_IDX, OP_CODE_DECL (assignment_devision, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L %= R */ /** L %= R */
OP_CODE_DECL (assignment_remainder, T_IDX_IDX, OP_CODE_DECL (assignment_remainder, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L += R */ /** L += R */
OP_CODE_DECL (assignment_addition, T_IDX_IDX, OP_CODE_DECL (assignment_addition, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L -= R */ /** L -= R */
OP_CODE_DECL (assignment_substruction, T_IDX_IDX, OP_CODE_DECL (assignment_substruction, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L <<= R */ /** L <<= R */
OP_CODE_DECL (assignment_shift_left, T_IDX_IDX, OP_CODE_DECL (assignment_shift_left, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L >>= R */ /** L >>= R */
OP_CODE_DECL (assignment_shift_right, T_IDX_IDX, OP_CODE_DECL (assignment_shift_right, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L >>>= R */ /** L >>>= R */
OP_CODE_DECL (assignment_shift_uright, T_IDX_IDX, OP_CODE_DECL (assignment_shift_uright, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L &= R */ /** L &= R */
OP_CODE_DECL (assignment_b_and, T_IDX_IDX, OP_CODE_DECL (assignment_b_and, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L ^= R */ /** L ^= R */
OP_CODE_DECL (assignment_b_xor, T_IDX_IDX, OP_CODE_DECL (assignment_b_xor, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
/** L |= R */ /** L |= R */
OP_CODE_DECL (assignment_b_or, T_IDX_IDX, OP_CODE_DECL (assignment_b_or, T_IDX_IDX,
value_left, value_left,
value_right); value_right)
// Functions calls, declarations and argument handling // Functions calls, declarations and argument handling
/** name(arg1); */ /** name(arg1); */
OP_CODE_DECL (call_1, T_IDX_IDX, OP_CODE_DECL (call_1, T_IDX_IDX,
name_lit_idx, name_lit_idx,
arg1_lit_idx); arg1_lit_idx)
/** name(arg1, arg2); */ /** name(arg1, arg2); */
OP_CODE_DECL (call_2, T_IDX_IDX_IDX, OP_CODE_DECL (call_2, T_IDX_IDX_IDX,
name_lit_idx, name_lit_idx,
arg1_lit_idx, arg1_lit_idx,
arg2_lit_idx); arg2_lit_idx)
/** name(arg1, arg2, ... */ /** name(arg1, arg2, ... */
OP_CODE_DECL (call_n, T_IDX_IDX_IDX, OP_CODE_DECL (call_n, T_IDX_IDX_IDX,
name_lit_idx, name_lit_idx,
arg1_lit_idx, arg1_lit_idx,
arg2_lit_idx); arg2_lit_idx)
/** name(arg1); */ /** name(arg1); */
OP_CODE_DECL (func_decl_1, T_IDX_IDX, OP_CODE_DECL (func_decl_1, T_IDX_IDX,
name_lit_idx, name_lit_idx,
arg1_lit_idx); arg1_lit_idx)
/** name(arg1, arg2); */ /** name(arg1, arg2); */
OP_CODE_DECL (func_decl_2, T_IDX_IDX_IDX, OP_CODE_DECL (func_decl_2, T_IDX_IDX_IDX,
name_lit_idx, name_lit_idx,
arg1_lit_idx, arg1_lit_idx,
arg2_lit_idx); arg2_lit_idx)
/** name(arg1, arg2, ... */ /** name(arg1, arg2, ... */
OP_CODE_DECL (func_decl_n, T_IDX_IDX_IDX, OP_CODE_DECL (func_decl_n, T_IDX_IDX_IDX,
name_lit_idx, name_lit_idx,
arg1_lit_idx, arg1_lit_idx,
arg2_lit_idx); arg2_lit_idx)
/** ..., arg1, ... */ /** ..., arg1, ... */
OP_CODE_DECL (varg_1, T_IDX, OP_CODE_DECL (varg_1, T_IDX,
arg1_lit_idx); arg1_lit_idx)
/** ..., arg1); */ /** ..., arg1); */
OP_CODE_DECL (varg_1_end, T_IDX, OP_CODE_DECL (varg_1_end, T_IDX,
arg1_lit_idx); arg1_lit_idx)
/** ..., arg1, arg2, ... */ /** ..., arg1, arg2, ... */
OP_CODE_DECL (varg_2, T_IDX_IDX, OP_CODE_DECL (varg_2, T_IDX_IDX,
arg1_lit_idx, arg1_lit_idx,
arg2_lit_idx); arg2_lit_idx)
/** ..., arg1, arg2); */ /** ..., arg1, arg2); */
OP_CODE_DECL (varg_2_end, T_IDX_IDX, OP_CODE_DECL (varg_2_end, T_IDX_IDX,
arg1_lit_idx, arg1_lit_idx,
arg2_lit_idx); arg2_lit_idx)
/** arg1, arg2, arg3, ... */ /** arg1, arg2, arg3, ... */
OP_CODE_DECL (varg_3, T_IDX_IDX_IDX, OP_CODE_DECL (varg_3, T_IDX_IDX_IDX,
arg1_lit_idx, arg1_lit_idx,
arg2_lit_idx, arg2_lit_idx,
arg3_lit_idx); arg3_lit_idx)
/** arg1, arg2, arg3); */ /** arg1, arg2, arg3); */
OP_CODE_DECL (varg_3_end, T_IDX_IDX_IDX, OP_CODE_DECL (varg_3_end, T_IDX_IDX_IDX,
arg1_lit_idx, arg1_lit_idx,
arg2_lit_idx, arg2_lit_idx,
arg3_lit_idx); arg3_lit_idx)
/** return value; */ /** return value; */
OP_CODE_DECL (retval, T_IDX, OP_CODE_DECL (retval, T_IDX,
ret_value); ret_value)
OP_CODE_DECL_VOID (ret); OP_CODE_DECL_VOID (ret)
// LOOPS // LOOPS
// Lately, all loops should be translated into different JMPs in an optimizer. // 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 /** End of body of infinite loop should be ended with unconditional JMP
* to loop_root (ie. next op after loop condition) */ * to loop_root (ie. next op after loop condition) */
OP_CODE_DECL (loop_inf, T_IDX, OP_CODE_DECL (loop_inf, T_IDX,
loop_root); loop_root)
/** Numeric loop initialization. /** Numeric loop initialization.
* for (start,stop,step) * 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, OP_CODE_DECL (loop_init_num, T_IDX_IDX_IDX,
start, start,
stop, stop,
step); step)
/** Check loop (condition). /** Check loop (condition).
* if (loop cond is true) * 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, OP_CODE_DECL (loop_precond_begin_num, T_IDX_IDX,
condition, condition,
after_loop_op); after_loop_op)
/** i++; /** i++;
* Increment iterator on step and JMP to PRECOND * 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, OP_CODE_DECL (loop_precond_end_num, T_IDX_IDX_IDX,
iterator, iterator,
step, step,
precond_begin); precond_begin)
/** do {...} while (cond); /** do {...} while (cond);
* If condition is true, JMP to BODY_ROOT * If condition is true, JMP to BODY_ROOT
*/ */
OP_CODE_DECL (loop_postcond, T_IDX_IDX, OP_CODE_DECL (loop_postcond, T_IDX_IDX,
condition, condition,
body_root); body_root)
///** for vars...in iter, state, ctl */ ///** for vars...in iter, state, ctl */
//OP_CODE_DECL (loop_init, T_IDX_IDX_IDX, //OP_CODE_DECL (loop_init, T_IDX_IDX_IDX,
// start_idx, stop_idx, step_idx); // start_idx, stop_idx, step_idx)
///** loop (condition) */ ///** loop (condition) */
//OP_CODE_DECL (loop_cond_pre_begin, T_IDX_IDX, //OP_CODE_DECL (loop_cond_pre_begin, T_IDX_IDX,
// condition, body_root); // condition, body_root)
///** i++;*/ ///** i++;*/
//OP_CODE_DECL (loop_cond_pre_end, T_IDX, //OP_CODE_DECL (loop_cond_pre_end, T_IDX,
// iterator, body_root); // iterator, body_root)
// Property accessors (array, objects, strings) // Property accessors (array, objects, strings)
/** Array ops for ILMIR*/ /** Array ops for ILMIR*/
//OP_CODE_DECL (array_copy, T_IDX_IDX, /** L = R */ //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 */ //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] */ //OP_CODE_DECL (array_get, T_IDX_IDX_IDX, /** dst = array[index] */
// dst, array, index); // dst, array, index)
//// TODO //// TODO
// Variable declarations // Variable declaration
OP_CODE_DECL (decl_var, T_IDX,
variable)
// TODO New constructor // TODO New constructor
#endif /* OPCODE_STRUCTURES_H */ #endif /* OPCODE_STRUCTURES_H */
+54 -54
View File
@@ -23,60 +23,60 @@ save_op_data (int pos, OPCODE opdata)
__program[pos] = opdata; __program[pos] = opdata;
} }
void opfunc_loop_init_num (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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_loop_postcond (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_call_2 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_call_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_call_n (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_call_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_func_decl_1 (OPCODE opdata, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_func_decl_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_varg_1 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_varg_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_varg_1_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_varg_1_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_varg_2 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_varg_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_varg_2_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_varg_2_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_varg_3 (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_varg_3 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_varg_3_end (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_varg_3_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_retval (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_retval (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_ret (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_ret (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_assignment (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_assignment (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_assignment_multiplication (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_assignment_multiplication (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_assignment_devision (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_assignment_devision (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_assignment_remainder (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_assignment_remainder (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_assignment_addition (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_assignment_addition (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_assignment_substruction (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_assignment_substruction (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_assignment_shift_left (OPCODE opdata, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_assignment_b_or (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_logical_and (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_logical_and (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_logical_or (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_logical_or (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_b_and (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_b_and (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_b_or (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_b_or (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_b_xor (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_b_xor (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_b_shift_left (OPCODE opdata, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_b_shift_uright (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_addition (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_addition (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_substraction (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_substraction (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_division (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_division (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_multiplication (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_multiplication (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_remainder (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_remainder (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_jmp_up (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_jmp_up (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_jmp_down (OPCODE opdata, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_jmp_down (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void opfunc_is_true_jmp (OPCODE opdata, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { 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, struct __int_data *int_data) { JERRY_UNREACHABLE (); } void opfunc_is_not_equal_value_type (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
void void
opfunc_loop_inf (OPCODE opdata, struct __int_data *int_data) opfunc_loop_inf (OPCODE opdata, struct __int_data *int_data)
+1 -1
View File
@@ -30,4 +30,4 @@ void led_on(int led_id)
void led_off(int led_id) void led_off(int led_id)
{ {
printf("led_off: %d", led_id); printf("led_off: %d", led_id);
} }
+2
View File
@@ -82,5 +82,7 @@ main( int __unused argc,
} }
} }
mem_HeapPrint( false);
return 0; return 0;
} /* main */ } /* main */
+24 -1
View File
@@ -36,7 +36,7 @@ const size_t test_heap_size = 8 * 1024;
const uint32_t test_iters = 16384; const uint32_t test_iters = 16384;
// Subiterations count // Subiterations count
const uint32_t test_max_sub_iters = 64; const uint32_t test_max_sub_iters = 32;
int int
main( int __unused argc, 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; return 0;
} /* main */ } /* main */