Eliminate control method 2-pass parse/execute.

Completed an AML interpreter performance enhancement for control method execution. Previously a 2-pass parse/execution, control methods are now completely parsed and executed in single pass. This improves overall interpreter performance by ~25%, reduces code size, and reduces CPU stack use.
This commit is contained in:
rmoore1 2006-10-06 22:29:34 +00:00
parent 893a7b5ab8
commit 830a10802d
2 changed files with 41 additions and 135 deletions

View File

@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: dsmethod - Parser/Interpreter interface - control method parsing
* $Revision: 1.131 $
* $Revision: 1.132 $
*
*****************************************************************************/
@ -428,7 +428,7 @@ AcpiDsCallControlMethod (
ACPI_FUNCTION_TRACE_PTR (DsCallControlMethod, ThisWalkState);
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Execute method %p, currentstate=%p\n",
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Calling method %p, currentstate=%p\n",
ThisWalkState->PrevOp, ThisWalkState));
/*
@ -455,51 +455,7 @@ AcpiDsCallControlMethod (
return_ACPI_STATUS (Status);
}
/*
* 1) Parse the method. All "normal" methods are parsed for each execution.
* Internal methods (_OSI, etc.) do not require parsing.
*/
if (!(ObjDesc->Method.MethodFlags & AML_METHOD_INTERNAL_ONLY))
{
/* Create a new walk state for the parse */
NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwnerId,
Op, ObjDesc, NULL);
if (!NextWalkState)
{
Status = AE_NO_MEMORY;
goto Cleanup;
}
/* Create and init a parse tree root */
Op = AcpiPsCreateScopeOp ();
if (!Op)
{
Status = AE_NO_MEMORY;
goto Cleanup;
}
Status = AcpiDsInitAmlWalk (NextWalkState, Op, MethodNode,
ObjDesc->Method.AmlStart, ObjDesc->Method.AmlLength,
NULL, 1);
if (ACPI_FAILURE (Status))
{
AcpiPsDeleteParseTree (Op);
goto Cleanup;
}
/* Begin AML parse (deletes NextWalkState) */
Status = AcpiPsParseAml (NextWalkState);
AcpiPsDeleteParseTree (Op);
if (ACPI_FAILURE (Status))
{
goto Cleanup;
}
}
/* 2) Begin method execution. Create a new walk state */
/* Begin method parse/execution. Create a new walk state */
NextWalkState = AcpiDsCreateWalkState (ObjDesc->Method.OwnerId,
NULL, ObjDesc, Thread);
@ -555,7 +511,8 @@ AcpiDsCallControlMethod (
ThisWalkState->NumOperands = 0;
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"Starting nested execution, newstate=%p\n", NextWalkState));
"**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
MethodNode->Name.Ascii, NextWalkState));
/* Invoke an internal method if necessary */

View File

@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: psxface - Parser external interfaces
* $Revision: 1.90 $
* $Revision: 1.91 $
*
*****************************************************************************/
@ -135,10 +135,6 @@ static void
AcpiPsStopTrace (
ACPI_EVALUATE_INFO *Info);
static ACPI_STATUS
AcpiPsExecutePass (
ACPI_EVALUATE_INFO *Info);
static void
AcpiPsUpdateParameterList (
ACPI_EVALUATE_INFO *Info,
@ -330,6 +326,8 @@ AcpiPsExecuteMethod (
ACPI_EVALUATE_INFO *Info)
{
ACPI_STATUS Status;
ACPI_PARSE_OBJECT *Op;
ACPI_WALK_STATE *WalkState;
ACPI_FUNCTION_TRACE (PsExecuteMethod);
@ -351,8 +349,7 @@ AcpiPsExecuteMethod (
}
/*
* The caller "owns" the parameters, so give each one an extra
* reference
* The caller "owns" the parameters, so give each one an extra reference
*/
AcpiPsUpdateParameterList (Info, REF_INCREMENT);
@ -361,32 +358,50 @@ AcpiPsExecuteMethod (
AcpiPsStartTrace (Info);
/*
* 1) Perform the first pass parse of the method to enter any
* named objects that it creates into the namespace
* Execute the method. Performs parse simultaneously
*/
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
"**** Begin Method Parse **** Entry=%p obj=%p\n",
Info->ResolvedNode, Info->ObjDesc));
"**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
Info->ResolvedNode->Name.Ascii, Info->ResolvedNode, Info->ObjDesc));
Info->PassNumber = 1;
Status = AcpiPsExecutePass (Info);
if (ACPI_FAILURE (Status))
/* Create and init a Root Node */
Op = AcpiPsCreateScopeOp ();
if (!Op)
{
Status = AE_NO_MEMORY;
goto Cleanup;
}
/*
* 2) Execute the method. Performs second pass parse simultaneously
*/
ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
"**** Begin Method Execution **** Entry=%p obj=%p\n",
Info->ResolvedNode, Info->ObjDesc));
/* Create and initialize a new walk state */
Info->PassNumber = 3;
Status = AcpiPsExecutePass (Info);
WalkState = AcpiDsCreateWalkState (
Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL);
if (!WalkState)
{
Status = AE_NO_MEMORY;
goto Cleanup;
}
Status = AcpiDsInitAmlWalk (WalkState, Op, Info->ResolvedNode,
Info->ObjDesc->Method.AmlStart,
Info->ObjDesc->Method.AmlLength, Info, Info->PassNumber);
if (ACPI_FAILURE (Status))
{
AcpiDsDeleteWalkState (WalkState);
goto Cleanup;
}
/* Parse the AML */
Status = AcpiPsParseAml (WalkState);
/* WalkState was deleted by ParseAml */
Cleanup:
AcpiPsDeleteParseTree (Op);
/* End optional tracing */
AcpiPsStopTrace (Info);
@ -456,69 +471,3 @@ AcpiPsUpdateParameterList (
}
/*******************************************************************************
*
* FUNCTION: AcpiPsExecutePass
*
* PARAMETERS: Info - See ACPI_EVALUATE_INFO
* (Used: PassNumber, Node, and ObjDesc)
*
* RETURN: Status
*
* DESCRIPTION: Single AML pass: Parse or Execute a control method
*
******************************************************************************/
static ACPI_STATUS
AcpiPsExecutePass (
ACPI_EVALUATE_INFO *Info)
{
ACPI_STATUS Status;
ACPI_PARSE_OBJECT *Op;
ACPI_WALK_STATE *WalkState;
ACPI_FUNCTION_TRACE (PsExecutePass);
/* Create and init a Root Node */
Op = AcpiPsCreateScopeOp ();
if (!Op)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Create and initialize a new walk state */
WalkState = AcpiDsCreateWalkState (
Info->ObjDesc->Method.OwnerId, NULL, NULL, NULL);
if (!WalkState)
{
Status = AE_NO_MEMORY;
goto Cleanup;
}
Status = AcpiDsInitAmlWalk (WalkState, Op, Info->ResolvedNode,
Info->ObjDesc->Method.AmlStart,
Info->ObjDesc->Method.AmlLength,
Info->PassNumber == 1 ? NULL : Info,
Info->PassNumber);
if (ACPI_FAILURE (Status))
{
AcpiDsDeleteWalkState (WalkState);
goto Cleanup;
}
/* Parse the AML */
Status = AcpiPsParseAml (WalkState);
/* Walk state was deleted by ParseAml */
Cleanup:
AcpiPsDeleteParseTree (Op);
return_ACPI_STATUS (Status);
}