Rework literal storage.

The new literal storage keeps ecma strings rather than having a
custom string implementation which duplicates the string management
routines. Conversions between string implementations are eliminated
which improved the performance by 4%.

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg 2016-06-27 00:25:09 -07:00
parent 0940be57f6
commit 0a32c97755
30 changed files with 744 additions and 1641 deletions

View File

@ -809,7 +809,6 @@ typedef struct
*/
typedef enum
{
ECMA_STRING_CONTAINER_LIT_TABLE, /**< actual data is in literal table */
ECMA_STRING_CONTAINER_HEAP_ASCII_STRING, /**< actual data is on the heap as an ascii string */
ECMA_STRING_CONTAINER_HEAP_UTF8_STRING, /**< actual data is on the heap as an utf-8 string */
ECMA_STRING_CONTAINER_UINT32_IN_DESC, /**< actual data is UInt32-represeneted Number
@ -817,7 +816,11 @@ typedef enum
ECMA_STRING_CONTAINER_MAGIC_STRING, /**< the ecma-string is equal to one of ECMA magic strings */
ECMA_STRING_CONTAINER_MAGIC_STRING_EX, /**< the ecma-string is equal to one of external magic strings */
ECMA_STRING_CONTAINER__MAX = ECMA_STRING_CONTAINER_MAGIC_STRING_EX /**< maximum value */
ECMA_STRING_LITERAL_NUMBER, /**< a literal number which is used solely by the literal storage
* so no string processing function supports this type except
* the ecma_deref_ecma_string function. */
ECMA_STRING_CONTAINER__MAX = ECMA_STRING_LITERAL_NUMBER /**< maximum value */
} ecma_string_container_t;
/**
@ -847,6 +850,12 @@ typedef enum
#define ECMA_STRING_GET_CONTAINER(string_desc_p) \
((ecma_string_container_t) ((string_desc_p)->refs_and_container & ECMA_STRING_CONTAINER_MASK))
/**
* Checks whether the reference counter is 1.
*/
#define ECMA_STRING_IS_REF_EQUALS_TO_ONE(string_desc_p) \
(((string_desc_p)->refs_and_container >> 3) == 1)
/**
* ECMA string-value descriptor
*/
@ -892,6 +901,9 @@ typedef struct ecma_string_t
/** Identifier of external magic string */
lit_magic_string_ex_id_t magic_string_ex_id;
/** Literal number */
ecma_value_t lit_number;
/** For zeroing and comparison in some cases */
uint32_t common_field;
} u;

View File

