summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobert Moore <Robert.Moore@intel.com>2014-08-14 09:50:01 -0700
committerRobert Moore <Robert.Moore@intel.com>2014-08-14 09:50:01 -0700
commitfcd2e228352682e64e60d594b228f8544241b580 (patch)
tree845bb99d2b22a94121b5c9ff2514b2c7a29b67a2 /source
parentf1596580344531d9ae7e68e3f6a20135f9afd976 (diff)
downloadacpica-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.c17
-rw-r--r--source/compiler/asldefine.h4
-rw-r--r--source/compiler/aslglobal.h4
-rw-r--r--source/compiler/asltree.c5
-rw-r--r--source/compiler/aslutils.c19
-rw-r--r--source/compiler/dtcompile.c10
-rw-r--r--source/compiler/dtcompiler.h26
-rw-r--r--source/compiler/dtio.c35
-rw-r--r--source/compiler/dtsubtable.c4
-rw-r--r--source/compiler/dtutils.c145
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;
}