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 */ 178inline 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 */ 212inline 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