Simplify serializer/deserializer. Reduce memory usage in lexer. Create HashTable data structure. Finish preparations for introducing new strings addressation.
This commit is contained in:
@@ -19,11 +19,7 @@
|
||||
#include "opcodes.h"
|
||||
#include "stack.h"
|
||||
#include "jerry-libc.h"
|
||||
|
||||
#ifndef OPCODE_T_STACK_DEFINED
|
||||
DEFINE_STACK_TYPE (opcode_counter_t, opcode_t)
|
||||
#define OPCODE_T_STACK_DEFINED
|
||||
#endif
|
||||
#include "lp-string.h"
|
||||
|
||||
/* bytecode_data contains identifiers, string and num literals.
|
||||
Memory map if the following.
|
||||
@@ -36,12 +32,21 @@ DEFINE_STACK_TYPE (opcode_counter_t, opcode_t)
|
||||
U8 nums_count;
|
||||
U32 nums[nums_count];
|
||||
} */
|
||||
extern uint8_t *bytecode_data;
|
||||
struct
|
||||
{
|
||||
uint8_t strs_count;
|
||||
uint8_t nums_count;
|
||||
|
||||
const lp_string *strings;
|
||||
const ecma_number_t *nums;
|
||||
}
|
||||
__packed
|
||||
bytecode_data;
|
||||
|
||||
enum
|
||||
{
|
||||
bytecode_opcodes_global_size
|
||||
};
|
||||
STACK (opcode_t, bytecode_opcodes)
|
||||
STACK (bytecode_opcodes, opcode_counter_t, opcode_t)
|
||||
|
||||
#endif // BYTECODE_DATA_H
|
||||
|
||||
@@ -16,70 +16,34 @@
|
||||
#include "deserializer.h"
|
||||
#include "bytecode-data.h"
|
||||
|
||||
ecma_number_t *num_data = NULL;
|
||||
uint8_t num_size = 0;
|
||||
|
||||
const ecma_char_t *
|
||||
deserialize_string_by_id (uint8_t id)
|
||||
{
|
||||
uint8_t size, *data;
|
||||
uint16_t offset;
|
||||
JERRY_ASSERT (bytecode_data.strings[id].str[bytecode_data.strings[id].length] == '\0');
|
||||
|
||||
if (bytecode_data == NULL)
|
||||
if (id >= bytecode_data.strs_count)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = *bytecode_data;
|
||||
|
||||
if (id >= size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = bytecode_data;
|
||||
|
||||
data += id * 2 + 1;
|
||||
|
||||
offset = *((uint16_t *) data);
|
||||
|
||||
return ((const ecma_char_t *) bytecode_data + offset);
|
||||
return ((const ecma_char_t *) bytecode_data.strings[id].str);
|
||||
}
|
||||
|
||||
ecma_number_t
|
||||
deserialize_num_by_id (uint8_t id)
|
||||
{
|
||||
uint16_t str_size;
|
||||
|
||||
str_size = *bytecode_data;
|
||||
if (id < str_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
id = (uint8_t) (id - str_size);
|
||||
|
||||
if (num_data == NULL)
|
||||
{
|
||||
// Go to last string's offset
|
||||
uint8_t *data = (uint8_t *) (bytecode_data + str_size * 2 - 1);
|
||||
uint16_t str_offset = *((uint16_t *) data);
|
||||
data = bytecode_data + str_offset;
|
||||
|
||||
while (*data)
|
||||
{
|
||||
data++;
|
||||
}
|
||||
|
||||
num_size = *(++data);
|
||||
num_data = (ecma_number_t *) ++data;
|
||||
}
|
||||
|
||||
if (id >= num_size)
|
||||
if (id < bytecode_data.strs_count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return num_data[id];
|
||||
id = (uint8_t) (id - bytecode_data.strs_count);
|
||||
|
||||
if (id >= bytecode_data.nums_count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return bytecode_data.nums[id];
|
||||
}
|
||||
|
||||
const void *
|
||||
@@ -92,12 +56,5 @@ deserialize_bytecode (void)
|
||||
uint8_t
|
||||
deserialize_min_temp (void)
|
||||
{
|
||||
uint8_t str_size = *bytecode_data;
|
||||
|
||||
if (num_size == 0)
|
||||
{
|
||||
deserialize_num_by_id (str_size); // Init num_data and num_size
|
||||
}
|
||||
|
||||
return (uint8_t) (str_size + num_size);
|
||||
return (uint8_t) (bytecode_data.strs_count + bytecode_data.nums_count);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#include "pretty-printer.h"
|
||||
#include "jerry-libc.h"
|
||||
#include "deserializer.h"
|
||||
#include "lexer.h"
|
||||
|
||||
#define NAME_TO_ID(op) (__op__idx_##op)
|
||||
|
||||
@@ -39,17 +39,24 @@ static uint8_t opcode_sizes[] =
|
||||
0
|
||||
};
|
||||
|
||||
void
|
||||
pp_strings (const char *strings[], uint8_t size)
|
||||
static void
|
||||
dump_lp (lp_string lp)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t offset = (uint16_t) (size * 2 + 1);
|
||||
|
||||
__printf ("STRINGS %d:\n", size);
|
||||
for (i = 0; i < size; i++)
|
||||
for (ecma_length_t i = 0; i < lp.length; i++)
|
||||
{
|
||||
__printf ("%3d %5d %20s\n", i, offset, strings[i]);
|
||||
offset = (uint16_t) (offset + __strlen (strings[i]) + 1);
|
||||
__putchar (lp.str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pp_strings (const lp_string strings[], uint8_t size)
|
||||
{
|
||||
__printf ("STRINGS %d:\n", size);
|
||||
for (uint8_t i = 0; i < size; i++)
|
||||
{
|
||||
__printf ("%3d ", i);
|
||||
dump_lp (strings[i]);
|
||||
__putchar ('\n');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,17 +84,17 @@ dump_arg_list (idx_t id)
|
||||
static void
|
||||
dump_variable (idx_t id)
|
||||
{
|
||||
if (id >= deserialize_min_temp ())
|
||||
if (id >= lexer_get_reserved_ids_count ())
|
||||
{
|
||||
__printf ("tmp%d", id);
|
||||
}
|
||||
else if (deserialize_string_by_id (id))
|
||||
else if (id < lexer_get_strings_count ())
|
||||
{
|
||||
__printf ("%s", deserialize_string_by_id (id));
|
||||
dump_lp (lexer_get_string_by_id (id));
|
||||
}
|
||||
else
|
||||
{
|
||||
__printf ("%d", (int) deserialize_num_by_id (id));
|
||||
__printf ("%d", (int) lexer_get_num_by_id (id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,14 +161,14 @@ dump_variable (idx_t id)
|
||||
} \
|
||||
__printf (": SIMPLE"); \
|
||||
} else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_STRING) { \
|
||||
__printf ("'%s'", deserialize_string_by_id (opcode.data.op.op2)); \
|
||||
dump_lp (lexer_get_string_by_id (opcode.data.op.op2)); \
|
||||
__printf (": STRING"); \
|
||||
} else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_NUMBER) {\
|
||||
__printf ("%d", (int) deserialize_num_by_id (opcode.data.op.op2)); \
|
||||
__printf ("%d", (int) lexer_get_num_by_id (opcode.data.op.op2)); \
|
||||
__printf (": NUMBER"); \
|
||||
} else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_SMALLINT) {\
|
||||
__printf ("%d", opcode.data.op.op2); \
|
||||
__printf (": NUMBER"); \
|
||||
__printf (": SMALLINT"); \
|
||||
} else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_VARIABLE) {\
|
||||
dump_variable (opcode.data.op.op2); \
|
||||
__printf (": TYPEOF("); \
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
#define PRETTY_PRINTER
|
||||
|
||||
#include "interpreter.h"
|
||||
#include "lp-string.h"
|
||||
|
||||
void pp_opcode (opcode_counter_t, opcode_t, bool);
|
||||
void pp_strings (const char **, uint8_t);
|
||||
void pp_strings (const lp_string *, uint8_t);
|
||||
void pp_nums (const ecma_number_t *, uint8_t, uint8_t);
|
||||
|
||||
#endif // PRETTY_PRINTER
|
||||
|
||||
@@ -22,94 +22,19 @@
|
||||
|
||||
static bool print_opcodes;
|
||||
|
||||
uint8_t *bytecode_data = NULL;
|
||||
|
||||
void
|
||||
serializer_init (bool show_opcodes)
|
||||
serializer_dump_strings_and_nums (const lp_string strings[], uint8_t strs_count,
|
||||
const ecma_number_t nums[], uint8_t nums_count)
|
||||
{
|
||||
print_opcodes = show_opcodes;
|
||||
INIT_STACK (opcode_t, bytecode_opcodes);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
serializer_dump_strings (const char *strings[], uint8_t size)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t offset = (uint16_t) (size * 2 + 1), res;
|
||||
|
||||
if (print_opcodes)
|
||||
{
|
||||
pp_strings (strings, size);
|
||||
pp_strings (strings, strs_count);
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
offset = (uint16_t) (offset + __strlen (strings[i]) + 1);
|
||||
}
|
||||
|
||||
bytecode_data = mem_heap_alloc_block (offset, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
res = offset;
|
||||
|
||||
bytecode_data[0] = size;
|
||||
offset = (uint16_t) (size * 2 + 1);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
*((uint16_t *) (bytecode_data + i * 2 + 1)) = offset;
|
||||
offset = (uint16_t) (offset + __strlen (strings[i]) + 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
offset = *((uint16_t *) (bytecode_data + i * 2 + 1));
|
||||
__strncpy ((char *) (bytecode_data + offset), strings[i], __strlen (strings[i]) + 1);
|
||||
}
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
JERRY_ASSERT (!__strcmp (strings[i], (const char *) deserialize_string_by_id (i)));
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
serializer_dump_nums (const ecma_number_t nums[], uint8_t size, uint16_t offset, uint8_t strings_num)
|
||||
{
|
||||
uint8_t i, *data, type_size = sizeof (ecma_number_t);
|
||||
|
||||
if (print_opcodes)
|
||||
{
|
||||
pp_nums (nums, size, strings_num);
|
||||
}
|
||||
|
||||
data = mem_heap_alloc_block ((size_t) (offset + size * type_size + 1), MEM_HEAP_ALLOC_LONG_TERM);
|
||||
if (!data)
|
||||
{
|
||||
parser_fatal (ERR_MEMORY);
|
||||
}
|
||||
|
||||
__memcpy (data, bytecode_data, offset);
|
||||
mem_heap_free_block (bytecode_data);
|
||||
bytecode_data = data;
|
||||
data += offset;
|
||||
data[0] = size;
|
||||
data++;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
__memcpy (data, nums + i, type_size);
|
||||
data += type_size;
|
||||
}
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
JERRY_ASSERT (nums[i] == deserialize_num_by_id ((uint8_t) (i + strings_num)));
|
||||
}
|
||||
|
||||
JERRY_ASSERT (deserialize_min_temp () == (uint8_t) (size + strings_num));
|
||||
#endif
|
||||
bytecode_data.strs_count = strs_count;
|
||||
bytecode_data.nums_count = nums_count;
|
||||
bytecode_data.strings = strings;
|
||||
bytecode_data.nums = nums;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -122,14 +47,14 @@ serializer_dump_opcode (opcode_t opcode)
|
||||
pp_opcode (STACK_SIZE (bytecode_opcodes), opcode, false);
|
||||
}
|
||||
|
||||
PUSH (bytecode_opcodes, opcode)
|
||||
STACK_PUSH (bytecode_opcodes, opcode);
|
||||
}
|
||||
|
||||
void
|
||||
serializer_rewrite_opcode (const opcode_counter_t loc, opcode_t opcode)
|
||||
{
|
||||
JERRY_ASSERT (loc < STACK_SIZE (bytecode_opcodes));
|
||||
bytecode_opcodes.data[loc] = opcode;
|
||||
STACK_ELEMENT (bytecode_opcodes, loc) = opcode;
|
||||
|
||||
if (print_opcodes)
|
||||
{
|
||||
@@ -151,18 +76,30 @@ serializer_print_opcodes (void)
|
||||
|
||||
for (loc = 0; loc < STACK_SIZE (bytecode_opcodes); loc++)
|
||||
{
|
||||
pp_opcode (loc, bytecode_opcodes.data[loc], false);
|
||||
pp_opcode (loc, STACK_ELEMENT (bytecode_opcodes, loc), false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make lp_strings also zero-terminated. */
|
||||
void
|
||||
serializer_adjust_strings (void)
|
||||
{
|
||||
for (uint8_t i = 0; i < bytecode_data.strs_count; i++)
|
||||
{
|
||||
const ecma_length_t len = bytecode_data.strings[i].length;
|
||||
((ecma_char_t *) (bytecode_data.strings[i]).str)[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
serializer_init (bool show_opcodes)
|
||||
{
|
||||
print_opcodes = show_opcodes;
|
||||
STACK_INIT (opcode_t, bytecode_opcodes);
|
||||
}
|
||||
|
||||
void
|
||||
serializer_free (void)
|
||||
{
|
||||
mem_heap_free_block (bytecode_data);
|
||||
bytecode_data = NULL;
|
||||
|
||||
if (bytecode_opcodes.data)
|
||||
{
|
||||
FREE_STACK (bytecode_opcodes);
|
||||
}
|
||||
STACK_FREE (bytecode_opcodes);
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
#include "globals.h"
|
||||
#include "opcodes.h"
|
||||
#include "interpreter.h"
|
||||
#include "lp-string.h"
|
||||
|
||||
void serializer_init (bool show_opcodes);
|
||||
|
||||
uint16_t serializer_dump_strings (const char **, uint8_t);
|
||||
|
||||
void serializer_dump_nums (const ecma_number_t *, uint8_t, uint16_t, uint8_t);
|
||||
void serializer_dump_strings_and_nums (const lp_string *, uint8_t,
|
||||
const ecma_number_t *, uint8_t);
|
||||
|
||||
void serializer_dump_opcode (opcode_t);
|
||||
|
||||
@@ -32,6 +32,8 @@ void serializer_rewrite_opcode (const opcode_counter_t, opcode_t);
|
||||
|
||||
void serializer_print_opcodes (void);
|
||||
|
||||
void serializer_adjust_strings (void);
|
||||
|
||||
void serializer_free (void);
|
||||
|
||||
#endif // SERIALIZER_H
|
||||
|
||||
Reference in New Issue
Block a user