Allocate stack memory by chunks

This commit is contained in:
Ilmir Usmanov 2014-09-30 18:40:24 +04:00
parent 1c3bf4951d
commit 9d129e15dc
10 changed files with 569 additions and 372 deletions

2
.gitignore vendored
View File

@ -4,6 +4,8 @@ out/
# IDE related files
nbproject
**.sublime-project
**.sublime-workspace
# Compiled Object files
*.slo

View File

@ -26,6 +26,8 @@
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
#include "linked-list.h"
#define DEFINE_BACKET_TYPE(NAME, KEY_TYPE, VALUE_TYPE) \
typedef struct \
{ \
@ -35,11 +37,14 @@ typedef struct \
__packed \
NAME##_backet;
TODO (/*Rewrite to NAME##_backet **backets when neccesary*/)
#define DEFINE_HASH_TYPE(NAME, KEY_TYPE, VALUE_TYPE) \
typedef struct \
{ \
uint8_t size; \
NAME##_backet_stack *backets; \
uint8_t max_lens; \
uint8_t *lens; \
NAME##_backet *backets; \
} \
__packed \
NAME##_hash_table;
@ -47,19 +52,19 @@ NAME##_hash_table;
#define HASH_INIT(NAME, SIZE) \
do { \
NAME.size = SIZE; \
size_t size = mem_heap_recommend_allocation_size (SIZE * sizeof (NAME##_backet_stack)); \
NAME.backets = (NAME##_backet_stack *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM); \
__memset (NAME.backets, 0, size); \
size_t backets_size = mem_heap_recommend_allocation_size (SIZE * sizeof (NAME##_backet)); \
size_t lens_size = mem_heap_recommend_allocation_size (SIZE); \
NAME.backets = (NAME##_backet *) mem_heap_alloc_block (backets_size, MEM_HEAP_ALLOC_SHORT_TERM); \
NAME.lens = mem_heap_alloc_block (lens_size, MEM_HEAP_ALLOC_SHORT_TERM); \
__memset (NAME.backets, 0, SIZE); \
__memset (NAME.lens, 0, SIZE); \
NAME.max_lens = 1; \
} while (0);
#define HASH_FREE(NAME) \
do { \
for (uint8_t i = 0; i < NAME.size; i++) { \
if (NAME.backets[i].length != 0) { \
mem_heap_free_block ((uint8_t *) NAME.backets[i].data); \
} \
} \
mem_heap_free_block ((uint8_t *) NAME.backets); \
mem_heap_free_block (NAME.lens); \
} while (0)
#define DEFINE_HASH_INSERT(NAME, KEY_TYPE, VALUE_TYPE) \
@ -69,42 +74,9 @@ static void hash_insert_##NAME (KEY_TYPE key, VALUE_TYPE value) { \
uint8_t hash = KEY_TYPE##_hash (key); \
JERRY_ASSERT (hash < NAME.size); \
JERRY_ASSERT (NAME.backets != NULL); \
if (NAME.backets[hash].length == 0) \
{ \
size_t stack_size = mem_heap_recommend_allocation_size (0); \
NAME.backets[hash].data = (NAME##_backet *) mem_heap_alloc_block \
(stack_size, MEM_HEAP_ALLOC_SHORT_TERM); \
NAME.backets[hash].current = 0; \
NAME.backets[hash].length = (__typeof__ (NAME.backets[hash].length)) \
(stack_size / sizeof (NAME##_backet)); \
} \
else if (NAME.backets[hash].current == NAME.backets[hash].length) \
{ \
size_t old_size = NAME.backets[hash].length * sizeof (NAME##_backet); \
size_t temp1_size = mem_heap_recommend_allocation_size ( \
(size_t) (sizeof (NAME##_backet))); \
size_t new_size = mem_heap_recommend_allocation_size ( \
(size_t) (temp1_size + old_size)); \
NAME##_backet *temp1 = (NAME##_backet *) mem_heap_alloc_block \
(temp1_size, MEM_HEAP_ALLOC_SHORT_TERM); \
NAME##_backet *temp2 = (NAME##_backet *) mem_heap_alloc_block \
(old_size, MEM_HEAP_ALLOC_SHORT_TERM); \
if (temp2 == NULL) \
{ \
mem_heap_print (true, false, true); \
JERRY_UNREACHABLE (); \
} \
__memcpy (temp2, NAME.backets[hash].data, old_size); \
mem_heap_free_block ((uint8_t *) NAME.backets[hash].data); \
mem_heap_free_block ((uint8_t *) temp1); \
NAME.backets[hash].data = (NAME##_backet *) mem_heap_alloc_block \
(new_size, MEM_HEAP_ALLOC_SHORT_TERM); \
__memcpy (NAME.backets[hash].data, temp2, old_size); \
mem_heap_free_block ((uint8_t *) temp2); \
NAME.backets[hash].length = (__typeof__ (NAME.backets[hash].length)) \
(new_size / sizeof (NAME##_backet)); \
} \
NAME.backets[hash].data[NAME.backets[hash].current++] = backet; \
JERRY_ASSERT (NAME.lens[hash] == 0); \
NAME.backets[hash] = backet; \
NAME.lens[hash] = 1; \
}
#define HASH_INSERT(NAME, KEY, VALUE) \
@ -114,16 +86,17 @@ do { \
#define DEFINE_HASH_LOOKUP(NAME, KEY_TYPE, VALUE_TYPE) \
static VALUE_TYPE *lookup_##NAME (KEY_TYPE key) __unused; \
static VALUE_TYPE *lookup_##NAME (KEY_TYPE key) { \
static VALUE_TYPE *lookup_##NAME (KEY_TYPE key) \
{ \
uint8_t hash = KEY_TYPE##_hash (key); \
JERRY_ASSERT (hash < NAME.size); \
if (NAME.backets[hash].length == 0) { \
if (NAME.lens[hash] == 0) \
{ \
return NULL; \
} \
for (size_t i = 0; i < NAME.backets[hash].current; i++) { \
if (KEY_TYPE##_equal (NAME.backets[hash].data[i].key, key)) { \
return &NAME.backets[hash].data[i].value; \
} \
if (KEY_TYPE##_equal (NAME.backets[hash].key, key)) \
{ \
return &NAME.backets[hash].value; \
} \
return NULL; \
}
@ -133,7 +106,6 @@ lookup_##NAME (KEY)
#define HASH_TABLE(NAME, KEY_TYPE, VALUE_TYPE) \
DEFINE_BACKET_TYPE (NAME, KEY_TYPE, VALUE_TYPE) \
DEFINE_STACK_TYPE (NAME##_backet, uint8_t, NAME##_backet) \
DEFINE_HASH_TYPE (NAME, KEY_TYPE, VALUE_TYPE) \
NAME##_hash_table NAME; \
DEFINE_HASH_INSERT (NAME, KEY_TYPE, VALUE_TYPE) \
@ -141,7 +113,6 @@ DEFINE_HASH_LOOKUP (NAME, KEY_TYPE, VALUE_TYPE)
#define STATIC_HASH_TABLE(NAME, KEY_TYPE, VALUE_TYPE) \
DEFINE_BACKET_TYPE (NAME, KEY_TYPE, VALUE_TYPE) \
DEFINE_STACK_TYPE (NAME##_backet, uint8_t, NAME##_backet) \
DEFINE_HASH_TYPE (NAME, KEY_TYPE, VALUE_TYPE) \
static NAME##_hash_table NAME; \
DEFINE_HASH_INSERT (NAME, KEY_TYPE, VALUE_TYPE) \

View File

@ -0,0 +1,49 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* 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 LINKED_LIST_H
#define LINKED_LIST_H
#define DEFINE_LINKED_LIST_TYPE(NAME, TYPE) \
typedef struct NAME##_linked_list \
{ \
struct NAME##_linked_list *next; \
struct NAME##_linked_list *prev; \
} \
__packed \
NAME##_linked_list;
#define DEFINE_LIST_FREE(NAME) \
static void free_##NAME##_linked_list (uint8_t *) __unused;\
static void free_##NAME##_linked_list (uint8_t *list) { \
if (((NAME##_linked_list *)list)->next) { \
free_##NAME##_linked_list ((uint8_t *) ((NAME##_linked_list *)list)->next); \
} \
mem_heap_free_block (list); \
}
#define DEFINE_LIST_ELEMENT(NAME, TYPE) \
static TYPE NAME##_list_element (uint8_t *, uint8_t) __unused; \
static TYPE NAME##_list_element (uint8_t * raw, uint8_t i) { \
return ((TYPE *) (raw + sizeof (NAME##_linked_list)))[i]; \
}
#define DEFINE_SET_LIST_ELEMENT(NAME, TYPE) \
static void set_##NAME##_list_element (uint8_t *, uint8_t, TYPE) __unused; \
static void set_##NAME##_list_element (uint8_t * raw, uint8_t i, TYPE value) { \
((TYPE *) (raw + sizeof (NAME##_linked_list)))[i] = value; \
}
#endif /* LINKED_LIST_H */

View File

@ -23,6 +23,11 @@
DO NOT FORGET to free stack memory by calling STACK_FREE macro.
For check usage of stack during a function, use STACK_DECLARE_USAGE and STACK_CHECK_USAGE macros.
For the purpose of memory fragmentation reduction, the memory is allocated by chunks and them are
used to store data. The chunks are connected to each other in manner of double-linked list.
Macro STACK_CONVERT_TO_RAW_DATA allocates memory, so use it after finishing working with the stack.
Example (parser.c):
enum
@ -61,12 +66,22 @@
#ifndef STACK_H
#define STACK_H
#include "linked-list.h"
#define DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
DEFINE_LINKED_LIST_TYPE (NAME, TYPE) \
DEFINE_LIST_FREE (NAME) \
DEFINE_LIST_ELEMENT (NAME, TYPE) \
DEFINE_SET_LIST_ELEMENT (NAME, TYPE) \
typedef TYPE NAME##_stack_value_type; \
typedef DATA_TYPE NAME##_stack_data_type; \
typedef struct \
{ \
DATA_TYPE length; \
DATA_TYPE current; \
TYPE *data; \
DATA_TYPE block_len; \
uint8_t *blocks; \
uint8_t *last; \
} \
__packed \
NAME##_stack;
@ -74,114 +89,212 @@ NAME##_stack;
#define STACK_INIT(TYPE, NAME) \
do { \
size_t stack_size = mem_heap_recommend_allocation_size (sizeof (TYPE) * NAME##_global_size); \
NAME.data = (TYPE *) mem_heap_alloc_block (stack_size, MEM_HEAP_ALLOC_SHORT_TERM); \
NAME.blocks = NAME.last = mem_heap_alloc_block (stack_size, MEM_HEAP_ALLOC_SHORT_TERM); \
__memset (NAME.blocks, 0, stack_size); \
NAME.current = NAME##_global_size; \
NAME.length = (__typeof__ (NAME.length)) (stack_size / sizeof (TYPE)); \
NAME.length = NAME.block_len = (NAME##_stack_data_type) ((stack_size-sizeof (NAME##_linked_list)) / sizeof (TYPE)); \
} while (0)
#define STACK_FREE(NAME) \
do { \
mem_heap_free_block ((uint8_t *) NAME.data); \
free_##NAME##_linked_list (NAME.blocks); \
NAME.length = NAME.current = 0; \
} while (0)
/* In most cases (for example, in parser) default size of stack is enough.
However, in serializer, there is a need for reallocation of memory.
Do this in several steps:
1) Allocate already allocated memory size twice.
2) Copy used memory to the last.
3) Dealocate first two chuncks.
4) Allocate new memory. (It must point to the memory before increasing).
5) Copy data back.
6) Free temp buffer. */
#define DEFINE_INCREASE_STACK_SIZE(NAME, TYPE) \
static void increase_##NAME##_stack_size (__typeof__ (NAME.length)) __unused; \
static void increase_##NAME##_stack_size (void) __unused; \
static void \
increase_##NAME##_stack_size (__typeof__ (NAME.length) elements_count) { \
if (NAME.current + elements_count >= NAME.length) \
increase_##NAME##_stack_size (void) { \
if (NAME.current == NAME.length && ((NAME##_linked_list *) NAME.last)->next == NULL) \
{ \
size_t old_size = NAME.length * sizeof (TYPE); \
size_t temp1_size = mem_heap_recommend_allocation_size ( \
(size_t) (elements_count * sizeof (TYPE))); \
size_t new_size = mem_heap_recommend_allocation_size ( \
(size_t) (temp1_size + old_size)); \
TYPE *temp1 = (TYPE *) mem_heap_alloc_block (temp1_size, MEM_HEAP_ALLOC_SHORT_TERM); \
TYPE *temp2 = (TYPE *) mem_heap_alloc_block (old_size, MEM_HEAP_ALLOC_SHORT_TERM); \
if (temp2 == NULL) \
size_t temp_size = mem_heap_recommend_allocation_size ((size_t) (sizeof (NAME##_linked_list))); \
JERRY_ASSERT ((temp_size-sizeof (NAME##_linked_list)) / sizeof (TYPE) == NAME.block_len); \
NAME##_linked_list *temp = (NAME##_linked_list *) mem_heap_alloc_block ( \
temp_size, MEM_HEAP_ALLOC_SHORT_TERM); \
if (temp == NULL) \
{ \
mem_heap_print (true, false, true); \
JERRY_UNREACHABLE (); \
} \
__memcpy (temp2, NAME.data, old_size); \
mem_heap_free_block ((uint8_t *) NAME.data); \
mem_heap_free_block ((uint8_t *) temp1); \
NAME.data = (TYPE *) mem_heap_alloc_block (new_size, MEM_HEAP_ALLOC_SHORT_TERM); \
if (NAME.data == NULL) \
{ \
__printf ("old_size: %d\ntemp1_size: %d\nnew_size: %d\n", old_size, temp1_size, new_size); \
mem_heap_print (true, false, true); \
JERRY_UNREACHABLE (); \
} \
__memcpy (NAME.data, temp2, old_size); \
mem_heap_free_block ((uint8_t *) temp2); \
NAME.length = (__typeof__ (NAME.length)) (new_size / sizeof (TYPE)); \
__memset (temp, 0, temp_size); \
((NAME##_linked_list *) NAME.last)->next = temp; \
temp->prev = (NAME##_linked_list *) NAME.last; \
NAME.last = (uint8_t *) temp; \
NAME.length = (NAME##_stack_data_type) (NAME.length + NAME.block_len); \
} \
NAME.current = (__typeof__ (NAME.current)) (NAME.current + elements_count); \
NAME.current = (NAME##_stack_data_type) (NAME.current + 1); \
}
#define DEFINE_DECREASE_STACE_SIZE(NAME) \
static void decrease_##NAME##_stack_size (__typeof__ (NAME.length)) __unused; \
#define DEFINE_DECREASE_STACE_SIZE(NAME, TYPE) \
static void decrease_##NAME##_stack_size (void) __unused; \
static void \
decrease_##NAME##_stack_size (__typeof__ (NAME.length) elements_count) { \
JERRY_ASSERT (NAME.current - elements_count >= NAME##_global_size); \
NAME.current = (__typeof__ (NAME.current)) (NAME.current - elements_count); \
decrease_##NAME##_stack_size (void) { \
JERRY_ASSERT (NAME.current - 1 >= NAME##_global_size); \
NAME.current = (NAME##_stack_data_type) (NAME.current - 1); \
}
#define DEFINE_STACK_ELEMENT(NAME, TYPE) \
static TYPE NAME##_stack_element (NAME##_stack_data_type) __unused; \
static TYPE NAME##_stack_element (NAME##_stack_data_type elem) { \
JERRY_ASSERT (elem < NAME.current); \
NAME##_linked_list *block = (NAME##_linked_list *) NAME.blocks; \
for (NAME##_stack_data_type i = 0; i < elem / NAME.block_len; i++) { \
JERRY_ASSERT (block->next); \
block = block->next; \
} \
return NAME##_list_element ((uint8_t *) block, (uint8_t) ((elem)%NAME.block_len)); \
}
#define DEFINE_SET_STACK_ELEMENT(NAME, TYPE) \
static void set_##NAME##_stack_element (NAME##_stack_data_type, TYPE) __unused; \
static void set_##NAME##_stack_element (NAME##_stack_data_type elem, TYPE value) { \
JERRY_ASSERT (elem < NAME.current); \
NAME##_linked_list *block = (NAME##_linked_list *) NAME.blocks; \
for (NAME##_stack_data_type i = 0; i < elem / NAME.block_len; i++) { \
JERRY_ASSERT (block->next); \
block = block->next; \
} \
set_##NAME##_list_element ((uint8_t *) block, (uint8_t) ((elem)%NAME.block_len), value); \
}
#define DEFINE_STACK_HEAD(NAME, TYPE) \
static TYPE NAME##_stack_head (NAME##_stack_data_type) __unused; \
static TYPE NAME##_stack_head (NAME##_stack_data_type elem) { \
JERRY_ASSERT (elem <= NAME.current); \
JERRY_ASSERT (elem <= NAME.block_len); \
if ((NAME.current % NAME.block_len) < elem) { \
return NAME##_list_element ((uint8_t *) ((NAME##_linked_list *) NAME.last)->prev, \
(uint8_t) ((NAME.current % NAME.block_len) - elem + NAME.block_len)); \
} else { \
return NAME##_list_element (NAME.last, (uint8_t) ((NAME.current % NAME.block_len) - elem)); \
} \
}
#define DEFINE_SET_STACK_HEAD(NAME, DATA_TYPE, TYPE) \
static void set_##NAME##_stack_head (DATA_TYPE, TYPE) __unused; \
static void set_##NAME##_stack_head (DATA_TYPE elem, TYPE value) { \
JERRY_ASSERT (elem <= NAME.current); \
JERRY_ASSERT (elem <= NAME.block_len); \
if ((NAME.current % NAME.block_len) < elem) { \
set_##NAME##_list_element ((uint8_t *) ((NAME##_linked_list *) NAME.last)->prev, \
(uint8_t) ((NAME.current % NAME.block_len) - elem + NAME.block_len), value); \
} else { \
set_##NAME##_list_element (NAME.last, (uint8_t) ((NAME.current % NAME.block_len) - elem), value); \
} \
}
#define DEFINE_STACK_PUSH(NAME, TYPE) \
static void NAME##_stack_push (TYPE) __unused; \
static void NAME##_stack_push (TYPE value) { \
if (NAME.current % NAME.block_len == 0 && NAME.current != 0) { \
increase_##NAME##_stack_size (); \
set_##NAME##_list_element (NAME.last, (uint8_t) ((NAME.current - 1) % NAME.block_len), value); \
} else { \
set_##NAME##_list_element (NAME.last, (uint8_t) ((NAME.current) % NAME.block_len), value); \
increase_##NAME##_stack_size (); \
} \
}
#define DEFINE_CONVERT_TO_RAW_DATA(NAME, TYPE) \
static TYPE *convert_##NAME##_to_raw_data (void) __unused; \
static TYPE *convert_##NAME##_to_raw_data (void) { \
size_t size = mem_heap_recommend_allocation_size ( \
((size_t) (NAME.current + 1) * sizeof (NAME##_stack_value_type))); \
TYPE *DATA = (TYPE *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM); \
__memset (DATA, 0, size); \
for (NAME##_stack_data_type i = 0; i < NAME.current; i++) { \
DATA[i] = STACK_ELEMENT (NAME, i); \
} \
return DATA; \
}
#define STACK_PUSH(NAME, VALUE) \
do { \
increase_##NAME##_stack_size (1); \
NAME.data[NAME.current - 1] = VALUE; \
} while (0)
do { NAME##_stack_push (VALUE); } while (0)
#define STACK_POP(NAME, VALUE) \
do { \
decrease_##NAME##_stack_size (1); \
VALUE = NAME.data[NAME.current]; \
decrease_##NAME##_stack_size (); \
VALUE = NAME##_list_element (NAME.last, (uint8_t) (NAME.current % NAME.block_len)); \
} while (0)
#define STACK_DROP(NAME, I) \
do { decrease_##NAME##_stack_size ((__typeof__(NAME.current))(I)); } while (0)
do { \
JERRY_ASSERT ((I) >= 0); \
for (size_t i = 0; i < (size_t) (I); i++) { \
decrease_##NAME##_stack_size (); } } while (0)
#define STACK_CLEAN(NAME) \
STACK_DROP (NAME, NAME.current - NAME##_global_size);
#define STACK_HEAD(NAME, I) \
NAME.data[NAME.current - I]
NAME##_stack_head ((NAME##_stack_data_type) (I))
#define STACK_SET_HEAD(NAME, I, VALUE) \
do { set_##NAME##_stack_head ((NAME##_stack_data_type) (I), VALUE); } while (0)
#define STACK_INCR_HEAD(NAME, I) \
do { STACK_SET_HEAD (NAME, I, (NAME##_stack_value_type) (STACK_HEAD (NAME, I) + 1)); } while (0)
#define STACK_TOP(NAME) \
STACK_HEAD (NAME, 1)
#define STACK_SWAP(NAME) \
do { \
NAME##_stack_value_type temp = STACK_TOP(NAME); \
STACK_SET_HEAD(NAME, 1, STACK_HEAD(NAME, 2)); \
STACK_SET_HEAD(NAME, 2, temp); \
} while (0)
#define STACK_SIZE(NAME) \
NAME.current
#define STACK_ELEMENT(NAME, I) \
NAME.data[I]
NAME##_stack_element ((NAME##_stack_data_type) (I))
#define STACK_RAW_DATA(NAME) \
NAME.data
#define STACK_SET_ELEMENT(NAME, I, VALUE) \
do { set_##NAME##_stack_element ((NAME##_stack_data_type) I, VALUE); } while (0);
#define STACK_CONVERT_TO_RAW_DATA(NAME, DATA) \
do { DATA = convert_##NAME##_to_raw_data (); } while (0)
#define STACK_INCR_ELEMENT(NAME, I) \
do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME, I) + 1)); } while (0)
#define STACK_DECR_ELEMENT(NAME, I) \
do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME, I) - 1)); } while (0)
#define STACK_ITERATE_VARG(NAME, FUNC, ...) \
do { for (NAME##_stack_data_type i = 0; i < NAME.current; i++) { \
FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__); \
} } while (0)
#define STACK(NAME, DATA_TYPE, TYPE) \
DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
NAME##_stack NAME; \
DEFINE_DECREASE_STACE_SIZE (NAME) \
DEFINE_INCREASE_STACK_SIZE (NAME, TYPE)
DEFINE_DECREASE_STACE_SIZE (NAME, TYPE) \
DEFINE_INCREASE_STACK_SIZE (NAME, TYPE) \
DEFINE_STACK_ELEMENT(NAME, TYPE) \
DEFINE_SET_STACK_ELEMENT(NAME, TYPE) \
DEFINE_STACK_HEAD(NAME, TYPE) \
DEFINE_CONVERT_TO_RAW_DATA(NAME, TYPE) \
DEFINE_SET_STACK_HEAD(NAME, DATA_TYPE, TYPE) \
DEFINE_STACK_PUSH(NAME, TYPE)
#define STATIC_STACK(NAME, DATA_TYPE, TYPE) \
DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
static NAME##_stack NAME; \
DEFINE_DECREASE_STACE_SIZE (NAME) \
DEFINE_INCREASE_STACK_SIZE (NAME, TYPE)
DEFINE_DECREASE_STACE_SIZE (NAME, TYPE) \
DEFINE_INCREASE_STACK_SIZE (NAME, TYPE) \
DEFINE_STACK_ELEMENT(NAME, TYPE) \
DEFINE_SET_STACK_ELEMENT(NAME, TYPE) \
DEFINE_STACK_HEAD(NAME, TYPE) \
DEFINE_CONVERT_TO_RAW_DATA(NAME, TYPE) \
DEFINE_SET_STACK_HEAD(NAME, DATA_TYPE, TYPE) \
DEFINE_STACK_PUSH(NAME, TYPE)
#ifndef JERRY_NDEBUG
#define STACK_DECLARE_USAGE(NAME) \
__typeof__(NAME.current) NAME##_current = NAME.current;
NAME##_stack_data_type NAME##_current = NAME.current;
#define STACK_CHECK_USAGE(NAME) \
do { \
JERRY_ASSERT (NAME.current == NAME##_current); \

View File

@ -496,7 +496,7 @@ convert_current_token_to_token (token_type tt)
for (uint8_t i = 0; i < STACK_SIZE (strings); i++)
{
if (current_token_equals_to_lp (strings.data[i]))
if (current_token_equals_to_lp (STACK_ELEMENT (strings, i)))
{
return (token)
{
@ -529,12 +529,12 @@ convert_seen_num_to_token (ecma_number_t num)
JERRY_ASSERT (STACK_SIZE (num_ids) == STACK_SIZE (numbers));
for (uint8_t i = 0; i < STACK_SIZE (numbers); i++)
{
if (numbers.data[i] == num)
if (STACK_ELEMENT (numbers, i) == num)
{
return (token)
{
.type = TOK_NUMBER,
.uid = num_ids.data[i]
.uid = STACK_ELEMENT (num_ids, i)
};
}
}
@ -553,7 +553,9 @@ convert_seen_num_to_token (ecma_number_t num)
const lp_string *
lexer_get_strings (void)
{
return STACK_RAW_DATA (strings);
lp_string *data = NULL;
STACK_CONVERT_TO_RAW_DATA (strings, data);
return data;
}
uint8_t
@ -578,7 +580,9 @@ lexer_get_string_by_id (uint8_t id)
const ecma_number_t *
lexer_get_nums (void)
{
return STACK_RAW_DATA (numbers);
ecma_number_t *data = NULL;
STACK_CONVERT_TO_RAW_DATA (numbers, data);
return data;
}
uint8_t
@ -593,7 +597,7 @@ lexer_adjust_num_ids (void)
JERRY_ASSERT (STACK_SIZE (numbers) == STACK_SIZE (num_ids));
for (uint8_t i = 0; i < STACK_SIZE (numbers); i++)
{
STACK_ELEMENT (num_ids, i) = (uint8_t) (STACK_ELEMENT (num_ids, i) + STACK_SIZE (strings));
STACK_SET_ELEMENT (num_ids, i, (uint8_t) (STACK_ELEMENT (num_ids, i) + STACK_SIZE (strings)));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,8 @@
#include "deserializer.h"
#include "bytecode-data.h"
static opcode_t *raw_bytecode;
const ecma_char_t *
deserialize_string_by_id (uint8_t id)
{
@ -41,7 +43,9 @@ const void *
deserialize_bytecode (void)
{
JERRY_ASSERT (STACK_SIZE (bytecode_opcodes) > 0);
return STACK_RAW_DATA (bytecode_opcodes);
JERRY_ASSERT (raw_bytecode == NULL);
STACK_CONVERT_TO_RAW_DATA (bytecode_opcodes, raw_bytecode);
return raw_bytecode;
}
opcode_t
@ -57,3 +61,22 @@ deserialize_min_temp (void)
{
return (uint8_t) (bytecode_data.strs_count + bytecode_data.nums_count);
}
void
deserializer_init (void)
{
raw_bytecode = NULL;
STACK_INIT (opcode_t, bytecode_opcodes);
}
void
deserializer_free (void)
{
STACK_FREE (bytecode_opcodes);
if (raw_bytecode)
{
mem_heap_free_block ((uint8_t *) raw_bytecode);
}
mem_heap_free_block ((uint8_t *) bytecode_data.strings);
mem_heap_free_block ((uint8_t *) bytecode_data.nums);
}

View File

@ -20,10 +20,12 @@
#include "ecma-globals.h"
#include "opcodes.h"
void deserializer_init (void);
const ecma_char_t *deserialize_string_by_id (uint8_t);
ecma_number_t deserialize_num_by_id (uint8_t);
const void *deserialize_bytecode (void);
opcode_t deserialize_opcode (opcode_counter_t);
uint8_t deserialize_min_temp (void);
void deserializer_free (void);
#endif //DESERIALIZER_H

View File

@ -61,7 +61,7 @@ void
serializer_rewrite_opcode (const opcode_counter_t loc, opcode_t opcode)
{
JERRY_ASSERT (loc < STACK_SIZE (bytecode_opcodes));
STACK_ELEMENT (bytecode_opcodes, loc) = opcode;
STACK_SET_ELEMENT (bytecode_opcodes, loc, opcode);
if (print_opcodes)
{
@ -102,11 +102,9 @@ void
serializer_init (bool show_opcodes)
{
print_opcodes = show_opcodes;
STACK_INIT (opcode_t, bytecode_opcodes);
}
void
serializer_free (void)
{
STACK_FREE (bytecode_opcodes);
}

View File

@ -39,6 +39,7 @@ jerry_run (const char *script_source, size_t script_source_size,
const opcode_t *opcodes;
mem_init ();
deserializer_init ();
parser_init (script_source, script_source_size, is_show_opcodes);
parser_parse_program ();
@ -50,10 +51,11 @@ jerry_run (const char *script_source, size_t script_source_size,
#ifdef __TARGET_HOST_x64
serializer_print_opcodes ();
#endif
parser_free ();
if (is_parse_only)
{
parser_free ();
deserializer_free ();
mem_finalize (is_show_mem_stats);
return true;
}
@ -62,8 +64,7 @@ jerry_run (const char *script_source, size_t script_source_size,
bool is_success = run_int ();
parser_free ();
deserializer_free ();
mem_finalize (is_show_mem_stats);
return is_success;