Skip to content

Commit

Permalink
Avoid expression evaluation in libStdC++ std::vector<bool> synthetic …
Browse files Browse the repository at this point in the history
…children provider (#108414)

Our customers is reporting a serious performance issue (expanding a this
pointer takes 70 seconds in VSCode) in a specific execution context.

Profiling shows the hot path is triggered by an expression evaluation
from libStdC++ synthetic children provider for `std::vector<bool>` since
it uses `CreateValueFromExpression()`.

This PR added a new `SBValue::CreateBoolValue()` API and switch
`std::vector<bool>` synthetic children provider to use the new API
without performing expression evaluation.

Note: there might be other cases of `CreateValueFromExpression()` in our
summary/synthetic children providers which I will sweep through in later
PRs.

With this PR, the customer's scenario reduces from 70 seconds => 50
seconds. I will add other PRs to further optimize the remaining 50
seconds (mostly from type/namespace lookup).

Testing:

`test/API/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py`
passes with the PR

---------

Co-authored-by: jeffreytan81 <jeffreytan@fb.com>
  • Loading branch information
jeffreytan81 and jeffreytan81 committed Sep 13, 2024
1 parent 02d8813 commit b6bf27e
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 5 deletions.
6 changes: 1 addition & 5 deletions lldb/examples/synthetic/gnu_libstdcpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,11 +473,7 @@ def get_child_at_index(self, index):
"[" + str(index) + "]", element_offset, element_type
)
bit = element.GetValueAsUnsigned(0) & (1 << bit_offset)
if bit != 0:
value_expr = "(bool)true"
else:
value_expr = "(bool)false"
return self.valobj.CreateValueFromExpression("[%d]" % index, value_expr)
return self.valobj.CreateBoolValue("[%d]" % index, bool(bit))

def update(self):
try:
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/API/SBValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ class LLDB_API SBValue {
// AddressOf() on the return of this call all return invalid
lldb::SBValue CreateValueFromData(const char *name, lldb::SBData data,
lldb::SBType type);
// Returned value has no address.
lldb::SBValue CreateBoolValue(const char *name, bool value);

/// Get a child value by index from a value.
///
Expand Down
16 changes: 16 additions & 0 deletions lldb/source/API/SBValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,22 @@ lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data,
return sb_value;
}

lldb::SBValue SBValue::CreateBoolValue(const char *name, bool value) {
LLDB_INSTRUMENT_VA(this, name);

lldb::SBValue sb_value;
lldb::ValueObjectSP new_value_sp;
ValueLocker locker;
lldb::ValueObjectSP value_sp(GetSP(locker));
lldb::TargetSP target_sp = m_opaque_sp->GetTargetSP();
if (value_sp && target_sp) {
new_value_sp =
ValueObject::CreateValueObjectFromBool(target_sp, value, name);
}
sb_value.SetSP(new_value_sp);
return sb_value;
}

SBValue SBValue::GetChildAtIndex(uint32_t idx) {
LLDB_INSTRUMENT_VA(this, idx);

Expand Down

0 comments on commit b6bf27e

Please sign in to comment.