From efdc06996bbe6d3dd21933f2ddf8986247c869ae Mon Sep 17 00:00:00 2001 From: Zoltan Herczeg Date: Wed, 31 May 2017 08:53:53 +0200 Subject: [PATCH] Improve instance management in JerryScript. (#1849) JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com --- jerry-core/api/jerry.c | 56 +++++++++++++++++---------- jerry-core/include/jerryscript-port.h | 8 ++-- jerry-core/jcontext/jcontext.h | 51 +++++++++++++----------- 3 files changed, 69 insertions(+), 46 deletions(-) diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c index 26059fbe7..466797289 100644 --- a/jerry-core/api/jerry.c +++ b/jerry-core/api/jerry.c @@ -2272,44 +2272,62 @@ jerry_create_instance (uint32_t heap_size, /**< the size of heap */ jerry_instance_alloc_t alloc, /**< the alloc function */ void *cb_data_p) /**< the cb_data for alloc function */ { + JERRY_UNUSED (heap_size); + #ifdef JERRY_ENABLE_EXTERNAL_CONTEXT - uint32_t lcache_size = 0; - -#ifndef CONFIG_ECMA_LCACHE_DISABLE - lcache_size = sizeof (jerry_hash_table_t); -#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ - - uint32_t alloc_size = (uint32_t) (sizeof (jerry_instance_t) + lcache_size); + size_t total_size = sizeof (jerry_instance_t) + JMEM_ALIGNMENT; #ifndef JERRY_SYSTEM_ALLOCATOR - alloc_size = alloc_size + heap_size + JMEM_ALIGNMENT - 1; + heap_size = JERRY_ALIGNUP (heap_size, JMEM_ALIGNMENT); + + /* Minimum heap size is 1Kbyte. */ + if (heap_size < 1024) + { + return NULL; + } + + total_size += heap_size; #endif /* !JERRY_SYSTEM_ALLOCATOR */ - jerry_instance_t *instance_p = (jerry_instance_t *) alloc (alloc_size, cb_data_p); - memset (instance_p, 0, alloc_size); +#ifndef CONFIG_ECMA_LCACHE_DISABLE + total_size += sizeof (jerry_hash_table_t); +#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ + + total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT); + + jerry_instance_t *instance_p = (jerry_instance_t *) alloc (total_size, cb_data_p); if (instance_p == NULL) { return NULL; } - instance_p->heap_size = heap_size; - instance_p->lcache_p = instance_p->buffer; + memset (instance_p, 0, total_size); + + uintptr_t instance_ptr = ((uintptr_t) instance_p) + sizeof (jerry_instance_t); + instance_ptr = JERRY_ALIGNUP (instance_ptr, (uintptr_t) JMEM_ALIGNMENT); + + uint8_t *byte_p = (uint8_t *) instance_ptr; #ifndef JERRY_SYSTEM_ALLOCATOR - uint8_t *unaligned_heap_p = instance_p->lcache_p + lcache_size; - uintptr_t alignment_mask = ~(uintptr_t) (JMEM_ALIGNMENT - 1); - instance_p->heap_p = (uint8_t *) (((uintptr_t) unaligned_heap_p + JMEM_ALIGNMENT - 1) & alignment_mask); - - JERRY_ASSERT (((uintptr_t) instance_p->heap_p & (uintptr_t) (JMEM_ALIGNMENT - 1)) == 0); + instance_p->heap_p = (jmem_heap_t *) byte_p; + instance_p->heap_size = heap_size; + byte_p += heap_size; #endif /* !JERRY_SYSTEM_ALLOCATOR */ +#ifndef CONFIG_ECMA_LCACHE_DISABLE + instance_p->lcache_p = byte_p; + byte_p += sizeof (jerry_hash_table_t); +#endif /* !JERRY_SYSTEM_ALLOCATOR */ + + JERRY_ASSERT (byte_p <= ((uint8_t *) instance_p) + total_size); + + JERRY_UNUSED (byte_p); return instance_p; #else /* !JERRY_ENABLE_EXTERNAL_CONTEXT */ - JERRY_UNUSED (heap_size); JERRY_UNUSED (alloc); JERRY_UNUSED (cb_data_p); @@ -2318,8 +2336,6 @@ jerry_create_instance (uint32_t heap_size, /**< the size of heap */ #endif /* JERRY_ENABLE_EXTERNAL_CONTEXT */ } /* jerry_create_instance */ - - /** * If JERRY_VM_EXEC_STOP is defined the callback passed to this function is * periodically called with the user_p argument. If frequency is greater diff --git a/jerry-core/include/jerryscript-port.h b/jerry-core/include/jerryscript-port.h index d4e4842bc..f15db6d68 100644 --- a/jerry-core/include/jerryscript-port.h +++ b/jerry-core/include/jerryscript-port.h @@ -127,12 +127,12 @@ bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p); double jerry_port_get_current_time (void); /** - * Get the current instance, which contains the current context, heap and other infomation. - * Each port should provide its own implementation of this interface. + * Get the current instance which contains the current context, heap and other + * structures. Each port should provide its own implementation of this interface. * *Note: - * This port function will be called automatically by jerry-core - * wnen JERRY_ENABLE_EXTERNAL_CONTEXT is defined. If not, this function will never be called. + * This port function is called by jerry-core when JERRY_ENABLE_EXTERNAL_CONTEXT + * is defined. Otherwise this function is not used. * * @return the pointer to the jerry instance. */ diff --git a/jerry-core/jcontext/jcontext.h b/jerry-core/jcontext/jcontext.h index 1a03b604f..1f6317382 100644 --- a/jerry-core/jcontext/jcontext.h +++ b/jerry-core/jcontext/jcontext.h @@ -133,22 +133,6 @@ typedef struct #endif /* JERRY_VALGRIND_FREYA */ } jerry_context_t; -/** - * Description of jerry instance, which contains the meta data and buffer. - */ -struct jerry_instance_t -{ - uint32_t heap_size; /**< size of the heap */ -#ifndef JERRY_SYSTEM_ALLOCATOR - uint8_t *heap_p; /**< point to the entrance of the heap in buffer */ -#endif /* !JERRY_SYSTEM_ALLOCATOR */ -#ifndef CONFIG_ECMA_LCACHE_DISABLE - uint8_t *lcache_p; /**< point to the entrance of the lcache in buffer */ -#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ - jerry_context_t context; /**< the context of the instance */ - uint8_t buffer[]; /**< the flexible array for storing context, heap and lcache */ -}; - #ifndef CONFIG_ECMA_LCACHE_DISABLE /** * Hash table for caching the last access of properties. @@ -161,24 +145,47 @@ typedef struct #ifdef JERRY_ENABLE_EXTERNAL_CONTEXT +#ifndef JERRY_GET_CURRENT_INSTANCE + +/** + * Default function if JERRY_GET_CURRENT_INSTANCE is not defined. + */ +#define JERRY_GET_CURRENT_INSTANCE() (jerry_port_get_current_instance ()) + +#endif /* !JERRY_GET_CURRENT_INSTANCE */ + /** * This part is for Jerry which enable external context. */ - typedef struct { jmem_heap_free_t first; /**< first node in free region list */ uint8_t area[]; /**< heap area */ } jmem_heap_t; -#define JERRY_CONTEXT(field) (jerry_port_get_current_instance ()->context.field) +/** + * Description of jerry instance which is the header of the context space. + */ +struct jerry_instance_t +{ + jerry_context_t context; /**< the context of the instance */ +#ifndef JERRY_SYSTEM_ALLOCATOR + jmem_heap_t *heap_p; /**< point to the heap aligned to JMEM_ALIGNMENT. */ + uint32_t heap_size; /**< size of the heap */ +#endif +#ifndef CONFIG_ECMA_LCACHE_DISABLE + uint8_t *lcache_p; /**< point to the entrance of the lcache in buffer */ +#endif /* !CONFIG_ECMA_LCACHE_DISABLE */ +}; + +#define JERRY_CONTEXT(field) (JERRY_GET_CURRENT_INSTANCE ()->context.field) #ifndef JERRY_SYSTEM_ALLOCATOR static inline jmem_heap_t * __attr_always_inline___ jerry_context_get_current_heap (void) { - return (jmem_heap_t *) (jerry_port_get_current_instance ()->heap_p); + return JERRY_GET_CURRENT_INSTANCE ()->heap_p; } /* jerry_context_get_current_heap */ #define JERRY_HEAP_CONTEXT(field) (jerry_context_get_current_heap ()->field) @@ -187,9 +194,9 @@ jerry_context_get_current_heap (void) #error "JMEM_HEAP_SIZE must not be defined if JERRY_ENABLE_EXTERNAL_CONTEXT is defined" #endif /* JMEM_HEAP_SIZE */ -#define JMEM_HEAP_SIZE (jerry_port_get_current_instance ()->heap_size) +#define JMEM_HEAP_SIZE (JERRY_GET_CURRENT_INSTANCE ()->heap_size) -#define JMEM_HEAP_AREA_SIZE (jerry_port_get_current_instance ()->heap_size - JMEM_ALIGNMENT) +#define JMEM_HEAP_AREA_SIZE (JERRY_GET_CURRENT_INSTANCE ()->heap_size - JMEM_ALIGNMENT) #endif /* !JERRY_SYSTEM_ALLOCATOR */ @@ -198,7 +205,7 @@ jerry_context_get_current_heap (void) static inline jerry_hash_table_t * __attr_always_inline___ jerry_context_get_current_lcache (void) { - return (jerry_hash_table_t *) (jerry_port_get_current_instance ()->lcache_p); + return (jerry_hash_table_t *) (JERRY_GET_CURRENT_INSTANCE ()->lcache_p); } /* jerry_context_get_current_lcache */ #define JERRY_HASH_TABLE_CONTEXT(field) (jerry_context_get_current_lcache ()->field)