Subversion Repositories Kolibri OS

Rev

Rev 1498 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: aslopt- Compiler optimizations
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  12.  * All rights reserved.
  13.  *
  14.  * 2. License
  15.  *
  16.  * 2.1. This is your license from Intel Corp. under its intellectual property
  17.  * rights.  You may have additional license terms from the party that provided
  18.  * you this software, covering your right to use that party's intellectual
  19.  * property rights.
  20.  *
  21.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22.  * copy of the source code appearing in this file ("Covered Code") an
  23.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25.  * make derivatives, distribute, use and display any portion of the Covered
  26.  * Code in any form, with the right to sublicense such rights; and
  27.  *
  28.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29.  * license (with the right to sublicense), under only those claims of Intel
  30.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31.  * offer to sell, and import the Covered Code and derivative works thereof
  32.  * solely to the minimum extent necessary to exercise the above copyright
  33.  * license, and in no event shall the patent license extend to any additions
  34.  * to or modifications of the Original Intel Code.  No other license or right
  35.  * is granted directly or by implication, estoppel or otherwise;
  36.  *
  37.  * The above copyright and patent license is granted only if the following
  38.  * conditions are met:
  39.  *
  40.  * 3. Conditions
  41.  *
  42.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43.  * Redistribution of source code of any substantial portion of the Covered
  44.  * Code or modification with rights to further distribute source must include
  45.  * the above Copyright Notice, the above License, this list of Conditions,
  46.  * and the following Disclaimer and Export Compliance provision.  In addition,
  47.  * Licensee must cause all Covered Code to which Licensee contributes to
  48.  * contain a file documenting the changes Licensee made to create that Covered
  49.  * Code and the date of any change.  Licensee must include in that file the
  50.  * documentation of any changes made by any predecessor Licensee.  Licensee
  51.  * must include a prominent statement that the modification is derived,
  52.  * directly or indirectly, from Original Intel Code.
  53.  *
  54.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55.  * Redistribution of source code of any substantial portion of the Covered
  56.  * Code or modification without rights to further distribute source must
  57.  * include the following Disclaimer and Export Compliance provision in the
  58.  * documentation and/or other materials provided with distribution.  In
  59.  * addition, Licensee may not authorize further sublicense of source of any
  60.  * portion of the Covered Code, and must include terms to the effect that the
  61.  * license from Licensee to its licensee is limited to the intellectual
  62.  * property embodied in the software Licensee provides to its licensee, and
  63.  * not to intellectual property embodied in modifications its licensee may
  64.  * make.
  65.  *
  66.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67.  * substantial portion of the Covered Code or modification must reproduce the
  68.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69.  * provision in the documentation and/or other materials provided with the
  70.  * distribution.
  71.  *
  72.  * 3.4. Intel retains all right, title, and interest in and to the Original
  73.  * Intel Code.
  74.  *
  75.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77.  * other dealings in products derived from or relating to the Covered Code
  78.  * without prior written authorization from Intel.
  79.  *
  80.  * 4. Disclaimer and Export Compliance
  81.  *
  82.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  85.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  86.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  87.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88.  * PARTICULAR PURPOSE.
  89.  *
  90.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  96.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97.  * LIMITED REMEDY.
  98.  *
  99.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100.  * software or system incorporating such software without first obtaining any
  101.  * required license or other approval from the U. S. Department of Commerce or
  102.  * any other agency or department of the United States Government.  In the
  103.  * event Licensee exports any such software from the United States or
  104.  * re-exports any such software from a foreign destination, Licensee shall
  105.  * ensure that the distribution and export/re-export of the software is in
  106.  * compliance with all laws, regulations, orders, or other restrictions of the
  107.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108.  * any of its subsidiaries will export/re-export any technical data, process,
  109.  * software, or service, directly or indirectly, to any country for which the
  110.  * United States government or any agency thereof requires an export license,
  111.  * other governmental approval, or letter of assurance, without first obtaining
  112.  * such license, approval or letter.
  113.  *
  114.  *****************************************************************************/
  115.  
  116.  
  117. #include "aslcompiler.h"
  118. #include "aslcompiler.y.h"
  119.  
  120. #include "acparser.h"
  121. #include "amlcode.h"
  122. #include "acnamesp.h"
  123.  
  124.  
  125. #define _COMPONENT          ACPI_COMPILER
  126.         ACPI_MODULE_NAME    ("aslopt")
  127.  
  128.  
  129. static UINT32 OptTotal = 0;
  130.  
  131. /* Local prototypes */
  132.  
  133. static ACPI_STATUS
  134. OptSearchToRoot (
  135.     ACPI_PARSE_OBJECT       *Op,
  136.     ACPI_WALK_STATE         *WalkState,
  137.     ACPI_NAMESPACE_NODE     *CurrentNode,
  138.     ACPI_NAMESPACE_NODE     *TargetNode,
  139.     ACPI_BUFFER             *TargetPath,
  140.     char                    **NewPath);
  141.  
  142. static ACPI_STATUS
  143. OptBuildShortestPath (
  144.     ACPI_PARSE_OBJECT       *Op,
  145.     ACPI_WALK_STATE         *WalkState,
  146.     ACPI_NAMESPACE_NODE     *CurrentNode,
  147.     ACPI_NAMESPACE_NODE     *TargetNode,
  148.     ACPI_BUFFER             *CurrentPath,
  149.     ACPI_BUFFER             *TargetPath,
  150.     ACPI_SIZE               AmlNameStringLength,
  151.     UINT8                   IsDeclaration,
  152.     char                    **ReturnNewPath);
  153.  
  154. static ACPI_STATUS
  155. OptOptimizeNameDeclaration (
  156.     ACPI_PARSE_OBJECT       *Op,
  157.     ACPI_WALK_STATE         *WalkState,
  158.     ACPI_NAMESPACE_NODE     *CurrentNode,
  159.     ACPI_NAMESPACE_NODE     *TargetNode,
  160.     char                    *AmlNameString,
  161.     char                    **NewPath);
  162.  
  163.  
  164. /*******************************************************************************
  165.  *
  166.  * FUNCTION:    OptSearchToRoot
  167.  *
  168.  * PARAMETERS:  Op                  - Current parser op
  169.  *              WalkState           - Current state
  170.  *              CurrentNode         - Where we are in the namespace
  171.  *              TargetNode          - Node to which we are referring
  172.  *              TargetPath          - External full path to the target node
  173.  *              NewPath             - Where the optimized path is returned
  174.  *
  175.  * RETURN:      Status
  176.  *
  177.  * DESCRIPTION: Attempt to optimize a reference to a single 4-character ACPI
  178.  *              name utilizing the search-to-root name resolution algorithm
  179.  *              that is used by AML interpreters.
  180.  *
  181.  ******************************************************************************/
  182.  
  183. static ACPI_STATUS
  184. OptSearchToRoot (
  185.     ACPI_PARSE_OBJECT       *Op,
  186.     ACPI_WALK_STATE         *WalkState,
  187.     ACPI_NAMESPACE_NODE     *CurrentNode,
  188.     ACPI_NAMESPACE_NODE     *TargetNode,
  189.     ACPI_BUFFER             *TargetPath,
  190.     char                    **NewPath)
  191. {
  192.     ACPI_NAMESPACE_NODE     *Node;
  193.     ACPI_GENERIC_STATE      ScopeInfo;
  194.     ACPI_STATUS             Status;
  195.     char                    *Path;
  196.  
  197.  
  198.     ACPI_FUNCTION_NAME (OptSearchToRoot);
  199.  
  200.  
  201.     /*
  202.      * Check if search-to-root can be utilized.  Use the last NameSeg of
  203.      * the NamePath and 1) See if can be found and 2) If found, make
  204.      * sure that it is the same node that we want.  If there is another
  205.      * name in the search path before the one we want, the nodes will
  206.      * not match, and we cannot use this optimization.
  207.      */
  208.     Path = &(((char *) TargetPath->Pointer)[TargetPath->Length -
  209.                                             ACPI_NAME_SIZE]),
  210.     ScopeInfo.Scope.Node = CurrentNode;
  211.  
  212.     /* Lookup the NameSeg using SEARCH_PARENT (search-to-root) */
  213.  
  214.     Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
  215.                     ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
  216.                     WalkState, &(Node));
  217.     if (ACPI_FAILURE (Status))
  218.     {
  219.         return (Status);
  220.     }
  221.  
  222.     /*
  223.      * We found the name, but we must check to make sure that the node
  224.      * matches.  Otherwise, there is another identical name in the search
  225.      * path that precludes the use of this optimization.
  226.      */
  227.     if (Node != TargetNode)
  228.     {
  229.         /*
  230.          * This means that another object with the same name was found first,
  231.          * and we cannot use this optimization.
  232.          */
  233.         return (AE_NOT_FOUND);
  234.     }
  235.  
  236.     /* Found the node, we can use this optimization */
  237.  
  238.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
  239.         "NAMESEG:   %-24s", Path));
  240.  
  241.     /* We must allocate a new string for the name (TargetPath gets deleted) */
  242.  
  243.     *NewPath = ACPI_ALLOCATE_ZEROED (ACPI_NAME_SIZE + 1);
  244.     ACPI_STRCPY (*NewPath, Path);
  245.  
  246.     if (ACPI_STRNCMP (*NewPath, "_T_", 3))
  247.     {
  248.         AslError (ASL_OPTIMIZATION, ASL_MSG_SINGLE_NAME_OPTIMIZATION, Op,
  249.                 *NewPath);
  250.     }
  251.  
  252.     return (AE_OK);
  253. }
  254.  
  255.  
  256. /*******************************************************************************
  257.  *
  258.  * FUNCTION:    OptBuildShortestPath
  259.  *
  260.  * PARAMETERS:  Op                  - Current parser op
  261.  *              WalkState           - Current state
  262.  *              CurrentNode         - Where we are in the namespace
  263.  *              TargetNode          - Node to which we are referring
  264.  *              CurrentPath         - External full path to the current node
  265.  *              TargetPath          - External full path to the target node
  266.  *              AmlNameStringLength - Length of the original namepath
  267.  *              IsDeclaration       - TRUE for declaration, FALSE for reference
  268.  *              ReturnNewPath       - Where the optimized path is returned
  269.  *
  270.  * RETURN:      Status
  271.  *
  272.  * DESCRIPTION: Build an optimal NamePath using carats
  273.  *
  274.  ******************************************************************************/
  275.  
  276. static ACPI_STATUS
  277. OptBuildShortestPath (
  278.     ACPI_PARSE_OBJECT       *Op,
  279.     ACPI_WALK_STATE         *WalkState,
  280.     ACPI_NAMESPACE_NODE     *CurrentNode,
  281.     ACPI_NAMESPACE_NODE     *TargetNode,
  282.     ACPI_BUFFER             *CurrentPath,
  283.     ACPI_BUFFER             *TargetPath,
  284.     ACPI_SIZE               AmlNameStringLength,
  285.     UINT8                   IsDeclaration,
  286.     char                    **ReturnNewPath)
  287. {
  288.     UINT32                  NumCommonSegments;
  289.     UINT32                  MaxCommonSegments;
  290.     UINT32                  Index;
  291.     UINT32                  NumCarats;
  292.     UINT32                  i;
  293.     char                    *NewPath;
  294.     char                    *NewPathExternal;
  295.     ACPI_NAMESPACE_NODE     *Node;
  296.     ACPI_GENERIC_STATE      ScopeInfo;
  297.     ACPI_STATUS             Status;
  298.     BOOLEAN                 SubPath = FALSE;
  299.  
  300.  
  301.     ACPI_FUNCTION_NAME (OptBuildShortestPath);
  302.  
  303.  
  304.     ScopeInfo.Scope.Node = CurrentNode;
  305.  
  306.     /*
  307.      * Determine the maximum number of NameSegs that the Target and Current paths
  308.      * can possibly have in common.  (To optimize, we have to have at least 1)
  309.      *
  310.      * Note: The external NamePath string lengths are always a multiple of 5
  311.      * (ACPI_NAME_SIZE + separator)
  312.      */
  313.     MaxCommonSegments = TargetPath->Length / ACPI_PATH_SEGMENT_LENGTH;
  314.     if (CurrentPath->Length < TargetPath->Length)
  315.     {
  316.         MaxCommonSegments = CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH;
  317.     }
  318.  
  319.     /*
  320.      * Determine how many NameSegs the two paths have in common.
  321.      * (Starting from the root)
  322.      */
  323.     for (NumCommonSegments = 0;
  324.          NumCommonSegments < MaxCommonSegments;
  325.          NumCommonSegments++)
  326.     {
  327.         /* Compare two single NameSegs */
  328.  
  329.         if (ACPI_STRNCMP (
  330.             &((char *) TargetPath->Pointer)[(NumCommonSegments *
  331.                                              ACPI_PATH_SEGMENT_LENGTH) + 1],
  332.             &((char *) CurrentPath->Pointer)[(NumCommonSegments *
  333.                                               ACPI_PATH_SEGMENT_LENGTH) + 1],
  334.             ACPI_NAME_SIZE))
  335.         {
  336.             /* Mismatch */
  337.  
  338.             break;
  339.         }
  340.     }
  341.  
  342.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " COMMON: %u",
  343.         NumCommonSegments));
  344.  
  345.     /* There must be at least 1 common NameSeg in order to optimize */
  346.  
  347.     if (NumCommonSegments == 0)
  348.     {
  349.         return (AE_NOT_FOUND);
  350.     }
  351.  
  352.     if (NumCommonSegments == MaxCommonSegments)
  353.     {
  354.         if (CurrentPath->Length == TargetPath->Length)
  355.         {
  356.             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SAME PATH"));
  357.             return (AE_NOT_FOUND);
  358.         }
  359.         else
  360.         {
  361.             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SUBPATH"));
  362.             SubPath = TRUE;
  363.         }
  364.     }
  365.  
  366.     /* Determine how many prefix Carats are required */
  367.  
  368.     NumCarats = (CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH) -
  369.                 NumCommonSegments;
  370.  
  371.     /*
  372.      * Construct a new target string
  373.      */
  374.     NewPathExternal = ACPI_ALLOCATE_ZEROED (
  375.         TargetPath->Length + NumCarats + 1);
  376.  
  377.     /* Insert the Carats into the Target string */
  378.  
  379.     for (i = 0; i < NumCarats; i++)
  380.     {
  381.         NewPathExternal[i] = '^';
  382.     }
  383.  
  384.     /*
  385.      * Copy only the necessary (optimal) segments from the original
  386.      * target string
  387.      */
  388.     Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1;
  389.  
  390.     /* Special handling for exact subpath in a name declaration */
  391.  
  392.     if (IsDeclaration && SubPath && (CurrentPath->Length > TargetPath->Length))
  393.     {
  394.         /*
  395.          * The current path is longer than the target, and the target is a
  396.          * subpath of the current path. We must include one more NameSeg of
  397.          * the target path
  398.          */
  399.         Index -= ACPI_PATH_SEGMENT_LENGTH;
  400.  
  401.         /* Special handling for Scope() operator */
  402.  
  403.         if (Op->Asl.AmlOpcode == AML_SCOPE_OP)
  404.         {
  405.             NewPathExternal[i] = '^';
  406.             i++;
  407.             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "(EXTRA ^)"));
  408.         }
  409.     }
  410.  
  411.     /* Make sure we haven't gone off the end of the target path */
  412.  
  413.     if (Index > TargetPath->Length)
  414.     {
  415.         Index = TargetPath->Length;
  416.     }
  417.  
  418.     ACPI_STRCPY (&NewPathExternal[i], &((char *) TargetPath->Pointer)[Index]);
  419.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " %-24s", NewPathExternal));
  420.  
  421.     /*
  422.      * Internalize the new target string and check it against the original
  423.      * string to make sure that this is in fact an optimization. If the
  424.      * original string is already optimal, there is no point in continuing.
  425.      */
  426.     Status = AcpiNsInternalizeName (NewPathExternal, &NewPath);
  427.     if (ACPI_FAILURE (Status))
  428.     {
  429.         AslCoreSubsystemError (Op, Status, "Internalizing new NamePath",
  430.             ASL_NO_ABORT);
  431.         ACPI_FREE (NewPathExternal);
  432.         return (Status);
  433.     }
  434.  
  435.     if (ACPI_STRLEN (NewPath) >= AmlNameStringLength)
  436.     {
  437.         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
  438.             " NOT SHORTER (New %u old %u)",
  439.             (UINT32) ACPI_STRLEN (NewPath), (UINT32) AmlNameStringLength));
  440.         ACPI_FREE (NewPathExternal);
  441.         return (AE_NOT_FOUND);
  442.     }
  443.  
  444.     /*
  445.      * Check to make sure that the optimization finds the node we are
  446.      * looking for.  This is simply a sanity check on the new
  447.      * path that has been created.
  448.      */
  449.     Status = AcpiNsLookup (&ScopeInfo,  NewPath,
  450.                     ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
  451.                     ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node));
  452.     if (ACPI_SUCCESS (Status))
  453.     {
  454.         /* Found the namepath, but make sure the node is correct */
  455.  
  456.         if (Node == TargetNode)
  457.         {
  458.             /* The lookup matched the node, accept this optimization */
  459.  
  460.             AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION,
  461.                 Op, NewPathExternal);
  462.             *ReturnNewPath = NewPath;
  463.         }
  464.         else
  465.         {
  466.             /* Node is not correct, do not use this optimization */
  467.  
  468.             Status = AE_NOT_FOUND;
  469.             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE"));
  470.             AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
  471.                 "Not using optimized name - found wrong node");
  472.         }
  473.     }
  474.     else
  475.     {
  476.         /* The lookup failed, we obviously cannot use this optimization */
  477.  
  478.         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND"));
  479.         AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
  480.             "Not using optimized name - did not find node");
  481.     }
  482.  
  483.     ACPI_FREE (NewPathExternal);
  484.     return (Status);
  485. }
  486.  
  487.  
  488. /*******************************************************************************
  489.  *
  490.  * FUNCTION:    OptOptimizeNameDeclaration
  491.  *
  492.  * PARAMETERS:  Op                  - Current parser op
  493.  *              WalkState           - Current state
  494.  *              CurrentNode         - Where we are in the namespace
  495.  *              AmlNameString       - Unoptimized namepath
  496.  *              NewPath             - Where the optimized path is returned
  497.  *
  498.  * RETURN:      Status. AE_OK If path is optimized
  499.  *
  500.  * DESCRIPTION: Perform a simple optimization of removing an extraneous
  501.  *              backslash prefix if we are already at the root scope.
  502.  *
  503.  ******************************************************************************/
  504.  
  505. static ACPI_STATUS
  506. OptOptimizeNameDeclaration (
  507.     ACPI_PARSE_OBJECT       *Op,
  508.     ACPI_WALK_STATE         *WalkState,
  509.     ACPI_NAMESPACE_NODE     *CurrentNode,
  510.     ACPI_NAMESPACE_NODE     *TargetNode,
  511.     char                    *AmlNameString,
  512.     char                    **NewPath)
  513. {
  514.     ACPI_STATUS             Status;
  515.     char                    *NewPathExternal;
  516.     ACPI_GENERIC_STATE      ScopeInfo;
  517.     ACPI_NAMESPACE_NODE     *Node;
  518.  
  519.  
  520.     ACPI_FUNCTION_TRACE (OptOptimizeNameDeclaration);
  521.  
  522.  
  523.     if (((CurrentNode == AcpiGbl_RootNode) ||
  524.         (Op->Common.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK)) &&
  525.             (AmlNameString[0] == '\\'))
  526.     {
  527.         /*
  528.          * The current scope is the root, and the namepath has a root prefix
  529.          * that is therefore extraneous.  Remove it.
  530.          */
  531.         *NewPath = &AmlNameString[1];
  532.  
  533.         /* Debug output */
  534.  
  535.         Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, *NewPath,
  536.                     NULL, &NewPathExternal);
  537.         if (ACPI_FAILURE (Status))
  538.         {
  539.             AslCoreSubsystemError (Op, Status, "Externalizing NamePath",
  540.                 ASL_NO_ABORT);
  541.             return (Status);
  542.         }
  543.  
  544.         /*
  545.          * Check to make sure that the optimization finds the node we are
  546.          * looking for.  This is simply a sanity check on the new
  547.          * path that has been created.
  548.          */
  549.         ScopeInfo.Scope.Node = CurrentNode;
  550.         Status = AcpiNsLookup (&ScopeInfo, *NewPath,
  551.                         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
  552.                         ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node));
  553.         if (ACPI_SUCCESS (Status))
  554.         {
  555.             /* Found the namepath, but make sure the node is correct */
  556.  
  557.             if (Node == TargetNode)
  558.             {
  559.                 /* The lookup matched the node, accept this optimization */
  560.  
  561.                 AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION,
  562.                     Op, NewPathExternal);
  563.  
  564.                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
  565.                     "AT ROOT:   %-24s", NewPathExternal));
  566.             }
  567.             else
  568.             {
  569.                 /* Node is not correct, do not use this optimization */
  570.  
  571.                 Status = AE_NOT_FOUND;
  572.                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
  573.                     " ***** WRONG NODE"));
  574.                 AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
  575.                     "Not using optimized name - found wrong node");
  576.             }
  577.         }
  578.         else
  579.         {
  580.             /* The lookup failed, we obviously cannot use this optimization */
  581.  
  582.             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
  583.                 " ***** NOT FOUND"));
  584.             AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
  585.                 "Not using optimized name - did not find node");
  586.         }
  587.  
  588.         ACPI_FREE (NewPathExternal);
  589.         return (Status);
  590.     }
  591.  
  592.     /* Could not optimize */
  593.  
  594.     return (AE_NOT_FOUND);
  595. }
  596.  
  597.  
  598. /*******************************************************************************
  599.  *
  600.  * FUNCTION:    OptOptimizeNamePath
  601.  *
  602.  * PARAMETERS:  Op                  - Current parser op
  603.  *              Flags               - Opcode info flags
  604.  *              WalkState           - Current state
  605.  *              AmlNameString       - Unoptimized namepath
  606.  *              TargetNode          - Node to which AmlNameString refers
  607.  *
  608.  * RETURN:      None.  If path is optimized, the Op is updated with new path
  609.  *
  610.  * DESCRIPTION: Optimize a Named Declaration or Reference to the minimal length.
  611.  *              Must take into account both the current location in the
  612.  *              namespace and the actual reference path.
  613.  *
  614.  ******************************************************************************/
  615.  
  616. void
  617. OptOptimizeNamePath (
  618.     ACPI_PARSE_OBJECT       *Op,
  619.     UINT32                  Flags,
  620.     ACPI_WALK_STATE         *WalkState,
  621.     char                    *AmlNameString,
  622.     ACPI_NAMESPACE_NODE     *TargetNode)
  623. {
  624.     ACPI_STATUS             Status;
  625.     ACPI_BUFFER             TargetPath;
  626.     ACPI_BUFFER             CurrentPath;
  627.     ACPI_SIZE               AmlNameStringLength;
  628.     ACPI_NAMESPACE_NODE     *CurrentNode;
  629.     char                    *ExternalNameString;
  630.     char                    *NewPath = NULL;
  631.     ACPI_SIZE               HowMuchShorter;
  632.     ACPI_PARSE_OBJECT       *NextOp;
  633.  
  634.  
  635.     ACPI_FUNCTION_TRACE (OptOptimizeNamePath);
  636.  
  637.  
  638.     /* This is an optional optimization */
  639.  
  640.     if (!Gbl_ReferenceOptimizationFlag)
  641.     {
  642.         return_VOID;
  643.     }
  644.  
  645.     /* Various required items */
  646.  
  647.     if (!TargetNode || !WalkState || !AmlNameString || !Op->Common.Parent)
  648.     {
  649.         return_VOID;
  650.     }
  651.  
  652.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "%5d [%12.12s] [%12.12s] ",
  653.         Op->Asl.LogicalLineNumber,
  654.         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode),
  655.         AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
  656.  
  657.     if (!(Flags & (AML_NAMED | AML_CREATE)))
  658.     {
  659.         if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
  660.         {
  661.             /* We don't want to fuss with actual name declaration nodes here */
  662.  
  663.             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
  664.                 "******* NAME DECLARATION\n"));
  665.             return_VOID;
  666.         }
  667.     }
  668.  
  669.     /*
  670.      * The original path must be longer than one NameSeg (4 chars) for there
  671.      * to be any possibility that it can be optimized to a shorter string
  672.      */
  673.     AmlNameStringLength = ACPI_STRLEN (AmlNameString);
  674.     if (AmlNameStringLength <= ACPI_NAME_SIZE)
  675.     {
  676.         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
  677.             "NAMESEG %4.4s\n", AmlNameString));
  678.         return_VOID;
  679.     }
  680.  
  681.     /*
  682.      * We need to obtain the node that represents the current scope -- where
  683.      * we are right now in the namespace.  We will compare this path
  684.      * against the Namepath, looking for commonality.
  685.      */
  686.     CurrentNode = AcpiGbl_RootNode;
  687.     if (WalkState->ScopeInfo)
  688.     {
  689.         CurrentNode = WalkState->ScopeInfo->Scope.Node;
  690.     }
  691.  
  692.     if (Flags & (AML_NAMED | AML_CREATE))
  693.     {
  694.         /* This is the declaration of a new name */
  695.  
  696.         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "NAME"));
  697.  
  698.         /*
  699.          * The node of interest is the parent of this node
  700.          * (the containing scope)
  701.          */
  702.         CurrentNode = Op->Asl.Parent->Asl.Node;
  703.         if (!CurrentNode)
  704.         {
  705.             CurrentNode = AcpiGbl_RootNode;
  706.         }
  707.     }
  708.     else
  709.     {
  710.         /* This is a reference to an existing named object */
  711.  
  712.         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "REF "));
  713.     }
  714.  
  715.     /*
  716.      * Obtain the full paths to the two nodes that we are interested in
  717.      * (Target and current namespace location) in external
  718.      * format -- something we can easily manipulate
  719.      */
  720.     TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
  721.     Status = AcpiNsHandleToPathname (TargetNode, &TargetPath);
  722.     if (ACPI_FAILURE (Status))
  723.     {
  724.         AslCoreSubsystemError (Op, Status, "Getting Target NamePath",
  725.             ASL_NO_ABORT);
  726.         return_VOID;
  727.     }
  728.     TargetPath.Length--;    /* Subtract one for null terminator */
  729.  
  730.     /* CurrentPath is the path to this scope (where we are in the namespace) */
  731.  
  732.     CurrentPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
  733.     Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath);
  734.     if (ACPI_FAILURE (Status))
  735.     {
  736.         AslCoreSubsystemError (Op, Status, "Getting Current NamePath",
  737.             ASL_NO_ABORT);
  738.         return_VOID;
  739.     }
  740.     CurrentPath.Length--;   /* Subtract one for null terminator */
  741.  
  742.     /* Debug output only */
  743.  
  744.     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, AmlNameString,
  745.                 NULL, &ExternalNameString);
  746.     if (ACPI_FAILURE (Status))
  747.     {
  748.         AslCoreSubsystemError (Op, Status, "Externalizing NamePath",
  749.             ASL_NO_ABORT);
  750.         return_VOID;
  751.     }
  752.  
  753.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
  754.         "%37s (%2u) ==> %-32s(%2u) %-32s",
  755.         (char *) CurrentPath.Pointer, (UINT32) CurrentPath.Length,
  756.         (char *) TargetPath.Pointer, (UINT32) TargetPath.Length, ExternalNameString));
  757.  
  758.     ACPI_FREE (ExternalNameString);
  759.  
  760.     /*
  761.      * Attempt an optmization depending on the type of namepath
  762.      */
  763.     if (Flags & (AML_NAMED | AML_CREATE))
  764.     {
  765.         /*
  766.          * This is a named opcode and the namepath is a name declaration, not
  767.          * a reference.
  768.          */
  769.         Status = OptOptimizeNameDeclaration (Op, WalkState, CurrentNode,
  770.                     TargetNode, AmlNameString, &NewPath);
  771.         if (ACPI_FAILURE (Status))
  772.         {
  773.             /*
  774.              * 2) now attempt to
  775.              *    optimize the namestring with carats (up-arrow)
  776.              */
  777.             Status = OptBuildShortestPath (Op, WalkState, CurrentNode,
  778.                             TargetNode, &CurrentPath, &TargetPath,
  779.                             AmlNameStringLength, 1, &NewPath);
  780.         }
  781.     }
  782.     else
  783.     {
  784.         /*
  785.          * This is a reference to an existing named object
  786.          *
  787.          * 1) Check if search-to-root can be utilized using the last
  788.          *    NameSeg of the NamePath
  789.          */
  790.         Status = OptSearchToRoot (Op, WalkState, CurrentNode,
  791.                         TargetNode, &TargetPath, &NewPath);
  792.         if (ACPI_FAILURE (Status))
  793.         {
  794.             /*
  795.              * 2) Search-to-root could not be used, now attempt to
  796.              *    optimize the namestring with carats (up-arrow)
  797.              */
  798.             Status = OptBuildShortestPath (Op, WalkState, CurrentNode,
  799.                             TargetNode, &CurrentPath, &TargetPath,
  800.                             AmlNameStringLength, 0, &NewPath);
  801.         }
  802.     }
  803.  
  804.     /*
  805.      * Success from above indicates that the NamePath was successfully
  806.      * optimized.  We need to update the parse op with the new name
  807.      */
  808.     if (ACPI_SUCCESS (Status))
  809.     {
  810.         HowMuchShorter = (AmlNameStringLength - ACPI_STRLEN (NewPath));
  811.         OptTotal += HowMuchShorter;
  812.  
  813.         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " REDUCED %2u (%u)",
  814.             (UINT32) HowMuchShorter, OptTotal));
  815.  
  816.         if (Flags & AML_NAMED)
  817.         {
  818.             if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
  819.             {
  820.                 /*
  821.                  * ALIAS is the only oddball opcode, the name declaration
  822.                  * (alias name) is the second operand
  823.                  */
  824.                 Op->Asl.Child->Asl.Next->Asl.Value.String = NewPath;
  825.                 Op->Asl.Child->Asl.Next->Asl.AmlLength = ACPI_STRLEN (NewPath);
  826.             }
  827.             else
  828.             {
  829.                 Op->Asl.Child->Asl.Value.String = NewPath;
  830.                 Op->Asl.Child->Asl.AmlLength = ACPI_STRLEN (NewPath);
  831.             }
  832.         }
  833.         else if (Flags & AML_CREATE)
  834.         {
  835.             /* Name must appear as the last parameter */
  836.  
  837.             NextOp = Op->Asl.Child;
  838.             while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
  839.             {
  840.                 NextOp = NextOp->Asl.Next;
  841.             }
  842.             /* Update the parse node with the new NamePath */
  843.  
  844.             NextOp->Asl.Value.String = NewPath;
  845.             NextOp->Asl.AmlLength = ACPI_STRLEN (NewPath);
  846.         }
  847.         else
  848.         {
  849.             /* Update the parse node with the new NamePath */
  850.  
  851.             Op->Asl.Value.String = NewPath;
  852.             Op->Asl.AmlLength = ACPI_STRLEN (NewPath);
  853.         }
  854.     }
  855.     else
  856.     {
  857.         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ALREADY OPTIMAL"));
  858.     }
  859.  
  860.     /* Cleanup path buffers */
  861.  
  862.     ACPI_FREE (TargetPath.Pointer);
  863.     ACPI_FREE (CurrentPath.Pointer);
  864.  
  865.     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "\n"));
  866.     return_VOID;
  867. }
  868.  
  869.