• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
jmem_stats_allocate_byte_code_bytes(size_t byte_code_size)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
jmem_stats_free_byte_code_bytes(size_t byte_code_size)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
jmem_stats_allocate_string_bytes(size_t string_size)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
jmem_stats_free_string_bytes(size_t string_size)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
jmem_stats_allocate_object_bytes(size_t object_size)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
jmem_stats_free_object_bytes(size_t object_size)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
jmem_stats_allocate_property_bytes(size_t property_size)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
jmem_stats_free_property_bytes(size_t property_size)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
jmem_init(void)150 jmem_init (void)
151 {
152   jmem_heap_init ();
153 } /* jmem_init */
154 
155 /**
156  * Finalize memory allocators.
157  */
158 void
jmem_finalize(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 inline jmem_cpointer_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
jmem_compress_pointer(const void * pointer_p)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 inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
jmem_decompress_pointer(uintptr_t compressed_pointer)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