| @@ -1,817 +1,817 @@ | | | @@ -1,817 +1,817 @@ |
1 | /****************************************************************************** | | 1 | /****************************************************************************** |
2 | * | | 2 | * |
3 | * Module Name: aslopt- Compiler optimizations | | 3 | * Module Name: aslopt- Compiler optimizations |
4 | * | | 4 | * |
5 | *****************************************************************************/ | | 5 | *****************************************************************************/ |
6 | | | 6 | |
7 | /* | | 7 | /* |
8 | * Copyright (C) 2000 - 2016, Intel Corp. | | 8 | * Copyright (C) 2000 - 2016, Intel Corp. |
9 | * All rights reserved. | | 9 | * All rights reserved. |
10 | * | | 10 | * |
11 | * Redistribution and use in source and binary forms, with or without | | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions | | 12 | * modification, are permitted provided that the following conditions |
13 | * are met: | | 13 | * are met: |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions, and the following disclaimer, | | 15 | * notice, this list of conditions, and the following disclaimer, |
16 | * without modification. | | 16 | * without modification. |
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | | 17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
18 | * substantially similar to the "NO WARRANTY" disclaimer below | | 18 | * substantially similar to the "NO WARRANTY" disclaimer below |
19 | * ("Disclaimer") and any redistribution must be conditioned upon | | 19 | * ("Disclaimer") and any redistribution must be conditioned upon |
20 | * including a substantially similar Disclaimer requirement for further | | 20 | * including a substantially similar Disclaimer requirement for further |
21 | * binary redistribution. | | 21 | * binary redistribution. |
22 | * 3. Neither the names of the above-listed copyright holders nor the names | | 22 | * 3. Neither the names of the above-listed copyright holders nor the names |
23 | * of any contributors may be used to endorse or promote products derived | | 23 | * of any contributors may be used to endorse or promote products derived |
24 | * from this software without specific prior written permission. | | 24 | * from this software without specific prior written permission. |
25 | * | | 25 | * |
26 | * Alternatively, this software may be distributed under the terms of the | | 26 | * Alternatively, this software may be distributed under the terms of the |
27 | * GNU General Public License ("GPL") version 2 as published by the Free | | 27 | * GNU General Public License ("GPL") version 2 as published by the Free |
28 | * Software Foundation. | | 28 | * Software Foundation. |
29 | * | | 29 | * |
30 | * NO WARRANTY | | 30 | * NO WARRANTY |
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | | 31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | | 32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | | 33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | | 34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | | 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | | 39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
41 | * POSSIBILITY OF SUCH DAMAGES. | | 41 | * POSSIBILITY OF SUCH DAMAGES. |
42 | */ | | 42 | */ |
43 | | | 43 | |
44 | #include "aslcompiler.h" | | 44 | #include "aslcompiler.h" |
45 | #include "aslcompiler.y.h" | | 45 | #include "aslcompiler.y.h" |
46 | | | 46 | |
47 | #include "acparser.h" | | 47 | #include "acparser.h" |
48 | #include "amlcode.h" | | 48 | #include "amlcode.h" |
49 | #include "acnamesp.h" | | 49 | #include "acnamesp.h" |
50 | | | 50 | |
51 | | | 51 | |
52 | #define _COMPONENT ACPI_COMPILER | | 52 | #define _COMPONENT ACPI_COMPILER |
53 | ACPI_MODULE_NAME ("aslopt") | | 53 | ACPI_MODULE_NAME ("aslopt") |
54 | | | 54 | |
55 | | | 55 | |
56 | static UINT32 OptTotal = 0; | | 56 | static UINT32 OptTotal = 0; |
57 | | | 57 | |
58 | /* Local prototypes */ | | 58 | /* Local prototypes */ |
59 | | | 59 | |
60 | static ACPI_STATUS | | 60 | static ACPI_STATUS |
61 | OptSearchToRoot ( | | 61 | OptSearchToRoot ( |
62 | ACPI_PARSE_OBJECT *Op, | | 62 | ACPI_PARSE_OBJECT *Op, |
63 | ACPI_WALK_STATE *WalkState, | | 63 | ACPI_WALK_STATE *WalkState, |
64 | ACPI_NAMESPACE_NODE *CurrentNode, | | 64 | ACPI_NAMESPACE_NODE *CurrentNode, |
65 | ACPI_NAMESPACE_NODE *TargetNode, | | 65 | ACPI_NAMESPACE_NODE *TargetNode, |
66 | ACPI_BUFFER *TargetPath, | | 66 | ACPI_BUFFER *TargetPath, |
67 | char **NewPath); | | 67 | char **NewPath); |
68 | | | 68 | |
69 | static ACPI_STATUS | | 69 | static ACPI_STATUS |
70 | OptBuildShortestPath ( | | 70 | OptBuildShortestPath ( |
71 | ACPI_PARSE_OBJECT *Op, | | 71 | ACPI_PARSE_OBJECT *Op, |
72 | ACPI_WALK_STATE *WalkState, | | 72 | ACPI_WALK_STATE *WalkState, |
73 | ACPI_NAMESPACE_NODE *CurrentNode, | | 73 | ACPI_NAMESPACE_NODE *CurrentNode, |
74 | ACPI_NAMESPACE_NODE *TargetNode, | | 74 | ACPI_NAMESPACE_NODE *TargetNode, |
75 | ACPI_BUFFER *CurrentPath, | | 75 | ACPI_BUFFER *CurrentPath, |
76 | ACPI_BUFFER *TargetPath, | | 76 | ACPI_BUFFER *TargetPath, |
77 | ACPI_SIZE AmlNameStringLength, | | 77 | ACPI_SIZE AmlNameStringLength, |
78 | UINT8 IsDeclaration, | | 78 | UINT8 IsDeclaration, |
79 | char **ReturnNewPath); | | 79 | char **ReturnNewPath); |
80 | | | 80 | |
81 | static ACPI_STATUS | | 81 | static ACPI_STATUS |
82 | OptOptimizeNameDeclaration ( | | 82 | OptOptimizeNameDeclaration ( |
83 | ACPI_PARSE_OBJECT *Op, | | 83 | ACPI_PARSE_OBJECT *Op, |
84 | ACPI_WALK_STATE *WalkState, | | 84 | ACPI_WALK_STATE *WalkState, |
85 | ACPI_NAMESPACE_NODE *CurrentNode, | | 85 | ACPI_NAMESPACE_NODE *CurrentNode, |
86 | ACPI_NAMESPACE_NODE *TargetNode, | | 86 | ACPI_NAMESPACE_NODE *TargetNode, |
87 | char *AmlNameString, | | 87 | char *AmlNameString, |
88 | char **NewPath); | | 88 | char **NewPath); |
89 | | | 89 | |
90 | | | 90 | |
91 | /******************************************************************************* | | 91 | /******************************************************************************* |
92 | * | | 92 | * |
93 | * FUNCTION: OptSearchToRoot | | 93 | * FUNCTION: OptSearchToRoot |
94 | * | | 94 | * |
95 | * PARAMETERS: Op - Current parser op | | 95 | * PARAMETERS: Op - Current parser op |
96 | * WalkState - Current state | | 96 | * WalkState - Current state |
97 | * CurrentNode - Where we are in the namespace | | 97 | * CurrentNode - Where we are in the namespace |
98 | * TargetNode - Node to which we are referring | | 98 | * TargetNode - Node to which we are referring |
99 | * TargetPath - External full path to the target node | | 99 | * TargetPath - External full path to the target node |
100 | * NewPath - Where the optimized path is returned | | 100 | * NewPath - Where the optimized path is returned |
101 | * | | 101 | * |
102 | * RETURN: Status | | 102 | * RETURN: Status |
103 | * | | 103 | * |
104 | * DESCRIPTION: Attempt to optimize a reference to a single 4-character ACPI | | 104 | * DESCRIPTION: Attempt to optimize a reference to a single 4-character ACPI |
105 | * name utilizing the search-to-root name resolution algorithm | | 105 | * name utilizing the search-to-root name resolution algorithm |
106 | * that is used by AML interpreters. | | 106 | * that is used by AML interpreters. |
107 | * | | 107 | * |
108 | ******************************************************************************/ | | 108 | ******************************************************************************/ |
109 | | | 109 | |
110 | static ACPI_STATUS | | 110 | static ACPI_STATUS |
111 | OptSearchToRoot ( | | 111 | OptSearchToRoot ( |
112 | ACPI_PARSE_OBJECT *Op, | | 112 | ACPI_PARSE_OBJECT *Op, |
113 | ACPI_WALK_STATE *WalkState, | | 113 | ACPI_WALK_STATE *WalkState, |
114 | ACPI_NAMESPACE_NODE *CurrentNode, | | 114 | ACPI_NAMESPACE_NODE *CurrentNode, |
115 | ACPI_NAMESPACE_NODE *TargetNode, | | 115 | ACPI_NAMESPACE_NODE *TargetNode, |
116 | ACPI_BUFFER *TargetPath, | | 116 | ACPI_BUFFER *TargetPath, |
117 | char **NewPath) | | 117 | char **NewPath) |
118 | { | | 118 | { |
119 | ACPI_NAMESPACE_NODE *Node; | | 119 | ACPI_NAMESPACE_NODE *Node; |
120 | ACPI_GENERIC_STATE ScopeInfo; | | 120 | ACPI_GENERIC_STATE ScopeInfo; |
121 | ACPI_STATUS Status; | | 121 | ACPI_STATUS Status; |
122 | char *Path; | | 122 | char *Path; |
123 | | | 123 | |
124 | | | 124 | |
125 | ACPI_FUNCTION_NAME (OptSearchToRoot); | | 125 | ACPI_FUNCTION_NAME (OptSearchToRoot); |
126 | | | 126 | |
127 | | | 127 | |
128 | /* | | 128 | /* |
129 | * Check if search-to-root can be utilized. Use the last NameSeg of | | 129 | * Check if search-to-root can be utilized. Use the last NameSeg of |
130 | * the NamePath and 1) See if can be found and 2) If found, make | | 130 | * the NamePath and 1) See if can be found and 2) If found, make |
131 | * sure that it is the same node that we want. If there is another | | 131 | * sure that it is the same node that we want. If there is another |
132 | * name in the search path before the one we want, the nodes will | | 132 | * name in the search path before the one we want, the nodes will |
133 | * not match, and we cannot use this optimization. | | 133 | * not match, and we cannot use this optimization. |
134 | */ | | 134 | */ |
135 | Path = &(((char *) TargetPath->Pointer)[ | | 135 | Path = &(((char *) TargetPath->Pointer)[ |
136 | TargetPath->Length - ACPI_NAME_SIZE]), | | 136 | TargetPath->Length - ACPI_NAME_SIZE]); |
137 | ScopeInfo.Scope.Node = CurrentNode; | | 137 | ScopeInfo.Scope.Node = CurrentNode; |
138 | | | 138 | |
139 | /* Lookup the NameSeg using SEARCH_PARENT (search-to-root) */ | | 139 | /* Lookup the NameSeg using SEARCH_PARENT (search-to-root) */ |
140 | | | 140 | |
141 | Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, | | 141 | Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, |
142 | ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, | | 142 | ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, |
143 | WalkState, &(Node)); | | 143 | WalkState, &(Node)); |
144 | if (ACPI_FAILURE (Status)) | | 144 | if (ACPI_FAILURE (Status)) |
145 | { | | 145 | { |
146 | return (Status); | | 146 | return (Status); |
147 | } | | 147 | } |
148 | | | 148 | |
149 | /* | | 149 | /* |
150 | * We found the name, but we must check to make sure that the node | | 150 | * We found the name, but we must check to make sure that the node |
151 | * matches. Otherwise, there is another identical name in the search | | 151 | * matches. Otherwise, there is another identical name in the search |
152 | * path that precludes the use of this optimization. | | 152 | * path that precludes the use of this optimization. |
153 | */ | | 153 | */ |
154 | if (Node != TargetNode) | | 154 | if (Node != TargetNode) |
155 | { | | 155 | { |
156 | /* | | 156 | /* |
157 | * This means that another object with the same name was found first, | | 157 | * This means that another object with the same name was found first, |
158 | * and we cannot use this optimization. | | 158 | * and we cannot use this optimization. |
159 | */ | | 159 | */ |
160 | return (AE_NOT_FOUND); | | 160 | return (AE_NOT_FOUND); |
161 | } | | 161 | } |
162 | | | 162 | |
163 | /* Found the node, we can use this optimization */ | | 163 | /* Found the node, we can use this optimization */ |
164 | | | 164 | |
165 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 165 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
166 | "NAMESEG: %-24s", Path)); | | 166 | "NAMESEG: %-24s", Path)); |
167 | | | 167 | |
168 | /* We must allocate a new string for the name (TargetPath gets deleted) */ | | 168 | /* We must allocate a new string for the name (TargetPath gets deleted) */ |
169 | | | 169 | |
170 | *NewPath = UtStringCacheCalloc (ACPI_NAME_SIZE + 1); | | 170 | *NewPath = UtStringCacheCalloc (ACPI_NAME_SIZE + 1); |
171 | strcpy (*NewPath, Path); | | 171 | strcpy (*NewPath, Path); |
172 | | | 172 | |
173 | if (strncmp (*NewPath, "_T_", 3)) | | 173 | if (strncmp (*NewPath, "_T_", 3)) |
174 | { | | 174 | { |
175 | AslError (ASL_OPTIMIZATION, ASL_MSG_SINGLE_NAME_OPTIMIZATION, | | 175 | AslError (ASL_OPTIMIZATION, ASL_MSG_SINGLE_NAME_OPTIMIZATION, |
176 | Op, *NewPath); | | 176 | Op, *NewPath); |
177 | } | | 177 | } |
178 | | | 178 | |
179 | return (AE_OK); | | 179 | return (AE_OK); |
180 | } | | 180 | } |
181 | | | 181 | |
182 | | | 182 | |
183 | /******************************************************************************* | | 183 | /******************************************************************************* |
184 | * | | 184 | * |
185 | * FUNCTION: OptBuildShortestPath | | 185 | * FUNCTION: OptBuildShortestPath |
186 | * | | 186 | * |
187 | * PARAMETERS: Op - Current parser op | | 187 | * PARAMETERS: Op - Current parser op |
188 | * WalkState - Current state | | 188 | * WalkState - Current state |
189 | * CurrentNode - Where we are in the namespace | | 189 | * CurrentNode - Where we are in the namespace |
190 | * TargetNode - Node to which we are referring | | 190 | * TargetNode - Node to which we are referring |
191 | * CurrentPath - External full path to the current node | | 191 | * CurrentPath - External full path to the current node |
192 | * TargetPath - External full path to the target node | | 192 | * TargetPath - External full path to the target node |
193 | * AmlNameStringLength - Length of the original namepath | | 193 | * AmlNameStringLength - Length of the original namepath |
194 | * IsDeclaration - TRUE for declaration, FALSE for reference | | 194 | * IsDeclaration - TRUE for declaration, FALSE for reference |
195 | * ReturnNewPath - Where the optimized path is returned | | 195 | * ReturnNewPath - Where the optimized path is returned |
196 | * | | 196 | * |
197 | * RETURN: Status | | 197 | * RETURN: Status |
198 | * | | 198 | * |
199 | * DESCRIPTION: Build an optimal NamePath using carats | | 199 | * DESCRIPTION: Build an optimal NamePath using carats |
200 | * | | 200 | * |
201 | ******************************************************************************/ | | 201 | ******************************************************************************/ |
202 | | | 202 | |
203 | static ACPI_STATUS | | 203 | static ACPI_STATUS |
204 | OptBuildShortestPath ( | | 204 | OptBuildShortestPath ( |
205 | ACPI_PARSE_OBJECT *Op, | | 205 | ACPI_PARSE_OBJECT *Op, |
206 | ACPI_WALK_STATE *WalkState, | | 206 | ACPI_WALK_STATE *WalkState, |
207 | ACPI_NAMESPACE_NODE *CurrentNode, | | 207 | ACPI_NAMESPACE_NODE *CurrentNode, |
208 | ACPI_NAMESPACE_NODE *TargetNode, | | 208 | ACPI_NAMESPACE_NODE *TargetNode, |
209 | ACPI_BUFFER *CurrentPath, | | 209 | ACPI_BUFFER *CurrentPath, |
210 | ACPI_BUFFER *TargetPath, | | 210 | ACPI_BUFFER *TargetPath, |
211 | ACPI_SIZE AmlNameStringLength, | | 211 | ACPI_SIZE AmlNameStringLength, |
212 | UINT8 IsDeclaration, | | 212 | UINT8 IsDeclaration, |
213 | char **ReturnNewPath) | | 213 | char **ReturnNewPath) |
214 | { | | 214 | { |
215 | UINT32 NumCommonSegments; | | 215 | UINT32 NumCommonSegments; |
216 | UINT32 MaxCommonSegments; | | 216 | UINT32 MaxCommonSegments; |
217 | UINT32 Index; | | 217 | UINT32 Index; |
218 | UINT32 NumCarats; | | 218 | UINT32 NumCarats; |
219 | UINT32 i; | | 219 | UINT32 i; |
220 | char *NewPathInternal; | | 220 | char *NewPathInternal; |
221 | char *NewPathExternal; | | 221 | char *NewPathExternal; |
222 | ACPI_NAMESPACE_NODE *Node; | | 222 | ACPI_NAMESPACE_NODE *Node; |
223 | ACPI_GENERIC_STATE ScopeInfo; | | 223 | ACPI_GENERIC_STATE ScopeInfo; |
224 | ACPI_STATUS Status; | | 224 | ACPI_STATUS Status; |
225 | BOOLEAN SubPath = FALSE; | | 225 | BOOLEAN SubPath = FALSE; |
226 | | | 226 | |
227 | | | 227 | |
228 | ACPI_FUNCTION_NAME (OptBuildShortestPath); | | 228 | ACPI_FUNCTION_NAME (OptBuildShortestPath); |
229 | | | 229 | |
230 | | | 230 | |
231 | ScopeInfo.Scope.Node = CurrentNode; | | 231 | ScopeInfo.Scope.Node = CurrentNode; |
232 | | | 232 | |
233 | /* | | 233 | /* |
234 | * Determine the maximum number of NameSegs that the Target and Current paths | | 234 | * Determine the maximum number of NameSegs that the Target and Current paths |
235 | * can possibly have in common. (To optimize, we have to have at least 1) | | 235 | * can possibly have in common. (To optimize, we have to have at least 1) |
236 | * | | 236 | * |
237 | * Note: The external NamePath string lengths are always a multiple of 5 | | 237 | * Note: The external NamePath string lengths are always a multiple of 5 |
238 | * (ACPI_NAME_SIZE + separator) | | 238 | * (ACPI_NAME_SIZE + separator) |
239 | */ | | 239 | */ |
240 | MaxCommonSegments = TargetPath->Length / ACPI_PATH_SEGMENT_LENGTH; | | 240 | MaxCommonSegments = TargetPath->Length / ACPI_PATH_SEGMENT_LENGTH; |
241 | if (CurrentPath->Length < TargetPath->Length) | | 241 | if (CurrentPath->Length < TargetPath->Length) |
242 | { | | 242 | { |
243 | MaxCommonSegments = CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH; | | 243 | MaxCommonSegments = CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH; |
244 | } | | 244 | } |
245 | | | 245 | |
246 | /* | | 246 | /* |
247 | * Determine how many NameSegs the two paths have in common. | | 247 | * Determine how many NameSegs the two paths have in common. |
248 | * (Starting from the root) | | 248 | * (Starting from the root) |
249 | */ | | 249 | */ |
250 | for (NumCommonSegments = 0; | | 250 | for (NumCommonSegments = 0; |
251 | NumCommonSegments < MaxCommonSegments; | | 251 | NumCommonSegments < MaxCommonSegments; |
252 | NumCommonSegments++) | | 252 | NumCommonSegments++) |
253 | { | | 253 | { |
254 | /* Compare two single NameSegs */ | | 254 | /* Compare two single NameSegs */ |
255 | | | 255 | |
256 | Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1; | | 256 | Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1; |
257 | | | 257 | |
258 | if (!ACPI_COMPARE_NAME ( | | 258 | if (!ACPI_COMPARE_NAME ( |
259 | &(ACPI_CAST_PTR (char, TargetPath->Pointer)) [Index], | | 259 | &(ACPI_CAST_PTR (char, TargetPath->Pointer)) [Index], |
260 | &(ACPI_CAST_PTR (char, CurrentPath->Pointer)) [Index])) | | 260 | &(ACPI_CAST_PTR (char, CurrentPath->Pointer)) [Index])) |
261 | { | | 261 | { |
262 | /* Mismatch */ | | 262 | /* Mismatch */ |
263 | | | 263 | |
264 | break; | | 264 | break; |
265 | } | | 265 | } |
266 | } | | 266 | } |
267 | | | 267 | |
268 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " COMMON: %u", | | 268 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " COMMON: %u", |
269 | NumCommonSegments)); | | 269 | NumCommonSegments)); |
270 | | | 270 | |
271 | /* There must be at least 1 common NameSeg in order to optimize */ | | 271 | /* There must be at least 1 common NameSeg in order to optimize */ |
272 | | | 272 | |
273 | if (NumCommonSegments == 0) | | 273 | if (NumCommonSegments == 0) |
274 | { | | 274 | { |
275 | return (AE_NOT_FOUND); | | 275 | return (AE_NOT_FOUND); |
276 | } | | 276 | } |
277 | | | 277 | |
278 | if (NumCommonSegments == MaxCommonSegments) | | 278 | if (NumCommonSegments == MaxCommonSegments) |
279 | { | | 279 | { |
280 | if (CurrentPath->Length == TargetPath->Length) | | 280 | if (CurrentPath->Length == TargetPath->Length) |
281 | { | | 281 | { |
282 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SAME PATH")); | | 282 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SAME PATH")); |
283 | return (AE_NOT_FOUND); | | 283 | return (AE_NOT_FOUND); |
284 | } | | 284 | } |
285 | else | | 285 | else |
286 | { | | 286 | { |
287 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SUBPATH")); | | 287 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SUBPATH")); |
288 | SubPath = TRUE; | | 288 | SubPath = TRUE; |
289 | } | | 289 | } |
290 | } | | 290 | } |
291 | | | 291 | |
292 | /* Determine how many prefix Carats are required */ | | 292 | /* Determine how many prefix Carats are required */ |
293 | | | 293 | |
294 | NumCarats = (CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH) - | | 294 | NumCarats = (CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH) - |
295 | NumCommonSegments; | | 295 | NumCommonSegments; |
296 | | | 296 | |
297 | /* | | 297 | /* |
298 | * Construct a new target string | | 298 | * Construct a new target string |
299 | */ | | 299 | */ |
300 | NewPathExternal = | | 300 | NewPathExternal = |
301 | ACPI_ALLOCATE_ZEROED (TargetPath->Length + NumCarats + 1); | | 301 | ACPI_ALLOCATE_ZEROED (TargetPath->Length + NumCarats + 1); |
302 | | | 302 | |
303 | /* Insert the Carats into the Target string */ | | 303 | /* Insert the Carats into the Target string */ |
304 | | | 304 | |
305 | for (i = 0; i < NumCarats; i++) | | 305 | for (i = 0; i < NumCarats; i++) |
306 | { | | 306 | { |
307 | NewPathExternal[i] = AML_PARENT_PREFIX; | | 307 | NewPathExternal[i] = AML_PARENT_PREFIX; |
308 | } | | 308 | } |
309 | | | 309 | |
310 | /* | | 310 | /* |
311 | * Copy only the necessary (optimal) segments from the original | | 311 | * Copy only the necessary (optimal) segments from the original |
312 | * target string | | 312 | * target string |
313 | */ | | 313 | */ |
314 | Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1; | | 314 | Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1; |
315 | | | 315 | |
316 | /* Special handling for exact subpath in a name declaration */ | | 316 | /* Special handling for exact subpath in a name declaration */ |
317 | | | 317 | |
318 | if (IsDeclaration && SubPath && | | 318 | if (IsDeclaration && SubPath && |
319 | (CurrentPath->Length > TargetPath->Length)) | | 319 | (CurrentPath->Length > TargetPath->Length)) |
320 | { | | 320 | { |
321 | /* | | 321 | /* |
322 | * The current path is longer than the target, and the target is a | | 322 | * The current path is longer than the target, and the target is a |
323 | * subpath of the current path. We must include one more NameSeg of | | 323 | * subpath of the current path. We must include one more NameSeg of |
324 | * the target path | | 324 | * the target path |
325 | */ | | 325 | */ |
326 | Index -= ACPI_PATH_SEGMENT_LENGTH; | | 326 | Index -= ACPI_PATH_SEGMENT_LENGTH; |
327 | | | 327 | |
328 | /* Special handling for Scope() operator */ | | 328 | /* Special handling for Scope() operator */ |
329 | | | 329 | |
330 | if (Op->Asl.AmlOpcode == AML_SCOPE_OP) | | 330 | if (Op->Asl.AmlOpcode == AML_SCOPE_OP) |
331 | { | | 331 | { |
332 | NewPathExternal[i] = AML_PARENT_PREFIX; | | 332 | NewPathExternal[i] = AML_PARENT_PREFIX; |
333 | i++; | | 333 | i++; |
334 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "(EXTRA ^)")); | | 334 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "(EXTRA ^)")); |
335 | } | | 335 | } |
336 | } | | 336 | } |
337 | | | 337 | |
338 | /* Make sure we haven't gone off the end of the target path */ | | 338 | /* Make sure we haven't gone off the end of the target path */ |
339 | | | 339 | |
340 | if (Index > TargetPath->Length) | | 340 | if (Index > TargetPath->Length) |
341 | { | | 341 | { |
342 | Index = TargetPath->Length; | | 342 | Index = TargetPath->Length; |
343 | } | | 343 | } |
344 | | | 344 | |
345 | strcpy (&NewPathExternal[i], | | 345 | strcpy (&NewPathExternal[i], |
346 | &(ACPI_CAST_PTR (char, TargetPath->Pointer))[Index]); | | 346 | &(ACPI_CAST_PTR (char, TargetPath->Pointer))[Index]); |
347 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " %-24s", NewPathExternal)); | | 347 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " %-24s", NewPathExternal)); |
348 | | | 348 | |
349 | /* | | 349 | /* |
350 | * Internalize the new target string and check it against the original | | 350 | * Internalize the new target string and check it against the original |
351 | * string to make sure that this is in fact an optimization. If the | | 351 | * string to make sure that this is in fact an optimization. If the |
352 | * original string is already optimal, there is no point in continuing. | | 352 | * original string is already optimal, there is no point in continuing. |
353 | */ | | 353 | */ |
354 | Status = AcpiNsInternalizeName (NewPathExternal, &NewPathInternal); | | 354 | Status = AcpiNsInternalizeName (NewPathExternal, &NewPathInternal); |
355 | if (ACPI_FAILURE (Status)) | | 355 | if (ACPI_FAILURE (Status)) |
356 | { | | 356 | { |
357 | AslCoreSubsystemError (Op, Status, "Internalizing new NamePath", | | 357 | AslCoreSubsystemError (Op, Status, "Internalizing new NamePath", |
358 | ASL_NO_ABORT); | | 358 | ASL_NO_ABORT); |
359 | goto Cleanup; | | 359 | goto Cleanup; |
360 | } | | 360 | } |
361 | | | 361 | |
362 | if (strlen (NewPathInternal) >= AmlNameStringLength) | | 362 | if (strlen (NewPathInternal) >= AmlNameStringLength) |
363 | { | | 363 | { |
364 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 364 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
365 | " NOT SHORTER (New %u old %u)", | | 365 | " NOT SHORTER (New %u old %u)", |
366 | (UINT32) strlen (NewPathInternal), | | 366 | (UINT32) strlen (NewPathInternal), |
367 | (UINT32) AmlNameStringLength)); | | 367 | (UINT32) AmlNameStringLength)); |
368 | | | 368 | |
369 | ACPI_FREE (NewPathInternal); | | 369 | ACPI_FREE (NewPathInternal); |
370 | Status = AE_NOT_FOUND; | | 370 | Status = AE_NOT_FOUND; |
371 | goto Cleanup; | | 371 | goto Cleanup; |
372 | } | | 372 | } |
373 | | | 373 | |
374 | /* | | 374 | /* |
375 | * Check to make sure that the optimization finds the node we are | | 375 | * Check to make sure that the optimization finds the node we are |
376 | * looking for. This is simply a sanity check on the new | | 376 | * looking for. This is simply a sanity check on the new |
377 | * path that has been created. | | 377 | * path that has been created. |
378 | */ | | 378 | */ |
379 | Status = AcpiNsLookup (&ScopeInfo, NewPathInternal, | | 379 | Status = AcpiNsLookup (&ScopeInfo, NewPathInternal, |
380 | ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, | | 380 | ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, |
381 | ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node)); | | 381 | ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node)); |
382 | if (ACPI_SUCCESS (Status)) | | 382 | if (ACPI_SUCCESS (Status)) |
383 | { | | 383 | { |
384 | /* Found the namepath, but make sure the node is correct */ | | 384 | /* Found the namepath, but make sure the node is correct */ |
385 | | | 385 | |
386 | if (Node == TargetNode) | | 386 | if (Node == TargetNode) |
387 | { | | 387 | { |
388 | /* The lookup matched the node, accept this optimization */ | | 388 | /* The lookup matched the node, accept this optimization */ |
389 | | | 389 | |
390 | AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION, | | 390 | AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION, |
391 | Op, NewPathExternal); | | 391 | Op, NewPathExternal); |
392 | *ReturnNewPath = NewPathInternal; | | 392 | *ReturnNewPath = NewPathInternal; |
393 | } | | 393 | } |
394 | else | | 394 | else |
395 | { | | 395 | { |
396 | /* Node is not correct, do not use this optimization */ | | 396 | /* Node is not correct, do not use this optimization */ |
397 | | | 397 | |
398 | Status = AE_NOT_FOUND; | | 398 | Status = AE_NOT_FOUND; |
399 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE")); | | 399 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE")); |
400 | AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, | | 400 | AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, |
401 | "Not using optimized name - found wrong node"); | | 401 | "Not using optimized name - found wrong node"); |
402 | } | | 402 | } |
403 | } | | 403 | } |
404 | else | | 404 | else |
405 | { | | 405 | { |
406 | /* The lookup failed, we obviously cannot use this optimization */ | | 406 | /* The lookup failed, we obviously cannot use this optimization */ |
407 | | | 407 | |
408 | ACPI_FREE (NewPathInternal); | | 408 | ACPI_FREE (NewPathInternal); |
409 | | | 409 | |
410 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND")); | | 410 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND")); |
411 | AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, | | 411 | AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, |
412 | "Not using optimized name - did not find node"); | | 412 | "Not using optimized name - did not find node"); |
413 | } | | 413 | } |
414 | | | 414 | |
415 | Cleanup: | | 415 | Cleanup: |
416 | | | 416 | |
417 | ACPI_FREE (NewPathExternal); | | 417 | ACPI_FREE (NewPathExternal); |
418 | return (Status); | | 418 | return (Status); |
419 | } | | 419 | } |
420 | | | 420 | |
421 | | | 421 | |
422 | /******************************************************************************* | | 422 | /******************************************************************************* |
423 | * | | 423 | * |
424 | * FUNCTION: OptOptimizeNameDeclaration | | 424 | * FUNCTION: OptOptimizeNameDeclaration |
425 | * | | 425 | * |
426 | * PARAMETERS: Op - Current parser op | | 426 | * PARAMETERS: Op - Current parser op |
427 | * WalkState - Current state | | 427 | * WalkState - Current state |
428 | * CurrentNode - Where we are in the namespace | | 428 | * CurrentNode - Where we are in the namespace |
429 | * AmlNameString - Unoptimized namepath | | 429 | * AmlNameString - Unoptimized namepath |
430 | * NewPath - Where the optimized path is returned | | 430 | * NewPath - Where the optimized path is returned |
431 | * | | 431 | * |
432 | * RETURN: Status. AE_OK If path is optimized | | 432 | * RETURN: Status. AE_OK If path is optimized |
433 | * | | 433 | * |
434 | * DESCRIPTION: Perform a simple optimization of removing an extraneous | | 434 | * DESCRIPTION: Perform a simple optimization of removing an extraneous |
435 | * backslash prefix if we are already at the root scope. | | 435 | * backslash prefix if we are already at the root scope. |
436 | * | | 436 | * |
437 | ******************************************************************************/ | | 437 | ******************************************************************************/ |
438 | | | 438 | |
439 | static ACPI_STATUS | | 439 | static ACPI_STATUS |
440 | OptOptimizeNameDeclaration ( | | 440 | OptOptimizeNameDeclaration ( |
441 | ACPI_PARSE_OBJECT *Op, | | 441 | ACPI_PARSE_OBJECT *Op, |
442 | ACPI_WALK_STATE *WalkState, | | 442 | ACPI_WALK_STATE *WalkState, |
443 | ACPI_NAMESPACE_NODE *CurrentNode, | | 443 | ACPI_NAMESPACE_NODE *CurrentNode, |
444 | ACPI_NAMESPACE_NODE *TargetNode, | | 444 | ACPI_NAMESPACE_NODE *TargetNode, |
445 | char *AmlNameString, | | 445 | char *AmlNameString, |
446 | char **NewPath) | | 446 | char **NewPath) |
447 | { | | 447 | { |
448 | ACPI_STATUS Status; | | 448 | ACPI_STATUS Status; |
449 | char *NewPathExternal; | | 449 | char *NewPathExternal; |
450 | ACPI_NAMESPACE_NODE *Node; | | 450 | ACPI_NAMESPACE_NODE *Node; |
451 | | | 451 | |
452 | | | 452 | |
453 | ACPI_FUNCTION_TRACE (OptOptimizeNameDeclaration); | | 453 | ACPI_FUNCTION_TRACE (OptOptimizeNameDeclaration); |
454 | | | 454 | |
455 | | | 455 | |
456 | if (((CurrentNode == AcpiGbl_RootNode) || | | 456 | if (((CurrentNode == AcpiGbl_RootNode) || |
457 | (Op->Common.Parent->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)) && | | 457 | (Op->Common.Parent->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)) && |
458 | (ACPI_IS_ROOT_PREFIX (AmlNameString[0]))) | | 458 | (ACPI_IS_ROOT_PREFIX (AmlNameString[0]))) |
459 | { | | 459 | { |
460 | /* | | 460 | /* |
461 | * The current scope is the root, and the namepath has a root prefix | | 461 | * The current scope is the root, and the namepath has a root prefix |
462 | * that is therefore extraneous. Remove it. | | 462 | * that is therefore extraneous. Remove it. |
463 | */ | | 463 | */ |
464 | *NewPath = &AmlNameString[1]; | | 464 | *NewPath = &AmlNameString[1]; |
465 | | | 465 | |
466 | /* Debug output */ | | 466 | /* Debug output */ |
467 | | | 467 | |
468 | Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, *NewPath, | | 468 | Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, *NewPath, |
469 | NULL, &NewPathExternal); | | 469 | NULL, &NewPathExternal); |
470 | if (ACPI_FAILURE (Status)) | | 470 | if (ACPI_FAILURE (Status)) |
471 | { | | 471 | { |
472 | AslCoreSubsystemError (Op, Status, "Externalizing NamePath", | | 472 | AslCoreSubsystemError (Op, Status, "Externalizing NamePath", |
473 | ASL_NO_ABORT); | | 473 | ASL_NO_ABORT); |
474 | return (Status); | | 474 | return (Status); |
475 | } | | 475 | } |
476 | | | 476 | |
477 | /* | | 477 | /* |
478 | * Check to make sure that the optimization finds the node we are | | 478 | * Check to make sure that the optimization finds the node we are |
479 | * looking for. This is simply a sanity check on the new | | 479 | * looking for. This is simply a sanity check on the new |
480 | * path that has been created. | | 480 | * path that has been created. |
481 | * | | 481 | * |
482 | * We know that we are at the root, so NULL is used for the scope. | | 482 | * We know that we are at the root, so NULL is used for the scope. |
483 | */ | | 483 | */ |
484 | Status = AcpiNsLookup (NULL, *NewPath, | | 484 | Status = AcpiNsLookup (NULL, *NewPath, |
485 | ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, | | 485 | ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, |
486 | ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node)); | | 486 | ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node)); |
487 | if (ACPI_SUCCESS (Status)) | | 487 | if (ACPI_SUCCESS (Status)) |
488 | { | | 488 | { |
489 | /* Found the namepath, but make sure the node is correct */ | | 489 | /* Found the namepath, but make sure the node is correct */ |
490 | | | 490 | |
491 | if (Node == TargetNode) | | 491 | if (Node == TargetNode) |
492 | { | | 492 | { |
493 | /* The lookup matched the node, accept this optimization */ | | 493 | /* The lookup matched the node, accept this optimization */ |
494 | | | 494 | |
495 | AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION, | | 495 | AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION, |
496 | Op, NewPathExternal); | | 496 | Op, NewPathExternal); |
497 | | | 497 | |
498 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 498 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
499 | "AT ROOT: %-24s", NewPathExternal)); | | 499 | "AT ROOT: %-24s", NewPathExternal)); |
500 | } | | 500 | } |
501 | else | | 501 | else |
502 | { | | 502 | { |
503 | /* Node is not correct, do not use this optimization */ | | 503 | /* Node is not correct, do not use this optimization */ |
504 | | | 504 | |
505 | Status = AE_NOT_FOUND; | | 505 | Status = AE_NOT_FOUND; |
506 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 506 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
507 | " ***** WRONG NODE")); | | 507 | " ***** WRONG NODE")); |
508 | AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, | | 508 | AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, |
509 | "Not using optimized name - found wrong node"); | | 509 | "Not using optimized name - found wrong node"); |
510 | } | | 510 | } |
511 | } | | 511 | } |
512 | else | | 512 | else |
513 | { | | 513 | { |
514 | /* The lookup failed, we obviously cannot use this optimization */ | | 514 | /* The lookup failed, we obviously cannot use this optimization */ |
515 | | | 515 | |
516 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 516 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
517 | " ***** NOT FOUND")); | | 517 | " ***** NOT FOUND")); |
518 | AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, | | 518 | AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, |
519 | "Not using optimized name - did not find node"); | | 519 | "Not using optimized name - did not find node"); |
520 | } | | 520 | } |
521 | | | 521 | |
522 | ACPI_FREE (NewPathExternal); | | 522 | ACPI_FREE (NewPathExternal); |
523 | return (Status); | | 523 | return (Status); |
524 | } | | 524 | } |
525 | | | 525 | |
526 | /* Could not optimize */ | | 526 | /* Could not optimize */ |
527 | | | 527 | |
528 | return (AE_NOT_FOUND); | | 528 | return (AE_NOT_FOUND); |
529 | } | | 529 | } |
530 | | | 530 | |
531 | | | 531 | |
532 | /******************************************************************************* | | 532 | /******************************************************************************* |
533 | * | | 533 | * |
534 | * FUNCTION: OptOptimizeNamePath | | 534 | * FUNCTION: OptOptimizeNamePath |
535 | * | | 535 | * |
536 | * PARAMETERS: Op - Current parser op | | 536 | * PARAMETERS: Op - Current parser op |
537 | * Flags - Opcode info flags | | 537 | * Flags - Opcode info flags |
538 | * WalkState - Current state | | 538 | * WalkState - Current state |
539 | * AmlNameString - Unoptimized namepath | | 539 | * AmlNameString - Unoptimized namepath |
540 | * TargetNode - Node to which AmlNameString refers | | 540 | * TargetNode - Node to which AmlNameString refers |
541 | * | | 541 | * |
542 | * RETURN: None. If path is optimized, the Op is updated with new path | | 542 | * RETURN: None. If path is optimized, the Op is updated with new path |
543 | * | | 543 | * |
544 | * DESCRIPTION: Optimize a Named Declaration or Reference to the minimal length. | | 544 | * DESCRIPTION: Optimize a Named Declaration or Reference to the minimal length. |
545 | * Must take into account both the current location in the | | 545 | * Must take into account both the current location in the |
546 | * namespace and the actual reference path. | | 546 | * namespace and the actual reference path. |
547 | * | | 547 | * |
548 | ******************************************************************************/ | | 548 | ******************************************************************************/ |
549 | | | 549 | |
550 | void | | 550 | void |
551 | OptOptimizeNamePath ( | | 551 | OptOptimizeNamePath ( |
552 | ACPI_PARSE_OBJECT *Op, | | 552 | ACPI_PARSE_OBJECT *Op, |
553 | UINT32 Flags, | | 553 | UINT32 Flags, |
554 | ACPI_WALK_STATE *WalkState, | | 554 | ACPI_WALK_STATE *WalkState, |
555 | char *AmlNameString, | | 555 | char *AmlNameString, |
556 | ACPI_NAMESPACE_NODE *TargetNode) | | 556 | ACPI_NAMESPACE_NODE *TargetNode) |
557 | { | | 557 | { |
558 | ACPI_STATUS Status; | | 558 | ACPI_STATUS Status; |
559 | ACPI_BUFFER TargetPath; | | 559 | ACPI_BUFFER TargetPath; |
560 | ACPI_BUFFER CurrentPath; | | 560 | ACPI_BUFFER CurrentPath; |
561 | ACPI_SIZE AmlNameStringLength; | | 561 | ACPI_SIZE AmlNameStringLength; |
562 | ACPI_NAMESPACE_NODE *CurrentNode; | | 562 | ACPI_NAMESPACE_NODE *CurrentNode; |
563 | char *ExternalNameString; | | 563 | char *ExternalNameString; |
564 | char *NewPath = NULL; | | 564 | char *NewPath = NULL; |
565 | ACPI_SIZE HowMuchShorter; | | 565 | ACPI_SIZE HowMuchShorter; |
566 | ACPI_PARSE_OBJECT *NextOp; | | 566 | ACPI_PARSE_OBJECT *NextOp; |
567 | | | 567 | |
568 | | | 568 | |
569 | ACPI_FUNCTION_TRACE (OptOptimizeNamePath); | | 569 | ACPI_FUNCTION_TRACE (OptOptimizeNamePath); |
570 | | | 570 | |
571 | | | 571 | |
572 | /* This is an optional optimization */ | | 572 | /* This is an optional optimization */ |
573 | | | 573 | |
574 | if (!Gbl_ReferenceOptimizationFlag) | | 574 | if (!Gbl_ReferenceOptimizationFlag) |
575 | { | | 575 | { |
576 | return_VOID; | | 576 | return_VOID; |
577 | } | | 577 | } |
578 | | | 578 | |
579 | /* Various required items */ | | 579 | /* Various required items */ |
580 | | | 580 | |
581 | if (!TargetNode || !WalkState || !AmlNameString || !Op->Common.Parent) | | 581 | if (!TargetNode || !WalkState || !AmlNameString || !Op->Common.Parent) |
582 | { | | 582 | { |
583 | return_VOID; | | 583 | return_VOID; |
584 | } | | 584 | } |
585 | | | 585 | |
586 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 586 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
587 | "PATH OPTIMIZE: Line %5d ParentOp [%12.12s] ThisOp [%12.12s] ", | | 587 | "PATH OPTIMIZE: Line %5d ParentOp [%12.12s] ThisOp [%12.12s] ", |
588 | Op->Asl.LogicalLineNumber, | | 588 | Op->Asl.LogicalLineNumber, |
589 | AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), | | 589 | AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), |
590 | AcpiPsGetOpcodeName (Op->Common.AmlOpcode))); | | 590 | AcpiPsGetOpcodeName (Op->Common.AmlOpcode))); |
591 | | | 591 | |
592 | if (!(Flags & (AML_NAMED | AML_CREATE))) | | 592 | if (!(Flags & (AML_NAMED | AML_CREATE))) |
593 | { | | 593 | { |
594 | if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION) | | 594 | if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION) |
595 | { | | 595 | { |
596 | /* We don't want to fuss with actual name declaration nodes here */ | | 596 | /* We don't want to fuss with actual name declaration nodes here */ |
597 | | | 597 | |
598 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 598 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
599 | "******* NAME DECLARATION\n")); | | 599 | "******* NAME DECLARATION\n")); |
600 | return_VOID; | | 600 | return_VOID; |
601 | } | | 601 | } |
602 | } | | 602 | } |
603 | | | 603 | |
604 | /* | | 604 | /* |
605 | * The original path must be longer than one NameSeg (4 chars) for there | | 605 | * The original path must be longer than one NameSeg (4 chars) for there |
606 | * to be any possibility that it can be optimized to a shorter string | | 606 | * to be any possibility that it can be optimized to a shorter string |
607 | */ | | 607 | */ |
608 | AmlNameStringLength = strlen (AmlNameString); | | 608 | AmlNameStringLength = strlen (AmlNameString); |
609 | if (AmlNameStringLength <= ACPI_NAME_SIZE) | | 609 | if (AmlNameStringLength <= ACPI_NAME_SIZE) |
610 | { | | 610 | { |
611 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 611 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
612 | "NAMESEG %4.4s\n", AmlNameString)); | | 612 | "NAMESEG %4.4s\n", AmlNameString)); |
613 | return_VOID; | | 613 | return_VOID; |
614 | } | | 614 | } |
615 | | | 615 | |
616 | /* | | 616 | /* |
617 | * We need to obtain the node that represents the current scope -- where | | 617 | * We need to obtain the node that represents the current scope -- where |
618 | * we are right now in the namespace. We will compare this path | | 618 | * we are right now in the namespace. We will compare this path |
619 | * against the Namepath, looking for commonality. | | 619 | * against the Namepath, looking for commonality. |
620 | */ | | 620 | */ |
621 | CurrentNode = AcpiGbl_RootNode; | | 621 | CurrentNode = AcpiGbl_RootNode; |
622 | if (WalkState->ScopeInfo) | | 622 | if (WalkState->ScopeInfo) |
623 | { | | 623 | { |
624 | CurrentNode = WalkState->ScopeInfo->Scope.Node; | | 624 | CurrentNode = WalkState->ScopeInfo->Scope.Node; |
625 | } | | 625 | } |
626 | | | 626 | |
627 | if (Flags & (AML_NAMED | AML_CREATE)) | | 627 | if (Flags & (AML_NAMED | AML_CREATE)) |
628 | { | | 628 | { |
629 | /* This is the declaration of a new name */ | | 629 | /* This is the declaration of a new name */ |
630 | | | 630 | |
631 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "NAME\n")); | | 631 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "NAME\n")); |
632 | | | 632 | |
633 | /* | | 633 | /* |
634 | * The node of interest is the parent of this node (the containing | | 634 | * The node of interest is the parent of this node (the containing |
635 | * scope). The actual namespace node may be up more than one level | | 635 | * scope). The actual namespace node may be up more than one level |
636 | * of parse op or it may not exist at all (if we traverse back | | 636 | * of parse op or it may not exist at all (if we traverse back |
637 | * up to the root.) | | 637 | * up to the root.) |
638 | */ | | 638 | */ |
639 | NextOp = Op->Asl.Parent; | | 639 | NextOp = Op->Asl.Parent; |
640 | while (NextOp && (!NextOp->Asl.Node)) | | 640 | while (NextOp && (!NextOp->Asl.Node)) |
641 | { | | 641 | { |
642 | NextOp = NextOp->Asl.Parent; | | 642 | NextOp = NextOp->Asl.Parent; |
643 | } | | 643 | } |
644 | | | 644 | |
645 | if (NextOp && NextOp->Asl.Node) | | 645 | if (NextOp && NextOp->Asl.Node) |
646 | { | | 646 | { |
647 | CurrentNode = NextOp->Asl.Node; | | 647 | CurrentNode = NextOp->Asl.Node; |
648 | } | | 648 | } |
649 | else | | 649 | else |
650 | { | | 650 | { |
651 | CurrentNode = AcpiGbl_RootNode; | | 651 | CurrentNode = AcpiGbl_RootNode; |
652 | } | | 652 | } |
653 | } | | 653 | } |
654 | else | | 654 | else |
655 | { | | 655 | { |
656 | /* This is a reference to an existing named object */ | | 656 | /* This is a reference to an existing named object */ |
657 | | | 657 | |
658 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "REFERENCE\n")); | | 658 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "REFERENCE\n")); |
659 | } | | 659 | } |
660 | | | 660 | |
661 | /* | | 661 | /* |
662 | * Obtain the full paths to the two nodes that we are interested in | | 662 | * Obtain the full paths to the two nodes that we are interested in |
663 | * (Target and current namespace location) in external | | 663 | * (Target and current namespace location) in external |
664 | * format -- something we can easily manipulate | | 664 | * format -- something we can easily manipulate |
665 | */ | | 665 | */ |
666 | TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; | | 666 | TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; |
667 | Status = AcpiNsHandleToPathname (TargetNode, &TargetPath, FALSE); | | 667 | Status = AcpiNsHandleToPathname (TargetNode, &TargetPath, FALSE); |
668 | if (ACPI_FAILURE (Status)) | | 668 | if (ACPI_FAILURE (Status)) |
669 | { | | 669 | { |
670 | AslCoreSubsystemError (Op, Status, "Getting Target NamePath", | | 670 | AslCoreSubsystemError (Op, Status, "Getting Target NamePath", |
671 | ASL_NO_ABORT); | | 671 | ASL_NO_ABORT); |
672 | return_VOID; | | 672 | return_VOID; |
673 | } | | 673 | } |
674 | | | 674 | |
675 | TargetPath.Length--; /* Subtract one for null terminator */ | | 675 | TargetPath.Length--; /* Subtract one for null terminator */ |
676 | | | 676 | |
677 | /* CurrentPath is the path to this scope (where we are in the namespace) */ | | 677 | /* CurrentPath is the path to this scope (where we are in the namespace) */ |
678 | | | 678 | |
679 | CurrentPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; | | 679 | CurrentPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; |
680 | Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath, FALSE); | | 680 | Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath, FALSE); |
681 | if (ACPI_FAILURE (Status)) | | 681 | if (ACPI_FAILURE (Status)) |
682 | { | | 682 | { |
683 | AslCoreSubsystemError (Op, Status, "Getting Current NamePath", | | 683 | AslCoreSubsystemError (Op, Status, "Getting Current NamePath", |
684 | ASL_NO_ABORT); | | 684 | ASL_NO_ABORT); |
685 | return_VOID; | | 685 | return_VOID; |
686 | } | | 686 | } |
687 | | | 687 | |
688 | CurrentPath.Length--; /* Subtract one for null terminator */ | | 688 | CurrentPath.Length--; /* Subtract one for null terminator */ |
689 | | | 689 | |
690 | /* Debug output only */ | | 690 | /* Debug output only */ |
691 | | | 691 | |
692 | Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, AmlNameString, | | 692 | Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, AmlNameString, |
693 | NULL, &ExternalNameString); | | 693 | NULL, &ExternalNameString); |
694 | if (ACPI_FAILURE (Status)) | | 694 | if (ACPI_FAILURE (Status)) |
695 | { | | 695 | { |
696 | AslCoreSubsystemError (Op, Status, "Externalizing NamePath", | | 696 | AslCoreSubsystemError (Op, Status, "Externalizing NamePath", |
697 | ASL_NO_ABORT); | | 697 | ASL_NO_ABORT); |
698 | return_VOID; | | 698 | return_VOID; |
699 | } | | 699 | } |
700 | | | 700 | |
701 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 701 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
702 | "CURRENT SCOPE: (%2u) %-37s FULL PATH TO NAME: (%2u) %-32s ACTUAL AML:%-32s\n", | | 702 | "CURRENT SCOPE: (%2u) %-37s FULL PATH TO NAME: (%2u) %-32s ACTUAL AML:%-32s\n", |
703 | (UINT32) CurrentPath.Length, (char *) CurrentPath.Pointer, | | 703 | (UINT32) CurrentPath.Length, (char *) CurrentPath.Pointer, |
704 | (UINT32) TargetPath.Length, (char *) TargetPath.Pointer, | | 704 | (UINT32) TargetPath.Length, (char *) TargetPath.Pointer, |
705 | ExternalNameString)); | | 705 | ExternalNameString)); |
706 | | | 706 | |
707 | ACPI_FREE (ExternalNameString); | | 707 | ACPI_FREE (ExternalNameString); |
708 | | | 708 | |
709 | /* | | 709 | /* |
710 | * Attempt an optmization depending on the type of namepath | | 710 | * Attempt an optmization depending on the type of namepath |
711 | */ | | 711 | */ |
712 | if (Flags & (AML_NAMED | AML_CREATE)) | | 712 | if (Flags & (AML_NAMED | AML_CREATE)) |
713 | { | | 713 | { |
714 | /* | | 714 | /* |
715 | * This is a named opcode and the namepath is a name declaration, not | | 715 | * This is a named opcode and the namepath is a name declaration, not |
716 | * a reference. | | 716 | * a reference. |
717 | */ | | 717 | */ |
718 | Status = OptOptimizeNameDeclaration (Op, WalkState, CurrentNode, | | 718 | Status = OptOptimizeNameDeclaration (Op, WalkState, CurrentNode, |
719 | TargetNode, AmlNameString, &NewPath); | | 719 | TargetNode, AmlNameString, &NewPath); |
720 | if (ACPI_FAILURE (Status)) | | 720 | if (ACPI_FAILURE (Status)) |
721 | { | | 721 | { |
722 | /* | | 722 | /* |
723 | * 2) now attempt to | | 723 | * 2) now attempt to |
724 | * optimize the namestring with carats (up-arrow) | | 724 | * optimize the namestring with carats (up-arrow) |
725 | */ | | 725 | */ |
726 | Status = OptBuildShortestPath (Op, WalkState, CurrentNode, | | 726 | Status = OptBuildShortestPath (Op, WalkState, CurrentNode, |
727 | TargetNode, &CurrentPath, &TargetPath, | | 727 | TargetNode, &CurrentPath, &TargetPath, |
728 | AmlNameStringLength, 1, &NewPath); | | 728 | AmlNameStringLength, 1, &NewPath); |
729 | } | | 729 | } |
730 | } | | 730 | } |
731 | else | | 731 | else |
732 | { | | 732 | { |
733 | /* | | 733 | /* |
734 | * This is a reference to an existing named object | | 734 | * This is a reference to an existing named object |
735 | * | | 735 | * |
736 | * 1) Check if search-to-root can be utilized using the last | | 736 | * 1) Check if search-to-root can be utilized using the last |
737 | * NameSeg of the NamePath | | 737 | * NameSeg of the NamePath |
738 | */ | | 738 | */ |
739 | Status = OptSearchToRoot (Op, WalkState, CurrentNode, | | 739 | Status = OptSearchToRoot (Op, WalkState, CurrentNode, |
740 | TargetNode, &TargetPath, &NewPath); | | 740 | TargetNode, &TargetPath, &NewPath); |
741 | if (ACPI_FAILURE (Status)) | | 741 | if (ACPI_FAILURE (Status)) |
742 | { | | 742 | { |
743 | /* | | 743 | /* |
744 | * 2) Search-to-root could not be used, now attempt to | | 744 | * 2) Search-to-root could not be used, now attempt to |
745 | * optimize the namestring with carats (up-arrow) | | 745 | * optimize the namestring with carats (up-arrow) |
746 | */ | | 746 | */ |
747 | Status = OptBuildShortestPath (Op, WalkState, CurrentNode, | | 747 | Status = OptBuildShortestPath (Op, WalkState, CurrentNode, |
748 | TargetNode, &CurrentPath, &TargetPath, | | 748 | TargetNode, &CurrentPath, &TargetPath, |
749 | AmlNameStringLength, 0, &NewPath); | | 749 | AmlNameStringLength, 0, &NewPath); |
750 | } | | 750 | } |
751 | } | | 751 | } |
752 | | | 752 | |
753 | /* | | 753 | /* |
754 | * Success from above indicates that the NamePath was successfully | | 754 | * Success from above indicates that the NamePath was successfully |
755 | * optimized. We need to update the parse op with the new name | | 755 | * optimized. We need to update the parse op with the new name |
756 | */ | | 756 | */ |
757 | if (ACPI_SUCCESS (Status)) | | 757 | if (ACPI_SUCCESS (Status)) |
758 | { | | 758 | { |
759 | HowMuchShorter = (AmlNameStringLength - strlen (NewPath)); | | 759 | HowMuchShorter = (AmlNameStringLength - strlen (NewPath)); |
760 | OptTotal += HowMuchShorter; | | 760 | OptTotal += HowMuchShorter; |
761 | | | 761 | |
762 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, | | 762 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, |
763 | " REDUCED BY %2u (TOTAL SAVED %2u)", | | 763 | " REDUCED BY %2u (TOTAL SAVED %2u)", |
764 | (UINT32) HowMuchShorter, OptTotal)); | | 764 | (UINT32) HowMuchShorter, OptTotal)); |
765 | | | 765 | |
766 | if (Flags & AML_NAMED) | | 766 | if (Flags & AML_NAMED) |
767 | { | | 767 | { |
768 | if (Op->Asl.AmlOpcode == AML_ALIAS_OP) | | 768 | if (Op->Asl.AmlOpcode == AML_ALIAS_OP) |
769 | { | | 769 | { |
770 | /* | | 770 | /* |
771 | * ALIAS is the only oddball opcode, the name declaration | | 771 | * ALIAS is the only oddball opcode, the name declaration |
772 | * (alias name) is the second operand | | 772 | * (alias name) is the second operand |
773 | */ | | 773 | */ |
774 | Op->Asl.Child->Asl.Next->Asl.Value.String = NewPath; | | 774 | Op->Asl.Child->Asl.Next->Asl.Value.String = NewPath; |
775 | Op->Asl.Child->Asl.Next->Asl.AmlLength = strlen (NewPath); | | 775 | Op->Asl.Child->Asl.Next->Asl.AmlLength = strlen (NewPath); |
776 | } | | 776 | } |
777 | else | | 777 | else |
778 | { | | 778 | { |
779 | Op->Asl.Child->Asl.Value.String = NewPath; | | 779 | Op->Asl.Child->Asl.Value.String = NewPath; |
780 | Op->Asl.Child->Asl.AmlLength = strlen (NewPath); | | 780 | Op->Asl.Child->Asl.AmlLength = strlen (NewPath); |
781 | } | | 781 | } |
782 | } | | 782 | } |
783 | else if (Flags & AML_CREATE) | | 783 | else if (Flags & AML_CREATE) |
784 | { | | 784 | { |
785 | /* Name must appear as the last parameter */ | | 785 | /* Name must appear as the last parameter */ |
786 | | | 786 | |
787 | NextOp = Op->Asl.Child; | | 787 | NextOp = Op->Asl.Child; |
788 | while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)) | | 788 | while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)) |
789 | { | | 789 | { |
790 | NextOp = NextOp->Asl.Next; | | 790 | NextOp = NextOp->Asl.Next; |
791 | } | | 791 | } |
792 | /* Update the parse node with the new NamePath */ | | 792 | /* Update the parse node with the new NamePath */ |
793 | | | 793 | |
794 | NextOp->Asl.Value.String = NewPath; | | 794 | NextOp->Asl.Value.String = NewPath; |
795 | NextOp->Asl.AmlLength = strlen (NewPath); | | 795 | NextOp->Asl.AmlLength = strlen (NewPath); |
796 | } | | 796 | } |
797 | else | | 797 | else |
798 | { | | 798 | { |
799 | /* Update the parse node with the new NamePath */ | | 799 | /* Update the parse node with the new NamePath */ |
800 | | | 800 | |
801 | Op->Asl.Value.String = NewPath; | | 801 | Op->Asl.Value.String = NewPath; |
802 | Op->Asl.AmlLength = strlen (NewPath); | | 802 | Op->Asl.AmlLength = strlen (NewPath); |
803 | } | | 803 | } |
804 | } | | 804 | } |
805 | else | | 805 | else |
806 | { | | 806 | { |
807 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ALREADY OPTIMAL")); | | 807 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ALREADY OPTIMAL")); |
808 | } | | 808 | } |
809 | | | 809 | |
810 | /* Cleanup path buffers */ | | 810 | /* Cleanup path buffers */ |
811 | | | 811 | |
812 | ACPI_FREE (TargetPath.Pointer); | | 812 | ACPI_FREE (TargetPath.Pointer); |
813 | ACPI_FREE (CurrentPath.Pointer); | | 813 | ACPI_FREE (CurrentPath.Pointer); |
814 | | | 814 | |
815 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "\n")); | | 815 | ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "\n")); |
816 | return_VOID; | | 816 | return_VOID; |
817 | } | | 817 | } |