Debugger: Expression evaluator optimization.

- When resolving an identifier, first attempt to match it against
  frame variable if applicable, and only attempt to look it up as a
  type name if the former comes up empty. The type lookup is
  significantly more expensive since if it doesn't match an already
  known type, it currently needs to search through all DIEs trying
  to find a candidate. This would significantly slow down expression
  evaluation involving identifier names, and was particularly noticeable
  for breakpoint condition processing.
This commit is contained in:
Rene Gollent 2014-12-28 23:36:12 -05:00
parent 6e724034a3
commit a146bd7784

View File

@ -1644,7 +1644,56 @@ CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode)
Token token = fTokenizer->NextToken();
const BString& identifierName = token.string;
if (fTypeInfo != NULL) {
ValueNodeChild* child = NULL;
if (fNodeManager != NULL) {
ValueNodeContainer* container = fNodeManager->GetContainer();
AutoLocker<ValueNodeContainer> containerLocker(container);
if (parentNode == NULL) {
ValueNodeChild* thisChild = NULL;
for (int32 i = 0; i < container->CountChildren(); i++) {
ValueNodeChild* current = container->ChildAt(i);
const BString& nodeName = current->Name();
if (nodeName == identifierName) {
child = current;
break;
} else if (nodeName == "this")
thisChild = current;
}
if (child == NULL && thisChild != NULL) {
// the name was not found in the variables or parameters,
// but we have a class pointer. Try to find the name in the
// list of members.
_RequestValueIfNeeded(token, thisChild);
ValueNode* thisNode = thisChild->Node();
fTokenizer->RewindToken();
return _ParseIdentifier(thisNode);
}
} else {
// skip intermediate address nodes
if (parentNode->GetType()->Kind() == TYPE_ADDRESS
&& parentNode->CountChildren() == 1) {
child = parentNode->ChildAt(0);
_RequestValueIfNeeded(token, child);
parentNode = child->Node();
fTokenizer->RewindToken();
return _ParseIdentifier(parentNode);
}
for (int32 i = 0; i < parentNode->CountChildren(); i++) {
ValueNodeChild* current = parentNode->ChildAt(i);
const BString& nodeName = current->Name();
if (nodeName == identifierName) {
child = current;
break;
}
}
}
}
if (child == NULL && fTypeInfo != NULL) {
Type* resultType = NULL;
status_t error = fTypeInfo->LookupTypeByName(identifierName,
TypeLookupConstraints(), resultType);
@ -1657,61 +1706,6 @@ CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode)
B_PRId32 ".", identifierName.String(), error);
throw ParseException(errorMessage.String(), token.position);
}
// we didn't recognize the identifier as a type name, fall through
// and see if it's possibly a value
}
if (fNodeManager == NULL) {
throw ParseException("Identifiers not resolvable without manager.",
token.position);
}
ValueNodeContainer* container = fNodeManager->GetContainer();
AutoLocker<ValueNodeContainer> containerLocker(container);
ValueNodeChild* child = NULL;
if (parentNode == NULL) {
ValueNodeChild* thisChild = NULL;
for (int32 i = 0; i < container->CountChildren(); i++) {
ValueNodeChild* current = container->ChildAt(i);
const BString& nodeName = current->Name();
if (nodeName == identifierName) {
child = current;
break;
} else if (nodeName == "this")
thisChild = current;
}
if (child == NULL && thisChild != NULL) {
// the name was not found in the variables or parameters,
// but we have a class pointer. Try to find the name in the
// list of members.
_RequestValueIfNeeded(token, thisChild);
ValueNode* thisNode = thisChild->Node();
fTokenizer->RewindToken();
return _ParseIdentifier(thisNode);
}
} else {
// skip intermediate address nodes
if (parentNode->GetType()->Kind() == TYPE_ADDRESS
&& parentNode->CountChildren() == 1) {
child = parentNode->ChildAt(0);
_RequestValueIfNeeded(token, child);
parentNode = child->Node();
fTokenizer->RewindToken();
return _ParseIdentifier(parentNode);
}
for (int32 i = 0; i < parentNode->CountChildren(); i++) {
ValueNodeChild* current = parentNode->ChildAt(i);
const BString& nodeName = current->Name();
if (nodeName == identifierName) {
child = current;
break;
}
}
}
BString errorMessage;