diff options
author | Robert Moore <Robert.Moore@intel.com> | 2014-08-14 09:50:01 -0700 |
---|---|---|
committer | Robert Moore <Robert.Moore@intel.com> | 2014-08-14 09:50:01 -0700 |
commit | fcd2e228352682e64e60d594b228f8544241b580 (patch) | |
tree | 845bb99d2b22a94121b5c9ff2514b2c7a29b67a2 /source | |
parent | f1596580344531d9ae7e68e3f6a20135f9afd976 (diff) | |
download | acpica-fcd2e228352682e64e60d594b228f8544241b580.tar.gz |
iASL/TableCompiler: Add object caching, cleanup memory leaks.
Add object caches for the field and subtable objects, to improve
performance and to simplify memory management.
Diffstat (limited to 'source')
-rw-r--r-- | source/compiler/aslcompile.c | 17 | ||||
-rw-r--r-- | source/compiler/asldefine.h | 4 | ||||
-rw-r--r-- | source/compiler/aslglobal.h | 4 | ||||
-rw-r--r-- | source/compiler/asltree.c | 5 | ||||
-rw-r--r-- | source/compiler/aslutils.c | 19 | ||||
-rw-r--r-- | source/compiler/dtcompile.c | 10 | ||||
-rw-r--r-- | source/compiler/dtcompiler.h | 26 | ||||
-rw-r--r-- | source/compiler/dtio.c | 35 | ||||
-rw-r--r-- | source/compiler/dtsubtable.c | 4 | ||||
-rw-r--r-- | source/compiler/dtutils.c | 145 |
10 files changed, 204 insertions, 65 deletions
diff --git a/source/compiler/aslcompile.c b/source/compiler/aslcompile.c index d47d87e95..a051e0f77 100644 --- a/source/compiler/aslcompile.c +++ b/source/compiler/aslcompile.c @@ -836,31 +836,48 @@ void CmDeleteCaches ( void) { + UINT32 BufferCount; ASL_CACHE_INFO *Next; /* Parse Op cache */ + BufferCount = 0; while (Gbl_ParseOpCacheList) { Next = Gbl_ParseOpCacheList->Next; ACPI_FREE (Gbl_ParseOpCacheList); Gbl_ParseOpCacheList = Next; + BufferCount++; } + DbgPrint (ASL_DEBUG_OUTPUT, + "%u ParseOps, Buffer size: %u ops (%u bytes), %u Buffers\n", + Gbl_ParseOpCount, ASL_PARSEOP_CACHE_SIZE, + (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE), BufferCount); + + Gbl_ParseOpCount = 0; Gbl_ParseOpCacheNext = NULL; Gbl_ParseOpCacheLast = NULL; RootNode = NULL; /* Generic string cache */ + BufferCount = 0; while (Gbl_StringCacheList) { Next = Gbl_StringCacheList->Next; ACPI_FREE (Gbl_StringCacheList); Gbl_StringCacheList = Next; + BufferCount++; } + DbgPrint (ASL_DEBUG_OUTPUT, + "%u Strings (%u bytes), Buffer size: %u bytes, %u Buffers\n", + Gbl_StringCount, Gbl_StringSize, ASL_STRING_CACHE_SIZE, BufferCount); + + Gbl_StringSize = 0; + Gbl_StringCount = 0; Gbl_StringCacheNext = NULL; Gbl_StringCacheLast = NULL; } diff --git a/source/compiler/asldefine.h b/source/compiler/asldefine.h index a772d9ad2..f4091dda4 100644 --- a/source/compiler/asldefine.h +++ b/source/compiler/asldefine.h @@ -133,8 +133,8 @@ /* Configuration constants */ #define ASL_MAX_ERROR_COUNT 200 -#define ASL_PARSEOP_CACHE_SIZE 1024 -#define ASL_STRING_CACHE_SIZE (1024 * 32) +#define ASL_PARSEOP_CACHE_SIZE (1024 * 16) +#define ASL_STRING_CACHE_SIZE (1024 * 64) #define ASL_FIRST_PARSE_OPCODE PARSEOP_ACCESSAS #define ASL_PARSE_OPCODE_BASE PARSEOP_ACCESSAS /* First Lex type */ diff --git a/source/compiler/aslglobal.h b/source/compiler/aslglobal.h index 3abe07c5e..53b5fbb47 100644 --- a/source/compiler/aslglobal.h +++ b/source/compiler/aslglobal.h @@ -283,9 +283,13 @@ ASL_EXTERN UINT32 ASL_INIT_GLOBAL (TotalFolds, 0); /* Local caches */ +ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_ParseOpCount, 0); ASL_EXTERN ASL_CACHE_INFO ASL_INIT_GLOBAL (*Gbl_ParseOpCacheList, NULL); ASL_EXTERN ACPI_PARSE_OBJECT ASL_INIT_GLOBAL (*Gbl_ParseOpCacheNext, NULL); ASL_EXTERN ACPI_PARSE_OBJECT ASL_INIT_GLOBAL (*Gbl_ParseOpCacheLast, NULL); + +ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_StringCount, 0); +ASL_EXTERN UINT32 ASL_INIT_GLOBAL (Gbl_StringSize, 0); ASL_EXTERN ASL_CACHE_INFO ASL_INIT_GLOBAL (*Gbl_StringCacheList, NULL); ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_StringCacheNext, NULL); ASL_EXTERN char ASL_INIT_GLOBAL (*Gbl_StringCacheLast, NULL); diff --git a/source/compiler/asltree.c b/source/compiler/asltree.c index 5b64c58b2..f1a9ed543 100644 --- a/source/compiler/asltree.c +++ b/source/compiler/asltree.c @@ -158,8 +158,8 @@ TrGetNextNode ( { /* Allocate a new buffer */ - Cache = UtLocalCalloc ( - sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE); + Cache = UtLocalCalloc (sizeof (Cache->Next) + + (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE)); /* Link new cache buffer to head of list */ @@ -172,6 +172,7 @@ TrGetNextNode ( Gbl_ParseOpCacheLast = Gbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE; } + Gbl_ParseOpCount++; return (Gbl_ParseOpCacheNext++); } diff --git a/source/compiler/aslutils.c b/source/compiler/aslutils.c index f60c8352d..5d9b4d452 100644 --- a/source/compiler/aslutils.c +++ b/source/compiler/aslutils.c @@ -646,12 +646,18 @@ UtStringCacheCalloc ( ASL_CACHE_INFO *Cache; + if (Length > ASL_STRING_CACHE_SIZE) + { + Buffer = UtLocalCalloc (Length); + return (Buffer); + } + if ((Gbl_StringCacheNext + Length) >= Gbl_StringCacheLast) { /* Allocate a new buffer */ - Cache = UtLocalCalloc (ASL_STRING_CACHE_SIZE + - sizeof (Cache->Next) + Length); + Cache = UtLocalCalloc (sizeof (Cache->Next) + + ASL_STRING_CACHE_SIZE); /* Link new cache buffer to head of list */ @@ -661,10 +667,12 @@ UtStringCacheCalloc ( /* Setup cache management pointers */ Gbl_StringCacheNext = Cache->Buffer; - Gbl_StringCacheLast = Gbl_StringCacheNext + - (ASL_STRING_CACHE_SIZE + Length); + Gbl_StringCacheLast = Gbl_StringCacheNext + ASL_STRING_CACHE_SIZE; } + Gbl_StringCount++; + Gbl_StringSize += Length; + Buffer = Gbl_StringCacheNext; Gbl_StringCacheNext += Length; return (Buffer); @@ -699,7 +707,8 @@ UtExpandLineBuffers ( NewSize = Gbl_LineBufferSize * 2; if (Gbl_CurrentLineBuffer) { - DbgPrint (ASL_DEBUG_OUTPUT,"Increasing line buffer size from %u to %u\n", + DbgPrint (ASL_DEBUG_OUTPUT, + "Increasing line buffer size from %u to %u\n", Gbl_LineBufferSize, NewSize); } diff --git a/source/compiler/dtcompile.c b/source/compiler/dtcompile.c index bda6afae5..c33564a04 100644 --- a/source/compiler/dtcompile.c +++ b/source/compiler/dtcompile.c @@ -213,8 +213,6 @@ DtDoCompile ( Status = DtCompileDataTable (&FieldList); UtEndEvent (Event); - DtFreeFieldList (); - if (ACPI_FAILURE (Status)) { /* TBD: temporary error message. Msgs should come from function above */ @@ -242,6 +240,8 @@ DtDoCompile ( CleanupAndExit: + AcpiUtDeleteCaches (); + DtDeleteCaches (); CmCleanupAndExit (); return (Status); } @@ -533,11 +533,11 @@ DtCompileTable ( return (AE_ERROR); } - Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE)); + Subtable = UtSubtableCacheCalloc (); if (Length > 0) { - Subtable->Buffer = UtLocalCalloc (Length); + Subtable->Buffer = ACPI_CAST_PTR (UINT8, UtStringCacheCalloc (Length)); } Subtable->Length = Length; Subtable->TotalLength = Length; @@ -639,8 +639,6 @@ DtCompileTable ( DtSetSubtableLength (InlineSubtable); ACPI_MEMCPY (Buffer, InlineSubtable->Buffer, FieldLength); - ACPI_FREE (InlineSubtable->Buffer); - ACPI_FREE (InlineSubtable); LocalField = *Field; break; diff --git a/source/compiler/dtcompiler.h b/source/compiler/dtcompiler.h index 1fb1f125a..2eda236c4 100644 --- a/source/compiler/dtcompiler.h +++ b/source/compiler/dtcompiler.h @@ -122,6 +122,10 @@ #include "acdisasm.h" +#define ASL_FIELD_CACHE_SIZE 512 +#define ASL_SUBTABLE_CACHE_SIZE 128 + + #undef DT_EXTERN #ifdef _DECLARE_DT_GLOBALS @@ -215,6 +219,18 @@ DT_EXTERN DT_FIELD DT_INIT_GLOBAL (*Gbl_LabelList, NULL); DT_EXTERN UINT32 DT_INIT_GLOBAL (Gbl_CurrentTableOffset, 0); +/* Local caches */ + +DT_EXTERN UINT32 DT_INIT_GLOBAL (Gbl_SubtableCount, 0); +DT_EXTERN ASL_CACHE_INFO DT_INIT_GLOBAL (*Gbl_SubtableCacheList, NULL); +DT_EXTERN DT_SUBTABLE DT_INIT_GLOBAL (*Gbl_SubtableCacheNext, NULL); +DT_EXTERN DT_SUBTABLE DT_INIT_GLOBAL (*Gbl_SubtableCacheLast, NULL); + +DT_EXTERN UINT32 DT_INIT_GLOBAL (Gbl_FieldCount, 0); +DT_EXTERN ASL_CACHE_INFO DT_INIT_GLOBAL (*Gbl_FieldCacheList, NULL); +DT_EXTERN DT_FIELD DT_INIT_GLOBAL (*Gbl_FieldCacheNext, NULL); +DT_EXTERN DT_FIELD DT_INIT_GLOBAL (*Gbl_FieldCacheLast, NULL); + /* dtcompiler - main module */ @@ -440,8 +456,16 @@ void DtSetTableLength( void); +DT_SUBTABLE * +UtSubtableCacheCalloc ( + void); + +DT_FIELD * +UtFieldCacheCalloc ( + void); + void -DtFreeFieldList ( +DtDeleteCaches ( void); diff --git a/source/compiler/dtio.c b/source/compiler/dtio.c index 90c10660b..7c93afea2 100644 --- a/source/compiler/dtio.c +++ b/source/compiler/dtio.c @@ -205,7 +205,7 @@ DtTrim ( if (!ACPI_STRCMP (String, " ")) { - ReturnString = UtLocalCalloc (1); + ReturnString = UtStringCacheCalloc (1); return (ReturnString); } @@ -253,7 +253,7 @@ DtTrim ( /* Create the trimmed return string */ Length = ACPI_PTR_DIFF (End, Start) + 1; - ReturnString = UtLocalCalloc (Length + 1); + ReturnString = UtStringCacheCalloc (Length + 1); if (ACPI_STRLEN (Start)) { ACPI_STRNCPY (ReturnString, Start, Length); @@ -442,7 +442,7 @@ DtParseLine ( if ((Value && *Value) || IsNullString) { - Field = UtLocalCalloc (sizeof (DT_FIELD)); + Field = UtFieldCacheCalloc (); Field->Name = Name; Field->Value = Value; Field->Line = Line; @@ -452,11 +452,7 @@ DtParseLine ( DtLinkField (Field); } - else /* Ignore this field, it has no valid data */ - { - ACPI_FREE (Name); - ACPI_FREE (Value); - } + /* Else -- Ignore this field, it has no valid data */ return (AE_OK); } @@ -1107,30 +1103,9 @@ DtDumpSubtableList ( DbgPrint (ASL_DEBUG_OUTPUT, "\nSubtable Tree: (Depth, Subtable, Length, TotalLength)\n\n"); DtWalkTableTree (Gbl_RootTable, DtDumpSubtableTree, NULL, NULL); -} - - -#ifdef __UNDER_DEVELOPMENT -static void -DtDeleteSubtable ( - DT_SUBTABLE *Subtable, - void *Context, - void *ReturnValue) -{ - - - ACPI_FREE (Subtable); -} - -void -DtDeleteSubtableTree ( - void) -{ - - DtWalkTableTree (Gbl_RootTable, DtDeleteSubtable, NULL, NULL); + DbgPrint (ASL_DEBUG_OUTPUT, "\n"); } -#endif /****************************************************************************** diff --git a/source/compiler/dtsubtable.c b/source/compiler/dtsubtable.c index 3892fdca1..e9f530b8c 100644 --- a/source/compiler/dtsubtable.c +++ b/source/compiler/dtsubtable.c @@ -147,11 +147,11 @@ DtCreateSubtable ( DT_SUBTABLE *Subtable; - Subtable = UtLocalCalloc (sizeof (DT_SUBTABLE)); + Subtable = UtSubtableCacheCalloc (); /* Create a new buffer for the subtable data */ - Subtable->Buffer = UtLocalCalloc (Length); + Subtable->Buffer = ACPI_CAST_PTR (UINT8, UtStringCacheCalloc (Length)); ACPI_MEMCPY (Subtable->Buffer, Buffer, Length); Subtable->Length = Length; diff --git a/source/compiler/dtutils.c b/source/compiler/dtutils.c index 3fdb703da..2eac7fa3e 100644 --- a/source/compiler/dtutils.c +++ b/source/compiler/dtutils.c @@ -917,40 +917,151 @@ DtWalkTableTree ( } -/****************************************************************************** +/******************************************************************************* + * + * FUNCTION: UtSubtableCacheCalloc + * + * PARAMETERS: None + * + * RETURN: Pointer to the buffer. Aborts on allocation failure + * + * DESCRIPTION: Allocate a subtable object buffer. Bypass the local + * dynamic memory manager for performance reasons (This has a + * major impact on the speed of the compiler.) + * + ******************************************************************************/ + +DT_SUBTABLE * +UtSubtableCacheCalloc ( + void) +{ + ASL_CACHE_INFO *Cache; + + + if (Gbl_SubtableCacheNext >= Gbl_SubtableCacheLast) + { + /* Allocate a new buffer */ + + Cache = UtLocalCalloc (sizeof (Cache->Next) + + (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE)); + + /* Link new cache buffer to head of list */ + + Cache->Next = Gbl_SubtableCacheList; + Gbl_SubtableCacheList = Cache; + + /* Setup cache management pointers */ + + Gbl_SubtableCacheNext = ACPI_CAST_PTR (DT_SUBTABLE, Cache->Buffer); + Gbl_SubtableCacheLast = Gbl_SubtableCacheNext + ASL_SUBTABLE_CACHE_SIZE; + } + + Gbl_SubtableCount++; + return (Gbl_SubtableCacheNext++); +} + + +/******************************************************************************* * - * FUNCTION: DtFreeFieldList + * FUNCTION: UtFieldCacheCalloc + * + * PARAMETERS: None + * + * RETURN: Pointer to the buffer. Aborts on allocation failure + * + * DESCRIPTION: Allocate a field object buffer. Bypass the local + * dynamic memory manager for performance reasons (This has a + * major impact on the speed of the compiler.) + * + ******************************************************************************/ + +DT_FIELD * +UtFieldCacheCalloc ( + void) +{ + ASL_CACHE_INFO *Cache; + + + if (Gbl_FieldCacheNext >= Gbl_FieldCacheLast) + { + /* Allocate a new buffer */ + + Cache = UtLocalCalloc (sizeof (Cache->Next) + + (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE)); + + /* Link new cache buffer to head of list */ + + Cache->Next = Gbl_FieldCacheList; + Gbl_FieldCacheList = Cache; + + /* Setup cache management pointers */ + + Gbl_FieldCacheNext = ACPI_CAST_PTR (DT_FIELD, Cache->Buffer); + Gbl_FieldCacheLast = Gbl_FieldCacheNext + ASL_FIELD_CACHE_SIZE; + } + + Gbl_FieldCount++; + return (Gbl_FieldCacheNext++); +} + + +/******************************************************************************* + * + * FUNCTION: DtDeleteCaches * * PARAMETERS: None * * RETURN: None * - * DESCRIPTION: Free the field list + * DESCRIPTION: Delete all local cache buffer blocks * - *****************************************************************************/ + ******************************************************************************/ void -DtFreeFieldList ( +DtDeleteCaches ( void) { - DT_FIELD *Field = Gbl_FieldList; - DT_FIELD *NextField; + UINT32 BufferCount; + ASL_CACHE_INFO *Next; - /* Walk and free entire field list */ + /* Field cache */ - while (Field) + BufferCount = 0; + while (Gbl_FieldCacheList) { - NextField = Field->Next; /* Save link */ + Next = Gbl_FieldCacheList->Next; + ACPI_FREE (Gbl_FieldCacheList); + Gbl_FieldCacheList = Next; + BufferCount++; + } - if (!(Field->Flags & DT_FIELD_NOT_ALLOCATED)) - { - /* No need to free the name, it is in the string cache */ + DbgPrint (ASL_DEBUG_OUTPUT, + "%u Fields, Buffer size: %u fields (%u bytes), %u Buffers\n", + Gbl_FieldCount, ASL_FIELD_CACHE_SIZE, + (sizeof (DT_FIELD) * ASL_FIELD_CACHE_SIZE), BufferCount); - ACPI_FREE (Field->Value); - } + Gbl_FieldCount = 0; + Gbl_FieldCacheNext = NULL; + Gbl_FieldCacheLast = NULL; + + /* Subtable cache */ - ACPI_FREE (Field); - Field = NextField; + BufferCount = 0; + while (Gbl_SubtableCacheList) + { + Next = Gbl_SubtableCacheList->Next; + ACPI_FREE (Gbl_SubtableCacheList); + Gbl_SubtableCacheList = Next; + BufferCount++; } + + DbgPrint (ASL_DEBUG_OUTPUT, + "%u Subtables, Buffer size: %u subtables (%u bytes), %u Buffers\n", + Gbl_SubtableCount, ASL_SUBTABLE_CACHE_SIZE, + (sizeof (DT_SUBTABLE) * ASL_SUBTABLE_CACHE_SIZE), BufferCount); + + Gbl_SubtableCount = 0; + Gbl_SubtableCacheNext = NULL; + Gbl_SubtableCacheLast = NULL; } |