@ -22,10 +22,7 @@
#include "jrt.h"
#include "jrt-libc-includes.h"
#include "lit-char-helpers.h"
#include "lit-literal.h"
#include "lit-magic-strings.h"
#include "lit-literal-storage.h"
#include "vm.h"
/** \addtogroup ecma ECMA
* @{
@ -72,9 +69,6 @@ typedef struct
uint16_t length; /* Number of characters in the string */
} ecma_string_heap_header_t;
static void
ecma_init_ecma_string_from_lit_cp (ecma_string_t *string_p,
lit_cpointer_t lit_index);
static void
ecma_init_ecma_string_from_magic_string_id (ecma_string_t *string_p,
lit_magic_string_id_t magic_string_id);
@ -83,39 +77,6 @@ static void
ecma_init_ecma_string_from_magic_string_ex_id (ecma_string_t *string_p,
lit_magic_string_ex_id_t magic_string_ex_id);
/**
* Initialize ecma-string descriptor with string described by index in literal table
*/
static void
ecma_init_ecma_string_from_lit_cp (ecma_string_t *string_p, /**< descriptor to initialize */
lit_cpointer_t lit_cp) /**< compressed pointer to literal */
{
lit_literal_t lit = lit_cpointer_decompress (lit_cp);
if (LIT_RECORD_IS_MAGIC_STR (lit))
{
ecma_init_ecma_string_from_magic_string_id (string_p,
lit_magic_literal_get_magic_str_id (lit));
return;
}
if (LIT_RECORD_IS_MAGIC_STR_EX (lit))
{
ecma_init_ecma_string_from_magic_string_ex_id (string_p,
lit_magic_literal_get_magic_str_ex_id (lit));
return;
}
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
string_p->refs_and_container = ECMA_STRING_CONTAINER_LIT_TABLE | ECMA_STRING_REF_ONE;
string_p->hash = lit_charset_literal_get_hash (lit);
string_p->u.common_field = 0;
string_p->u.lit_cp = lit_cp;
} /* ecma_init_ecma_string_from_lit_cp */
/**
* Initialize ecma-string descriptor with specified magic string
*/
@ -320,21 +281,6 @@ ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */
return string_desc_p;
} /* ecma_new_ecma_string_from_number */
/**
* Allocate new ecma-string and fill it with reference to string literal
*
* @return pointer to ecma-string descriptor
*/
ecma_string_t *
ecma_new_ecma_string_from_lit_cp (lit_cpointer_t lit_cp) /**< index in the literal table */
{
ecma_string_t *string_desc_p = ecma_alloc_string ();
ecma_init_ecma_string_from_lit_cp (string_desc_p, lit_cp);
return string_desc_p;
} /* ecma_new_ecma_string_from_lit_cp */
/**
* Allocate new ecma-string and fill it with reference to ECMA magic string
*
@ -502,7 +448,6 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
break;
}
case ECMA_STRING_CONTAINER_LIT_TABLE:
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
case ECMA_STRING_CONTAINER_MAGIC_STRING:
case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
@ -510,6 +455,15 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
/* only the string descriptor itself should be freed */
break;
}
case ECMA_STRING_LITERAL_NUMBER:
{
ecma_fast_free_value (string_p->u.lit_number);
break;
}
default:
{
JERRY_UNREACHABLE ();
}
}
ecma_dealloc_string (string_p);
@ -532,7 +486,6 @@ ecma_string_to_number (const ecma_string_t *str_p) /**< ecma-string */
return ((ecma_number_t) uint32_number);
}
case ECMA_STRING_CONTAINER_LIT_TABLE:
case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
case ECMA_STRING_CONTAINER_HEAP_ASCII_STRING:
case ECMA_STRING_CONTAINER_MAGIC_STRING:
@ -553,9 +506,12 @@ ecma_string_to_number (const ecma_string_t *str_p) /**< ecma-string */
return num;
}
}
JERRY_UNREACHABLE ();
default:
{
JERRY_UNREACHABLE ();
}
}
} /* ecma_string_to_number */
/**
@ -628,14 +584,6 @@ ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_desc_p, /**< ecma-s
memcpy (buffer_p, data_p, size);
break;
}
case ECMA_STRING_CONTAINER_LIT_TABLE:
{
const lit_literal_t lit = lit_get_literal_by_cp (string_desc_p->u.lit_cp);
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
size = lit_charset_literal_get_size (lit);
memcpy (buffer_p, lit_charset_literal_get_charset (lit), size);
break;
}
case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
{
const uint32_t uint32_number = string_desc_p->u.uint32_number;
@ -762,16 +710,6 @@ ecma_string_raw_chars (const ecma_string_t *string_p, /**< ecma-string */
switch (ECMA_STRING_GET_CONTAINER (string_p))
{
case ECMA_STRING_CONTAINER_LIT_TABLE:
{
lit_literal_t lit = lit_get_literal_by_cp (string_p->u.lit_cp);
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
length = lit_charset_literal_get_length (lit);
size = lit_charset_literal_get_size (lit);
result_p = lit_charset_literal_get_charset (lit);
break;
}
case ECMA_STRING_CONTAINER_HEAP_UTF8_STRING:
{
const ecma_string_heap_header_t *data_p = ECMA_GET_NON_NULL_POINTER (ecma_string_heap_header_t,
@ -861,11 +799,6 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
{
switch (ECMA_STRING_GET_CONTAINER (string1_p))
{
case ECMA_STRING_CONTAINER_LIT_TABLE:
{
JERRY_ASSERT (string1_p->u.lit_cp != string2_p->u.lit_cp);
return false;
}
case ECMA_STRING_CONTAINER_MAGIC_STRING:
{
JERRY_ASSERT (string1_p->u.magic_string_id != string2_p->u.magic_string_id);
@ -958,13 +891,6 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
utf8_string1_p = data_p;
}
else if (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_LIT_TABLE)
{
const lit_literal_t lit = lit_get_literal_by_cp (string1_p->u.lit_cp);
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
utf8_string1_p = (lit_utf8_byte_t *) lit_charset_literal_get_charset (lit);
}
else
{
utf8_string1_p = (lit_utf8_byte_t *) jmem_heap_alloc_block ((size_t) strings_size);
@ -988,13 +914,6 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /* ecma-stri
utf8_string2_p = data_p;
}
else if (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_LIT_TABLE)
{
const lit_literal_t lit = lit_get_literal_by_cp (string2_p->u.lit_cp);
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
utf8_string2_p = (lit_utf8_byte_t *) lit_charset_literal_get_charset (lit);
}
else
{
utf8_string2_p = (lit_utf8_byte_t *) jmem_heap_alloc_block ((size_t) strings_size);
@ -1088,14 +1007,6 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
utf8_string1_p = data_p;
utf8_string1_size = (lit_utf8_size_t) string1_p->u.ascii_string.size;
}
else if (ECMA_STRING_GET_CONTAINER (string1_p) == ECMA_STRING_CONTAINER_LIT_TABLE)
{
const lit_literal_t lit = lit_get_literal_by_cp (string1_p->u.lit_cp);
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
utf8_string1_p = (lit_utf8_byte_t *) lit_charset_literal_get_charset (lit);
utf8_string1_size = (lit_utf8_size_t) lit_charset_literal_get_size (lit);
}
else
{
utf8_string1_size = ecma_string_get_size (string1_p);
@ -1129,14 +1040,6 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
utf8_string2_p = data_p;
utf8_string2_size = (lit_utf8_size_t) string2_p->u.ascii_string.size;
}
else if (ECMA_STRING_GET_CONTAINER (string2_p) == ECMA_STRING_CONTAINER_LIT_TABLE)
{
const lit_literal_t lit = lit_get_literal_by_cp (string2_p->u.lit_cp);
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
utf8_string2_p = (lit_utf8_byte_t *) lit_charset_literal_get_charset (lit);
utf8_string2_size = (lit_utf8_size_t) lit_charset_literal_get_size (lit);
}
else
{
utf8_string2_size = ecma_string_get_size (string2_p);
@ -1182,12 +1085,6 @@ ecma_string_get_length (const ecma_string_t *string_p) /**< ecma-string */
{
switch (ECMA_STRING_GET_CONTAINER (string_p))
{
case ECMA_STRING_CONTAINER_LIT_TABLE:
{
lit_literal_t lit = lit_get_literal_by_cp (string_p->u.lit_cp);
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
return lit_charset_literal_get_length (lit);
}
case ECMA_STRING_CONTAINER_MAGIC_STRING:
{
JERRY_ASSERT (ECMA_STRING_IS_ASCII (lit_get_magic_string_utf8 (string_p->u.magic_string_id),
@ -1229,13 +1126,6 @@ ecma_string_get_size (const ecma_string_t *string_p) /**< ecma-string */
{
switch (ECMA_STRING_GET_CONTAINER (string_p))
{
case ECMA_STRING_CONTAINER_LIT_TABLE:
{
lit_literal_t lit = lit_get_literal_by_cp (string_p->u.lit_cp);
JERRY_ASSERT (LIT_RECORD_IS_CHARSET (lit));
return lit_charset_literal_get_size (lit);
}
case ECMA_STRING_CONTAINER_MAGIC_STRING:
{
return lit_get_magic_string_size (string_p->u.magic_string_id);

View File

@ -1429,14 +1429,14 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
{
lit_cpointer_t *literal_start_p = NULL;
jmem_cpointer_t *literal_start_p = NULL;
uint32_t literal_end;
uint32_t const_literal_end;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
literal_start_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_p;
literal_end = args_p->literal_end;
@ -1445,7 +1445,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
else
{
uint8_t *byte_p = (uint8_t *) bytecode_p;
literal_start_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
literal_start_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_p;
literal_end = args_p->literal_end;

View File

@ -19,7 +19,6 @@
#include "ecma-globals.h"
#include "jmem-allocator.h"
#include "lit-cpointer.h"
#include "lit-strings.h"
/** \addtogroup ecma ECMA
@ -165,7 +164,6 @@ extern ecma_string_t *ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *, l
extern ecma_string_t *ecma_new_ecma_string_from_code_unit (ecma_char_t);
extern ecma_string_t *ecma_new_ecma_string_from_uint32 (uint32_t);
extern ecma_string_t *ecma_new_ecma_string_from_number (ecma_number_t);
extern ecma_string_t *ecma_new_ecma_string_from_lit_cp (lit_cpointer_t);
extern ecma_string_t *ecma_new_ecma_string_from_magic_string_id (lit_magic_string_id_t);
extern ecma_string_t *ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t);
extern ecma_string_t *ecma_concat_ecma_strings (ecma_string_t *, ecma_string_t *);

View File

@ -19,6 +19,7 @@
#include "ecma-init-finalize.h"
#include "ecma-lcache.h"
#include "ecma-lex-env.h"
#include "ecma-literal-storage.h"
#include "jmem-allocator.h"
/** \addtogroup ecma ECMA
@ -37,6 +38,7 @@ ecma_init (void)
ecma_gc_init ();
ecma_init_builtins ();
ecma_lcache_init ();
ecma_init_lit_storage ();
ecma_init_environment ();
jmem_register_free_unused_memory_callback (ecma_free_unused_memory);
@ -53,6 +55,7 @@ ecma_finalize (void)
ecma_finalize_environment ();
ecma_finalize_builtins ();
ecma_gc_run ();
ecma_finalize_lit_storage ();
} /* ecma_finalize */
/**

View File

@ -0,0 +1,541 @@
/* Copyright 2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-literal-storage.h"
#include "ecma-helpers.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmalitstorage Literal storage
* @{
*/
/**
* Number of values in a literal storage item
*/
#define ECMA_LIT_STORAGE_VALUE_COUNT 3
/**
* Literal storage item
*/
typedef struct
{
jmem_cpointer_t next_cp; /**< cpointer ot next item */
jmem_cpointer_t values[ECMA_LIT_STORAGE_VALUE_COUNT]; /**< list of values */
} ecma_lit_storage_item_t;
JERRY_STATIC_ASSERT (sizeof (ecma_lit_storage_item_t) <= sizeof (uint64_t),
size_of_ecma_lit_storage_item_t_must_be_less_than_or_equal_to_8_bytes);
static ecma_lit_storage_item_t *string_list_first_p;
static ecma_lit_storage_item_t *number_list_first_p;
/**
* Initialize literal storage
*/
void
ecma_init_lit_storage (void)
{
string_list_first_p = NULL;
number_list_first_p = NULL;
} /* ecma_init_lit_storage */
/**
* Free string list
*/
static void
ecma_free_string_list (ecma_lit_storage_item_t *string_list_p) /**< string list */
{
while (string_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (string_list_p->values[i] != JMEM_CP_NULL)
{
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_IS_REF_EQUALS_TO_ONE (string_p));
ecma_deref_ecma_string (string_p);
}
}
ecma_lit_storage_item_t *prev_item = string_list_p;
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
jmem_pools_free (prev_item);
}
} /* ecma_free_string_list */
/**
* Finalize literal storage
*/
void
ecma_finalize_lit_storage (void)
{
ecma_free_string_list (string_list_first_p);
ecma_free_string_list (number_list_first_p);
} /* ecma_finalize_lit_storage */
/**
* Find or create a literal string.
*
* @return ecma_string_t compressed pointer
*/
jmem_cpointer_t
ecma_find_or_create_literal_string (const lit_utf8_byte_t *chars_p, /**< string to be searched */
lit_utf8_size_t size) /**< size of the string */
{
ecma_string_t *string_p = ecma_new_ecma_string_from_utf8 (chars_p, size);
ecma_lit_storage_item_t *string_list_p = string_list_first_p;
jmem_cpointer_t *empty_cpointer_p = NULL;
while (string_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (string_list_p->values[i] == JMEM_CP_NULL)
{
if (empty_cpointer_p == NULL)
{
empty_cpointer_p = string_list_p->values + i;
}
}
else
{
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
if (ecma_compare_ecma_strings (string_p, value_p))
{
/* Return with string if found in the list. */
ecma_deref_ecma_string (string_p);
return string_list_p->values[i];
}
}
}
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
}
jmem_cpointer_t result;
JMEM_CP_SET_NON_NULL_POINTER (result, string_p);
if (empty_cpointer_p != NULL)
{
*empty_cpointer_p = result;
return result;
}
ecma_lit_storage_item_t *new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc ();
new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
new_item_p->values[i] = JMEM_CP_NULL;
}
JMEM_CP_SET_POINTER (new_item_p->next_cp, string_list_first_p);
string_list_first_p = new_item_p;
return result;
} /* ecma_find_or_create_literal_string */
/**
* Find or create a literal number.
*
* @return ecma_string_t compressed pointer
*/
jmem_cpointer_t
ecma_find_or_create_literal_number (ecma_number_t number_arg) /**< number to be searched */
{
ecma_value_t num = ecma_make_number_value (number_arg);
ecma_lit_storage_item_t *number_list_p = number_list_first_p;
jmem_cpointer_t *empty_cpointer_p = NULL;
while (number_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] == JMEM_CP_NULL)
{
if (empty_cpointer_p == NULL)
{
empty_cpointer_p = number_list_p->values + i;
}
}
else
{
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
number_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
if (ecma_is_value_integer_number (num))
{
if (value_p->u.lit_number == num)
{
return number_list_p->values[i];
}
}
else
{
if (ecma_is_value_float_number (value_p->u.lit_number)
&& ecma_get_float_from_value (value_p->u.lit_number) == ecma_get_float_from_value (num))
{
ecma_free_value (num);
return number_list_p->values[i];
}
}
}
}
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
ecma_string_t *string_p = (ecma_string_t *) jmem_pools_alloc ();
string_p->refs_and_container = ECMA_STRING_REF_ONE | ECMA_STRING_LITERAL_NUMBER;
string_p->u.lit_number = num;
jmem_cpointer_t result;
JMEM_CP_SET_NON_NULL_POINTER (result, string_p);
if (empty_cpointer_p != NULL)
{
*empty_cpointer_p = result;
return result;
}
ecma_lit_storage_item_t *new_item_p = (ecma_lit_storage_item_t *) jmem_pools_alloc ();
new_item_p->values[0] = result;
for (int i = 1; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
new_item_p->values[i] = JMEM_CP_NULL;
}
JMEM_CP_SET_POINTER (new_item_p->next_cp, number_list_first_p);
number_list_first_p = new_item_p;
return result;
} /* ecma_find_or_create_literal_number */
/**
* Log2 of snapshot literal alignment.
*/
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG 2
/**
* Snapshot literal alignment.
*/
#define JERRY_SNAPSHOT_LITERAL_ALIGNMENT (1u << JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG)
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
/**
* Save literals to specified snapshot buffer.
*
* @return true, if save was performed successfully (i.e. buffer size is sufficient),
* false - otherwise.
*/
bool
ecma_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot buffer */
size_t buffer_size, /**< size of the buffer */
size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers
* to the literal offsets
* in snapshot */
uint32_t *out_map_len_p, /**< [out] number of literals */
uint32_t *out_lit_table_size_p) /**< [out] number of bytes, saved to snapshot buffer */
{
/* Count literals and literal space. */
uint32_t string_count = 0;
uint32_t number_count = 0;
uint32_t lit_table_size = 2 * sizeof (uint32_t);
ecma_lit_storage_item_t *string_list_p = string_list_first_p;
while (string_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (string_list_p->values[i] != JMEM_CP_NULL)
{
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
lit_table_size += (uint32_t) JERRY_ALIGNUP (sizeof (uint16_t) + ecma_string_get_size (string_p),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
string_count++;
}
}
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
}
ecma_lit_storage_item_t *number_list_p = number_list_first_p;
while (number_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] != JMEM_CP_NULL)
{
lit_table_size += (uint32_t) sizeof (ecma_number_t);
number_count++;
}
}
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
/* Check whether enough space is available. */
if (*in_out_buffer_offset_p + lit_table_size > buffer_size)
{
return false;
}
/* Check whether the maximum literal table size is reached. */
if ((lit_table_size >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG) > UINT16_MAX)
{
return false;
}
uint32_t total_count = string_count + number_count;
lit_mem_to_snapshot_id_map_entry_t *map_p;
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
/* Set return values (no error is possible from here). */
buffer_p += *in_out_buffer_offset_p;
*in_out_buffer_offset_p += lit_table_size;
*out_map_p = map_p;
*out_map_len_p = total_count;
*out_lit_table_size_p = lit_table_size;
/* Write data into the buffer. */
/* The zero value is reserved for NULL (no literal)
* constant so the first literal must have offset one. */
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
((uint32_t *) buffer_p)[0] = string_count;
((uint32_t *) buffer_p)[1] = number_count;
buffer_p += 2 * sizeof (uint32_t);
string_list_p = string_list_first_p;
while (string_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (string_list_p->values[i] != JMEM_CP_NULL)
{
map_p->literal_id = string_list_p->values[i];
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_string_t *string_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
string_list_p->values[i]);
ecma_length_t length = ecma_string_get_size (string_p);
*((uint16_t *) buffer_p) = (uint16_t) length;
ecma_string_to_utf8_bytes (string_p, buffer_p + sizeof (uint16_t), length);
length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
}
}
string_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, string_list_p->next_cp);
}
number_list_p = number_list_first_p;
while (number_list_p != NULL)
{
for (int i = 0; i < ECMA_LIT_STORAGE_VALUE_COUNT; i++)
{
if (number_list_p->values[i] != JMEM_CP_NULL)
{
map_p->literal_id = number_list_p->values[i];
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
number_list_p->values[i]);
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
ecma_number_t num = ecma_get_number_from_value (value_p->u.lit_number);
memcpy (buffer_p, &num, sizeof (ecma_number_t));
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
}
}
number_list_p = JMEM_CP_GET_POINTER (ecma_lit_storage_item_t, number_list_p->next_cp);
}
return true;
} /* ecma_save_literals_for_snapshot */
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
/**
* Helper function for ecma_load_literals_from_snapshot.
*
* Note: always inline because it is used only once.
*
* @return true, if load was performed successfully
* false - otherwise (i.e. buffer length is incorrect).
*/
static inline bool __attr_always_inline___
ecma_load_literals_from_buffer (const uint8_t *buffer_p, /**< buffer with literal table in snapshot */
uint32_t lit_table_size, /**< size of literal table in snapshot */
lit_mem_to_snapshot_id_map_entry_t *map_p, /**< literal map */
uint32_t string_count, /**< number of strings */
uint32_t number_count) /**< number of numbers */
{
/* The zero value is reserved for NULL (no literal)
* constant so the first literal must have offset one. */
uint32_t literal_offset = JERRY_SNAPSHOT_LITERAL_ALIGNMENT;
/* Load strings first. */
while (string_count > 0)
{
if (lit_table_size < literal_offset + sizeof (uint32_t))
{
/* Buffer is not sufficent. */
return false;
}
lit_utf8_size_t length = *((uint16_t *) buffer_p);
lit_utf8_size_t aligned_length = JERRY_ALIGNUP (sizeof (uint16_t) + length,
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
if (lit_table_size < literal_offset + aligned_length)
{
/* Buffer is not sufficent. */
return false;
}
map_p->literal_id = ecma_find_or_create_literal_string (buffer_p + sizeof (uint16_t), length);
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
buffer_p += aligned_length;
literal_offset += aligned_length;
string_count--;
}
/* Load numbers. */
while (number_count > 0)
{
if (lit_table_size < literal_offset + sizeof (ecma_number_t))
{
/* Buffer is not sufficent. */
return false;
}
ecma_number_t num;
memcpy (&num, buffer_p, sizeof (ecma_number_t));
map_p->literal_id = ecma_find_or_create_literal_number (num);
map_p->literal_offset = (jmem_cpointer_t) (literal_offset >> JERRY_SNAPSHOT_LITERAL_ALIGNMENT_LOG);
map_p++;
ecma_length_t length = JERRY_ALIGNUP (sizeof (ecma_number_t),
JERRY_SNAPSHOT_LITERAL_ALIGNMENT);
buffer_p += length;
literal_offset += length;
number_count--;
}
return (lit_table_size == (literal_offset + 2 * sizeof (uint32_t) - JERRY_SNAPSHOT_LITERAL_ALIGNMENT));
} /* ecma_load_literals_from_buffer */
/**
* Load literals from snapshot.
*
* @return true, if load was performed successfully (i.e. literals saved in the snapshot are consistent),
* false - otherwise (i.e. snapshot is incorrect).
*/
bool
ecma_load_literals_from_snapshot (const uint8_t *buffer_p, /**< buffer with literal table in snapshot */
uint32_t lit_table_size, /**< size of literal table in snapshot */
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal offsets
* in snapshot to identifiers
* of loaded literals in literal
* storage */
uint32_t *out_map_len_p) /**< [out] literals number */
{
*out_map_p = NULL;
if (lit_table_size < 2 * sizeof (uint32_t))
{
/* Buffer is not sufficent. */
return false;
}
uint32_t string_count = ((uint32_t *) buffer_p)[0];
uint32_t number_count = ((uint32_t *) buffer_p)[1];
buffer_p += 2 * sizeof (uint32_t);
uint32_t total_count = string_count + number_count;
lit_mem_to_snapshot_id_map_entry_t *map_p;
*out_map_len_p = total_count;
if (total_count == 0)
{
return true;
}
map_p = jmem_heap_alloc_block (total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
*out_map_p = map_p;
if (ecma_load_literals_from_buffer (buffer_p, lit_table_size, map_p, string_count, number_count))
{
return true;
}
jmem_heap_free_block (map_p, total_count * sizeof (lit_mem_to_snapshot_id_map_entry_t));
*out_map_p = NULL;
return false;
} /* ecma_load_literals_from_snapshot */
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
/**
* @}
* @}
*/

View File

@ -0,0 +1,63 @@
/* Copyright 2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMA_LIT_STORAGE_H
#define ECMA_LIT_STORAGE_H
#include "ecma-globals.h"
#include "jmem-allocator.h"
#include "lit-globals.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmalitstorage Literal storage
* @{
*/
/**
* Snapshot literal - offset map
*/
typedef struct
{
jmem_cpointer_t literal_id; /**< literal id */
jmem_cpointer_t literal_offset; /**< literal offset */
} lit_mem_to_snapshot_id_map_entry_t;
extern void ecma_init_lit_storage (void);
extern void ecma_finalize_lit_storage (void);
extern jmem_cpointer_t ecma_find_or_create_literal_string (const lit_utf8_byte_t *, lit_utf8_size_t);
extern jmem_cpointer_t ecma_find_or_create_literal_number (ecma_number_t);
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
extern bool
ecma_save_literals_for_snapshot (uint8_t *, size_t, size_t *,
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *, uint32_t *);
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
extern bool
ecma_load_literals_from_snapshot (const uint8_t *, uint32_t,
lit_mem_to_snapshot_id_map_entry_t **, uint32_t *);
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
/**
* @}
* @}
*/
#endif /* !ECMA_LIT_STORAGE_H */

View File

@ -102,7 +102,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
if (bytecode_data_p != NULL)
{
ecma_length_t formal_params_number;
lit_cpointer_t *literal_p;
jmem_cpointer_t *literal_p;
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
@ -110,7 +110,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
formal_params_number = args_p->argument_end;
literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
}
else
{
@ -118,7 +118,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
formal_params_number = args_p->argument_end;
literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
}
if (!is_strict
@ -139,7 +139,7 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
continue;
}
ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_p[indx]);
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p[indx]);
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx);
prop_desc.is_value_defined = true;
@ -155,7 +155,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
JERRY_ASSERT (ecma_is_value_true (completion));
ecma_deref_ecma_string (indx_string_p);
ecma_deref_ecma_string (name_p);
}
// 12.

View File

@ -37,6 +37,6 @@ typedef struct
/**
* Jerry snapshot format version
*/
#define JERRY_SNAPSHOT_VERSION (4u)
#define JERRY_SNAPSHOT_VERSION (5u)
#endif /* !JERRY_SNAPSHOT_H */

View File

@ -25,13 +25,12 @@
#include "ecma-gc.h"
#include "ecma-helpers.h"
#include "ecma-init-finalize.h"
#include "ecma-literal-storage.h"
#include "ecma-objects.h"
#include "ecma-objects-general.h"
#include "ecma-try-catch-macro.h"
#include "jerry-snapshot.h"
#include "lit-literal.h"
#include "lit-magic-strings.h"
#include "lit-snapshot.h"
#include "js-parser.h"
#include "re-compiler.h"
@ -1359,7 +1358,6 @@ jerry_init (jerry_flag_t flags) /**< combination of Jerry flags */
jerry_make_api_available ();
jmem_init ();
lit_init ();
ecma_init ();
} /* jerry_init */
@ -1375,7 +1373,6 @@ jerry_cleanup (void)
vm_finalize ();
ecma_finalize ();
lit_finalize ();
jmem_finalize (is_show_mem_stats);
} /* jerry_cleanup */
@ -1604,15 +1601,15 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p) /**< compiled
/* Sub-functions and regular expressions are stored recursively. */
uint8_t *src_buffer_p = (uint8_t *) compiled_code_p;
uint8_t *dst_buffer_p = (uint8_t *) copied_compiled_code_p;
lit_cpointer_t *src_literal_start_p;
uint16_t *dst_literal_start_p;
jmem_cpointer_t *src_literal_start_p;
jmem_cpointer_t *dst_literal_start_p;
uint32_t const_literal_end;
uint32_t literal_end;
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
src_literal_start_p = (lit_cpointer_t *) (src_buffer_p + sizeof (cbc_uint16_arguments_t));
dst_literal_start_p = (uint16_t *) (dst_buffer_p + sizeof (cbc_uint16_arguments_t));
src_literal_start_p = (jmem_cpointer_t *) (src_buffer_p + sizeof (cbc_uint16_arguments_t));
dst_literal_start_p = (jmem_cpointer_t *) (dst_buffer_p + sizeof (cbc_uint16_arguments_t));
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) src_buffer_p;
literal_end = args_p->literal_end;
@ -1620,8 +1617,8 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p) /**< compiled
}
else
{
src_literal_start_p = (lit_cpointer_t *) (src_buffer_p + sizeof (cbc_uint8_arguments_t));
dst_literal_start_p = (uint16_t *) (dst_buffer_p + sizeof (cbc_uint8_arguments_t));
src_literal_start_p = (jmem_cpointer_t *) (src_buffer_p + sizeof (cbc_uint8_arguments_t));
dst_literal_start_p = (jmem_cpointer_t *) (dst_buffer_p + sizeof (cbc_uint8_arguments_t));
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) src_buffer_p;
literal_end = args_p->literal_end;
@ -1663,14 +1660,14 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
{
lit_cpointer_t *literal_start_p;
jmem_cpointer_t *literal_start_p;
uint32_t argument_end;
uint32_t register_end;
uint32_t const_literal_end;
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
literal_start_p = (lit_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint16_arguments_t));
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) buffer_p;
argument_end = args_p->argument_end;
@ -1679,7 +1676,7 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
}
else
{
literal_start_p = (lit_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
literal_start_p = (jmem_cpointer_t *) (buffer_p + sizeof (cbc_uint8_arguments_t));
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) buffer_p;
argument_end = args_p->argument_end;
@ -1703,7 +1700,7 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
current_p++;
}
literal_start_p[i] = (uint16_t) current_p->literal_offset;
literal_start_p[i] = current_p->literal_offset;
}
}
@ -1726,7 +1723,7 @@ jerry_snapshot_set_offsets (uint8_t *buffer_p, /**< buffer */
current_p++;
}
literal_start_p[i] = (uint16_t) current_p->literal_offset;
literal_start_p[i] = current_p->literal_offset;
}
}
@ -1811,12 +1808,12 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source
lit_mem_to_snapshot_id_map_entry_t *lit_map_p = NULL;
uint32_t literals_num;
if (!lit_save_literals_for_snapshot (buffer_p,
buffer_size,
&snapshot_buffer_write_offset,
&lit_map_p,
&literals_num,
&header.lit_table_size))
if (!ecma_save_literals_for_snapshot (buffer_p,
buffer_size,
&snapshot_buffer_write_offset,
&lit_map_p,
&literals_num,
&header.lit_table_size))
{
JERRY_ASSERT (lit_map_p == NULL);
return 0;
@ -1836,7 +1833,7 @@ jerry_parse_and_save_snapshot (const jerry_char_t *source_p, /**< script source
if (lit_map_p != NULL)
{
jmem_heap_free_block_size_stored (lit_map_p);
jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t));
}
ecma_bytecode_deref (bytecode_data_p);
@ -1929,7 +1926,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
}
else
{
code_size = (uint32_t) (header_size + literal_end * sizeof (lit_cpointer_t));
code_size = (uint32_t) (header_size + literal_end * sizeof (jmem_cpointer_t));
uint8_t *real_bytecode_p = ((uint8_t *) bytecode_p) + code_size;
uint32_t total_size = JERRY_ALIGNUP (code_size + 1 + sizeof (uint8_t *), JMEM_ALIGNMENT);
@ -1948,7 +1945,7 @@ snapshot_load_compiled_code (const uint8_t *snapshot_data_p, /**< snapshot data
JERRY_ASSERT (bytecode_p->refs == 1);
lit_cpointer_t *literal_start_p = (lit_cpointer_t *) (((uint8_t *) bytecode_p) + header_size);
jmem_cpointer_t *literal_start_p = (jmem_cpointer_t *) (((uint8_t *) bytecode_p) + header_size);
for (uint32_t i = 0; i < const_literal_end; i++)
{
@ -2038,10 +2035,10 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_VERSION;
}
if (!lit_load_literals_from_snapshot (snapshot_data_p + header_p->lit_table_offset,
header_p->lit_table_size,
&lit_map_p,
&literals_num))
if (!ecma_load_literals_from_snapshot (snapshot_data_p + header_p->lit_table_offset,
header_p->lit_table_size,
&lit_map_p,
&literals_num))
{
JERRY_ASSERT (lit_map_p == NULL);
return JERRY_COMPLETION_CODE_INVALID_SNAPSHOT_FORMAT;
@ -2055,7 +2052,7 @@ jerry_exec_snapshot (const void *snapshot_p, /**< snapshot */
if (lit_map_p != NULL)
{
jmem_heap_free_block_size_stored (lit_map_p);
jmem_heap_free_block (lit_map_p, literals_num * sizeof (lit_mem_to_snapshot_id_map_entry_t));
}
if (bytecode_p == NULL)

View File

@ -1,61 +0,0 @@
/* Copyright 2015 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lit-cpointer.h"
#include "jrt-bit-fields.h"
/**
* Compress pointer to extended compressed pointer.
*
* @return dynamic storage-specific extended compressed pointer
*/
inline lit_cpointer_t __attr_pure___ __attr_always_inline___
lit_cpointer_compress (lit_record_t *pointer) /**< pointer to compress */
{
if (pointer == NULL)
{
return JMEM_CP_NULL;
}
return (lit_cpointer_t) jmem_compress_pointer (pointer);
} /* lit_cpointer_compress */
/**
* Decompress extended compressed pointer.
*
* @return decompressed pointer
*/
inline lit_record_t * __attr_pure___ __attr_always_inline___
lit_cpointer_decompress (lit_cpointer_t compressed_pointer) /**< recordset-specific compressed pointer */
{
if (compressed_pointer == JMEM_CP_NULL)
{
return NULL;
}
return (lit_record_t *) jmem_decompress_pointer (compressed_pointer);
} /* lit_cpointer_decompress */
/**
* Create NULL compressed pointer.
*
* @return NULL compressed pointer
*/
inline lit_cpointer_t __attr_pure___ __attr_always_inline___
lit_cpointer_null_cp (void)
{
return JMEM_CP_NULL;
} /* lit_cpointer_null_cp */

View File

@ -1,38 +0,0 @@
/* Copyright 2015 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIT_CPOINTER_H
#define LIT_CPOINTER_H
#include "lit-literal-storage.h"
#include "jmem-allocator.h"
#define LIT_CPOINTER_WIDTH (JMEM_CP_WIDTH + JMEM_ALIGNMENT_LOG - JMEM_ALIGNMENT_LOG)
/**
* Dynamic storage-specific extended compressed pointer
*
* Note:
* the pointer can represent addresses aligned by lit_DYN_STORAGE_LENGTH_UNIT,
* while jmem_cpointer_t can only represent addresses aligned by JMEM_ALIGNMENT.
*/
typedef uint16_t lit_cpointer_t;
extern lit_cpointer_t lit_cpointer_compress (lit_record_t *);
extern lit_record_t *lit_cpointer_decompress (lit_cpointer_t);
extern lit_cpointer_t lit_cpointer_null_cp ();
#endif /* !LIT_CPOINTER_H */

View File

@ -1,265 +0,0 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lit-literal-storage.h"
#include "lit-cpointer.h"
#include "ecma-helpers.h"
lit_record_t *lit_storage = NULL;
/**
* Create charset record in the literal storage
*
* @return pointer to the created record
*/
lit_record_t *
lit_create_charset_literal (const lit_utf8_byte_t *str_p, /**< string to be placed into the record */
const lit_utf8_size_t buf_size) /**< size in bytes of the buffer which holds the string */
{
lit_charset_record_t *rec_p = (lit_charset_record_t *) jmem_heap_alloc_block (buf_size + LIT_CHARSET_HEADER_SIZE);
rec_p->type = LIT_RECORD_TYPE_CHARSET;
rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage);
lit_storage = (lit_record_t *) rec_p;
rec_p->hash = (uint8_t) lit_utf8_string_calc_hash (str_p, buf_size);
rec_p->size = (uint16_t) buf_size;
rec_p->length = (uint16_t) lit_utf8_string_length (str_p, buf_size);
memcpy (rec_p + 1, str_p, buf_size);
return (lit_record_t *) rec_p;
} /* lit_create_charset_literal */
/**
* Create magic string record in the literal storage.
*
* @return pointer to the created record
*/
lit_record_t *
lit_create_magic_literal (const lit_magic_string_id_t id) /**< id of magic string */
{
lit_magic_record_t *rec_p = (lit_magic_record_t *) jmem_heap_alloc_block (sizeof (lit_magic_record_t));
rec_p->type = LIT_RECORD_TYPE_MAGIC_STR;
rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage);
lit_storage = (lit_record_t *) rec_p;
rec_p->magic_id = (uint32_t) id;
return (lit_record_t *) rec_p;
} /* lit_create_magic_literal */
/**
* Create external magic string record in the literal storage.
*
* @return pointer to the created record
*/
lit_record_t *
lit_create_magic_literal_ex (const lit_magic_string_ex_id_t id) /**< id of magic string */
{
lit_magic_record_t *rec_p = (lit_magic_record_t *) jmem_heap_alloc_block (sizeof (lit_magic_record_t));
rec_p->type = LIT_RECORD_TYPE_MAGIC_STR_EX;
rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage);
lit_storage = (lit_record_t *) rec_p;
rec_p->magic_id = (uint32_t) id;
return (lit_record_t *) rec_p;
} /* lit_create_magic_literal_ex */
/**
* Create number record in the literal storage.
*
* @return pointer to the created record
*/
lit_record_t *
lit_create_number_literal (const ecma_number_t num) /**< numeric value */
{
lit_number_record_t *rec_p = (lit_number_record_t *) jmem_heap_alloc_block (sizeof (lit_number_record_t));
rec_p->type = (uint8_t) LIT_RECORD_TYPE_NUMBER;
rec_p->next = (uint16_t) lit_cpointer_compress (lit_storage);
lit_storage = (lit_record_t *) rec_p;
rec_p->number = num;
return (lit_record_t *) rec_p;
} /* lit_create_number_literal */
/**
* Get size of stored literal
*
* @return size of literal
*/
size_t __attr_pure___
lit_get_literal_size (const lit_record_t *lit_p) /**< literal record */
{
const lit_record_type_t type = (const lit_record_type_t) lit_p->type;
size_t size = 0;
switch (type)
{
case LIT_RECORD_TYPE_NUMBER:
{
size = sizeof (lit_number_record_t);
break;
}
case LIT_RECORD_TYPE_CHARSET:
{
const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit_p;
size = rec_p->size + LIT_CHARSET_HEADER_SIZE;
break;
}
case LIT_RECORD_TYPE_MAGIC_STR:
case LIT_RECORD_TYPE_MAGIC_STR_EX:
{
size = sizeof (lit_magic_record_t);
break;
}
default:
{
JERRY_UNREACHABLE ();
break;
}
}
JERRY_ASSERT (size > 0);
return size;
} /* lit_get_literal_size */
/**
* Free stored literal
*
* @return pointer to the next literal in the list
*/
lit_record_t *
lit_free_literal (lit_record_t *lit_p) /**< literal record */
{
lit_record_t *const ret_p = lit_cpointer_decompress (lit_p->next);
jmem_heap_free_block (lit_p, lit_get_literal_size (lit_p));
return ret_p;
} /* lit_free_literal */
/**
* Count literal records in the storage
*
* @return number of literals
*/
uint32_t
lit_count_literals ()
{
uint32_t num = 0;
lit_record_t *rec_p;
for (rec_p = lit_storage;
rec_p != NULL;
rec_p = lit_cpointer_decompress (rec_p->next))
{
if (rec_p->type > LIT_RECORD_TYPE_FREE)
{
num++;
}
}
return num;
} /* lit_count_literals */
#ifdef JERRY_ENABLE_LOG
/**
* Dump the contents of the literal storage.
*/
void
lit_dump_literals ()
{
lit_record_t *rec_p;
size_t i;
JERRY_DLOG ("LITERALS:\n");
for (rec_p = lit_storage;
rec_p != NULL;
rec_p = lit_cpointer_decompress (rec_p->next))
{
JERRY_DLOG ("%p ", rec_p);
JERRY_DLOG ("[%3zu] ", lit_get_literal_size (rec_p));
switch (rec_p->type)
{
case LIT_RECORD_TYPE_CHARSET:
{
const lit_charset_record_t *const record_p = (const lit_charset_record_t *) rec_p;
char *str = (char *) (record_p + 1);
for (i = 0; i < record_p->size; ++i, ++str)
{
/* TODO: Support proper printing of characters which occupy more than one byte. */
JERRY_DLOG ("%c", *str);
}
JERRY_DLOG (" : STRING");
break;
}
case LIT_RECORD_TYPE_MAGIC_STR:
{
lit_magic_string_id_t id = (lit_magic_string_id_t) ((lit_magic_record_t *) rec_p)->magic_id;
JERRY_DLOG ("%s : MAGIC STRING", lit_get_magic_string_utf8 (id));
JERRY_DLOG (" [id=%d] ", id);
break;
}
case LIT_RECORD_TYPE_MAGIC_STR_EX:
{
lit_magic_string_ex_id_t id = ((lit_magic_record_t *) rec_p)->magic_id;
JERRY_DLOG ("%s : EXT MAGIC STRING", lit_get_magic_string_ex_utf8 (id));
JERRY_DLOG (" [id=%d] ", id);
break;
}
case LIT_RECORD_TYPE_NUMBER:
{
const lit_number_record_t *const record_p = (const lit_number_record_t *) rec_p;
ecma_number_t value;
memcpy (&value, &record_p->number, sizeof (ecma_number_t));
if (ecma_number_is_nan (value))
{
JERRY_DLOG ("%s : NUMBER", "NaN");
}
else
{
lit_utf8_byte_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER + 1u];
memset (buff, 0, sizeof (buff));
lit_utf8_size_t sz = ecma_number_to_utf8_string (value, buff, sizeof (buff));
JERRY_ASSERT (sz <= ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
JERRY_DLOG ("%s : NUMBER", buff);
}
break;
}
default:
{
JERRY_UNREACHABLE ();
}
}
JERRY_DLOG ("\n");
}
} /* lit_dump_literals */
#endif /* JERRY_ENABLE_LOG */

