1 | /* Copyright JS Foundation and other contributors, http://js.foundation |
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 | /** |
17 | * Allocator implementation |
18 | */ |
19 | #include "ecma-globals.h" |
20 | #include "jcontext.h" |
21 | #include "jmem.h" |
22 | #include "jrt-libc-includes.h" |
23 | |
24 | #define JMEM_ALLOCATOR_INTERNAL |
25 | #include "jmem-allocator-internal.h" |
26 | |
27 | #if ENABLED (JERRY_MEM_STATS) |
28 | /** |
29 | * Register byte code allocation. |
30 | */ |
31 | void |
32 | jmem_stats_allocate_byte_code_bytes (size_t byte_code_size) |
33 | { |
34 | jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); |
35 | |
36 | heap_stats->byte_code_bytes += byte_code_size; |
37 | |
38 | if (heap_stats->byte_code_bytes >= heap_stats->peak_byte_code_bytes) |
39 | { |
40 | heap_stats->peak_byte_code_bytes = heap_stats->byte_code_bytes; |
41 | } |
42 | } /* jmem_stats_allocate_byte_code_bytes */ |
43 | |
44 | /** |
45 | * Register byte code free. |
46 | */ |
47 | void |
48 | jmem_stats_free_byte_code_bytes (size_t byte_code_size) |
49 | { |
50 | jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); |
51 | |
52 | JERRY_ASSERT (heap_stats->byte_code_bytes >= byte_code_size); |
53 | |
54 | heap_stats->byte_code_bytes -= byte_code_size; |
55 | } /* jmem_stats_free_byte_code_bytes */ |
56 | |
57 | /** |
58 | * Register string allocation. |
59 | */ |
60 | void |
61 | jmem_stats_allocate_string_bytes (size_t string_size) |
62 | { |
63 | jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); |
64 | |
65 | heap_stats->string_bytes += string_size; |
66 | |
67 | if (heap_stats->string_bytes >= heap_stats->peak_string_bytes) |
68 | { |
69 | heap_stats->peak_string_bytes = heap_stats->string_bytes; |
70 | } |
71 | } /* jmem_stats_allocate_string_bytes */ |
72 | |
73 | /** |
74 | * Register string free. |
75 | */ |
76 | void |
77 | jmem_stats_free_string_bytes (size_t string_size) |
78 | { |
79 | jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); |
80 | |
81 | JERRY_ASSERT (heap_stats->string_bytes >= string_size); |
82 | |
83 | heap_stats->string_bytes -= string_size; |
84 | } /* jmem_stats_free_string_bytes */ |
85 | |
86 | /** |
87 | * Register object allocation. |
88 | */ |
89 | void |
90 | jmem_stats_allocate_object_bytes (size_t object_size) |
91 | { |
92 | jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); |
93 | |
94 | heap_stats->object_bytes += object_size; |
95 | |
96 | if (heap_stats->object_bytes >= heap_stats->peak_object_bytes) |
97 | { |
98 | heap_stats->peak_object_bytes = heap_stats->object_bytes; |
99 | } |
100 | } /* jmem_stats_allocate_object_bytes */ |
101 | |
102 | /** |
103 | * Register object free. |
104 | */ |
105 | void |
106 | jmem_stats_free_object_bytes (size_t object_size) |
107 | { |
108 | jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); |
109 | |
110 | JERRY_ASSERT (heap_stats->object_bytes >= object_size); |
111 | |
112 | heap_stats->object_bytes -= object_size; |
113 | } /* jmem_stats_free_object_bytes */ |
114 | |
115 | /** |
116 | * Register property allocation. |
117 | */ |
118 | void |
119 | jmem_stats_allocate_property_bytes (size_t property_size) |
120 | { |
121 | jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); |
122 | |
123 | heap_stats->property_bytes += property_size; |
124 | |
125 | if (heap_stats->property_bytes >= heap_stats->peak_property_bytes) |
126 | { |
127 | heap_stats->peak_property_bytes = heap_stats->property_bytes; |
128 | } |
129 | } /* jmem_stats_allocate_property_bytes */ |
130 | |
131 | /** |
132 | * Register property free. |
133 | */ |
134 | void |
135 | jmem_stats_free_property_bytes (size_t property_size) |
136 | { |
137 | jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats); |
138 | |
139 | JERRY_ASSERT (heap_stats->property_bytes >= property_size); |
140 | |
141 | heap_stats->property_bytes -= property_size; |
142 | } /* jmem_stats_free_property_bytes */ |
143 | |
144 | #endif /* ENABLED (JERRY_MEM_STATS) */ |
145 | |
146 | /** |
147 | * Initialize memory allocators. |
148 | */ |
149 | void |
150 | jmem_init (void) |
151 | { |
152 | jmem_heap_init (); |
153 | } /* jmem_init */ |
154 | |
155 | /** |
156 | * Finalize memory allocators. |
157 | */ |
158 | void |
159 | jmem_finalize (void) |
160 | { |
161 | jmem_pools_finalize (); |
162 | |
163 | #if ENABLED (JERRY_MEM_STATS) |
164 | if (JERRY_CONTEXT (jerry_init_flags) & ECMA_INIT_MEM_STATS) |
165 | { |
166 | jmem_heap_stats_print (); |
167 | } |
168 | #endif /* ENABLED (JERRY_MEM_STATS) */ |
169 | |
170 | jmem_heap_finalize (); |
171 | } /* jmem_finalize */ |
172 | |
173 | /** |
174 | * Compress pointer |
175 | * |
176 | * @return packed pointer |
177 | */ |
178 | extern inline jmem_cpointer_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE |
179 | jmem_compress_pointer (const void *pointer_p) /**< pointer to compress */ |
180 | { |
181 | JERRY_ASSERT (pointer_p != NULL); |
182 | JERRY_ASSERT (jmem_is_heap_pointer (pointer_p)); |
183 | |
184 | uintptr_t uint_ptr = (uintptr_t) pointer_p; |
185 | |
186 | JERRY_ASSERT (uint_ptr % JMEM_ALIGNMENT == 0); |
187 | |
188 | #if defined (ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY) && ENABLED (JERRY_CPOINTER_32_BIT) |
189 | JERRY_ASSERT (((jmem_cpointer_t) uint_ptr) == uint_ptr); |
190 | #else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY || !ENABLED (JERRY_CPOINTER_32_BIT) */ |
191 | const uintptr_t heap_start = (uintptr_t) &JERRY_HEAP_CONTEXT (first); |
192 | |
193 | uint_ptr -= heap_start; |
194 | uint_ptr >>= JMEM_ALIGNMENT_LOG; |
195 | |
196 | #if ENABLED (JERRY_CPOINTER_32_BIT) |
197 | JERRY_ASSERT (uint_ptr <= UINT32_MAX); |
198 | #else /* !ENABLED (JERRY_CPOINTER_32_BIT) */ |
199 | JERRY_ASSERT (uint_ptr <= UINT16_MAX); |
200 | #endif /* ENABLED (JERRY_CPOINTER_32_BIT) */ |
201 | JERRY_ASSERT (uint_ptr != JMEM_CP_NULL); |
202 | #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY && ENABLED (JERRY_CPOINTER_32_BIT) */ |
203 | |
204 | return (jmem_cpointer_t) uint_ptr; |
205 | } /* jmem_compress_pointer */ |
206 | |
207 | /** |
208 | * Decompress pointer |
209 | * |
210 | * @return unpacked pointer |
211 | */ |
212 | extern inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE |
213 | jmem_decompress_pointer (uintptr_t compressed_pointer) /**< pointer to decompress */ |
214 | { |
215 | JERRY_ASSERT (compressed_pointer != JMEM_CP_NULL); |
216 | |
217 | uintptr_t uint_ptr = compressed_pointer; |
218 | |
219 | JERRY_ASSERT (((jmem_cpointer_t) uint_ptr) == uint_ptr); |
220 | |
221 | #if defined (ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY) && ENABLED (JERRY_CPOINTER_32_BIT) |
222 | JERRY_ASSERT (uint_ptr % JMEM_ALIGNMENT == 0); |
223 | #else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY || !ENABLED (JERRY_CPOINTER_32_BIT) */ |
224 | const uintptr_t heap_start = (uintptr_t) &JERRY_HEAP_CONTEXT (first); |
225 | |
226 | uint_ptr <<= JMEM_ALIGNMENT_LOG; |
227 | uint_ptr += heap_start; |
228 | |
229 | JERRY_ASSERT (jmem_is_heap_pointer ((void *) uint_ptr)); |
230 | #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY && ENABLED (JERRY_CPOINTER_32_BIT) */ |
231 | |
232 | return (void *) uint_ptr; |
233 | } /* jmem_decompress_pointer */ |
234 | |