1 /******************************************************************************
2 *
3 * Module Name: uttrack - Memory allocation tracking routines (debug only)
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2016, 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 MERCHANTIBILITY 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 /*
45 * These procedures are used for tracking memory leaks in the subsystem, and
46 * they get compiled out when the ACPI_DBG_TRACK_ALLOCATIONS is not set.
47 *
48 * Each memory allocation is tracked via a doubly linked list. Each
49 * element contains the caller's component, module name, function name, and
50 * line number. AcpiUtAllocate and AcpiUtAllocateZeroed call
51 * AcpiUtTrackAllocation to add an element to the list; deletion
52 * occurs in the body of AcpiUtFree.
53 */
54
55 #include "acpi.h"
56 #include "accommon.h"
57
58 #ifdef ACPI_DBG_TRACK_ALLOCATIONS
59
60 #define _COMPONENT ACPI_UTILITIES
61 ACPI_MODULE_NAME ("uttrack")
62
63
64 /* Local prototypes */
65
66 static ACPI_DEBUG_MEM_BLOCK *
67 AcpiUtFindAllocation (
68 ACPI_DEBUG_MEM_BLOCK *Allocation);
69
70 static ACPI_STATUS
71 AcpiUtTrackAllocation (
72 ACPI_DEBUG_MEM_BLOCK *Address,
73 ACPI_SIZE Size,
74 UINT8 AllocType,
75 UINT32 Component,
76 const char *Module,
77 UINT32 Line);
78
79 static ACPI_STATUS
80 AcpiUtRemoveAllocation (
81 ACPI_DEBUG_MEM_BLOCK *Address,
82 UINT32 Component,
83 const char *Module,
84 UINT32 Line);
85
86
87 /*******************************************************************************
88 *
89 * FUNCTION: AcpiUtCreateList
90 *
91 * PARAMETERS: CacheName - Ascii name for the cache
92 * ObjectSize - Size of each cached object
93 * ReturnCache - Where the new cache object is returned
94 *
95 * RETURN: Status
96 *
97 * DESCRIPTION: Create a local memory list for tracking purposed
98 *
99 ******************************************************************************/
100
101 ACPI_STATUS
AcpiUtCreateList(const char * ListName,UINT16 ObjectSize,ACPI_MEMORY_LIST ** ReturnCache)102 AcpiUtCreateList (
103 const char *ListName,
104 UINT16 ObjectSize,
105 ACPI_MEMORY_LIST **ReturnCache)
106 {
107 ACPI_MEMORY_LIST *Cache;
108
109
110 Cache = AcpiOsAllocate (sizeof (ACPI_MEMORY_LIST));
111 if (!Cache)
112 {
113 return (AE_NO_MEMORY);
114 }
115
116 memset (Cache, 0, sizeof (ACPI_MEMORY_LIST));
117
118 Cache->ListName = ListName;
119 Cache->ObjectSize = ObjectSize;
120
121 *ReturnCache = Cache;
122 return (AE_OK);
123 }
124
125
126 /*******************************************************************************
127 *
128 * FUNCTION: AcpiUtAllocateAndTrack
129 *
130 * PARAMETERS: Size - Size of the allocation
131 * Component - Component type of caller
132 * Module - Source file name of caller
133 * Line - Line number of caller
134 *
135 * RETURN: Address of the allocated memory on success, NULL on failure.
136 *
137 * DESCRIPTION: The subsystem's equivalent of malloc.
138 *
139 ******************************************************************************/
140
141 void *
AcpiUtAllocateAndTrack(ACPI_SIZE Size,UINT32 Component,const char * Module,UINT32 Line)142 AcpiUtAllocateAndTrack (
143 ACPI_SIZE Size,
144 UINT32 Component,
145 const char *Module,
146 UINT32 Line)
147 {
148 ACPI_DEBUG_MEM_BLOCK *Allocation;
149 ACPI_STATUS Status;
150
151
152 /* Check for an inadvertent size of zero bytes */
153
154 if (!Size)
155 {
156 ACPI_WARNING ((Module, Line,
157 "Attempt to allocate zero bytes, allocating 1 byte"));
158 Size = 1;
159 }
160
161 Allocation = AcpiOsAllocate (Size + sizeof (ACPI_DEBUG_MEM_HEADER));
162 if (!Allocation)
163 {
164 /* Report allocation error */
165
166 ACPI_WARNING ((Module, Line,
167 "Could not allocate size %u", (UINT32) Size));
168
169 return (NULL);
170 }
171
172 Status = AcpiUtTrackAllocation (
173 Allocation, Size, ACPI_MEM_MALLOC, Component, Module, Line);
174 if (ACPI_FAILURE (Status))
175 {
176 AcpiOsFree (Allocation);
177 return (NULL);
178 }
179
180 AcpiGbl_GlobalList->TotalAllocated++;
181 AcpiGbl_GlobalList->TotalSize += (UINT32) Size;
182 AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size;
183
184 if (AcpiGbl_GlobalList->CurrentTotalSize >
185 AcpiGbl_GlobalList->MaxOccupied)
186 {
187 AcpiGbl_GlobalList->MaxOccupied =
188 AcpiGbl_GlobalList->CurrentTotalSize;
189 }
190
191 return ((void *) &Allocation->UserSpace);
192 }
193
194
195 /*******************************************************************************
196 *
197 * FUNCTION: AcpiUtAllocateZeroedAndTrack
198 *
199 * PARAMETERS: Size - Size of the allocation
200 * Component - Component type of caller
201 * Module - Source file name of caller
202 * Line - Line number of caller
203 *
204 * RETURN: Address of the allocated memory on success, NULL on failure.
205 *
206 * DESCRIPTION: Subsystem equivalent of calloc.
207 *
208 ******************************************************************************/
209
210 void *
AcpiUtAllocateZeroedAndTrack(ACPI_SIZE Size,UINT32 Component,const char * Module,UINT32 Line)211 AcpiUtAllocateZeroedAndTrack (
212 ACPI_SIZE Size,
213 UINT32 Component,
214 const char *Module,
215 UINT32 Line)
216 {
217 ACPI_DEBUG_MEM_BLOCK *Allocation;
218 ACPI_STATUS Status;
219
220
221 /* Check for an inadvertent size of zero bytes */
222
223 if (!Size)
224 {
225 ACPI_WARNING ((Module, Line,
226 "Attempt to allocate zero bytes, allocating 1 byte"));
227 Size = 1;
228 }
229
230 Allocation = AcpiOsAllocateZeroed (
231 Size + sizeof (ACPI_DEBUG_MEM_HEADER));
232 if (!Allocation)
233 {
234 /* Report allocation error */
235
236 ACPI_ERROR ((Module, Line,
237 "Could not allocate size %u", (UINT32) Size));
238 return (NULL);
239 }
240
241 Status = AcpiUtTrackAllocation (Allocation, Size,
242 ACPI_MEM_CALLOC, Component, Module, Line);
243 if (ACPI_FAILURE (Status))
244 {
245 AcpiOsFree (Allocation);
246 return (NULL);
247 }
248
249 AcpiGbl_GlobalList->TotalAllocated++;
250 AcpiGbl_GlobalList->TotalSize += (UINT32) Size;
251 AcpiGbl_GlobalList->CurrentTotalSize += (UINT32) Size;
252
253 if (AcpiGbl_GlobalList->CurrentTotalSize >
254 AcpiGbl_GlobalList->MaxOccupied)
255 {
256 AcpiGbl_GlobalList->MaxOccupied =
257 AcpiGbl_GlobalList->CurrentTotalSize;
258 }
259
260 return ((void *) &Allocation->UserSpace);
261 }
262
263
264 /*******************************************************************************
265 *
266 * FUNCTION: AcpiUtFreeAndTrack
267 *
268 * PARAMETERS: Allocation - Address of the memory to deallocate
269 * Component - Component type of caller
270 * Module - Source file name of caller
271 * Line - Line number of caller
272 *
273 * RETURN: None
274 *
275 * DESCRIPTION: Frees the memory at Allocation
276 *
277 ******************************************************************************/
278
279 void
AcpiUtFreeAndTrack(void * Allocation,UINT32 Component,const char * Module,UINT32 Line)280 AcpiUtFreeAndTrack (
281 void *Allocation,
282 UINT32 Component,
283 const char *Module,
284 UINT32 Line)
285 {
286 ACPI_DEBUG_MEM_BLOCK *DebugBlock;
287 ACPI_STATUS Status;
288
289
290 ACPI_FUNCTION_TRACE_PTR (UtFree, Allocation);
291
292
293 if (NULL == Allocation)
294 {
295 ACPI_ERROR ((Module, Line,
296 "Attempt to delete a NULL address"));
297
298 return_VOID;
299 }
300
301 DebugBlock = ACPI_CAST_PTR (ACPI_DEBUG_MEM_BLOCK,
302 (((char *) Allocation) - sizeof (ACPI_DEBUG_MEM_HEADER)));
303
304 AcpiGbl_GlobalList->TotalFreed++;
305 AcpiGbl_GlobalList->CurrentTotalSize -= DebugBlock->Size;
306
307 Status = AcpiUtRemoveAllocation (DebugBlock, Component, Module, Line);
308 if (ACPI_FAILURE (Status))
309 {
310 ACPI_EXCEPTION ((AE_INFO, Status, "Could not free memory"));
311 }
312
313 AcpiOsFree (DebugBlock);
314 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "%p freed (block %p)\n",
315 Allocation, DebugBlock));
316 return_VOID;
317 }
318
319
320 /*******************************************************************************
321 *
322 * FUNCTION: AcpiUtFindAllocation
323 *
324 * PARAMETERS: Allocation - Address of allocated memory
325 *
326 * RETURN: Three cases:
327 * 1) List is empty, NULL is returned.
328 * 2) Element was found. Returns Allocation parameter.
329 * 3) Element was not found. Returns position where it should be
330 * inserted into the list.
331 *
332 * DESCRIPTION: Searches for an element in the global allocation tracking list.
333 * If the element is not found, returns the location within the
334 * list where the element should be inserted.
335 *
336 * Note: The list is ordered by larger-to-smaller addresses.
337 *
338 * This global list is used to detect memory leaks in ACPICA as
339 * well as other issues such as an attempt to release the same
340 * internal object more than once. Although expensive as far
341 * as cpu time, this list is much more helpful for finding these
342 * types of issues than using memory leak detectors outside of
343 * the ACPICA code.
344 *
345 ******************************************************************************/
346
347 static ACPI_DEBUG_MEM_BLOCK *
AcpiUtFindAllocation(ACPI_DEBUG_MEM_BLOCK * Allocation)348 AcpiUtFindAllocation (
349 ACPI_DEBUG_MEM_BLOCK *Allocation)
350 {
351 ACPI_DEBUG_MEM_BLOCK *Element;
352
353
354 Element = AcpiGbl_GlobalList->ListHead;
355 if (!Element)
356 {
357 return (NULL);
358 }
359
360 /*
361 * Search for the address.
362 *
363 * Note: List is ordered by larger-to-smaller addresses, on the
364 * assumption that a new allocation usually has a larger address
365 * than previous allocations.
366 */
367 while (Element > Allocation)
368 {
369 /* Check for end-of-list */
370
371 if (!Element->Next)
372 {
373 return (Element);
374 }
375
376 Element = Element->Next;
377 }
378
379 if (Element == Allocation)
380 {
381 return (Element);
382 }
383
384 return (Element->Previous);
385 }
386
387
388 /*******************************************************************************
389 *
390 * FUNCTION: AcpiUtTrackAllocation
391 *
392 * PARAMETERS: Allocation - Address of allocated memory
393 * Size - Size of the allocation
394 * AllocType - MEM_MALLOC or MEM_CALLOC
395 * Component - Component type of caller
396 * Module - Source file name of caller
397 * Line - Line number of caller
398 *
399 * RETURN: Status
400 *
401 * DESCRIPTION: Inserts an element into the global allocation tracking list.
402 *
403 ******************************************************************************/
404
405 static ACPI_STATUS
AcpiUtTrackAllocation(ACPI_DEBUG_MEM_BLOCK * Allocation,ACPI_SIZE Size,UINT8 AllocType,UINT32 Component,const char * Module,UINT32 Line)406 AcpiUtTrackAllocation (
407 ACPI_DEBUG_MEM_BLOCK *Allocation,
408 ACPI_SIZE Size,
409 UINT8 AllocType,
410 UINT32 Component,
411 const char *Module,
412 UINT32 Line)
413 {
414 ACPI_MEMORY_LIST *MemList;
415 ACPI_DEBUG_MEM_BLOCK *Element;
416 ACPI_STATUS Status = AE_OK;
417
418
419 ACPI_FUNCTION_TRACE_PTR (UtTrackAllocation, Allocation);
420
421
422 if (AcpiGbl_DisableMemTracking)
423 {
424 return_ACPI_STATUS (AE_OK);
425 }
426
427 MemList = AcpiGbl_GlobalList;
428 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
429 if (ACPI_FAILURE (Status))
430 {
431 return_ACPI_STATUS (Status);
432 }
433
434 /*
435 * Search the global list for this address to make sure it is not
436 * already present. This will catch several kinds of problems.
437 */
438 Element = AcpiUtFindAllocation (Allocation);
439 if (Element == Allocation)
440 {
441 ACPI_ERROR ((AE_INFO,
442 "UtTrackAllocation: Allocation (%p) already present in global list!",
443 Allocation));
444 goto UnlockAndExit;
445 }
446
447 /* Fill in the instance data */
448
449 Allocation->Size = (UINT32) Size;
450 Allocation->AllocType = AllocType;
451 Allocation->Component = Component;
452 Allocation->Line = Line;
453
454 strncpy (Allocation->Module, Module, ACPI_MAX_MODULE_NAME);
455 Allocation->Module[ACPI_MAX_MODULE_NAME-1] = 0;
456
457 if (!Element)
458 {
459 /* Insert at list head */
460
461 if (MemList->ListHead)
462 {
463 ((ACPI_DEBUG_MEM_BLOCK *)(MemList->ListHead))->Previous =
464 Allocation;
465 }
466
467 Allocation->Next = MemList->ListHead;
468 Allocation->Previous = NULL;
469
470 MemList->ListHead = Allocation;
471 }
472 else
473 {
474 /* Insert after element */
475
476 Allocation->Next = Element->Next;
477 Allocation->Previous = Element;
478
479 if (Element->Next)
480 {
481 (Element->Next)->Previous = Allocation;
482 }
483
484 Element->Next = Allocation;
485 }
486
487
488 UnlockAndExit:
489 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
490 return_ACPI_STATUS (Status);
491 }
492
493
494 /*******************************************************************************
495 *
496 * FUNCTION: AcpiUtRemoveAllocation
497 *
498 * PARAMETERS: Allocation - Address of allocated memory
499 * Component - Component type of caller
500 * Module - Source file name of caller
501 * Line - Line number of caller
502 *
503 * RETURN: Status
504 *
505 * DESCRIPTION: Deletes an element from the global allocation tracking list.
506 *
507 ******************************************************************************/
508
509 static ACPI_STATUS
AcpiUtRemoveAllocation(ACPI_DEBUG_MEM_BLOCK * Allocation,UINT32 Component,const char * Module,UINT32 Line)510 AcpiUtRemoveAllocation (
511 ACPI_DEBUG_MEM_BLOCK *Allocation,
512 UINT32 Component,
513 const char *Module,
514 UINT32 Line)
515 {
516 ACPI_MEMORY_LIST *MemList;
517 ACPI_STATUS Status;
518
519
520 ACPI_FUNCTION_NAME (UtRemoveAllocation);
521
522
523 if (AcpiGbl_DisableMemTracking)
524 {
525 return (AE_OK);
526 }
527
528 MemList = AcpiGbl_GlobalList;
529 if (NULL == MemList->ListHead)
530 {
531 /* No allocations! */
532
533 ACPI_ERROR ((Module, Line,
534 "Empty allocation list, nothing to free!"));
535
536 return (AE_OK);
537 }
538
539 Status = AcpiUtAcquireMutex (ACPI_MTX_MEMORY);
540 if (ACPI_FAILURE (Status))
541 {
542 return (Status);
543 }
544
545 /* Unlink */
546
547 if (Allocation->Previous)
548 {
549 (Allocation->Previous)->Next = Allocation->Next;
550 }
551 else
552 {
553 MemList->ListHead = Allocation->Next;
554 }
555
556 if (Allocation->Next)
557 {
558 (Allocation->Next)->Previous = Allocation->Previous;
559 }
560
561 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Freeing %p, size 0%X\n",
562 &Allocation->UserSpace, Allocation->Size));
563
564 /* Mark the segment as deleted */
565
566 memset (&Allocation->UserSpace, 0xEA, Allocation->Size);
567
568 Status = AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
569 return (Status);
570 }
571
572
573 /*******************************************************************************
574 *
575 * FUNCTION: AcpiUtDumpAllocationInfo
576 *
577 * PARAMETERS: None
578 *
579 * RETURN: None
580 *
581 * DESCRIPTION: Print some info about the outstanding allocations.
582 *
583 ******************************************************************************/
584
585 void
AcpiUtDumpAllocationInfo(void)586 AcpiUtDumpAllocationInfo (
587 void)
588 {
589 /*
590 ACPI_MEMORY_LIST *MemList;
591 */
592
593 ACPI_FUNCTION_TRACE (UtDumpAllocationInfo);
594
595 /*
596 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
597 ("%30s: %4d (%3d Kb)\n", "Current allocations",
598 MemList->CurrentCount,
599 ROUND_UP_TO_1K (MemList->CurrentSize)));
600
601 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
602 ("%30s: %4d (%3d Kb)\n", "Max concurrent allocations",
603 MemList->MaxConcurrentCount,
604 ROUND_UP_TO_1K (MemList->MaxConcurrentSize)));
605
606
607 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
608 ("%30s: %4d (%3d Kb)\n", "Total (all) internal objects",
609 RunningObjectCount,
610 ROUND_UP_TO_1K (RunningObjectSize)));
611
612 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
613 ("%30s: %4d (%3d Kb)\n", "Total (all) allocations",
614 RunningAllocCount,
615 ROUND_UP_TO_1K (RunningAllocSize)));
616
617
618 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
619 ("%30s: %4d (%3d Kb)\n", "Current Nodes",
620 AcpiGbl_CurrentNodeCount,
621 ROUND_UP_TO_1K (AcpiGbl_CurrentNodeSize)));
622
623 ACPI_DEBUG_PRINT (TRACE_ALLOCATIONS | TRACE_TABLES,
624 ("%30s: %4d (%3d Kb)\n", "Max Nodes",
625 AcpiGbl_MaxConcurrentNodeCount,
626 ROUND_UP_TO_1K ((AcpiGbl_MaxConcurrentNodeCount *
627 sizeof (ACPI_NAMESPACE_NODE)))));
628 */
629 return_VOID;
630 }
631
632
633 /*******************************************************************************
634 *
635 * FUNCTION: AcpiUtDumpAllocations
636 *
637 * PARAMETERS: Component - Component(s) to dump info for.
638 * Module - Module to dump info for. NULL means all.
639 *
640 * RETURN: None
641 *
642 * DESCRIPTION: Print a list of all outstanding allocations.
643 *
644 ******************************************************************************/
645
646 void
AcpiUtDumpAllocations(UINT32 Component,const char * Module)647 AcpiUtDumpAllocations (
648 UINT32 Component,
649 const char *Module)
650 {
651 ACPI_DEBUG_MEM_BLOCK *Element;
652 ACPI_DESCRIPTOR *Descriptor;
653 UINT32 NumOutstanding = 0;
654 UINT8 DescriptorType;
655
656
657 ACPI_FUNCTION_TRACE (UtDumpAllocations);
658
659
660 if (AcpiGbl_DisableMemTracking)
661 {
662 return_VOID;
663 }
664
665 /*
666 * Walk the allocation list.
667 */
668 if (ACPI_FAILURE (AcpiUtAcquireMutex (ACPI_MTX_MEMORY)))
669 {
670 return_VOID;
671 }
672
673 Element = AcpiGbl_GlobalList->ListHead;
674 while (Element)
675 {
676 if ((Element->Component & Component) &&
677 ((Module == NULL) || (0 == strcmp (Module, Element->Module))))
678 {
679 Descriptor = ACPI_CAST_PTR (
680 ACPI_DESCRIPTOR, &Element->UserSpace);
681
682 if (Element->Size < sizeof (ACPI_COMMON_DESCRIPTOR))
683 {
684 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u "
685 "[Not a Descriptor - too small]\n",
686 Descriptor, Element->Size, Element->Module,
687 Element->Line);
688 }
689 else
690 {
691 /* Ignore allocated objects that are in a cache */
692
693 if (ACPI_GET_DESCRIPTOR_TYPE (Descriptor) !=
694 ACPI_DESC_TYPE_CACHED)
695 {
696 AcpiOsPrintf ("%p Length 0x%04X %9.9s-%u [%s] ",
697 Descriptor, Element->Size, Element->Module,
698 Element->Line, AcpiUtGetDescriptorName (Descriptor));
699
700 /* Validate the descriptor type using Type field and length */
701
702 DescriptorType = 0; /* Not a valid descriptor type */
703
704 switch (ACPI_GET_DESCRIPTOR_TYPE (Descriptor))
705 {
706 case ACPI_DESC_TYPE_OPERAND:
707
708 if (Element->Size == sizeof (ACPI_OPERAND_OBJECT))
709 {
710 DescriptorType = ACPI_DESC_TYPE_OPERAND;
711 }
712 break;
713
714 case ACPI_DESC_TYPE_PARSER:
715
716 if (Element->Size == sizeof (ACPI_PARSE_OBJECT))
717 {
718 DescriptorType = ACPI_DESC_TYPE_PARSER;
719 }
720 break;
721
722 case ACPI_DESC_TYPE_NAMED:
723
724 if (Element->Size == sizeof (ACPI_NAMESPACE_NODE))
725 {
726 DescriptorType = ACPI_DESC_TYPE_NAMED;
727 }
728 break;
729
730 default:
731
732 break;
733 }
734
735 /* Display additional info for the major descriptor types */
736
737 switch (DescriptorType)
738 {
739 case ACPI_DESC_TYPE_OPERAND:
740
741 AcpiOsPrintf ("%12.12s RefCount 0x%04X\n",
742 AcpiUtGetTypeName (Descriptor->Object.Common.Type),
743 Descriptor->Object.Common.ReferenceCount);
744 break;
745
746 case ACPI_DESC_TYPE_PARSER:
747
748 AcpiOsPrintf ("AmlOpcode 0x%04hX\n",
749 Descriptor->Op.Asl.AmlOpcode);
750 break;
751
752 case ACPI_DESC_TYPE_NAMED:
753
754 AcpiOsPrintf ("%4.4s\n",
755 AcpiUtGetNodeName (&Descriptor->Node));
756 break;
757
758 default:
759
760 AcpiOsPrintf ( "\n");
761 break;
762 }
763 }
764 }
765
766 NumOutstanding++;
767 }
768
769 Element = Element->Next;
770 }
771
772 (void) AcpiUtReleaseMutex (ACPI_MTX_MEMORY);
773
774 /* Print summary */
775
776 if (!NumOutstanding)
777 {
778 ACPI_INFO (("No outstanding allocations"));
779 }
780 else
781 {
782 ACPI_ERROR ((AE_INFO, "%u(0x%X) Outstanding allocations",
783 NumOutstanding, NumOutstanding));
784 }
785
786 return_VOID;
787 }
788
789 #endif /* ACPI_DBG_TRACK_ALLOCATIONS */
790