View File

@ -1,106 +0,0 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIT_LITERAL_STORAGE_H
#define LIT_LITERAL_STORAGE_H
#include "lit-magic-strings.h"
#include "lit-globals.h"
#include "ecma-globals.h"
/**
* Represents the type of the record.
*/
typedef enum
{
LIT_RECORD_TYPE_FREE = 0, /**< Free record that marks an empty space. It doesn't hold any values. */
LIT_RECORD_TYPE_CHARSET = 1, /**< Charset record that holds characters. */
LIT_RECORD_TYPE_MAGIC_STR = 2, /**< Magic string record that holds a magic string id. */
LIT_RECORD_TYPE_MAGIC_STR_EX = 3, /**< External magic string record that holds an extrernal magic string id. */
LIT_RECORD_TYPE_NUMBER = 4 /**< Number record that holds a numeric value. */
} lit_record_type_t;
/**
* Record header
*/
typedef struct
{
uint16_t next; /* Compressed pointer to next record */
uint8_t type; /* Type of record */
} lit_record_t;
/**
* Head pointer to literal storage
*/
extern lit_record_t *lit_storage;
typedef lit_record_t *lit_literal_t;
/**
* Charset record header
*
* String is stored after the header.
*/
typedef struct
{
uint16_t next; /* Compressed pointer to next record */
uint8_t type; /* Type of record */
uint8_t hash; /* Hash of the string */
uint16_t size; /* Size of the string in bytes */
uint16_t length; /* Number of character in the string */
} lit_charset_record_t;
/**
* Number record header
*/
typedef struct
{
uint16_t next; /* Compressed pointer to next record */
uint8_t type; /* Type of record */
ecma_number_t number; /* Number stored in the record */
} lit_number_record_t;
/**
* Magic record header
*/
typedef struct
{
uint16_t next; /* Compressed pointer to next record */
uint8_t type; /* Type of record */
uint32_t magic_id; /* Magic ID stored in the record */
} lit_magic_record_t;
#define LIT_CHARSET_HEADER_SIZE (sizeof(lit_charset_record_t))
extern lit_record_t *lit_create_charset_literal (const lit_utf8_byte_t *, const lit_utf8_size_t);
extern lit_record_t *lit_create_magic_literal (const lit_magic_string_id_t);
extern lit_record_t *lit_create_magic_literal_ex (const lit_magic_string_ex_id_t);
extern lit_record_t *lit_create_number_literal (const ecma_number_t);
extern lit_record_t *lit_free_literal (lit_record_t *);
extern size_t lit_get_literal_size (const lit_record_t *);
extern uint32_t lit_count_literals ();
#ifdef JERRY_ENABLE_LOG
extern void lit_dump_literals ();
#endif /* JERRY_ENABLE_LOG */
#define LIT_RECORD_IS_CHARSET(lit) (((lit_record_t *) lit)->type == LIT_RECORD_TYPE_CHARSET)
#define LIT_RECORD_IS_MAGIC_STR(lit) (((lit_record_t *) lit)->type == LIT_RECORD_TYPE_MAGIC_STR)
#define LIT_RECORD_IS_MAGIC_STR_EX(lit) (((lit_record_t *) lit)->type == LIT_RECORD_TYPE_MAGIC_STR_EX)
#define LIT_RECORD_IS_NUMBER(lit) (((lit_record_t *) lit)->type == LIT_RECORD_TYPE_NUMBER)
#endif /* !LIT_LITERAL_STORAGE_H */

