forked from jerryscript-project/jerryscript
-
Notifications
You must be signed in to change notification settings - Fork 0
Design primitive layout
Yonggang Luo edited this page Nov 28, 2024
·
19 revisions
- Optimize
lit_is_utf8_string_pair_magic
by suffix-array - Optimize
ecma_string_t
with quickjs atom like things
#include <assert.h>
#include <stdint.h>
#if defined(JERRY_CPOINTER_64_BIT) && defined(JERRY_CPOINTER_32_BIT)
#error "Do not define JERRY_CPOINTER_64_BIT JERRY_CPOINTER_32_BIT at the same time"
#endif /* defined(JERRY_CPOINTER_64_BIT) && defined(JERRY_CPOINTER_32_BIT) */
#if defined(JERRY_CPOINTER_64_BIT) && defined(JERRY_CPOINTER_16_BIT)
#error "Do not define JERRY_CPOINTER_64_BIT JERRY_CPOINTER_16_BIT at the same time"
#endif /* defined(JERRY_CPOINTER_64_BIT) && defined(JERRY_CPOINTER_16_BIT) */
#if defined(JERRY_CPOINTER_32_BIT) && defined(JERRY_CPOINTER_16_BIT)
#error "Do not define JERRY_CPOINTER_32_BIT JERRY_CPOINTER_16_BIT at the same time"
#endif /* defined(JERRY_CPOINTER_32_BIT) && defined(JERRY_CPOINTER_16_BIT) */
#if 0
#define JERRY_CPOINTER_64_BIT 1
#define JERRY_CPOINTER_32_BIT 1
#define JERRY_CPOINTER_16_BIT 1
#endif
#if !defined(JERRY_CPOINTER_64_BIT) && !defined(JERRY_CPOINTER_32_BIT) && !defined(JERRY_CPOINTER_16_BIT)
#define JERRY_CPOINTER_16_BIT 1
#endif /* !defined(JERRY_CPOINTER_64_BIT) && !defined(JERRY_CPOINTER_32_BIT) && !defined(JERRY_CPOINTER_16_BIT) */
#ifndef JERRY_CPOINTER_64_BIT
#define JERRY_CPOINTER_64_BIT 0
#endif /* JERRY_CPOINTER_64_BIT */
#ifndef JERRY_CPOINTER_32_BIT
#define JERRY_CPOINTER_32_BIT 0
#endif /* JERRY_CPOINTER_32_BIT */
#ifndef JERRY_CPOINTER_16_BIT
#define JERRY_CPOINTER_16_BIT 0
#endif /* JERRY_CPOINTER_16_BIT */
#if JERRY_CPOINTER_64_BIT && UINTPTR_MAX <= UINT32_MAX
#warning "Do not support JERRY_CPOINTER_64_BIT on 32bit system"
#endif /* JERRY_CPOINTER_64_BIT && UINTPTR_MAX <= UINT32_MAX */
#if (JERRY_CPOINTER_64_BIT + JERRY_CPOINTER_32_BIT + JERRY_CPOINTER_16_BIT) == 0
#error "One of JERRY_CPOINTER_64_BIT, JERRY_CPOINTER_32_BIT, JERRY_CPOINTER_16_BIT should be defined"
#endif /* (JERRY_CPOINTER_64_BIT + JERRY_CPOINTER_32_BIT + JERRY_CPOINTER_16_BIT) == 0 */
#if JERRY_CPOINTER_64_BIT
typedef uint64_t jerry_uintptr_t;
#define JERRY_UINTPTR_MAX UINT64_MAX
#elif JERRY_CPOINTER_32_BIT
typedef uint32_t jerry_uintptr_t;
#define JERRY_UINTPTR_MAX UINT32_MAX
#elif JERRY_CPOINTER_16_BIT
typedef uint16_t jerry_uintptr_t;
#define JERRY_UINTPTR_MAX UINT16_MAX
#endif /* JERRY_CPOINTER_64_BIT */
#if JERRY_CPOINTER_16_BIT
typedef uint16_t lit_string_hash_t;
typedef uint16_t ecma_tag_t;
#else /* !JERRY_CPOINTER_16_BIT */
typedef uint32_t lit_string_hash_t;
typedef uint32_t ecma_tag_t;
#endif /* JERRY_CPOINTER_16_BIT */
#if JERRY_CPOINTER_16_BIT
#define ECMA_STRING_CONTAINER_SHORT_ASCII_PADDING 5
#else
#define ECMA_STRING_CONTAINER_SHORT_ASCII_PADDING 3
#endif /* JERRY_CPOINTER_16_BIT */
#define ECMA_STRING_CONTAINER_SHORT_UTF16_PADDING 2
#define ECMA_STRING_CONTAINER_SHORT_ASCII_LIMIT (ECMA_STRING_CONTAINER_SHORT_ASCII_PADDING + 8)
#define ECMA_STRING_CONTAINER_SHORT_UTF16_LIMIT (ECMA_STRING_CONTAINER_SHORT_UTF16_PADDING + 4)
typedef enum
{
/**
* actual data is on the heap
* ASCII string: 0 <= size < ECMA_STRING_CONTAINER_SHORT_ASCII_LIMIT
* UTF16 string: 0 < size < ECMA_STRING_CONTAINER_SHORT_UTF16_LIMIT
*/
ECMA_STRING_CONTAINER_SHORT,
/**
* actual data is on the heap
* ASCII string: ECMA_STRING_CONTAINER_SHORT_ASCII_LIMIT <= size
* UTF16 string: ECMA_STRING_CONTAINER_SHORT_UTF16_LIMIT <= size
* the upper limit of size is depends on the sizeof jerry_uintptr_t
*/
ECMA_STRING_CONTAINER_NORMAL,
ECMA_STRING_CONTAINER_EXTERNAL, /**< any size, ASCII/UTF16 string, actual data is allocated by external */
} ecma_string_container_t;
typedef struct
{
ecma_tag_t type : 2; /**< ecma_string_container_t */
ecma_tag_t ascii : 1; /**< 1 means ASCII string */
#if JERRY_CPOINTER_16_BIT
ecma_tag_t refs : 13; /**< 13 / 29 bit (max 8190 / 536870910) */
#else
ecma_tag_t refs : 29;
#endif
} ecma_string_t;
#if JERRY_CPOINTER_16_BIT
static_assert (sizeof (ecma_string_t) == 2, "");
#else
static_assert (sizeof (ecma_string_t) == 4, "");
#endif
/**
* Actual data of ecma_string_t depending on `tag::type:ecma_string_container_t` and `tag::ascii` field)
* the allocated size for ecma_string_short_t could be 8 or 16
*/
typedef struct
{
ecma_string_t tag;
union
{
lit_string_hash_t hash;
struct
{
#if JERRY_CPOINTER_16_BIT
/* The cobmine size,hash_partial,str[0..0] is hash */
uint8_t size : 3;
uint8_t hash_partial : 5;
#else
/* The size,str[0..2] is hash */
uint8_t size;
#endif
uint8_t str[ECMA_STRING_CONTAINER_SHORT_ASCII_PADDING];
} ascii;
struct
{
/* The content of str[0..0] or str[0..1] is hash */
/* size always be 1 */
uint16_t str[ECMA_STRING_CONTAINER_SHORT_UTF16_PADDING];
} utf16;
} u;
} ecma_string_short_t;
static_assert (sizeof (ecma_string_short_t) == 8, "");
#if JERRY_CPOINTER_64_BIT
#define ECMA_STRING_CONTAINER_NORMAL_ASCII_PADDING 8
#define ECMA_STRING_CONTAINER_NORMAL_UTF16_PADDING 4
#elif JERRY_CPOINTER_32_BIT
#define ECMA_STRING_CONTAINER_NORMAL_ASCII_PADDING 12
#define ECMA_STRING_CONTAINER_NORMAL_UTF16_PADDING 6
#elif JERRY_CPOINTER_16_BIT
#define ECMA_STRING_CONTAINER_NORMAL_ASCII_PADDING 18
#define ECMA_STRING_CONTAINER_NORMAL_UTF16_PADDING 9
#endif /* JERRY_CPOINTER_64_BIT */
/**
* Actual data of ecma_string_t depending on `tag::type:ecma_string_container_t` and `tag::ascii` field)
*/
typedef struct
{
ecma_string_t tag;
lit_string_hash_t hash;
jerry_uintptr_t size;
union
{
uint16_t utf16[ECMA_STRING_CONTAINER_NORMAL_UTF16_PADDING];
uint8_t ascii[ECMA_STRING_CONTAINER_NORMAL_ASCII_PADDING];
} u;
} ecma_string_normal_t;
static_assert (sizeof (ecma_string_normal_t) == 24, "");
typedef struct
{
union
{
uint8_t *ascii;
uint16_t *utf16;
} u;
void *user_p; /**< user pointer passed to the callback when the string is freed */
} ecma_external_string_body_t;
/**
* Actual data of ecma_string_t depending on `tag::type:ecma_string_container_t` and `tag::ascii` field)
*/
typedef struct
{
ecma_string_t tag;
lit_string_hash_t hash;
#if JERRY_CPOINTER_16_BIT
uint32_t size;
#else
uint64_t size;
#endif
ecma_external_string_body_t body;
} ecma_external_string_t;
#if JERRY_CPOINTER_16_BIT
#if UINTPTR_MAX > UINT32_MAX
static_assert (sizeof (ecma_external_string_t) == 24, "");
#else
static_assert (sizeof (ecma_external_string_t) == 16, "");
#endif
#elif JERRY_CPOINTER_32_BIT
#if UINTPTR_MAX > UINT32_MAX
static_assert (sizeof (ecma_external_string_t) == 32, "");
#else
static_assert (sizeof (ecma_external_string_t) == 24, "");
#endif
#elif JERRY_CPOINTER_64_BIT
static_assert (sizeof (ecma_external_string_t) == 32, "");
#else
static_assert (false, "CPOINTER is not configured");
#endif
typedef struct
{
void *origin;
uint8_t *str;
uint64_t len;
} ecma_string_tracked_utf8_t;
typedef struct
{
void *origin;
uint8_t *str;
uint64_t len;
} ecma_string_tracked_cesu8_t;
typedef struct
{
void *origin;
uint16_t *str;
uint64_t len;
} ecma_string_tracked_utf16_t;
typedef enum
{
ECMA_ATOM_TYPE_SYMBOL,
ECMA_ATOM_TYPE_GLOBAL_SYMBOL,
ECMA_ATOM_TYPE_STRING,
ECMA_ATOM_TYPE_PRIVATE
} ecma_atom_type_t;
typedef struct
{
ecma_string_t *str;
union
{
struct
{
uint32_t type : 3; /* ecma_atom_type_t */
uint32_t next_index : 29;
} tag;
uint32_t value;
} u;
} ecma_atom_hash_entry_t;
typedef uint32_t ecma_atom_value_t;
typedef union
{
struct
{
uint32_t is_string : 1;
uint32_t padding : 31;
} tag;
struct
{
uint32_t is_string : 1;
uint32_t value : 31;
} i;
struct
{
uint32_t is_string : 1;
uint32_t type : 2; /* ecma_atom_type_t */
uint32_t index : 29;
} s;
ecma_atom_value_t value;
} ecma_atom_t;
static_assert (sizeof (ecma_atom_t) == 4, "");
static_assert (sizeof (ecma_atom_t) == sizeof (ecma_atom_value_t), "");
- 4 ECMA_ATOM_NUMBER
31 bit unsigned integer
- 1 ECMA_ATOM_SYMBOL
- 1 ECMA_ATOM_GLOBAL_SYMBOL
- 1 ECMA_ATOM_STRING
- 1 ECMA_ATOM_PRIVATE
- 1 ECMA_TYPE_INTEGER
- directly encoded number value
29 bit signed integer
- directly encoded number value
- 1 ECMA_TYPE_DIRECT
- directly encoded
simple value
,extend point for future
- directly encoded
- 1 ECMA_TYPE_FLOAT
-
pointer
to a 64 bit floating point number (8 byte aligned)
-
- 1 ECMA_TYPE_OBJECT
-
pointer
to (object
,function
,extend point for future
) (8 byte aligned)
-
- 1 ECMA_TYPE_STRING
-
pointer
to description of astring
, that isecma_string_t
(8 byte aligned)
-
- 1 ECMA_TYPE_SYMBOL
-
pointer
to description of asymbol
that isecma_symbol_t
(8 byte aligned)
-
- 1 ECMA_TYPE_BIG_NUMBER
-
pointer
to description of abignumber
that isecma_bignumber_t
(8 byte aligned)- The
bignumber
maybebigint
,bigfloat
orbigdecimal
- The
-
- 1 ECMA_TYPE_ERROR
- pointer to description of an error reference(exception) (only supported by C API)
clang-cl --target=i686-pc-windows-msvc -DJERRY_CPOINTER_64_BIT=1 -c test-api.c
clang-cl --target=i686-pc-windows-msvc -DJERRY_CPOINTER_16_BIT=1 -c test-api.c
clang-cl --target=i686-pc-windows-msvc -DJERRY_CPOINTER_32_BIT=1 -c test-api.c
clang-cl --target=x86_64-pc-windows-msvc -DJERRY_CPOINTER_16_BIT=1 -c test-api.c
clang-cl --target=x86_64-pc-windows-msvc -DJERRY_CPOINTER_32_BIT=1 -c test-api.c
clang-cl --target=x86_64-pc-windows-msvc -DJERRY_CPOINTER_64_BIT=1 -c test-api.c