diff --git a/jerry-core/CMakeLists.txt b/jerry-core/CMakeLists.txt index d24ac1b101..163ff5c1ae 100644 --- a/jerry-core/CMakeLists.txt +++ b/jerry-core/CMakeLists.txt @@ -93,6 +93,7 @@ project (JerryCore CXX C ASM) # Include directories set(INCLUDE_CORE ${CMAKE_SOURCE_DIR}/jerry-core + ${CMAKE_SOURCE_DIR}/jerry-core/rcs ${CMAKE_SOURCE_DIR}/jerry-core/mem ${CMAKE_SOURCE_DIR}/jerry-core/vm ${CMAKE_SOURCE_DIR}/jerry-core/ecma/builtin-objects @@ -109,6 +110,7 @@ project (JerryCore CXX C ASM) # Sources # Jerry core file(GLOB SOURCE_CORE_API *.cpp) + file(GLOB SOURCE_CORE_RCS rcs/*.cpp) file(GLOB SOURCE_CORE_MEM mem/*.cpp) file(GLOB SOURCE_CORE_VM vm/*.cpp) file(GLOB SOURCE_CORE_ECMA_BUILTINS ecma/builtin-objects/*.cpp) @@ -121,6 +123,7 @@ project (JerryCore CXX C ASM) set(SOURCE_CORE jerry.cpp ${SOURCE_CORE_API} + ${SOURCE_CORE_RCS} ${SOURCE_CORE_MEM} ${SOURCE_CORE_VM} ${SOURCE_CORE_ECMA_BUILTINS} diff --git a/jerry-core/rcs/rcs-chunked-list.cpp b/jerry-core/rcs/rcs-chunked-list.cpp new file mode 100644 index 0000000000..29a28bee25 --- /dev/null +++ b/jerry-core/rcs/rcs-chunked-list.cpp @@ -0,0 +1,334 @@ +/* Copyright 2015 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. + */ + +#include "rcs-chunked-list.h" + +/** + * Constructor + */ +void +rcs_chunked_list_t::init (void) +{ + head_p = NULL; + tail_p = NULL; +} /* rcs_chunked_list_t::init */ + +/** + * Destructor + */ +void +rcs_chunked_list_t::free (void) +{ + JERRY_ASSERT (head_p == NULL); + JERRY_ASSERT (tail_p == NULL); +} /* rcs_chunked_list_t::free */ + +/** + * Get first node of the list + * + * @return pointer to the first node + */ +rcs_chunked_list_t::node_t* +rcs_chunked_list_t::get_first (void) +const +{ + return head_p; +} /* rcs_chunked_list_t::get_first */ + +/** + * Get last node of the list + * + * @return pointer to the last node + */ +rcs_chunked_list_t::node_t* +rcs_chunked_list_t::get_last (void) +const +{ + return tail_p; +} /* rcs_chunked_list_t::get_last */ + +/** + * Get node, previous to specified + * + * @return pointer to previous node + */ +rcs_chunked_list_t::node_t* +rcs_chunked_list_t::get_prev (rcs_chunked_list_t::node_t *node_p) /**< node to get previous for */ +const +{ + JERRY_ASSERT (node_p != NULL); + + return MEM_CP_GET_POINTER (node_t, node_p->prev_cp); +} /* rcs_chunked_list_t::get_prev */ + +/** + * Get node, next to specified + * + * @return pointer to next node + */ +rcs_chunked_list_t::node_t* +rcs_chunked_list_t::get_next (rcs_chunked_list_t::node_t *node_p) /**< node to get next for */ +const +{ + JERRY_ASSERT (node_p != NULL); + + return MEM_CP_GET_POINTER (node_t, node_p->next_cp); +} /* rcs_chunked_list_t::get_next */ + +/** + * Append new node to end of the list + * + * @return pointer to the new node + */ +rcs_chunked_list_t::node_t* +rcs_chunked_list_t::append_new (void) +{ + assert_list_is_correct (); + + node_t *node_p = (node_t*) mem_heap_alloc_chunked_block (MEM_HEAP_ALLOC_LONG_TERM); + + set_prev (node_p, tail_p); + set_next (node_p, NULL); + + if (head_p == NULL) + { + JERRY_ASSERT (tail_p == NULL); + + head_p = node_p; + tail_p = node_p; + } + else + { + JERRY_ASSERT (tail_p != NULL); + + set_next (tail_p, node_p); + + tail_p = node_p; + } + + assert_node_is_correct (node_p); + + return node_p; +} /* rcs_chunked_list_t::append_new */ + +/** + * Insert new node after the specified node + * + * @return pointer to the new node + */ +rcs_chunked_list_t::node_t* +rcs_chunked_list_t::insert_new (rcs_chunked_list_t::node_t* after_p) /**< the node to insert the new node after */ +{ + assert_list_is_correct (); + + node_t *node_p = (node_t*) mem_heap_alloc_chunked_block (MEM_HEAP_ALLOC_LONG_TERM); + + JERRY_ASSERT (head_p != NULL); + JERRY_ASSERT (tail_p != NULL); + assert_node_is_correct (after_p); + + set_next (after_p, node_p); + if (tail_p == after_p) + { + tail_p = node_p; + } + + set_prev (node_p, after_p); + set_next (node_p, NULL); + + assert_node_is_correct (node_p); + + return node_p; +} /* rcs_chunked_list_t::insert_new */ + +/** + * Remove specified node + */ +void +rcs_chunked_list_t::remove (rcs_chunked_list_t::node_t* node_p) /**< node to remove */ +{ + JERRY_ASSERT (head_p != NULL); + JERRY_ASSERT (tail_p != NULL); + + assert_node_is_correct (node_p); + + node_t *prev_node_p, *next_node_p; + prev_node_p = get_prev (node_p); + next_node_p = get_next (node_p); + + if (prev_node_p == NULL) + { + JERRY_ASSERT (head_p == node_p); + head_p = next_node_p; + } + else + { + set_next (prev_node_p, next_node_p); + } + + if (next_node_p == NULL) + { + JERRY_ASSERT (tail_p == node_p); + tail_p = prev_node_p; + } + else + { + set_prev (next_node_p, prev_node_p); + } + + mem_heap_free_block (node_p); + + assert_list_is_correct (); +} /* rcs_chunked_list_t::remove */ + +/** + * Find node containing space, pointed by specified pointer + * + * @return pointer to the node that contains the pointed area + */ +rcs_chunked_list_t::node_t* +rcs_chunked_list_t::get_node_from_pointer (void* ptr) /**< the pointer value */ +const +{ + node_t *node_p = (node_t*) mem_heap_get_chunked_block_start (ptr); + + assert_node_is_correct (node_p); + + return node_p; +} /* rcs_chunked_list_t::get_node_from_pointer */ + +/** + * Get the node's data space + * + * @return pointer to beginning of the node's data space + */ +uint8_t* +rcs_chunked_list_t::get_data_space (rcs_chunked_list_t::node_t* node_p) /**< the node */ +const +{ + assert_node_is_correct (node_p); + + return (uint8_t*) (node_p + 1); +} /* rcs_chunked_list_t::get_data_space */ + +/** + * Get size of a node's data space + * + * @return size + */ +size_t +rcs_chunked_list_t::get_data_space_size (void) +{ + return rcs_chunked_list_t::get_node_size () - sizeof (node_t); +} /* rcs_chunked_list_t::get_data_space_size */ + +/** + * Set previous node for the specified node + */ +void +rcs_chunked_list_t::set_prev (rcs_chunked_list_t::node_t *node_p, /**< node to set previous for */ + rcs_chunked_list_t::node_t *prev_node_p) /**< the previous node */ +{ + JERRY_ASSERT (node_p != NULL); + + MEM_CP_SET_POINTER (node_p->prev_cp, prev_node_p); +} /* rcs_chunked_list_t::set_prev */ + +/** + * Set next node for the specified node + */ +void +rcs_chunked_list_t::set_next (rcs_chunked_list_t::node_t *node_p, /**< node to set next for */ + rcs_chunked_list_t::node_t *next_node_p) /**< the next node */ +{ + JERRY_ASSERT (node_p != NULL); + + MEM_CP_SET_POINTER (node_p->next_cp, next_node_p); +} /* rcs_chunked_list_t::set_next */ + +/** + * Get size of the node + * + * @return size of node, including header and data space + */ +size_t +rcs_chunked_list_t::get_node_size (void) +{ + size_t size = mem_heap_recommend_allocation_size (sizeof (node_t) + 1u); + + JERRY_ASSERT (size != 0 && size >= sizeof (node_t)); + + return size; +} /* rcs_chunked_list_t::get_node_size */ + +/** + * Assert that the list state is correct + */ +void +rcs_chunked_list_t::assert_list_is_correct (void) +const +{ +#ifndef JERRY_NDEBUG + for (node_t *node_iter_p = get_first (); + node_iter_p != NULL; + node_iter_p = get_next (node_iter_p)) + { + node_t *prev_node_p = get_prev (node_iter_p); + node_t *next_node_p = get_next (node_iter_p); + + JERRY_ASSERT ((node_iter_p == head_p + && prev_node_p == NULL) + || (node_iter_p != head_p + && prev_node_p != NULL + && get_next (prev_node_p) == node_iter_p)); + JERRY_ASSERT ((node_iter_p == tail_p + && next_node_p == NULL) + || (node_iter_p != tail_p + && next_node_p != NULL + && get_prev (next_node_p) == node_iter_p)); + } +#endif /* !JERRY_NDEBUG */ +} /* rcs_chunked_list_t::assert_list_is_correct */ + +/** + * Assert that state of specified node is correct + */ +void +rcs_chunked_list_t::assert_node_is_correct (const rcs_chunked_list_t::node_t* node_p) /**< the node */ +const +{ +#ifndef JERRY_NDEBUG + JERRY_ASSERT (node_p != NULL); + + assert_list_is_correct (); + + bool is_in_list = false; + for (node_t *node_iter_p = get_first (); + node_iter_p != NULL; + node_iter_p = get_next (node_iter_p)) + { + if (node_iter_p == node_p) + { + is_in_list = true; + + break; + } + } + + JERRY_ASSERT (is_in_list); +#else /* JERRY_NDEBUG */ + (void) node_p; +#endif /* JERRY_NDEBUG */ +} /* rcs_chunked_list_t::assert_node_is_correct */ diff --git a/jerry-core/rcs/rcs-chunked-list.h b/jerry-core/rcs/rcs-chunked-list.h new file mode 100644 index 0000000000..3365bd78d0 --- /dev/null +++ b/jerry-core/rcs/rcs-chunked-list.h @@ -0,0 +1,86 @@ +/* Copyright 2015 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 RCS_CHUNKED_LIST_H +#define RCS_CHUNKED_LIST_H + +#include "mem-allocator.h" + +/** \addtogroup recordset Recordset + * @{ + * + * \addtogroup chunkedlist Chunked list + * + * List of nodes with size exactly fit to one memory heap's chunk. + * + * @{ + */ + +/** + * Chunked list + * + * Note: + * Each node exactly fits size of one memory heap's chunk + */ +class rcs_chunked_list_t +{ + public: + /** + * List node + */ + typedef struct + { + mem_cpointer_t prev_cp; /**< prev list's node */ + mem_cpointer_t next_cp; /**< next list's node */ + } node_t; + + void init (void); + void free (void); + + node_t *get_first (void) const; + node_t *get_last (void) const; + + node_t *get_prev (node_t *node_p) const; + node_t *get_next (node_t *node_p) const; + + node_t *append_new (void); + node_t *insert_new (node_t *after_p); + + void remove (node_t *node_p); + + node_t *get_node_from_pointer (void *ptr) const; + uint8_t* get_data_space (node_t *node_p) const; + + static size_t get_data_space_size (void); + + private: + void set_prev (node_t *node_p, node_t *prev_node_p); + void set_next (node_t *node_p, node_t *next_node_p); + + static size_t get_node_size (void); + + void assert_list_is_correct (void) const; + void assert_node_is_correct (const node_t *node_p) const; + + node_t* head_p; /**< head node of list */ + node_t* tail_p; /**< tail node of list */ +}; + +/** + * @} + * @} + */ + +#endif /* RCS_CHUNKED_LIST_H */ diff --git a/tools/cppcheck/suppressions-list b/tools/cppcheck/suppressions-list index b02af84f1c..7d240ff292 100644 --- a/tools/cppcheck/suppressions-list +++ b/tools/cppcheck/suppressions-list @@ -1 +1,2 @@ operatorEqVarError +noConstructor