1 /****************************************************************************** 2 * 3 * Module Name: aslcache -- Local cache support for iASL 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2025, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "aslcompiler.h" 45 46 /* 47 * Local caches. The caches are fully deleted after the compilation/disassembly 48 * of each individual input file. Thus, individual allocations from the cache 49 * memory do not need to be freed or even released back into the cache. 50 * 51 * See aslallocate.c for standard heap allocations. 52 */ 53 54 55 /******************************************************************************* 56 * 57 * FUNCTION: UtLocalCacheCalloc 58 * 59 * PARAMETERS: Length - Size of buffer requested 60 * 61 * RETURN: Pointer to the buffer. Aborts compiler on allocation failure 62 * 63 * DESCRIPTION: Allocate a string buffer. Bypass the local 64 * dynamic memory manager for performance reasons (This has a 65 * major impact on the speed of the compiler.) 66 * 67 ******************************************************************************/ 68 69 char * 70 UtLocalCacheCalloc ( 71 UINT32 Length) 72 { 73 char *Buffer; 74 ASL_CACHE_INFO *Cache; 75 UINT32 CacheSize = ASL_STRING_CACHE_SIZE; 76 77 78 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED 79 /* Used for objects other than strings, so keep allocations aligned */ 80 Length = ACPI_ROUND_UP_TO_NATIVE_WORD (Length); 81 #endif 82 83 if (Length > CacheSize) 84 { 85 CacheSize = Length; 86 87 if (AslGbl_StringCacheList) 88 { 89 Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize); 90 91 /* Link new cache buffer just following head of list */ 92 93 Cache->Next = AslGbl_StringCacheList->Next; 94 AslGbl_StringCacheList->Next = Cache; 95 96 /* Leave cache management pointers alone as they pertain to head */ 97 98 AslGbl_StringCount++; 99 AslGbl_StringSize += Length; 100 101 return (Cache->Buffer); 102 } 103 } 104 105 if ((!AslGbl_StringCacheNext) || 106 ((AslGbl_StringCacheNext + Length) >= AslGbl_StringCacheLast)) 107 { 108 /* Allocate a new buffer */ 109 110 Cache = UtLocalCalloc (sizeof (Cache->Next) + CacheSize); 111 112 /* Link new cache buffer to head of list */ 113 114 Cache->Next = AslGbl_StringCacheList; 115 AslGbl_StringCacheList = Cache; 116 117 /* Setup cache management pointers */ 118 119 AslGbl_StringCacheNext = Cache->Buffer; 120 AslGbl_StringCacheLast = AslGbl_StringCacheNext + CacheSize; 121 } 122 123 AslGbl_StringCount++; 124 AslGbl_StringSize += Length; 125 126 Buffer = AslGbl_StringCacheNext; 127 AslGbl_StringCacheNext += Length; 128 return (Buffer); 129 } 130 131 132 /******************************************************************************* 133 * 134 * FUNCTION: UtParseOpCacheCalloc 135 * 136 * PARAMETERS: None 137 * 138 * RETURN: New parse op. Aborts on allocation failure 139 * 140 * DESCRIPTION: Allocate a new parse op for the parse tree. Bypass the local 141 * dynamic memory manager for performance reasons (This has a 142 * major impact on the speed of the compiler.) 143 * 144 ******************************************************************************/ 145 146 ACPI_PARSE_OBJECT * 147 UtParseOpCacheCalloc ( 148 void) 149 { 150 ASL_CACHE_INFO *Cache; 151 152 153 if (AslGbl_ParseOpCacheNext >= AslGbl_ParseOpCacheLast) 154 { 155 /* Allocate a new buffer */ 156 157 Cache = UtLocalCalloc (sizeof (Cache->Next) + 158 (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE)); 159 160 /* Link new cache buffer to head of list */ 161 162 Cache->Next = AslGbl_ParseOpCacheList; 163 AslGbl_ParseOpCacheList = Cache; 164 165 /* Setup cache management pointers */ 166 167 AslGbl_ParseOpCacheNext = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Cache->Buffer); 168 AslGbl_ParseOpCacheLast = AslGbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE; 169 } 170 171 AslGbl_ParseOpCount++; 172 return (AslGbl_ParseOpCacheNext++); 173 } 174 175 176 /******************************************************************************* 177 * 178 * FUNCTION: UtSubtableCacheCalloc - Data Table compiler 179 * 180 * PARAMETERS: None 181 * 182 * RETURN: Pointer to the buffer. Aborts on allocation failure 183 * 184 * DESCRIPTION: Allocate a subtable object buffer. Bypass the local 185 * dynamic memory manager for performance reasons (This has a 186 * major impact on the speed of the compiler.) 187 * 188 ******************************************************************************/ 189 190 DT_SUBTABLE * 191 UtSubtableCacheCalloc ( 192 void) 193 { 194 ASL_CACHE_INFO *Cache; 195 196 197 if (AslGbl_SubtableCacheNext >= AslGbl_SubtableCacheLast) 198 { 199 /* Allocate a new buffer */ 200 201 Cache = UtLocalCalloc (sizeof (Cache->Next) + 202 (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE)); 203 204 /* Link new cache buffer to head of list */ 205 206 Cache->Next = AslGbl_SubtableCacheList; 207 AslGbl_SubtableCacheList = Cache; 208 209 /* Setup cache management pointers */ 210 211 AslGbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer); 212 AslGbl_SubtableCacheLast = AslGbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE; 213 } 214 215 AslGbl_SubtableCount++; 216 return (AslGbl_SubtableCacheNext++); 217 } 218 219 220 /******************************************************************************* 221 * 222 * FUNCTION: UtFieldCacheCalloc - Data Table compiler 223 * 224 * PARAMETERS: None 225 * 226 * RETURN: Pointer to the buffer. Aborts on allocation failure 227 * 228 * DESCRIPTION: Allocate a field object buffer. Bypass the local 229 * dynamic memory manager for performance reasons (This has a 230 * major impact on the speed of the compiler.) 231 * 232 ******************************************************************************/ 233 234 DT_FIELD * 235 UtFieldCacheCalloc ( 236 void) 237 { 238 ASL_CACHE_INFO *Cache; 239 240 241 if (AslGbl_FieldCacheNext >= AslGbl_FieldCacheLast) 242 { 243 /* Allocate a new buffer */ 244 245 Cache = UtLocalCalloc (sizeof (Cache->Next) + 246 (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE)); 247 248 /* Link new cache buffer to head of list */ 249 250 Cache->Next = AslGbl_FieldCacheList; 251 AslGbl_FieldCacheList = Cache; 252 253 /* Setup cache management pointers */ 254 255 AslGbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer); 256 AslGbl_FieldCacheLast =AslGbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE; 257 } 258 259 AslGbl_FieldCount++; 260 return (AslGbl_FieldCacheNext++); 261 } 262 263 264 /******************************************************************************* 265 * 266 * FUNCTION: UtDeleteLocalCaches 267 * 268 * PARAMETERS: None 269 * 270 * RETURN: None 271 * 272 * DESCRIPTION: Delete all local cache buffer blocks 273 * 274 ******************************************************************************/ 275 276 void 277 UtDeleteLocalCaches ( 278 void) 279 { 280 UINT32 BufferCount; 281 ASL_CACHE_INFO *Next; 282 283 284 /* 285 * Generic cache, arbitrary size allocations 286 */ 287 BufferCount = 0; 288 while (AslGbl_StringCacheList) 289 { 290 Next = AslGbl_StringCacheList->Next; 291 ACPI_FREE (AslGbl_StringCacheList); 292 AslGbl_StringCacheList = Next; 293 BufferCount++; 294 } 295 296 DbgPrint (ASL_DEBUG_OUTPUT, 297 "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n", 298 AslGbl_StringCount, AslGbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount); 299 300 /* Reset cache globals */ 301 302 AslGbl_StringSize = 0; 303 AslGbl_StringCount = 0; 304 AslGbl_StringCacheNext = NULL; 305 AslGbl_StringCacheLast = NULL; 306 307 /* 308 * Parse Op cache 309 */ 310 BufferCount = 0; 311 while (AslGbl_ParseOpCacheList) 312 { 313 Next = AslGbl_ParseOpCacheList->Next; 314 ACPI_FREE (AslGbl_ParseOpCacheList); 315 AslGbl_ParseOpCacheList = Next; 316 BufferCount++; 317 } 318 319 DbgPrint (ASL_DEBUG_OUTPUT, 320 "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n", 321 AslGbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE, 322 ((UINT32) sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount); 323 324 /* Reset cache globals */ 325 326 AslGbl_ParseOpCount = 0; 327 AslGbl_ParseOpCacheNext = NULL; 328 AslGbl_ParseOpCacheLast = NULL; 329 AslGbl_ParseTreeRoot = NULL; 330 331 /* 332 * Table Compiler - Field cache 333 */ 334 BufferCount = 0; 335 while (AslGbl_FieldCacheList) 336 { 337 Next = AslGbl_FieldCacheList->Next; 338 ACPI_FREE (AslGbl_FieldCacheList); 339 AslGbl_FieldCacheList = Next; 340 BufferCount++; 341 } 342 343 DbgPrint (ASL_DEBUG_OUTPUT, 344 "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n", 345 AslGbl_FieldCount, ASL_FIELD_CACHE_SIZE, 346 ((UINT32) sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount); 347 348 /* Reset cache globals */ 349 350 AslGbl_FieldCount = 0; 351 AslGbl_FieldCacheNext = NULL; 352 AslGbl_FieldCacheLast = NULL; 353 354 /* 355 * Table Compiler - Subtable cache 356 */ 357 BufferCount = 0; 358 while (AslGbl_SubtableCacheList) 359 { 360 Next = AslGbl_SubtableCacheList->Next; 361 ACPI_FREE (AslGbl_SubtableCacheList); 362 AslGbl_SubtableCacheList = Next; 363 BufferCount++; 364 } 365 366 DbgPrint (ASL_DEBUG_OUTPUT, 367 "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n", 368 AslGbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE, 369 ((UINT32) sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount); 370 371 /* Reset cache globals */ 372 373 AslGbl_SubtableCount = 0; 374 AslGbl_SubtableCacheNext = NULL; 375 AslGbl_SubtableCacheLast = NULL; 376 } 377