View File

@ -1,384 +0,0 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lit-literal.h"
#include "ecma-helpers.h"
#include "lit-cpointer.h"
#include "lit-magic-strings.h"
#include "lit-literal-storage.h"
/**
* Initialize literal storage
*/
void
lit_init (void)
{
lit_magic_strings_ex_init ();
} /* lit_init */
/**
* Finalize literal storage
*/
void
lit_finalize (void)
{
#ifdef JERRY_ENABLE_LOG
lit_dump_literals ();
#endif /* JERRY_ENABLE_LOG */
while (lit_storage)
{
lit_storage = lit_free_literal (lit_storage);
}
} /* lit_finalize */
/**
* Create new literal in literal storage from characters buffer.
* Don't check if the same literal already exists.
*
* @return pointer to created record
*/
lit_literal_t
lit_create_literal_from_utf8_string (const lit_utf8_byte_t *str_p, /**< string to initialize the record,
* could be non-zero-terminated */
lit_utf8_size_t str_size) /**< length of the string */
{
JERRY_ASSERT (str_p || !str_size);
lit_magic_string_id_t m_str_id;
for (m_str_id = (lit_magic_string_id_t) 0;
m_str_id < LIT_MAGIC_STRING__COUNT;
m_str_id = (lit_magic_string_id_t) (m_str_id + 1))
{
if (lit_get_magic_string_size (m_str_id) != str_size)
{
continue;
}
if (!strncmp ((const char *) str_p, (const char *) lit_get_magic_string_utf8 (m_str_id), str_size))
{
return lit_create_magic_literal (m_str_id);
}
}
lit_magic_string_ex_id_t m_str_ex_id;
for (m_str_ex_id = (lit_magic_string_ex_id_t) 0;
m_str_ex_id < lit_get_magic_string_ex_count ();
m_str_ex_id = (lit_magic_string_ex_id_t) (m_str_ex_id + 1))
{
if (lit_get_magic_string_ex_size (m_str_ex_id) != str_size)
{
continue;
}
if (!strncmp ((const char *) str_p, (const char *) lit_get_magic_string_ex_utf8 (m_str_ex_id), str_size))
{
return lit_create_magic_literal_ex (m_str_ex_id);
}
}
return lit_create_charset_literal (str_p, str_size);
} /* lit_create_literal_from_utf8_string */
/**
* Find a literal in literal storage.
* Only charset and magic string records are checked during search.
*
* @return pointer to a literal or NULL if no corresponding literal exists
*/
lit_literal_t
lit_find_literal_by_utf8_string (const lit_utf8_byte_t *str_p, /**< a string to search for */
lit_utf8_size_t str_size) /**< length of the string */
{
JERRY_ASSERT (str_p || !str_size);
lit_string_hash_t str_hash = lit_utf8_string_calc_hash (str_p, str_size);
lit_literal_t lit;
for (lit = lit_storage;
lit != NULL;
lit = lit_cpointer_decompress (lit->next))
{
const lit_record_type_t type = (lit_record_type_t) lit->type;
switch (type)
{
case LIT_RECORD_TYPE_CHARSET:
{
const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit;
if (rec_p->hash != str_hash)
{
continue;
}
if (rec_p->size != str_size)
{
continue;
}
if (!strncmp ((const char *) (rec_p + 1), (const char *) str_p, str_size))
{
return lit;
}
break;
}
case LIT_RECORD_TYPE_MAGIC_STR:
{
lit_magic_string_id_t magic_id = (lit_magic_string_id_t) ((lit_magic_record_t *) lit)->magic_id;
const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_utf8 (magic_id);
if (lit_get_magic_string_size (magic_id) != str_size)
{
continue;
}
if (!strncmp ((const char *) magic_str_p, (const char *) str_p, str_size))
{
return lit;
}
break;
}
case LIT_RECORD_TYPE_MAGIC_STR_EX:
{
lit_magic_string_ex_id_t magic_id = ((lit_magic_record_t *) lit)->magic_id;
const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_ex_utf8 (magic_id);
if (lit_get_magic_string_ex_size (magic_id) != str_size)
{
continue;
}
if (!strncmp ((const char *) magic_str_p, (const char *) str_p, str_size))
{
return lit;
}
break;
}
default:
{
JERRY_ASSERT (type == LIT_RECORD_TYPE_NUMBER);
break;
}
}
}
return NULL;
} /* lit_find_literal_by_utf8_string */
/**
* Check if a literal which holds the passed string exists.
* If it doesn't exist, create a new one.
*
* @return pointer to existing or newly created record
*/
lit_literal_t
lit_find_or_create_literal_from_utf8_string (const lit_utf8_byte_t *str_p, /**< string, could be non-zero-terminated */
const lit_utf8_size_t str_size) /**< length of the string */
{
lit_literal_t lit = lit_find_literal_by_utf8_string (str_p, str_size);
if (lit == NULL)
{
lit = lit_create_literal_from_utf8_string (str_p, str_size);
}
return lit;
} /* lit_find_or_create_literal_from_utf8_string */
/**
* Create new literal in literal storage from number.
*
* @return pointer to a newly created record
*/
inline lit_literal_t __attr_always_inline___
lit_create_literal_from_num (const ecma_number_t num) /**< number to initialize a new number literal */
{
return lit_create_number_literal (num);
} /* lit_create_literal_from_num */
/**
* Find existing or create new number literal in literal storage.
*
* @return pointer to existing or a newly created record
*/
lit_literal_t
lit_find_or_create_literal_from_num (ecma_number_t num) /**< number which a literal should contain */
{
lit_literal_t lit = lit_find_literal_by_num (num);
if (lit == NULL)
{
lit = lit_create_literal_from_num (num);
}
return lit;
} /* lit_find_or_create_literal_from_num */
/**
* Find an existing number literal which contains the passed number
*
* @return pointer to existing or null
*/
lit_literal_t
lit_find_literal_by_num (const ecma_number_t num) /**< a number to search for */
{
lit_literal_t lit;
for (lit = lit_storage;
lit != NULL;
lit = lit_cpointer_decompress (lit->next))
{
const lit_record_type_t type = (lit_record_type_t) lit->type;
if (type != LIT_RECORD_TYPE_NUMBER)
{
continue;
}
const ecma_number_t lit_num = lit_number_literal_get_number (lit);
if (lit_num == num)
{
return lit;
}
}
return NULL;
} /* lit_find_literal_by_num */
#ifndef JERRY_NDEBUG
/**
* Check if literal really exists in the storage
*
* @return true if literal exists in the storage
* false otherwise
*/
static bool
lit_literal_exists (lit_literal_t lit) /**< literal to check for existence */
{
lit_literal_t current_lit;
for (current_lit = lit_storage;
current_lit != NULL;
current_lit = lit_cpointer_decompress (current_lit->next))
{
if (current_lit == lit)
{
return true;
}
}
return false;
} /* lit_literal_exists */
#endif /* !JERRY_NDEBUG */
/**
* Convert compressed pointer to literal
*
* @return literal
*/
lit_literal_t
lit_get_literal_by_cp (lit_cpointer_t lit_cp) /**< compressed pointer to literal */
{
lit_literal_t lit = lit_cpointer_decompress (lit_cp);
#ifndef JERRY_NDEBUG
JERRY_ASSERT (lit_literal_exists (lit));
#endif /* !JERRY_NDEBUG */
return lit;
} /* lit_get_literal_by_cp */
lit_string_hash_t
lit_charset_literal_get_hash (lit_literal_t lit) /**< literal */
{
JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_CHARSET);
const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit;
return (lit_string_hash_t) rec_p->hash;
} /* lit_charset_literal_get_hash */
lit_magic_string_id_t
lit_magic_literal_get_magic_str_id (lit_literal_t lit) /**< literal */
{
JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_MAGIC_STR);
const lit_magic_record_t *const rec_p = (const lit_magic_record_t *) lit;
return (lit_magic_string_id_t) rec_p->magic_id;
} /* lit_magic_literal_get_magic_str_id */
lit_magic_string_ex_id_t
lit_magic_literal_get_magic_str_ex_id (lit_literal_t lit) /**< literal */
{
JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_MAGIC_STR_EX);
const lit_magic_record_t *const rec_p = (const lit_magic_record_t *) lit;
return (lit_magic_string_ex_id_t) rec_p->magic_id;
} /* lit_magic_literal_get_magic_str_ex_id */
inline lit_utf8_size_t __attr_always_inline___ __attr_pure___
lit_charset_literal_get_size (lit_literal_t lit) /**< literal */
{
JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_CHARSET);
const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit;
return (lit_utf8_size_t) rec_p->size;
} /* lit_charset_literal_get_size */
/**
* Get length of the literal
*
* @return code units count
*/
inline ecma_length_t __attr_always_inline___ __attr_pure___
lit_charset_literal_get_length (lit_literal_t lit) /**< literal */
{
JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_CHARSET);
const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit;
return (ecma_length_t) rec_p->length;
} /* lit_charset_literal_get_length */
inline ecma_number_t __attr_always_inline___ __attr_pure___
lit_number_literal_get_number (lit_literal_t lit) /**< literal */
{
JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_NUMBER);
const lit_number_record_t *const rec_p = (const lit_number_record_t *) lit;
return rec_p->number;
} /* lit_number_literal_get_number */
inline lit_utf8_byte_t * __attr_always_inline___ __attr_pure___
lit_charset_literal_get_charset (lit_literal_t lit) /**< literal */
{
JERRY_ASSERT (lit->type == LIT_RECORD_TYPE_CHARSET);
const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit;
return (lit_utf8_byte_t *) (rec_p + 1);
} /* lit_charset_literal_get_charset */

