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:43:57 -05:00
parent 6e724034a3
commit a146bd7784
@@ -1644,33 +1644,11 @@ CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode)
Token token = fTokenizer->NextToken(); Token token = fTokenizer->NextToken();
const BString& identifierName = token.string; const BString& identifierName = token.string;
if (fTypeInfo != NULL) { ValueNodeChild* child = NULL;
Type* resultType = NULL; if (fNodeManager != NULL) {
status_t error = fTypeInfo->LookupTypeByName(identifierName,
TypeLookupConstraints(), resultType);
if (error == B_OK) {
BReference<Type> typeReference(resultType, true);
return _ParseType(resultType);
} else if (error != B_ENTRY_NOT_FOUND) {
BString errorMessage;
errorMessage.SetToFormat("Failed to look up type name '%s': %"
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(); ValueNodeContainer* container = fNodeManager->GetContainer();
AutoLocker<ValueNodeContainer> containerLocker(container); AutoLocker<ValueNodeContainer> containerLocker(container);
ValueNodeChild* child = NULL;
if (parentNode == NULL) { if (parentNode == NULL) {
ValueNodeChild* thisChild = NULL; ValueNodeChild* thisChild = NULL;
for (int32 i = 0; i < container->CountChildren(); i++) { for (int32 i = 0; i < container->CountChildren(); i++) {
@@ -1713,6 +1691,22 @@ CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode)
} }
} }
} }
}
if (child == NULL && fTypeInfo != NULL) {
Type* resultType = NULL;
status_t error = fTypeInfo->LookupTypeByName(identifierName,
TypeLookupConstraints(), resultType);
if (error == B_OK) {
BReference<Type> typeReference(resultType, true);
return _ParseType(resultType);
} else if (error != B_ENTRY_NOT_FOUND) {
BString errorMessage;
errorMessage.SetToFormat("Failed to look up type name '%s': %"
B_PRId32 ".", identifierName.String(), error);
throw ParseException(errorMessage.String(), token.position);
}
}
BString errorMessage; BString errorMessage;
if (child == NULL) { if (child == NULL) {