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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user