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 */
31void
32jmem_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 */
47void
48jmem_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 */
60void
61jmem_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 */
76void
77jmem_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 */
89void
90jmem_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 */
105void
106jmem_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 */
118void
119jmem_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 */
134void
135jmem_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 */
149void
150jmem_init (void)
151{
152 jmem_heap_init ();
153} /* jmem_init */
154
155/**
156 * Finalize memory allocators.
157 */
158void
159jmem_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 */
178extern inline jmem_cpointer_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
179jmem_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 */
212extern inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
213jmem_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