-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[lldb] Add interface to check if UserExpression::Parse() is cacheable #66826
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presumably this will do something for Swift expressions? I don't think there's any reason that the expression for a location in C/C++/ObjC code would not be cacheable, so the fact that this is a no-op in all of llvm.org lldb is expected.
This got forgotten it seems. Could you add a comment in the header to address Jim's question? So folks upstream know whether to care about overriding this for whatever new thing they might be building (there are lots of mysterious methods over in llvm and I end up ignoring them and hoping they're not important). |
@DavidSpickett thanks for reminding me. I'll add a comment describing the situation. Right now, for conditional breakpoints, we assume that the condition expression is cacheable, since it's being run over and over again in the exact same context. This works for C/C++, but not for Swift, because Swift generics aren't monomorphized (the same problem would happen for other languages where generics aren't monomorphized either, so a more general escape hatch seemed appropriate to me). To illustrate what I mean, a function such as the following (in C++ syntax but Swift semantics):
Is lowered only once as a truly generic function (unlike C++ which will generate one version per instantiation), so it isn't safe to cache the expression parse, as the argument type may be different in every invocation. |
5593f33
to
fcc27c3
Compare
@llvm/pr-subscribers-lldb Author: Augusto Noronha (augusto2112) ChangesWhen setting conditional breakpoints, we currently assume that a call to UserExpression::Parse() can be cached and resued multiple times. This may not be true for every user expression. Add a new method so subclasses of UserExpression can customize if they are parseable or not. Full diff: https://github.com/llvm/llvm-project/pull/66826.diff 2 Files Affected:
diff --git a/lldb/include/lldb/Expression/UserExpression.h b/lldb/include/lldb/Expression/UserExpression.h
index df7a76664f6d5b6..b6cfeec7e899330 100644
--- a/lldb/include/lldb/Expression/UserExpression.h
+++ b/lldb/include/lldb/Expression/UserExpression.h
@@ -192,6 +192,14 @@ class UserExpression : public Expression {
/// expression. Text() should contain the definition of this function.
const char *FunctionName() override { return "$__lldb_expr"; }
+ /// Returns whether the call to Parse on this user expression is cacheable.
+ /// This function exists to provide an escape hatch for supporting languages
+ /// where parsing an expression in the exact same context is unsafe. For
+ /// example, languages where generic functions aren't monomorphized, but
+ /// implement some other mechanism to represent generic values, may be unsafe
+ /// to cache, as the concrete type substitution may be different in every
+ /// expression evaluation.
+ virtual bool IsParseCacheable() { return true; }
/// Return the language that should be used when parsing. To use the
/// default, return eLanguageTypeUnknown.
lldb::LanguageType Language() const override { return m_language; }
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp
index 0fcefe5c63be749..2d2e00883f32ef7 100644
--- a/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -250,6 +250,7 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
DiagnosticManager diagnostics;
if (condition_hash != m_condition_hash || !m_user_expression_sp ||
+ !m_user_expression_sp->IsParseCacheable() ||
!m_user_expression_sp->MatchesContext(exe_ctx)) {
LanguageType language = eLanguageTypeUnknown;
// See if we can figure out the language from the frame, otherwise use the
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
When setting conditional breakpoints, we currently assume that a call to UserExpression::Parse() can be cached and resued multiple times. This may not be true for every user expression. Add a new method so subclasses of UserExpression can customize if they are parseable or not.
fcc27c3
to
5323ac9
Compare
…llvm#66826) When setting conditional breakpoints, we currently assume that a call to UserExpression::Parse() can be cached and resued multiple times. This may not be true for every user expression. Add a new method so subclasses of UserExpression can customize if they are parseable or not.
…llvm#66826) When setting conditional breakpoints, we currently assume that a call to UserExpression::Parse() can be cached and resued multiple times. This may not be true for every user expression. Add a new method so subclasses of UserExpression can customize if they are parseable or not.
When setting conditional breakpoints, we currently assume that a call to UserExpression::Parse() can be cached and resued multiple times. This may not be true for every user expression. Add a new method so subclasses of UserExpression can customize if they are parseable or not.