mirror of
https://github.com/acpica/acpica/
synced 2025-02-15 04:54:20 +03:00
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:
parent
893a7b5ab8
commit
830a10802d
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user