View File

@ -1,52 +0,0 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2016 University of Szeged.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIT_LITERAL_H
#define LIT_LITERAL_H
#include "ecma-globals.h"
#include "lit-globals.h"
#include "lit-literal-storage.h"
#include "lit-cpointer.h"
/**
* Invalid literal
*/
#define NOT_A_LITERAL (lit_cpointer_null_cp ())
extern void lit_init ();
extern void lit_finalize ();
extern lit_literal_t lit_create_literal_from_utf8_string (const lit_utf8_byte_t *, lit_utf8_size_t);
extern lit_literal_t lit_find_literal_by_utf8_string (const lit_utf8_byte_t *, lit_utf8_size_t);
extern lit_literal_t lit_find_or_create_literal_from_utf8_string (const lit_utf8_byte_t *, lit_utf8_size_t);
extern lit_literal_t lit_create_literal_from_num (ecma_number_t);
extern lit_literal_t lit_find_literal_by_num (ecma_number_t);
extern lit_literal_t lit_find_or_create_literal_from_num (ecma_number_t);
extern lit_literal_t lit_get_literal_by_cp (lit_cpointer_t);
extern ecma_number_t lit_number_literal_get_number (lit_literal_t);
extern lit_string_hash_t lit_charset_literal_get_hash (lit_literal_t);
extern lit_utf8_size_t lit_charset_literal_get_size (lit_literal_t);
extern ecma_length_t lit_charset_literal_get_length (lit_literal_t);
extern lit_utf8_byte_t *lit_charset_literal_get_charset (lit_literal_t);
extern lit_magic_string_id_t lit_magic_literal_get_magic_str_id (lit_literal_t);
extern lit_magic_string_ex_id_t lit_magic_literal_get_magic_str_ex_id (lit_literal_t);
#endif /* !LIT_LITERAL_H */

