Support external context, heap and lcache (#1778)

JerryScript should support external context, heap and lcache,
so that it can have multiple instances and runtime configurable heap
size.

Related issue: 1746

JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang zidong.jiang@intel.com
This commit is contained in:
Zidong Jiang
2017-05-20 11:00:19 +08:00
committed by GitHub
parent c6d890ee13
commit 5e28bfc28a
16 changed files with 319 additions and 21 deletions
+11
View File
@@ -21,6 +21,7 @@ set(FEATURE_CPOINTER_32_BIT OFF CACHE BOOL "Enable 32 bit compressed poin
set(FEATURE_DEBUGGER OFF CACHE BOOL "Enable JerryScript debugger?")
set(FEATURE_DEBUGGER_PORT "5001" CACHE STRING "Set debugger port number (default: 5001)")
set(FEATURE_ERROR_MESSAGES OFF CACHE BOOL "Enable error messages?")
set(FEATURE_EXTERNAL_CONTEXT OFF CACHE BOOL "Enable external context?")
set(FEATURE_JS_PARSER ON CACHE BOOL "Enable js-parser?")
set(FEATURE_MEM_STATS OFF CACHE BOOL "Enable memory statistics?")
set(FEATURE_MEM_STRESS_TEST OFF CACHE BOOL "Enable mem-stress test?")
@@ -44,6 +45,7 @@ message(STATUS "FEATURE_CPOINTER_32_BIT " ${FEATURE_CPOINTER_32_BIT})
message(STATUS "FEATURE_DEBUGGER " ${FEATURE_DEBUGGER})
message(STATUS "FEATURE_DEBUGGER_PORT " ${FEATURE_DEBUGGER_PORT})
message(STATUS "FEATURE_ERROR_MESSAGES " ${FEATURE_ERROR_MESSAGES})
message(STATUS "FEATURE_EXTERNAL_CONTEXT " ${FEATURE_EXTERNAL_CONTEXT})
message(STATUS "FEATURE_JS_PARSER " ${FEATURE_JS_PARSER})
message(STATUS "FEATURE_MEM_STATS " ${FEATURE_MEM_STATS})
message(STATUS "FEATURE_MEM_STRESS_TEST " ${FEATURE_MEM_STRESS_TEST})
@@ -154,6 +156,11 @@ if(FEATURE_ERROR_MESSAGES)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_ERROR_MESSAGES)
endif()
# Use external context instead of static one
if(FEATURE_EXTERNAL_CONTEXT)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_EXTERNAL_CONTEXT)
endif()
# JS-Parser
if(FEATURE_JS_PARSER)
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_JS_PARSER=1)
@@ -210,6 +217,10 @@ if(JERRY_LIBC AND FEATURE_DEBUGGER)
MESSAGE(FATAL_ERROR "This configuration is not supported. Please build against your system libc to enable the JerryScript debugger.")
endif()
if(JERRY_LIBC AND FEATURE_SYSTEM_ALLOCATOR)
MESSAGE(FATAL_ERROR "This configuration is not supported. Please build against your system libc to enable the system allocator.")
endif()
# RegExp byte-code dumps
if(FEATURE_REGEXP_DUMP)
set(DEFINES_JERRY ${DEFINES_JERRY} REGEXP_DUMP_BYTE_CODE)
+58
View File
@@ -2248,6 +2248,64 @@ jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string
(lit_utf8_size_t) buf_size);
} /* jerry_is_valid_cesu8_string */
/*
* Create a jerry instance for external context.
*
* @return the pointer to the instance.
*/
jerry_instance_t *
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 */
{
#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);
#ifndef JERRY_SYSTEM_ALLOCATOR
alloc_size = alloc_size + heap_size + JMEM_ALIGNMENT - 1;
#endif /* !JERRY_SYSTEM_ALLOCATOR */
jerry_instance_t *instance_p = (jerry_instance_t *) alloc (alloc_size, cb_data_p);
memset (instance_p, 0, alloc_size);
if (instance_p == NULL)
{
return NULL;
}
instance_p->heap_size = heap_size;
instance_p->lcache_p = instance_p->buffer;
#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);
#endif /* !JERRY_SYSTEM_ALLOCATOR */
return instance_p;
#else /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
JERRY_UNUSED (heap_size);
JERRY_UNUSED (alloc);
JERRY_UNUSED (cb_data_p);
return NULL;
#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
+1 -1
View File
@@ -98,7 +98,7 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
size_t row_index = ecma_lcache_row_index (object_cp, name_hash);
ecma_lcache_hash_entry_t *entries_p = JERRY_HASH_TABLE_CONTEXT (table)[row_index];
int32_t entry_index;
uint32_t entry_index;
for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
{
if (entries_p[entry_index].object_cp == ECMA_NULL_POINTER)
+15
View File
@@ -205,6 +205,11 @@ typedef void *(*jerry_user_context_init_t) (void);
*/
typedef void (*jerry_user_context_deinit_t) (void *user_context_p);
/**
* Function type for allocating buffer for JerryScript instance.
*/
typedef void *(*jerry_instance_alloc_t) (size_t size, void *cb_data_p);
/**
* Type information of a native pointer.
*/
@@ -213,6 +218,11 @@ typedef struct
jerry_object_native_free_callback_t free_cb; /**< the free callback of the native pointer */
} jerry_object_native_info_t;
/**
* A forward declaration of the JerryScript instance structure.
*/
typedef struct jerry_instance_t jerry_instance_t;
/**
* General engine functions.
*/
@@ -403,6 +413,11 @@ jerry_value_t jerry_resolve_or_reject_promise (jerry_value_t promise, jerry_valu
bool jerry_is_valid_utf8_string (const jerry_char_t *utf8_buf_p, jerry_size_t buf_size);
bool jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, jerry_size_t buf_size);
/*
* External context functions.
*/
jerry_instance_t *jerry_create_instance (uint32_t heap_size, jerry_instance_alloc_t alloc, void *cb_data_p);
/**
* Miscellaneous functions.
*/
+12
View File
@@ -126,6 +126,18 @@ 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.
*
*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.
*
* @return the pointer to the jerry instance.
*/
struct jerry_instance_t *jerry_port_get_current_instance (void);
/**
* @}
*/
+2
View File
@@ -19,6 +19,7 @@
* @{
*/
#ifndef JERRY_ENABLE_EXTERNAL_CONTEXT
/**
* Global context.
*/
@@ -48,6 +49,7 @@ jmem_heap_t jerry_global_heap __attribute__ ((aligned (JMEM_ALIGNMENT))) JERRY_G
jerry_hash_table_t jerry_global_hash_table;
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
#endif /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
/**
* @}
+82 -15
View File
@@ -21,6 +21,7 @@
#include "ecma-builtins.h"
#include "ecma-jobqueue.h"
#include "jerryscript-port.h"
#include "jerry-debugger.h"
#include "jmem.h"
#include "re-bytecode.h"
@@ -120,6 +121,84 @@ 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.
*/
typedef struct
{
ecma_lcache_hash_entry_t table[ECMA_LCACHE_HASH_ROWS_COUNT][ECMA_LCACHE_HASH_ROW_LENGTH];
} jerry_hash_table_t;
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
#ifdef JERRY_ENABLE_EXTERNAL_CONTEXT
/**
* 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)
#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);
} /* jerry_context_get_current_heap */
#define JERRY_HEAP_CONTEXT(field) (jerry_context_get_current_heap ()->field)
#ifdef JMEM_HEAP_SIZE
#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_AREA_SIZE (jerry_port_get_current_instance ()->heap_size - JMEM_ALIGNMENT)
#endif /* !JERRY_SYSTEM_ALLOCATOR */
#ifndef CONFIG_ECMA_LCACHE_DISABLE
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);
} /* jerry_context_get_current_lcache */
#define JERRY_HASH_TABLE_CONTEXT(field) (jerry_context_get_current_lcache ()->field)
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
#else /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
/**
* This part is for Jerry which use default context.
*/
/**
* Calculate heap area size, leaving space for a pointer to the free list
*/
@@ -143,21 +222,6 @@ typedef struct
uint8_t area[JMEM_HEAP_AREA_SIZE]; /**< heap area */
} jmem_heap_t;
#ifndef CONFIG_ECMA_LCACHE_DISABLE
/**
* JerryScript global hash table for caching the last access of properties.
*/
typedef struct
{
/**
* Hash table
*/
ecma_lcache_hash_entry_t table[ECMA_LCACHE_HASH_ROWS_COUNT][ECMA_LCACHE_HASH_ROW_LENGTH];
} jerry_hash_table_t;
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
/**
* Global context.
*/
@@ -189,6 +253,7 @@ extern jerry_hash_table_t jerry_global_hash_table;
* Provides a reference to the area field of the heap.
*/
#define JERRY_HEAP_CONTEXT(field) (jerry_global_heap.field)
#endif /* !JERRY_SYSTEM_ALLOCATOR */
#ifndef CONFIG_ECMA_LCACHE_DISABLE
@@ -200,6 +265,8 @@ extern jerry_hash_table_t jerry_global_hash_table;
#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
#endif /* JERRY_ENABLE_EXTERNAL_CONTEXT */
/**
* @}
*/
+5 -3
View File
@@ -103,11 +103,13 @@ jmem_heap_get_region_end (jmem_heap_free_t *curr_p) /**< current region */
} /* jmem_heap_get_region_end */
#endif /* !JERRY_SYSTEM_ALLOCATOR */
#ifndef JERRY_ENABLE_EXTERNAL_CONTEXT
/**
* Check size of heap is corresponding to configuration
*/
JERRY_STATIC_ASSERT (sizeof (jmem_heap_t) <= JMEM_HEAP_SIZE,
size_of_mem_heap_must_be_less_than_or_equal_to_MEM_HEAP_SIZE);
#endif /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
#ifdef JMEM_STATS
@@ -148,8 +150,8 @@ void
jmem_heap_init (void)
{
#ifndef JERRY_CPOINTER_32_BIT
JERRY_STATIC_ASSERT (((UINT16_MAX + 1) << JMEM_ALIGNMENT_LOG) >= JMEM_HEAP_SIZE,
maximum_heap_size_for_16_bit_compressed_pointers_is_512K);
/* the maximum heap size for 16bit compressed pointers should be 512K */
JERRY_ASSERT (((UINT16_MAX + 1) << JMEM_ALIGNMENT_LOG) >= JMEM_HEAP_SIZE);
#endif /* !JERRY_CPOINTER_32_BIT */
#ifndef JERRY_SYSTEM_ALLOCATOR
@@ -181,7 +183,7 @@ jmem_heap_finalize (void)
{
JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_allocated_size) == 0);
#ifndef JERRY_SYSTEM_ALLOCATOR
VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_t));
VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), JMEM_HEAP_SIZE);
#endif /* !JERRY_SYSTEM_ALLOCATOR */
} /* jmem_heap_finalize */
+2
View File
@@ -25,10 +25,12 @@
* @{
*/
#ifndef JERRY_ENABLE_EXTERNAL_CONTEXT
/**
* Size of heap
*/
#define JMEM_HEAP_SIZE ((size_t) (CONFIG_MEM_HEAP_AREA_SIZE))
#endif /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
/**
* Logarithm of required alignment for allocated units/blocks