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)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 */ 47 void jmem_stats_free_byte_code_bytes(size_t byte_code_size)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 */ 60 void jmem_stats_allocate_string_bytes(size_t string_size)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 */ 76 void jmem_stats_free_string_bytes(size_t string_size)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 */ 89 void jmem_stats_allocate_object_bytes(size_t object_size)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 */ 105 void jmem_stats_free_object_bytes(size_t object_size)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 */ 118 void jmem_stats_allocate_property_bytes(size_t property_size)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 */ 134 void jmem_stats_free_property_bytes(size_t property_size)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 */ 149 void jmem_init(void)150jmem_init (void) 151 { 152 jmem_heap_init (); 153 } /* jmem_init */ 154 155 /** 156 * Finalize memory allocators. 157 */ 158 void jmem_finalize(void)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 */ 178 inline jmem_cpointer_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE jmem_compress_pointer(const void * pointer_p)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 */ 212 inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE jmem_decompress_pointer(uintptr_t compressed_pointer)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