View File

@ -1,402 +0,0 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lit-snapshot.h"
#include "lit-literal.h"
#include "lit-literal-storage.h"
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
/**
* Save a record to specified snapshot buffer.
*
* @return number of bytes saved,
* or 0 - upon save failure
*/
static uint32_t
lit_snapshot_save (lit_literal_t lit, /**< literal to save */
uint8_t *buffer_p, /**< buffer to save to */
size_t buffer_size, /**< buffer size */
size_t *in_out_buffer_offset_p) /**< [in,out] buffer write offset */
{
const lit_record_type_t record_type = (lit_record_type_t) lit->type;
switch (record_type)
{
case LIT_RECORD_TYPE_CHARSET:
{
const lit_charset_record_t *const rec_p = (const lit_charset_record_t *) lit;
lit_utf8_size_t size = lit_charset_literal_get_size (lit);
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
in_out_buffer_offset_p,
&size,
sizeof (size)))
{
return 0;
}
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
in_out_buffer_offset_p,
(void *) (rec_p + 1),
size))
{
return 0;
}
return (uint32_t) (sizeof (uint32_t) + size * sizeof (uint8_t));
}
case LIT_RECORD_TYPE_NUMBER:
{
double num_value = lit_number_literal_get_number (lit);
const size_t size = sizeof (num_value);
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
in_out_buffer_offset_p,
&num_value,
size))
{
return 0;
}
return (uint32_t) size;
}
case LIT_RECORD_TYPE_MAGIC_STR:
{
lit_magic_string_id_t id = lit_magic_literal_get_magic_str_id (lit);
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
in_out_buffer_offset_p,
&id,
sizeof (id)))
{
return 0;
}
return (uint32_t) sizeof (lit_magic_string_id_t);
}
case LIT_RECORD_TYPE_MAGIC_STR_EX:
{
lit_magic_string_ex_id_t id = lit_magic_literal_get_magic_str_ex_id (lit);
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
in_out_buffer_offset_p,
&id,
sizeof (id)))
{
return 0;
}
return (uint32_t) sizeof (lit_magic_string_ex_id_t);
}
default:
{
JERRY_UNREACHABLE ();
break;
}
}
JERRY_UNREACHABLE ();
return 0;
} /* lit_snapshot_save */
/**
* Save literals to specified snapshot buffer.
*
* @return true, if save was performed successfully (i.e. buffer size is sufficient),
* false - otherwise.
*/
bool
lit_save_literals_for_snapshot (uint8_t *buffer_p, /**< [out] output snapshot buffer */
size_t buffer_size, /**< size of the buffer */
size_t *in_out_buffer_offset_p, /**< [in,out] write position in the buffer */
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal identifiers
* to the literal offsets
* in snapshot */
uint32_t *out_map_num_p, /**< [out] number of literals */
uint32_t *out_lit_table_size_p) /**< [out] number of bytes, saved to snapshot buffer */
{
uint32_t literals_num = lit_count_literals ();
uint32_t lit_table_size = 0;
*out_map_p = NULL;
*out_map_num_p = 0;
*out_lit_table_size_p = 0;
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
in_out_buffer_offset_p,
&literals_num,
sizeof (literals_num)))
{
return false;
}
lit_table_size += (uint32_t) sizeof (literals_num);
if (literals_num != 0)
{
bool is_ok = true;
size_t id_map_size = sizeof (lit_mem_to_snapshot_id_map_entry_t) * literals_num;
lit_mem_to_snapshot_id_map_entry_t *id_map_p;
id_map_p = (lit_mem_to_snapshot_id_map_entry_t *) jmem_heap_alloc_block_store_size (id_map_size);
uint32_t literal_index = 0;
lit_literal_t lit;
for (lit = lit_storage;
lit != NULL;
lit = lit_cpointer_decompress (lit->next))
{
lit_record_type_t record_type = (lit_record_type_t) lit->type;
if (record_type == LIT_RECORD_TYPE_FREE)
{
continue;
}
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
in_out_buffer_offset_p,
&record_type,
sizeof (record_type)))
{
is_ok = false;
break;
}
uint32_t bytes = lit_snapshot_save (lit, buffer_p, buffer_size, in_out_buffer_offset_p);
if (bytes == 0)
{
/* write failed */
is_ok = false;
break;
}
lit_cpointer_t lit_cp = lit_cpointer_compress (lit);
id_map_p[literal_index].literal_id = lit_cp;
id_map_p[literal_index].literal_offset = lit_table_size;
lit_table_size += (uint32_t) sizeof (record_type);
lit_table_size += bytes;
literal_index++;
}
if (!is_ok)
{
jmem_heap_free_block_size_stored (id_map_p);
return false;
}
JERRY_ASSERT (literal_index == literals_num);
*out_map_p = id_map_p;
}
uint32_t aligned_size = JERRY_ALIGNUP (lit_table_size, JMEM_ALIGNMENT);
if (aligned_size != lit_table_size)
{
JERRY_ASSERT (aligned_size > lit_table_size);
uint8_t padding = 0;
uint32_t padding_bytes_num = (uint32_t) (aligned_size - lit_table_size);
uint32_t i;
for (i = 0; i < padding_bytes_num; i++)
{
if (!jrt_write_to_buffer_by_offset (buffer_p,
buffer_size,
in_out_buffer_offset_p,
&padding,
sizeof (uint8_t)))
{
return false;
}
}
}
*out_map_num_p = literals_num;
*out_lit_table_size_p = aligned_size;
return true;
} /* lit_save_literals_for_snapshot */
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
/**
* Load literals from snapshot.
*
* @return true, if load was performed successfully (i.e. literals saved in the snapshot are consistent),
* false - otherwise (i.e. snapshot is incorrect).
*/
bool
lit_load_literals_from_snapshot (const uint8_t *lit_table_p, /**< buffer with literal table in snapshot */
uint32_t lit_table_size, /**< size of literal table in snapshot */
lit_mem_to_snapshot_id_map_entry_t **out_map_p, /**< [out] map from literal offsets
* in snapshot to identifiers
* of loaded literals in literal
* storage */
uint32_t *out_map_num_p) /**< [out] literals number */
{
*out_map_p = NULL;
*out_map_num_p = 0;
size_t lit_table_read = 0;
uint32_t literals_num;
if (!jrt_read_from_buffer_by_offset (lit_table_p,
lit_table_size,
&lit_table_read,
&literals_num,
sizeof (literals_num)))
{
return false;
}
if (literals_num == 0)
{
return true;
}
size_t id_map_size = sizeof (lit_mem_to_snapshot_id_map_entry_t) * literals_num;
lit_mem_to_snapshot_id_map_entry_t *id_map_p;
id_map_p = (lit_mem_to_snapshot_id_map_entry_t *) jmem_heap_alloc_block_store_size (id_map_size);
bool is_ok = true;
uint32_t lit_index;
for (lit_index = 0; lit_index < literals_num; ++lit_index)
{
uint32_t offset = (uint32_t) lit_table_read;
JERRY_ASSERT (offset == lit_table_read);
lit_record_type_t type;
if (!jrt_read_from_buffer_by_offset (lit_table_p,
lit_table_size,
&lit_table_read,
&type,
sizeof (type)))
{
is_ok = false;
break;
}
lit_literal_t lit;
if (type == LIT_RECORD_TYPE_CHARSET)
{
lit_utf8_size_t length;
if (!jrt_read_from_buffer_by_offset (lit_table_p,
lit_table_size,
&lit_table_read,
&length,
sizeof (length))
|| (lit_table_read + length > lit_table_size))
{
is_ok = false;
break;
}
lit = (lit_literal_t) lit_find_or_create_literal_from_utf8_string (lit_table_p + lit_table_read, length);
lit_table_read += length;
}
else if (type == LIT_RECORD_TYPE_MAGIC_STR)
{
lit_magic_string_id_t id;
if (!jrt_read_from_buffer_by_offset (lit_table_p,
lit_table_size,
&lit_table_read,
&id,
sizeof (id)))
{
is_ok = false;
break;
}
const lit_utf8_byte_t *magic_str_p = lit_get_magic_string_utf8 (id);
lit_utf8_size_t magic_str_sz = lit_get_magic_string_size (id);
/* TODO: Consider searching literal storage by magic string identifier instead of by its value */
lit = (lit_literal_t) lit_find_or_create_literal_from_utf8_string (magic_str_p, magic_str_sz);
}
else if (type == LIT_RECORD_TYPE_MAGIC_STR_EX)
{
lit_magic_string_ex_id_t id;
if (!jrt_read_from_buffer_by_offset (lit_table_p,
lit_table_size,
&lit_table_read,
&id,
sizeof (id)))
{
is_ok = false;
break;
}
const lit_utf8_byte_t *magic_str_ex_p = lit_get_magic_string_ex_utf8 (id);
lit_utf8_size_t magic_str_ex_sz = lit_get_magic_string_ex_size (id);
/* TODO: Consider searching literal storage by magic string identifier instead of by its value */
lit = (lit_literal_t) lit_find_or_create_literal_from_utf8_string (magic_str_ex_p, magic_str_ex_sz);
}
else if (type == LIT_RECORD_TYPE_NUMBER)
{
double num;
if (!jrt_read_from_buffer_by_offset (lit_table_p,
lit_table_size,
&lit_table_read,
&num,
sizeof (num)))
{
is_ok = false;
break;
}
lit = (lit_literal_t) lit_find_or_create_literal_from_num ((ecma_number_t) num);
}
else
{
is_ok = false;
break;
}
id_map_p[lit_index].literal_offset = offset;
id_map_p[lit_index].literal_id = lit_cpointer_compress (lit);
}
if (is_ok)
{
*out_map_p = id_map_p;
*out_map_num_p = literals_num;
return true;
}
jmem_heap_free_block_size_stored (id_map_p);
return false;
} /* lit_load_literals_from_snapshot */
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */

