diff --git a/jerry-core/lit/lit-literal-storage.h b/jerry-core/lit/lit-literal-storage.h index 315ebdda0..cce8ad497 100644 --- a/jerry-core/lit/lit-literal-storage.h +++ b/jerry-core/lit/lit-literal-storage.h @@ -88,7 +88,7 @@ public: void set_alignment_bytes_count (size_t count) /**< count of the alignment bytes */ { - JERRY_ASSERT (count <= RCS_DYN_STORAGE_ALIGNMENT); + JERRY_ASSERT (count <= RCS_DYN_STORAGE_LENGTH_UNIT); set_field (_alignment_field_pos, _alignment_field_width, count); } /* set_alignment_bytes_count */ @@ -141,9 +141,9 @@ private: void set_size (size_t size) /**< size in bytes */ { - JERRY_ASSERT (JERRY_ALIGNUP (size, RCS_DYN_STORAGE_ALIGNMENT) == size); + JERRY_ASSERT (JERRY_ALIGNUP (size, RCS_DYN_STORAGE_LENGTH_UNIT) == size); - set_field (_length_field_pos, _length_field_width, size >> RCS_DYN_STORAGE_ALIGNMENT_LOG); + set_field (_length_field_pos, _length_field_width, size >> RCS_DYN_STORAGE_LENGTH_UNIT_LOG); } /* set_size */ /** @@ -163,12 +163,12 @@ private: * Offset and length of 'alignment' field, in bits */ static const uint32_t _alignment_field_pos = _fields_offset_begin; - static const uint32_t _alignment_field_width = 2u; + static const uint32_t _alignment_field_width = RCS_DYN_STORAGE_LENGTH_UNIT_LOG; /** * Offset and length of 'hash' field, in bits */ - static const uint32_t _hash_field_pos = _alignment_field_pos + _alignment_field_width + 2u; + static const uint32_t _hash_field_pos = _alignment_field_pos + _alignment_field_width; static const uint32_t _hash_field_width = 8u; /** diff --git a/jerry-core/mem/mem-allocator.h b/jerry-core/mem/mem-allocator.h index 306c9a210..3cc8c8736 100644 --- a/jerry-core/mem/mem-allocator.h +++ b/jerry-core/mem/mem-allocator.h @@ -53,11 +53,6 @@ typedef uint16_t mem_cpointer_t; */ #define MEM_CP_MASK ((1ull << MEM_CP_WIDTH) - 1) -/** - * Heap offset value mask - */ -#define MEM_HEAP_OFFSET_MASK ((1ull << MEM_HEAP_OFFSET_LOG) - 1) - /** * Severity of a 'try give memory back' request * diff --git a/jerry-core/mem/mem-poolman.cpp b/jerry-core/mem/mem-poolman.cpp index 8ee38f5e6..b4e33ec90 100644 --- a/jerry-core/mem/mem-poolman.cpp +++ b/jerry-core/mem/mem-poolman.cpp @@ -95,9 +95,19 @@ typedef struct mem_pool_chunk_t * in the pool containing this chunk */ uint8_t list_id; /**< identifier of a pool list */ } pool_gc; + + /** + * The field is added to make sizeof (mem_pool_chunk_t) equal to MEM_POOL_CHUNK_SIZE + */ + uint8_t allocated_area[MEM_POOL_CHUNK_SIZE]; } u; } mem_pool_chunk_t; +/** + * The condition is assumed when using pointer arithmetics on (mem_pool_chunk_t *) pointer type + */ +JERRY_STATIC_ASSERT (sizeof (mem_pool_chunk_t) == MEM_POOL_CHUNK_SIZE); + /** * List of free pool chunks */ diff --git a/jerry-core/rcs/rcs-chunked-list.cpp b/jerry-core/rcs/rcs-chunked-list.cpp index 9ef4bb8d1..5a9676c53 100644 --- a/jerry-core/rcs/rcs-chunked-list.cpp +++ b/jerry-core/rcs/rcs-chunked-list.cpp @@ -223,14 +223,14 @@ const * * @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 */ +uint8_t * +rcs_chunked_list_t::get_node_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 */ + return (uint8_t *) (node_p + 1); +} /* rcs_chunked_list_t::get_node_data_space */ /** * Get size of a node's data space @@ -238,10 +238,10 @@ const * @return size */ size_t -rcs_chunked_list_t::get_data_space_size (void) +rcs_chunked_list_t::get_node_data_space_size (void) { return rcs_chunked_list_t::get_node_size () - sizeof (node_t); -} /* rcs_chunked_list_t::get_data_space_size */ +} /* rcs_chunked_list_t::get_node_data_space_size */ /** * Set previous node for the specified node diff --git a/jerry-core/rcs/rcs-chunked-list.h b/jerry-core/rcs/rcs-chunked-list.h index 4ac91bfbb..6b9429d99 100644 --- a/jerry-core/rcs/rcs-chunked-list.h +++ b/jerry-core/rcs/rcs-chunked-list.h @@ -70,9 +70,9 @@ public: void remove (node_t *); node_t *get_node_from_pointer (void *) const; - uint8_t *get_data_space (node_t *) const; + uint8_t *get_node_data_space (node_t *) const; - static size_t get_data_space_size (void); + static size_t get_node_data_space_size (void); private: void set_prev (node_t *, node_t *); diff --git a/jerry-core/rcs/rcs-recordset.cpp b/jerry-core/rcs/rcs-recordset.cpp index d3a07e012..145f2dccb 100644 --- a/jerry-core/rcs/rcs-recordset.cpp +++ b/jerry-core/rcs/rcs-recordset.cpp @@ -53,29 +53,43 @@ rcs_recordset_t::record_t::set_type (rcs_record_t::type_t type) /**< record type * @return dynamic storage-specific extended compressed pointer */ rcs_cpointer_t -rcs_recordset_t::record_t::cpointer_t::compress (rcs_record_t* pointer) /**< pointer to compress */ +rcs_recordset_t::record_t::cpointer_t::compress (rcs_record_t *pointer) /**< pointer to compress */ { rcs_cpointer_t cpointer; + cpointer.packed_value = 0; + uintptr_t base_pointer = JERRY_ALIGNDOWN ((uintptr_t) pointer, MEM_ALIGNMENT); - uintptr_t diff = (uintptr_t) pointer - base_pointer; - JERRY_ASSERT (diff < MEM_ALIGNMENT); - JERRY_ASSERT (jrt_extract_bit_field (diff, 0, RCS_DYN_STORAGE_ALIGNMENT_LOG) == 0); - - uintptr_t ext_part = (uintptr_t) jrt_extract_bit_field (diff, - RCS_DYN_STORAGE_ALIGNMENT_LOG, - MEM_ALIGNMENT_LOG - RCS_DYN_STORAGE_ALIGNMENT_LOG); - - if ((void*) base_pointer == NULL) + if ((void *) base_pointer == NULL) { cpointer.value.base_cp = MEM_CP_NULL; } else { - cpointer.value.base_cp = mem_compress_pointer ((void*) base_pointer) & MEM_CP_MASK; + cpointer.value.base_cp = mem_compress_pointer ((void *) base_pointer) & MEM_CP_MASK; } - cpointer.value.ext = ext_part & ((1ull << (MEM_ALIGNMENT_LOG - RCS_DYN_STORAGE_ALIGNMENT_LOG)) - 1); + +#if MEM_ALIGNMENT_LOG > RCS_DYN_STORAGE_LENGTH_UNIT_LOG + /* + * If alignment of a unit in recordset storage is less than required by MEM_ALIGNMENT_LOG, + * then mem_cpointer_t can't store pointer to the unit, and so, rcs_cpointer_t stores + * mem_cpointer_t to block, aligned to MEM_ALIGNMENT, and also extension with difference + * between positions of the MEM_ALIGNMENT-aligned block and the unit. + */ + uintptr_t diff = (uintptr_t) pointer - base_pointer; + + JERRY_ASSERT (diff < MEM_ALIGNMENT); + JERRY_ASSERT (jrt_extract_bit_field (diff, 0, RCS_DYN_STORAGE_LENGTH_UNIT_LOG) == 0); + + uintptr_t ext_part = (uintptr_t) jrt_extract_bit_field (diff, + RCS_DYN_STORAGE_LENGTH_UNIT_LOG, + MEM_ALIGNMENT_LOG - RCS_DYN_STORAGE_LENGTH_UNIT_LOG); + + cpointer.value.ext = ext_part & ((1ull << (MEM_ALIGNMENT_LOG - RCS_DYN_STORAGE_LENGTH_UNIT_LOG)) - 1); +#endif /* MEM_ALIGNMENT > RCS_DYN_STORAGE_LENGTH_UNIT_LOG */ + + JERRY_ASSERT (decompress (cpointer) == pointer); return cpointer; } /* rcs_recordset_t::record_t::cpointer_t::compress */ @@ -99,9 +113,20 @@ rcs_recordset_t::record_t::cpointer_t::decompress (rcs_cpointer_t compressed_poi base_pointer = (uint8_t*) mem_decompress_pointer (compressed_pointer.value.base_cp); } - uintptr_t diff = (uintptr_t) compressed_pointer.value.ext << RCS_DYN_STORAGE_ALIGNMENT_LOG; + uintptr_t diff = 0; - return (rcs_recordset_t::record_t*) (base_pointer + diff); +#if MEM_ALIGNMENT_LOG > RCS_DYN_STORAGE_LENGTH_UNIT_LOG + /* + * See also: + * rcs_recordset_t::record_t::cpointer_t::compress + */ + + diff = (uintptr_t) compressed_pointer.value.ext << RCS_DYN_STORAGE_LENGTH_UNIT_LOG; +#endif /* MEM_ALIGNMENT_LOG > RCS_DYN_STORAGE_LENGTH_UNIT_LOG */ + + rcs_record_t *rec_p = (rcs_record_t *) (base_pointer + diff); + + return rec_p; } /* rcs_recordset_t::record_t::cpointer_t::decompress */ /** @@ -128,7 +153,7 @@ const uintptr_t ptr = (uintptr_t) this; - JERRY_ASSERT (JERRY_ALIGNUP (ptr, RCS_DYN_STORAGE_ALIGNMENT) == ptr); + JERRY_ASSERT (JERRY_ALIGNUP (ptr, RCS_DYN_STORAGE_LENGTH_UNIT) == ptr); } /* rcs_recordset_t::record_t::check_this */ /** @@ -143,7 +168,7 @@ const { check_this (); - JERRY_ASSERT (sizeof (uint32_t) == RCS_DYN_STORAGE_LENGTH_UNIT); + JERRY_ASSERT (sizeof (uint32_t) <= RCS_DYN_STORAGE_LENGTH_UNIT); JERRY_ASSERT (field_pos + field_width <= RCS_DYN_STORAGE_LENGTH_UNIT * JERRY_BITSINBYTE); uint32_t value = *reinterpret_cast (this); @@ -160,7 +185,7 @@ rcs_recordset_t::record_t::set_field (uint32_t field_pos, /**< offset, in bits * { check_this (); - JERRY_ASSERT (sizeof (uint32_t) == RCS_DYN_STORAGE_LENGTH_UNIT); + JERRY_ASSERT (sizeof (uint32_t) <= RCS_DYN_STORAGE_LENGTH_UNIT); JERRY_ASSERT (field_pos + field_width <= RCS_DYN_STORAGE_LENGTH_UNIT * JERRY_BITSINBYTE); uint32_t prev_value = *reinterpret_cast (this); @@ -215,7 +240,7 @@ rcs_recordset_t::alloc_record_in_place (rcs_record_t* place_p, /**< where to ini * and next allocated record */ rcs_record_t* next_record_p) /**< next allocated record */ { - const size_t node_data_space_size = _chunk_list.get_data_space_size (); + const size_t node_data_space_size = get_node_data_space_size (); if (next_record_p != NULL) { @@ -226,7 +251,7 @@ rcs_recordset_t::alloc_record_in_place (rcs_record_t* place_p, /**< where to ini else { rcs_chunked_list_t::node_t* node_p = _chunk_list.get_node_from_pointer (next_record_p); - uint8_t* node_data_space_p = _chunk_list.get_data_space (node_p); + uint8_t* node_data_space_p = get_node_data_space (node_p); JERRY_ASSERT ((uint8_t*) next_record_p < node_data_space_p + node_data_space_size); @@ -242,7 +267,7 @@ rcs_recordset_t::alloc_record_in_place (rcs_record_t* place_p, /**< where to ini JERRY_ASSERT (size_passed_back < free_size && size_passed_back + node_data_space_size > free_size); node_p = _chunk_list.get_prev (node_p); - node_data_space_p = _chunk_list.get_data_space (node_p); + node_data_space_p = get_node_data_space (node_p); free_rec_p = (rcs_record_t*) (node_data_space_p + node_data_space_size - \ (free_size - size_passed_back)); @@ -265,8 +290,8 @@ rcs_recordset_t::alloc_record_in_place (rcs_record_t* place_p, /**< where to ini next_node_p = _chunk_list.get_next (node_p); } - uint8_t* node_data_space_p = _chunk_list.get_data_space (node_p); - const size_t node_data_space_size = _chunk_list.get_data_space_size (); + uint8_t* node_data_space_p = get_node_data_space (node_p); + const size_t node_data_space_size = get_node_data_space_size (); rcs_record_t* free_rec_p = (rcs_record_t*) (node_data_space_p + node_data_space_size \ - free_size); @@ -300,6 +325,35 @@ rcs_recordset_t::is_record_free (rcs_record_t *record_p) /**< a record */ return (record_p->get_type () == _free_record_type_id); } /* rcs_recordset_t::is_record_free */ +/** + * Get the node's data space + * + * @return pointer to beginning of the node's data space + */ +uint8_t * +rcs_recordset_t::get_node_data_space (rcs_chunked_list_t::node_t *node_p) /**< the node */ +const +{ + uintptr_t unaligned_data_space_beg = (uintptr_t) _chunk_list.get_node_data_space (node_p); + uintptr_t aligned_data_space_beg = JERRY_ALIGNUP (unaligned_data_space_beg, RCS_DYN_STORAGE_LENGTH_UNIT); + + JERRY_ASSERT (unaligned_data_space_beg + rcs_chunked_list_t::get_node_data_space_size () + == aligned_data_space_beg + rcs_recordset_t::get_node_data_space_size ()); + + return (uint8_t *) aligned_data_space_beg; +} /* rcs_recordset_t::get_node_data_space */ + +/** + * Get size of a node's data space + * + * @return size + */ +size_t +rcs_recordset_t::get_node_data_space_size (void) +{ + return JERRY_ALIGNDOWN (rcs_chunked_list_t::get_node_data_space_size (), RCS_DYN_STORAGE_LENGTH_UNIT); +} /* rcs_recordset_t::get_node_data_space_size */ + /** * Allocate record of specified size * @@ -313,10 +367,10 @@ rcs_recordset_t::alloc_space_for_record (size_t bytes, /**< size */ { assert_state_is_correct (); - JERRY_ASSERT (JERRY_ALIGNUP (bytes, RCS_DYN_STORAGE_ALIGNMENT) == bytes); + JERRY_ASSERT (JERRY_ALIGNUP (bytes, RCS_DYN_STORAGE_LENGTH_UNIT) == bytes); JERRY_ASSERT (out_prev_rec_p != NULL); - const size_t node_data_space_size = _chunk_list.get_data_space_size (); + const size_t node_data_space_size = get_node_data_space_size (); *out_prev_rec_p = NULL; @@ -340,7 +394,7 @@ rcs_recordset_t::alloc_space_for_record (size_t bytes, /**< size */ else { rcs_chunked_list_t::node_t* node_p = _chunk_list.get_node_from_pointer (rec_p); - uint8_t* node_data_space_p = _chunk_list.get_data_space (node_p); + uint8_t* node_data_space_p = get_node_data_space (node_p); uint8_t* node_data_space_end_p = node_data_space_p + node_data_space_size; uint8_t* rec_space_p = (uint8_t*) rec_p; @@ -379,7 +433,7 @@ rcs_recordset_t::alloc_space_for_record (size_t bytes, /**< size */ /* free record of sufficient size was not found */ rcs_chunked_list_t::node_t *node_p = _chunk_list.append_new (); - rcs_record_t* new_rec_p = (rcs_record_t*) _chunk_list.get_data_space (node_p); + rcs_record_t* new_rec_p = (rcs_record_t*) get_node_data_space (node_p); size_t allocated_size = node_data_space_size; @@ -442,7 +496,7 @@ rcs_recordset_t::free_record (rcs_record_t* record_p) /**< record to free */ node_to_p = _chunk_list.get_node_from_pointer (rec_to_p); } - const size_t node_data_space_size = _chunk_list.get_data_space_size (); + const size_t node_data_space_size = get_node_data_space_size (); uint8_t* rec_from_beg_p = (uint8_t*) rec_from_p; uint8_t* rec_to_beg_p = (uint8_t*) rec_to_p; @@ -467,10 +521,10 @@ rcs_recordset_t::free_record (rcs_record_t* record_p) /**< record to free */ JERRY_ASSERT (_chunk_list.get_next (node_from_p) == node_to_p); - size_t node_from_space = (size_t) (_chunk_list.get_data_space (node_from_p) + + size_t node_from_space = (size_t) (get_node_data_space (node_from_p) + node_data_space_size - rec_from_beg_p); size_t node_to_space = (size_t) (node_to_p != NULL - ? rec_to_beg_p - _chunk_list.get_data_space (node_to_p) + ? rec_to_beg_p - get_node_data_space (node_to_p) : 0); free_size = node_from_space + node_to_space; @@ -510,7 +564,7 @@ rcs_recordset_t::get_first (void) } else { - return (rcs_record_t*) _chunk_list.get_data_space (first_node_p); + return (rcs_record_t*) get_node_data_space (first_node_p); } } /* rcs_recordset_t::get_first */ @@ -539,8 +593,8 @@ rcs_recordset_t::get_next (rcs_record_t* rec_p) /**< record */ { rcs_chunked_list_t::node_t* node_p = _chunk_list.get_node_from_pointer (rec_p); - const uint8_t* data_space_begin_p = _chunk_list.get_data_space (node_p); - const size_t data_space_size = _chunk_list.get_data_space_size (); + const uint8_t* data_space_begin_p = get_node_data_space (node_p); + const size_t data_space_size = get_node_data_space_size (); const uint8_t* record_start_p = (const uint8_t*) rec_p; size_t record_size = get_record_size (rec_p); @@ -575,7 +629,7 @@ rcs_recordset_t::get_next (rcs_record_t* rec_p) /**< record */ } else { - return (rcs_record_t*) (_chunk_list.get_data_space (node_p) + record_size_left); + return (rcs_record_t*) (get_node_data_space (node_p) + record_size_left); } } } /* rcs_recordset_t::get_next */ @@ -643,7 +697,7 @@ rcs_recordset_t::assert_state_is_correct (void) while (node_p != next_node_p) { node_p = _chunk_list.get_next (node_p); - node_size_sum += _chunk_list.get_data_space_size (); + node_size_sum += get_node_data_space_size (); } } @@ -671,14 +725,14 @@ rcs_record_iterator_t::access (access_t access_type, /**< type of access: read, void *data, /**< in/out data to read or write */ size_t size) /**< size of the data in bytes */ { - const size_t node_data_space_size = _recordset_p->_chunk_list.get_data_space_size (); + const size_t node_data_space_size = _recordset_p->get_node_data_space_size (); JERRY_ASSERT (2 * node_data_space_size >= size); const size_t record_size = _recordset_p->get_record_size (_record_start_p); JERRY_ASSERT (!finished ()); rcs_chunked_list_t::node_t *current_node_p = _recordset_p->_chunk_list.get_node_from_pointer (_current_pos_p); - uint8_t *current_node_data_space_p = _recordset_p->_chunk_list.get_data_space (current_node_p); + uint8_t *current_node_data_space_p = _recordset_p->get_node_data_space (current_node_p); size_t left_in_node = node_data_space_size - (size_t)(_current_pos_p - current_node_data_space_p); JERRY_ASSERT (_current_offset + size <= record_size); @@ -709,7 +763,7 @@ rcs_record_iterator_t::access (access_t access_type, /**< type of access: read, { current_node_p = _recordset_p->_chunk_list.get_next (current_node_p); JERRY_ASSERT (current_node_p); - _current_pos_p = _recordset_p->_chunk_list.get_data_space (current_node_p); + _current_pos_p = _recordset_p->get_node_data_space (current_node_p); } else { @@ -733,7 +787,7 @@ rcs_record_iterator_t::access (access_t access_type, /**< type of access: read, rcs_chunked_list_t::node_t *next_node_p = _recordset_p->_chunk_list.get_next (current_node_p); JERRY_ASSERT (next_node_p != NULL); - uint8_t *next_node_data_space_p = _recordset_p->_chunk_list.get_data_space (next_node_p); + uint8_t *next_node_data_space_p = _recordset_p->get_node_data_space (next_node_p); if (access_type == ACCESS_READ) { @@ -781,9 +835,9 @@ const void rcs_free_record_t::set_size (size_t size) /**< size to set */ { - JERRY_ASSERT (JERRY_ALIGNUP (size, RCS_DYN_STORAGE_ALIGNMENT) == size); + JERRY_ASSERT (JERRY_ALIGNUP (size, RCS_DYN_STORAGE_LENGTH_UNIT) == size); - set_field (_length_field_pos, _length_field_width, size >> RCS_DYN_STORAGE_ALIGNMENT_LOG); + set_field (_length_field_pos, _length_field_width, size >> RCS_DYN_STORAGE_LENGTH_UNIT_LOG); } /* rcs_free_record_t::set_size */ /** diff --git a/jerry-core/rcs/rcs-recordset.h b/jerry-core/rcs/rcs-recordset.h index fbdb39ec7..f6e7fed97 100644 --- a/jerry-core/rcs/rcs-recordset.h +++ b/jerry-core/rcs/rcs-recordset.h @@ -34,20 +34,12 @@ /** * Logarithm of a dynamic storage unit alignment */ -#define RCS_DYN_STORAGE_ALIGNMENT_LOG (2u) - -/** - * Dynamic storage unit alignment - */ -#define RCS_DYN_STORAGE_ALIGNMENT (1ull << RCS_DYN_STORAGE_ALIGNMENT_LOG) +#define RCS_DYN_STORAGE_LENGTH_UNIT_LOG (2u) /** * Unit of length - * - * See also: - * rcs_dyn_storage_length_t */ -#define RCS_DYN_STORAGE_LENGTH_UNIT (4u) +#define RCS_DYN_STORAGE_LENGTH_UNIT ((size_t) (1ull << RCS_DYN_STORAGE_LENGTH_UNIT_LOG)) /** * Dynamic storage @@ -65,7 +57,7 @@ public: { _chunk_list.init (); - JERRY_ASSERT (_chunk_list.get_data_space_size () % RCS_DYN_STORAGE_LENGTH_UNIT == 0); + JERRY_ASSERT (get_node_data_space_size () % RCS_DYN_STORAGE_LENGTH_UNIT == 0); } /* init */ /* Destructor */ @@ -95,24 +87,24 @@ public: * Dynamic storage-specific extended compressed pointer * * Note: - * the pointer can represent addresses aligned by RCS_DYN_STORAGE_ALIGNMENT, - * while mem_cpointer_t can only represent addressed aligned by MEM_ALIGNMENT. + * the pointer can represent addresses aligned by RCS_DYN_STORAGE_LENGTH_UNIT, + * while mem_cpointer_t can only represent addresses aligned by MEM_ALIGNMENT. */ struct cpointer_t { - static const uint32_t bit_field_width = MEM_CP_WIDTH + MEM_ALIGNMENT_LOG - RCS_DYN_STORAGE_ALIGNMENT_LOG; + static const uint32_t bit_field_width = MEM_CP_WIDTH + MEM_ALIGNMENT_LOG - RCS_DYN_STORAGE_LENGTH_UNIT_LOG; union { struct { mem_cpointer_t base_cp : MEM_CP_WIDTH; /**< pointer to base of addressed area */ -#if MEM_ALIGNMENT_LOG > RCS_DYN_STORAGE_ALIGNMENT_LOG - uint16_t ext : (MEM_ALIGNMENT_LOG - RCS_DYN_STORAGE_ALIGNMENT_LOG); /**< extension of the basic - * compressed pointer - * used for more detailed - * addressing */ -#endif /* MEM_ALIGNMENT_LOG > RCS_DYN_STORAGE_ALIGNMENT_LOG */ +#if MEM_ALIGNMENT_LOG > RCS_DYN_STORAGE_LENGTH_UNIT_LOG + uint16_t ext : (MEM_ALIGNMENT_LOG - RCS_DYN_STORAGE_LENGTH_UNIT_LOG); /**< extension of the basic + * compressed pointer + * used for more detailed + * addressing */ +#endif /* MEM_ALIGNMENT_LOG > RCS_DYN_STORAGE_LENGTH_UNIT_LOG */ } value; uint16_t packed_value; }; @@ -129,12 +121,12 @@ public: /** * Offset of 'type' field, in bits */ - static const uint32_t _type_field_pos = 0u; + static constexpr uint32_t _type_field_pos = 0u; /** * Width of 'type' field, in bits */ - static const uint32_t _type_field_width = 4u; + static constexpr uint32_t _type_field_width = 4u; protected: void check_this (void) const; @@ -148,7 +140,7 @@ public: /** * Offset of a derived record's fields, in bits */ - static const uint32_t _fields_offset_begin = _type_field_pos + _type_field_width; + static constexpr uint32_t _fields_offset_begin = _type_field_pos + _type_field_width; }; record_t *get_first (void); @@ -172,6 +164,8 @@ private: void init_free_record (record_t *, size_t, record_t *); bool is_record_free (record_t *); + uint8_t *get_node_data_space (rcs_chunked_list_t::node_t *) const; + static size_t get_node_data_space_size (void); protected: /** * First type identifier that can be used for storage-specific record types @@ -357,22 +351,29 @@ private: /** * Offset of 'length' field, in bits */ - static const uint32_t _length_field_pos = _fields_offset_begin; + static constexpr uint32_t _length_field_pos = _fields_offset_begin; /** * Width of 'length' field, in bits */ - static const uint32_t _length_field_width = 12u; + static constexpr uint32_t _length_field_width = 14u - RCS_DYN_STORAGE_LENGTH_UNIT_LOG; /** * Offset of 'previous record' field, in bits */ - static const uint32_t _prev_field_pos = _length_field_pos + _length_field_width; + static constexpr uint32_t _prev_field_pos = _length_field_pos + _length_field_width; /** * Width of 'previous record' field, in bits */ - static const uint32_t _prev_field_width = rcs_cpointer_t::bit_field_width; + static constexpr uint32_t _prev_field_width = rcs_cpointer_t::bit_field_width; + + /** + * Free record should be be placeable at any free space unit of recordset, + * and so its size should be less than minimal size of a free space unit + * that is RCS_DYN_STORAGE_LENGTH_UNIT bytes. + */ + JERRY_STATIC_ASSERT (_prev_field_pos + _prev_field_width <= RCS_DYN_STORAGE_LENGTH_UNIT * JERRY_BITSINBYTE); }; /** diff --git a/tests/unit/test-recordset.cpp b/tests/unit/test-recordset.cpp index c2a39098e..358bbc4c0 100644 --- a/tests/unit/test-recordset.cpp +++ b/tests/unit/test-recordset.cpp @@ -33,9 +33,6 @@ // Maximum number of elements in a type-one record #define test_max_type_one_record_elements 64 -// Element size in a type-one record -#define test_element_size_type_one_record (sizeof (uint16_t)) - class test_rcs_record_type_one_t : public rcs_record_t { public: @@ -52,9 +49,9 @@ public: void set_size (size_t size) { - JERRY_ASSERT (JERRY_ALIGNUP (size, RCS_DYN_STORAGE_ALIGNMENT) == size); + JERRY_ASSERT (JERRY_ALIGNUP (size, RCS_DYN_STORAGE_LENGTH_UNIT) == size); - set_field (length_field_pos, length_field_width, size >> RCS_DYN_STORAGE_ALIGNMENT_LOG); + set_field (length_field_pos, length_field_width, size >> RCS_DYN_STORAGE_LENGTH_UNIT_LOG); } rcs_record_t* get_prev () const @@ -67,15 +64,16 @@ public: set_pointer (prev_field_pos, prev_field_width, prev_rec_p); } + typedef uint16_t element_t; + + static const size_t header_size = 2 * RCS_DYN_STORAGE_LENGTH_UNIT; + static const size_t element_size = sizeof (test_rcs_record_type_one_t::element_t); private: static const uint32_t length_field_pos = _fields_offset_begin; static const uint32_t length_field_width = 12u; static const uint32_t prev_field_pos = length_field_pos + length_field_width; static const uint32_t prev_field_width = rcs_cpointer_t::bit_field_width; - - static const size_t header_size = 2 * RCS_DYN_STORAGE_LENGTH_UNIT; - static const size_t element_size = test_element_size_type_one_record; }; class test_rcs_record_type_two_t : public rcs_record_t @@ -106,11 +104,10 @@ public: set_pointer (prev_field_pos, prev_field_width, prev_rec_p); } + static const size_t header_size = RCS_DYN_STORAGE_LENGTH_UNIT; private: static const uint32_t prev_field_pos = _fields_offset_begin; static const uint32_t prev_field_width = rcs_cpointer_t::bit_field_width; - - static const size_t header_size = RCS_DYN_STORAGE_LENGTH_UNIT; }; class test_rcs_recordset_t : public rcs_recordset_t @@ -224,7 +221,7 @@ main (int __attr_unused___ argc, { test_rcs_record_type_one_t *type_one_records[test_sub_iters]; uint32_t type_one_record_element_counts[test_sub_iters]; - uint16_t type_one_record_elements[test_sub_iters][test_max_type_one_record_elements]; + test_rcs_record_type_one_t::element_t type_one_record_elements[test_sub_iters][test_max_type_one_record_elements]; int type_one_records_number = 0; test_rcs_record_type_two_t *type_two_records[test_sub_iters]; @@ -243,11 +240,12 @@ main (int __attr_unused___ argc, JERRY_ASSERT (type_one_records[type_one_records_number] != NULL); rcs_record_iterator_t it (&storage, type_one_records[type_one_records_number]); - it.skip (); // skip header - it.skip (); // skip header - for (uint32_t i = 0; i < type_one_record_element_counts[type_one_records_number]; it.skip(), i++) + it.skip (test_rcs_record_type_one_t::header_size); // skip header + for (uint32_t i = 0; + i < type_one_record_element_counts[type_one_records_number]; + it.skip(), i++) { - uint16_t val = (uint16_t)rand (); + test_rcs_record_type_one_t::element_t val = (test_rcs_record_type_one_t::element_t) rand (); type_one_record_elements[type_one_records_number][i] = val; it.write (val); } @@ -255,12 +253,13 @@ main (int __attr_unused___ argc, JERRY_ASSERT (type_one_records[type_one_records_number] != NULL); it.reset (); - it.skip (); // skip header - it.skip (); // skip header - for (uint32_t i = 0; i < type_one_record_element_counts[type_one_records_number]; it.skip(), i++) + it.skip (test_rcs_record_type_one_t::header_size); // skip header + for (uint32_t i = 0; + i < type_one_record_element_counts[type_one_records_number]; + it.skip(), i++) { - uint16_t val = type_one_record_elements[type_one_records_number][i]; - JERRY_ASSERT (val == it.read ()); + test_rcs_record_type_one_t::element_t val = type_one_record_elements[type_one_records_number][i]; + JERRY_ASSERT (val == it.read ()); } type_one_records_number++; @@ -287,16 +286,20 @@ main (int __attr_unused___ argc, JERRY_ASSERT (index_to_free >= 0 && index_to_free < type_one_records_number); rcs_record_iterator_t it (&storage, type_one_records[index_to_free]); - it.skip (); // skip header - it.skip (); // skip header - for (uint32_t i = 0; i < type_one_record_element_counts[index_to_free]; it.skip(), i++) + it.skip (test_rcs_record_type_one_t::header_size); // skip header + for (uint32_t i = 0; + i < type_one_record_element_counts[index_to_free]; + it.skip(), i++) { - uint16_t val = type_one_record_elements[index_to_free][i]; - JERRY_ASSERT (it.read () == val); + test_rcs_record_type_one_t::element_t val = type_one_record_elements[index_to_free][i]; + JERRY_ASSERT (it.read () == val); } - JERRY_ASSERT (JERRY_ALIGNUP (type_one_record_element_counts[index_to_free]*2 + 8, RCS_DYN_STORAGE_ALIGNMENT) == - type_one_records[index_to_free]->get_size ()); + JERRY_ASSERT (JERRY_ALIGNUP (type_one_record_element_counts[index_to_free] + * sizeof (test_rcs_record_type_one_t::element_t) + + test_rcs_record_type_one_t::header_size, + RCS_DYN_STORAGE_LENGTH_UNIT) + == type_one_records[index_to_free]->get_size ()); } bool free_type_one; @@ -326,12 +329,13 @@ main (int __attr_unused___ argc, JERRY_ASSERT (index_to_free >= 0 && index_to_free < type_one_records_number); rcs_record_iterator_t it (&storage, type_one_records[index_to_free]); - it.skip (); // skip header - it.skip (); // skip header - for (uint32_t i = 0; i < type_one_record_element_counts[index_to_free]; it.skip(), i++) + it.skip (test_rcs_record_type_one_t::header_size); // skip header + for (uint32_t i = 0; + i < type_one_record_element_counts[index_to_free]; + it.skip(), i++) { - uint16_t val = type_one_record_elements[index_to_free][i]; - JERRY_ASSERT (it.read () == val); + test_rcs_record_type_one_t::element_t val = type_one_record_elements[index_to_free][i]; + JERRY_ASSERT (it.read () == val); } // free the record @@ -343,7 +347,7 @@ main (int __attr_unused___ argc, type_one_records[index_to_free] = type_one_records[index_to_free + 1]; type_one_record_element_counts[index_to_free] = type_one_record_element_counts[index_to_free + 1]; memcpy (type_one_record_elements[index_to_free], type_one_record_elements[index_to_free + 1], - test_max_type_one_record_elements * test_element_size_type_one_record); + test_max_type_one_record_elements * sizeof (test_rcs_record_type_one_t::element_t)); index_to_free++; }