Skip to content

Commit b5d8444

Browse files
Introducing chunked lists (list of nodes that exactly fit the heap chunk size).
JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
1 parent 82f9afc commit b5d8444

File tree

4 files changed

+424
-0
lines changed

4 files changed

+424
-0
lines changed

jerry-core/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ project (JerryCore CXX C ASM)
9393
# Include directories
9494
set(INCLUDE_CORE
9595
${CMAKE_SOURCE_DIR}/jerry-core
96+
${CMAKE_SOURCE_DIR}/jerry-core/rcs
9697
${CMAKE_SOURCE_DIR}/jerry-core/mem
9798
${CMAKE_SOURCE_DIR}/jerry-core/vm
9899
${CMAKE_SOURCE_DIR}/jerry-core/ecma/builtin-objects
@@ -109,6 +110,7 @@ project (JerryCore CXX C ASM)
109110
# Sources
110111
# Jerry core
111112
file(GLOB SOURCE_CORE_API *.cpp)
113+
file(GLOB SOURCE_CORE_RCS rcs/*.cpp)
112114
file(GLOB SOURCE_CORE_MEM mem/*.cpp)
113115
file(GLOB SOURCE_CORE_VM vm/*.cpp)
114116
file(GLOB SOURCE_CORE_ECMA_BUILTINS ecma/builtin-objects/*.cpp)
@@ -121,6 +123,7 @@ project (JerryCore CXX C ASM)
121123
set(SOURCE_CORE
122124
jerry.cpp
123125
${SOURCE_CORE_API}
126+
${SOURCE_CORE_RCS}
124127
${SOURCE_CORE_MEM}
125128
${SOURCE_CORE_VM}
126129
${SOURCE_CORE_ECMA_BUILTINS}

jerry-core/rcs/rcs-chunked-list.cpp

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
/* Copyright 2015 Samsung Electronics Co., Ltd.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#include "rcs-chunked-list.h"
17+
18+
/**
19+
* Constructor
20+
*/
21+
void
22+
rcs_chunked_list_t::init (void)
23+
{
24+
head_p = NULL;
25+
tail_p = NULL;
26+
} /* rcs_chunked_list_t::init */
27+
28+
/**
29+
* Destructor
30+
*/
31+
void
32+
rcs_chunked_list_t::free (void)
33+
{
34+
JERRY_ASSERT (head_p == NULL);
35+
JERRY_ASSERT (tail_p == NULL);
36+
} /* rcs_chunked_list_t::free */
37+
38+
/**
39+
* Get first node of the list
40+
*
41+
* @return pointer to the first node
42+
*/
43+
rcs_chunked_list_t::node_t*
44+
rcs_chunked_list_t::get_first (void)
45+
const
46+
{
47+
return head_p;
48+
} /* rcs_chunked_list_t::get_first */
49+
50+
/**
51+
* Get last node of the list
52+
*
53+
* @return pointer to the last node
54+
*/
55+
rcs_chunked_list_t::node_t*
56+
rcs_chunked_list_t::get_last (void)
57+
const
58+
{
59+
return tail_p;
60+
} /* rcs_chunked_list_t::get_last */
61+
62+
/**
63+
* Get node, previous to specified
64+
*
65+
* @return pointer to previous node
66+
*/
67+
rcs_chunked_list_t::node_t*
68+
rcs_chunked_list_t::get_prev (rcs_chunked_list_t::node_t *node_p) /**< node to get previous for */
69+
const
70+
{
71+
JERRY_ASSERT (node_p != NULL);
72+
73+
return MEM_CP_GET_POINTER (node_t, node_p->prev_cp);
74+
} /* rcs_chunked_list_t::get_prev */
75+
76+
/**
77+
* Get node, next to specified
78+
*
79+
* @return pointer to next node
80+
*/
81+
rcs_chunked_list_t::node_t*
82+
rcs_chunked_list_t::get_next (rcs_chunked_list_t::node_t *node_p) /**< node to get next for */
83+
const
84+
{
85+
JERRY_ASSERT (node_p != NULL);
86+
87+
return MEM_CP_GET_POINTER (node_t, node_p->next_cp);
88+
} /* rcs_chunked_list_t::get_next */
89+
90+
/**
91+
* Append new node to end of the list
92+
*
93+
* @return pointer to the new node
94+
*/
95+
rcs_chunked_list_t::node_t*
96+
rcs_chunked_list_t::append_new (void)
97+
{
98+
assert_list_is_correct ();
99+
100+
node_t *node_p = (node_t*) mem_heap_alloc_chunked_block (MEM_HEAP_ALLOC_LONG_TERM);
101+
102+
set_prev (node_p, tail_p);
103+
set_next (node_p, NULL);
104+
105+
if (head_p == NULL)
106+
{
107+
JERRY_ASSERT (tail_p == NULL);
108+
109+
head_p = node_p;
110+
tail_p = node_p;
111+
}
112+
else
113+
{
114+
JERRY_ASSERT (tail_p != NULL);
115+
116+
set_next (tail_p, node_p);
117+
118+
tail_p = node_p;
119+
}
120+
121+
assert_node_is_correct (node_p);
122+
123+
return node_p;
124+
} /* rcs_chunked_list_t::append_new */
125+
126+
/**
127+
* Insert new node after the specified node
128+
*
129+
* @return pointer to the new node
130+
*/
131+
rcs_chunked_list_t::node_t*
132+
rcs_chunked_list_t::insert_new (rcs_chunked_list_t::node_t* after_p) /**< the node to insert the new node after */
133+
{
134+
assert_list_is_correct ();
135+
136+
node_t *node_p = (node_t*) mem_heap_alloc_chunked_block (MEM_HEAP_ALLOC_LONG_TERM);
137+
138+
JERRY_ASSERT (head_p != NULL);
139+
JERRY_ASSERT (tail_p != NULL);
140+
assert_node_is_correct (after_p);
141+
142+
set_next (after_p, node_p);
143+
if (tail_p == after_p)
144+
{
145+
tail_p = node_p;
146+
}
147+
148+
set_prev (node_p, after_p);
149+
set_next (node_p, NULL);
150+
151+
assert_node_is_correct (node_p);
152+
153+
return node_p;
154+
} /* rcs_chunked_list_t::insert_new */
155+
156+
/**
157+
* Remove specified node
158+
*/
159+
void
160+
rcs_chunked_list_t::remove (rcs_chunked_list_t::node_t* node_p) /**< node to remove */
161+
{
162+
JERRY_ASSERT (head_p != NULL);
163+
JERRY_ASSERT (tail_p != NULL);
164+
165+
assert_node_is_correct (node_p);
166+
167+
node_t *prev_node_p, *next_node_p;
168+
prev_node_p = get_prev (node_p);
169+
next_node_p = get_next (node_p);
170+
171+
if (prev_node_p == NULL)
172+
{
173+
JERRY_ASSERT (head_p == node_p);
174+
head_p = next_node_p;
175+
}
176+
else
177+
{
178+
set_next (prev_node_p, next_node_p);
179+
}
180+
181+
if (next_node_p == NULL)
182+
{
183+
JERRY_ASSERT (tail_p == node_p);
184+
tail_p = prev_node_p;
185+
}
186+
else
187+
{
188+
set_prev (next_node_p, prev_node_p);
189+
}
190+
191+
mem_heap_free_block (node_p);
192+
193+
assert_list_is_correct ();
194+
} /* rcs_chunked_list_t::remove */
195+
196+
/**
197+
* Find node containing space, pointed by specified pointer
198+
*
199+
* @return pointer to the node that contains the pointed area
200+
*/
201+
rcs_chunked_list_t::node_t*
202+
rcs_chunked_list_t::get_node_from_pointer (void* ptr) /**< the pointer value */
203+
const
204+
{
205+
node_t *node_p = (node_t*) mem_heap_get_chunked_block_start (ptr);
206+
207+
assert_node_is_correct (node_p);
208+
209+
return node_p;
210+
} /* rcs_chunked_list_t::get_node_from_pointer */
211+
212+
/**
213+
* Get the node's data space
214+
*
215+
* @return pointer to beginning of the node's data space
216+
*/
217+
uint8_t*
218+
rcs_chunked_list_t::get_data_space (rcs_chunked_list_t::node_t* node_p) /**< the node */
219+
const
220+
{
221+
assert_node_is_correct (node_p);
222+
223+
return (uint8_t*) (node_p + 1);
224+
} /* rcs_chunked_list_t::get_data_space */
225+
226+
/**
227+
* Get size of a node's data space
228+
*
229+
* @return size
230+
*/
231+
size_t
232+
rcs_chunked_list_t::get_data_space_size (void)
233+
{
234+
return rcs_chunked_list_t::get_node_size () - sizeof (node_t);
235+
} /* rcs_chunked_list_t::get_data_space_size */
236+
237+
/**
238+
* Set previous node for the specified node
239+
*/
240+
void
241+
rcs_chunked_list_t::set_prev (rcs_chunked_list_t::node_t *node_p, /**< node to set previous for */
242+
rcs_chunked_list_t::node_t *prev_node_p) /**< the previous node */
243+
{
244+
JERRY_ASSERT (node_p != NULL);
245+
246+
MEM_CP_SET_POINTER (node_p->prev_cp, prev_node_p);
247+
} /* rcs_chunked_list_t::set_prev */
248+
249+
/**
250+
* Set next node for the specified node
251+
*/
252+
void
253+
rcs_chunked_list_t::set_next (rcs_chunked_list_t::node_t *node_p, /**< node to set next for */
254+
rcs_chunked_list_t::node_t *next_node_p) /**< the next node */
255+
{
256+
JERRY_ASSERT (node_p != NULL);
257+
258+
MEM_CP_SET_POINTER (node_p->next_cp, next_node_p);
259+
} /* rcs_chunked_list_t::set_next */
260+
261+
/**
262+
* Get size of the node
263+
*
264+
* @return size of node, including header and data space
265+
*/
266+
size_t
267+
rcs_chunked_list_t::get_node_size (void)
268+
{
269+
size_t size = mem_heap_recommend_allocation_size (sizeof (node_t) + 1u);
270+
271+
JERRY_ASSERT (size != 0 && size >= sizeof (node_t));
272+
273+
return size;
274+
} /* rcs_chunked_list_t::get_node_size */
275+
276+
/**
277+
* Assert that the list state is correct
278+
*/
279+
void
280+
rcs_chunked_list_t::assert_list_is_correct (void)
281+
const
282+
{
283+
#ifndef JERRY_NDEBUG
284+
for (node_t *node_iter_p = get_first ();
285+
node_iter_p != NULL;
286+
node_iter_p = get_next (node_iter_p))
287+
{
288+
node_t *prev_node_p = get_prev (node_iter_p);
289+
node_t *next_node_p = get_next (node_iter_p);
290+
291+
JERRY_ASSERT ((node_iter_p == head_p
292+
&& prev_node_p == NULL)
293+
|| (node_iter_p != head_p
294+
&& prev_node_p != NULL
295+
&& get_next (prev_node_p) == node_iter_p));
296+
JERRY_ASSERT ((node_iter_p == tail_p
297+
&& next_node_p == NULL)
298+
|| (node_iter_p != tail_p
299+
&& next_node_p != NULL
300+
&& get_prev (next_node_p) == node_iter_p));
301+
}
302+
#endif /* !JERRY_NDEBUG */
303+
} /* rcs_chunked_list_t::assert_list_is_correct */
304+
305+
/**
306+
* Assert that state of specified node is correct
307+
*/
308+
void
309+
rcs_chunked_list_t::assert_node_is_correct (const rcs_chunked_list_t::node_t* node_p) /**< the node */
310+
const
311+
{
312+
#ifndef JERRY_NDEBUG
313+
JERRY_ASSERT (node_p != NULL);
314+
315+
assert_list_is_correct ();
316+
317+
bool is_in_list = false;
318+
for (node_t *node_iter_p = get_first ();
319+
node_iter_p != NULL;
320+
node_iter_p = get_next (node_iter_p))
321+
{
322+
if (node_iter_p == node_p)
323+
{
324+
is_in_list = true;
325+
326+
break;
327+
}
328+
}
329+
330+
JERRY_ASSERT (is_in_list);
331+
#else /* JERRY_NDEBUG */
332+
(void) node_p;
333+
#endif /* JERRY_NDEBUG */
334+
} /* rcs_chunked_list_t::assert_node_is_correct */

0 commit comments

Comments
 (0)