View File

@ -1,47 +0,0 @@
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
* Copyright 2015-2016 University of Szeged
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LIT_SNAPSHOT_H
#define LIT_SNAPSHOT_H
#include "lit-cpointer.h"
#include "ecma-globals.h"
typedef struct
{
lit_cpointer_t literal_id;
uint32_t literal_offset;
} lit_mem_to_snapshot_id_map_entry_t;
#ifdef JERRY_ENABLE_SNAPSHOT_SAVE
extern bool
lit_save_literals_for_snapshot (uint8_t *,
size_t,
size_t *,
lit_mem_to_snapshot_id_map_entry_t **,
uint32_t *,
uint32_t *);
#endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
extern bool
lit_load_literals_from_snapshot (const uint8_t *,
uint32_t,
lit_mem_to_snapshot_id_map_entry_t **,
uint32_t *);
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
#endif /* !LIT_SNAPSHOT_H */

View File

@ -106,9 +106,12 @@ util_print_literal (lexer_literal_t *literal_p) /**< literal */
}
else if (literal_p->type == LEXER_NUMBER_LITERAL)
{
lit_literal_t literal = lit_get_literal_by_cp (literal_p->u.value);
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, literal_p->u.value);
JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER);
printf ("number(");
util_print_number (lit_number_literal_get_number (literal));
util_print_number (ecma_get_number_from_value (value_p->u.lit_number));
}
else if (literal_p->type == LEXER_REGEXP_LITERAL)
{

View File

@ -44,7 +44,6 @@
#include "ecma-globals.h"
#include "ecma-regexp-object.h"
#include "lit-literal.h"
#include "jmem-heap.h"
/* Immediate management. */
@ -90,7 +89,7 @@ typedef struct
{
union
{
lit_cpointer_t value; /**< literal value (not processed by the parser) */
jmem_cpointer_t value; /**< literal value (not processed by the parser) */
const uint8_t *char_p; /**< character value */
ecma_compiled_code_t *bytecode_p; /**< compiled function or regexp pointer */
uint32_t source_data; /**< encoded source literal */

View File

@ -17,7 +17,7 @@
#include "ecma-alloc.h"
#include "ecma-helpers.h"
#include "ecma-function-object.h"
#include "jerry-snapshot.h"
#include "ecma-literal-storage.h"
#include "js-parser-internal.h"
#include "lit-char-helpers.h"
@ -1523,7 +1523,6 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
{
parser_list_iterator_t literal_iterator;
lexer_literal_t *literal_p;
lit_cpointer_t lit_cp;
ecma_number_t num;
uint32_t literal_index = 0;
uint16_t length = context_p->token.lit_location.length;
@ -1567,7 +1566,7 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
num = -num;
}
lit_cp = lit_cpointer_compress (lit_find_or_create_literal_from_num (num));
jmem_cpointer_t lit_cp = ecma_find_or_create_literal_number (num);
parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL)

View File

@ -15,10 +15,8 @@
*/
#include "ecma-helpers.h"
#include "jerry-snapshot.h"
#include "ecma-literal-storage.h"
#include "js-parser-internal.h"
#include "lit-literal.h"
#include "lit-cpointer.h"
#ifdef PARSER_DUMP_BYTE_CODE
static int parser_show_instrs = PARSER_FALSE;
@ -99,9 +97,8 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
if (char_p != NULL)
{
lit_literal_t lit = lit_find_or_create_literal_from_utf8_string (char_p,
literal_p->prop.length);
literal_p->u.value = lit_cpointer_compress (lit);
literal_p->u.value = ecma_find_or_create_literal_string (char_p,
literal_p->prop.length);
if (!(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
{
@ -424,7 +421,7 @@ parser_encode_literal (uint8_t *dst_p, /**< destination buffer */
static uint8_t *
parser_generate_initializers (parser_context_t *context_p, /**< context */
uint8_t *dst_p, /**< destination buffer */
lit_cpointer_t *literal_pool_p, /**< start of literal pool */
jmem_cpointer_t *literal_pool_p, /**< start of literal pool */
uint16_t uninitialized_var_end, /**< end of the uninitialized var group */
uint16_t initialized_var_end, /**< end of the initialized var group */
uint16_t const_literal_end, /**< end of the const literal group */
@ -520,9 +517,9 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
|| literal_p->type == LEXER_STRING_LITERAL)
{
#ifdef PARSER_DUMP_BYTE_CODE
lit_literal_t lit = lit_find_or_create_literal_from_utf8_string (literal_p->u.char_p,
literal_p->prop.length);
literal_pool_p[literal_p->prop.index] = lit_cpointer_compress (lit);
jmem_cpointer_t lit_cp = ecma_find_or_create_literal_string (literal_p->u.char_p,
literal_p->prop.length);
literal_pool_p[literal_p->prop.index] = lit_cp;
if (!context_p->is_show_opcodes
&& !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
@ -1095,7 +1092,7 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
byte_code_start_p += sizeof (cbc_uint8_arguments_t);
}
byte_code_start_p += literal_end * sizeof (lit_cpointer_t);
byte_code_start_p += literal_end * sizeof (jmem_cpointer_t);
byte_code_end_p = byte_code_start_p + length;
byte_code_p = byte_code_start_p;
@ -1263,7 +1260,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
int needs_uint16_arguments;
cbc_opcode_t last_opcode = CBC_EXT_OPCODE;
ecma_compiled_code_t *compiled_code_p;
lit_cpointer_t *literal_pool_p;
jmem_cpointer_t *literal_pool_p;
uint8_t *dst_p;
if ((size_t) context_p->stack_limit + (size_t) context_p->register_count > PARSER_MAXIMUM_STACK_LIMIT)
@ -1460,7 +1457,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
total_size = sizeof (cbc_uint16_arguments_t);
}
total_size += length + context_p->literal_count * sizeof (lit_cpointer_t);
total_size += length + context_p->literal_count * sizeof (jmem_cpointer_t);
total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT);
compiled_code_p = (ecma_compiled_code_t *) parser_malloc (context_p, total_size);
@ -1520,8 +1517,8 @@ parser_post_processing (parser_context_t *context_p) /**< context */
compiled_code_p->status_flags |= CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED;
}
literal_pool_p = (lit_cpointer_t *) byte_code_p;
byte_code_p += context_p->literal_count * sizeof (lit_cpointer_t);
literal_pool_p = (jmem_cpointer_t *) byte_code_p;
byte_code_p += context_p->literal_count * sizeof (jmem_cpointer_t);
dst_p = parser_generate_initializers (context_p,
byte_code_p,
@ -1713,9 +1710,9 @@ parser_post_processing (parser_context_t *context_p) /**< context */
{
uint32_t source_data = literal_p->u.source_data;
const uint8_t *char_p = context_p->source_end_p - (source_data & 0xfffff);
lit_literal_t lit = lit_find_or_create_literal_from_utf8_string (char_p,
source_data >> 20);
literal_pool_p[literal_p->prop.index] = lit_cpointer_compress (lit);
jmem_cpointer_t lit_cp = ecma_find_or_create_literal_string (char_p,
source_data >> 20);
literal_pool_p[literal_p->prop.index] = lit_cp;
}
}
}
@ -1745,7 +1742,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
{
if (literal_p->u.char_p == NULL)
{
literal_pool_p[argument_count] = lit_cpointer_null_cp ();
literal_pool_p[argument_count] = JMEM_CP_NULL;
argument_count++;
continue;
}

View File

@ -259,15 +259,14 @@ vm_op_delete_prop (ecma_value_t object, /**< base object */
* Returned value must be freed with ecma_free_value
*/
ecma_value_t
vm_op_delete_var (lit_cpointer_t name_literal, /**< name literal */
vm_op_delete_var (jmem_cpointer_t name_literal, /**< name literal */
ecma_object_t *lex_env_p, /**< lexical environment */
bool is_strict) /**< strict mode */
{
ecma_value_t completion_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_string_t *var_name_str_p;
ecma_string_t *var_name_str_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, name_literal);
var_name_str_p = ecma_new_ecma_string_from_lit_cp (name_literal);
ecma_reference_t ref = ecma_op_get_identifier_reference (lex_env_p,
var_name_str_p,
is_strict);
@ -297,7 +296,6 @@ vm_op_delete_var (lit_cpointer_t name_literal, /**< name literal */
}
ecma_free_reference (ref);
ecma_deref_ecma_string (var_name_str_p);
return completion_value;
} /* vm_op_delete_var */

View File

@ -107,7 +107,7 @@ ecma_value_t
vm_op_delete_prop (ecma_value_t, ecma_value_t, bool);
ecma_value_t
vm_op_delete_var (lit_cpointer_t, ecma_object_t *, bool);
vm_op_delete_var (jmem_cpointer_t, ecma_object_t *, bool);
ecma_collection_header_t *
opfunc_for_in (ecma_value_t, ecma_value_t *);

View File

@ -47,7 +47,7 @@ typedef struct
uint8_t *byte_code_start_p; /**< byte code start pointer */
ecma_value_t *registers_p; /**< register start pointer */
ecma_value_t *stack_top_p; /**< stack top pointer */
lit_cpointer_t *literal_start_p; /**< literal list start pointer */
jmem_cpointer_t *literal_start_p; /**< literal list start pointer */
ecma_object_t *lex_env_p; /**< current lexical environment */
ecma_value_t this_binding; /**< this binding */
ecma_value_t call_block_result; /**< preserve block result during a call */

View File

@ -31,7 +31,6 @@
#include "ecma-objects-general.h"
#include "ecma-regexp-object.h"
#include "ecma-try-catch-macro.h"
#include "lit-literal-storage.h"
#include "opcodes.h"
#include "vm.h"
#include "vm-stack.h"
@ -295,7 +294,7 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */
*/
static ecma_value_t
vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
lit_cpointer_t lit_cp) /**< literal */
jmem_cpointer_t lit_cp) /**< literal */
{
ecma_compiled_code_t *bytecode_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
lit_cp);
@ -504,7 +503,8 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
} \
else \
{ \
ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]); \
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, \
literal_start_p[literal_index]); \
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p, \
name_p); \
if (ref_base_lex_env_p != NULL) \
@ -518,8 +518,6 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
result = ecma_raise_reference_error (ECMA_ERR_MSG ("")); \
} \
\
ecma_deref_ecma_string (name_p); \
\
if (ECMA_IS_VALUE_ERROR (result)) \
{ \
goto error; \
@ -529,17 +527,17 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
} \
else if (literal_index < const_literal_end) \
{ \
lit_cpointer_t lit_cpointer = literal_start_p[literal_index]; \
lit_literal_t lit = lit_cpointer_decompress (lit_cpointer); \
if (unlikely (LIT_RECORD_IS_NUMBER (lit))) \
ecma_string_t *value_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t, \
literal_start_p[literal_index]); \
\
if (unlikely (ECMA_STRING_GET_CONTAINER (value_p) == ECMA_STRING_LITERAL_NUMBER)) \
{ \
ecma_number_t number = lit_number_literal_get_number (lit); \
(target_value) = ecma_make_number_value (number); \
(target_value) = ecma_fast_copy_value (value_p->u.lit_number); \
} \
else \
{ \
ecma_string_t *string_p = ecma_new_ecma_string_from_lit_cp (lit_cpointer); \
(target_value) = ecma_make_string_value (string_p); \
ecma_ref_ecma_string (value_p); \
(target_value) = ecma_make_string_value (value_p); \
} \
} \
else \
@ -578,7 +576,7 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
uint16_t encoding_limit;
uint16_t encoding_delta;
uint16_t register_end;
lit_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p;
jmem_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p;
bool is_strict = ((frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0);
/* Prepare. */
@ -618,9 +616,9 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
while (literal_index <= literal_index_end)
{
ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]);
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
literal_start_p[literal_index]);
vm_var_decl (frame_ctx_p, name_p);
ecma_deref_ecma_string (name_p);
literal_index++;
}
break;
@ -649,7 +647,8 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{
uint32_t value_index;
ecma_value_t lit_value;
ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]);
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
literal_start_p[literal_index]);
vm_var_decl (frame_ctx_p, name_p);
@ -678,7 +677,6 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
ecma_free_value (lit_value);
}
ecma_deref_ecma_string (name_p);
literal_index++;
}
break;
@ -714,7 +712,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{
const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
uint8_t *byte_code_p = frame_ctx_p->byte_code_p;
lit_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p;
jmem_cpointer_t *literal_start_p = frame_ctx_p->literal_start_p;
ecma_value_t *stack_top_p;
uint16_t encoding_limit;
@ -1109,7 +1107,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
}
else
{
ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]);
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
literal_start_p[literal_index]);
ecma_object_t *ref_base_lex_env_p;
ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p,
@ -1128,11 +1127,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (ECMA_IS_VALUE_ERROR (result))
{
ecma_deref_ecma_string (name_p);
goto error;
}
ecma_ref_object (ref_base_lex_env_p);
ecma_ref_ecma_string (name_p);
*stack_top_p++ = ecma_make_object_value (ref_base_lex_env_p);
*stack_top_p++ = ecma_make_string_value (name_p);
*stack_top_p++ = result;
@ -1611,7 +1610,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
}
else
{
ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]);
ecma_string_t *name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
literal_start_p[literal_index]);
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p,
name_p);
@ -1627,8 +1628,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
}
ecma_deref_ecma_string (name_p);
if (ECMA_IS_VALUE_ERROR (result))
{
goto error;
@ -2158,20 +2157,16 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
}
else
{
ecma_string_t *var_name_str_p;
ecma_object_t *ref_base_lex_env_p;
var_name_str_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]);
ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p,
var_name_str_p);
ecma_string_t *var_name_str_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
literal_start_p[literal_index]);
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p,
var_name_str_p);
ecma_value_t put_value_result = ecma_op_put_value_lex_env_base (ref_base_lex_env_p,
var_name_str_p,
is_strict,
result);
ecma_deref_ecma_string (var_name_str_p);
if (ECMA_IS_VALUE_ERROR (put_value_result))
{
ecma_free_value (result);
@ -2325,12 +2320,11 @@ error:
catch_env_p = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p);
catch_name_p = ecma_new_ecma_string_from_lit_cp (literal_start_p[literal_index]);
catch_name_p = JMEM_CP_GET_NON_NULL_POINTER (ecma_string_t,
literal_start_p[literal_index]);
ecma_op_create_mutable_binding (catch_env_p, catch_name_p, false);
ecma_deref_ecma_string (catch_name_p);
stack_top_p[-2 - 1] = ecma_make_object_value (frame_ctx_p->lex_env_p);
frame_ctx_p->lex_env_p = catch_env_p;
}
@ -2498,7 +2492,7 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
const ecma_value_t *arg_list_p, /**< arguments list */
ecma_length_t arg_list_len) /**< length of arguments list */
{
lit_cpointer_t *literal_p;
jmem_cpointer_t *literal_p;
vm_frame_ctx_t frame_ctx;
uint32_t call_stack_size;
@ -2507,7 +2501,7 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_header_p;
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
frame_ctx.literal_start_p = literal_p;
literal_p += args_p->literal_end;
call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit);
@ -2517,7 +2511,7 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_header_p;
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
literal_p = (jmem_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
frame_ctx.literal_start_p = literal_p;
literal_p += args_p->literal_end;
call_stack_size = (uint32_t) (args_p->register_end + args_p->stack_limit);

View File

@ -18,7 +18,6 @@
#define VM_H
#include "ecma-globals.h"
#include "lit-cpointer.h"
#include "jrt.h"
#include "vm-defines.h"

View File

@ -16,7 +16,6 @@
#include "ecma-helpers.h"
#include "lit-strings.h"
#include "ecma-init-finalize.h"
#include "lit-literal.h"
#include "lit-char-helpers.h"
#include "js-parser-internal.h"
@ -28,7 +27,6 @@ main ()
TEST_INIT ();
jmem_init ();
lit_init ();
ecma_init ();
const uint8_t _1_byte_long1[] = "\\u007F";
@ -76,7 +74,6 @@ main ()
JERRY_ASSERT (length == 3);
ecma_finalize ();
lit_finalize ();
jmem_finalize (true);
return 0;

View File

@ -15,8 +15,7 @@
*/
#include "ecma-helpers.h"
#include "lit-literal.h"
#include "lit-literal-storage.h"
#include "ecma-literal-storage.h"
#include "test-common.h"
// Iterations count
@ -55,31 +54,6 @@ generate_number ()
return num;
} /* generate_number */
static bool
compare_utf8_string_and_string_literal (const lit_utf8_byte_t *str_p, lit_utf8_size_t str_size, lit_literal_t lit)
{
if (LIT_RECORD_IS_CHARSET (lit))
{
lit_utf8_byte_t *lit_str_p = lit_charset_literal_get_charset (lit);
lit_utf8_size_t lit_str_size = lit_charset_literal_get_size (lit);
return lit_compare_utf8_strings (str_p, str_size, lit_str_p, lit_str_size);
}
else if (LIT_RECORD_IS_MAGIC_STR (lit))
{
lit_magic_string_id_t magic_id = lit_magic_literal_get_magic_str_id (lit);
return lit_compare_utf8_string_and_magic_string (str_p, str_size, magic_id);
}
else if (LIT_RECORD_IS_MAGIC_STR_EX (lit))
{
lit_magic_string_ex_id_t magic_id = lit_magic_literal_get_magic_str_ex_id (lit);
return lit_compare_utf8_string_and_magic_string_ex (str_p, str_size, magic_id);
}
return false;
} /* compare_utf8_string_and_string_literal */
int
main ()
{
@ -91,7 +65,7 @@ main ()
lit_utf8_size_t lengths[test_sub_iters];
jmem_init ();
lit_init ();
ecma_init_lit_storage ();
for (uint32_t i = 0; i < test_iters; i++)
{
@ -106,7 +80,7 @@ main ()
{
lengths[j] = (lit_utf8_size_t) (rand () % max_characters_in_string + 1);
generate_string (strings[j], lengths[j]);
lit_create_literal_from_utf8_string (strings[j], lengths[j]);
ecma_find_or_create_literal_string (strings[j], lengths[j]);
strings[j][lengths[j]] = '\0';
ptrs[j] = strings[j];
JERRY_ASSERT (ptrs[j]);
@ -117,36 +91,34 @@ main ()
ptrs[j] = lit_get_magic_string_utf8 (msi);
JERRY_ASSERT (ptrs[j]);
lengths[j] = (lit_utf8_size_t) lit_zt_utf8_string_size (ptrs[j]);
lit_create_literal_from_utf8_string (ptrs[j], lengths[j]);
ecma_find_or_create_literal_string (ptrs[j], lengths[j]);
}
else
{
ecma_number_t num = generate_number ();
lengths[j] = ecma_number_to_utf8_string (num, strings[j], max_characters_in_string);
lit_create_literal_from_num (num);
ecma_find_or_create_literal_number (num);
}
}
// Add empty string
lit_create_literal_from_utf8_string (NULL, 0);
ecma_find_or_create_literal_string (NULL, 0);
for (uint32_t j = 0; j < test_sub_iters; j++)
{
lit_literal_t lit1;
lit_literal_t lit2;
jmem_cpointer_t lit1;
jmem_cpointer_t lit2;
if (ptrs[j])
{
lit1 = lit_find_or_create_literal_from_utf8_string (ptrs[j], lengths[j]);
lit2 = lit_find_literal_by_utf8_string (ptrs[j], lengths[j]);
JERRY_ASSERT (compare_utf8_string_and_string_literal (ptrs[j], lengths[j], lit1));
JERRY_ASSERT (compare_utf8_string_and_string_literal (ptrs[j], lengths[j], lit2));
lit1 = ecma_find_or_create_literal_string (ptrs[j], lengths[j]);
lit2 = ecma_find_or_create_literal_string (ptrs[j], lengths[j]);
JERRY_ASSERT (lit1 == lit2);
}
else
{
lit1 = lit_find_or_create_literal_from_num (numbers[j]);
lit2 = lit_find_literal_by_num (numbers[j]);
JERRY_ASSERT (numbers[j] == lit_number_literal_get_number (lit1));
JERRY_ASSERT (numbers[j] == lit_number_literal_get_number (lit2));
lit1 = ecma_find_or_create_literal_number (numbers[j]);
lit2 = ecma_find_or_create_literal_number (numbers[j]);
JERRY_ASSERT (lit1 == lit2);
}
JERRY_ASSERT (lit1);
JERRY_ASSERT (lit2);
@ -154,10 +126,10 @@ main ()
}
// Check empty string exists
JERRY_ASSERT (lit_find_literal_by_utf8_string (NULL, 0));
JERRY_ASSERT (ecma_find_or_create_literal_string (NULL, 0) != JMEM_CP_NULL);
}
lit_finalize ();
ecma_finalize_lit_storage ();
jmem_finalize (true);
return 0;
} /* main */

View File

@ -17,7 +17,6 @@
#include "ecma-helpers.h"
#include "lit-strings.h"
#include "ecma-init-finalize.h"
#include "lit-literal.h"
#include "test-common.h"
@ -107,7 +106,6 @@ main ()
TEST_INIT ();
jmem_init ();
lit_init ();
ecma_init ();
lit_utf8_byte_t cesu8_string[max_bytes_in_string];
@ -219,7 +217,6 @@ main ()
JERRY_ASSERT (res_buf[2] == 0xBF);
ecma_finalize ();
lit_finalize ();
jmem_finalize (true);
return 0;