llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-lldb Author: None (jeffreytan81) <details> <summary>Changes</summary> 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). --- Full diff: https://github.com/llvm/llvm-project/pull/108414.diff 3 Files Affected: - (modified) lldb/examples/synthetic/gnu_libstdcpp.py (+1-5) - (modified) lldb/include/lldb/API/SBValue.h (+2) - (modified) lldb/source/API/SBValue.cpp (+27) ``````````diff diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py index d98495b8a9df38..597298dfce36b4 100644 --- a/lldb/examples/synthetic/gnu_libstdcpp.py +++ b/lldb/examples/synthetic/gnu_libstdcpp.py @@ -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.CreateBooleanValue("[%d]" % index, bool(bit)) def update(self): try: diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index bec816fb451844..aeda26cb6dd795 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -146,6 +146,8 @@ class LLDB_API SBValue { lldb::SBValue CreateValueFromData(const char *name, lldb::SBData data, lldb::SBType type); + lldb::SBValue CreateBoolValue(const char *name, bool value); + /// Get a child value by index from a value. /// /// Structs, unions, classes, arrays and pointers have child diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 273aac5ad47989..eb54213f4e60bc 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -645,6 +645,33 @@ 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)); + ProcessSP process_sp = m_opaque_sp->GetProcessSP(); + lldb::SBTarget target = GetTarget(); + if (!target.IsValid()) + return sb_value; + lldb::SBType boolean_type = target.GetBasicType(lldb::eBasicTypeBool); + lldb::TypeImplSP type_impl_sp(boolean_type.GetSP()); + if (value_sp && process_sp && type_impl_sp) { + int data_buf[1] = {value ? 1 : 0}; + lldb::SBData data = lldb::SBData::CreateDataFromSInt32Array( + process_sp->GetByteOrder(), sizeof(data_buf[0]), data_buf, + sizeof(data_buf) / sizeof(data_buf[0])); + ExecutionContext exe_ctx(value_sp->GetExecutionContextRef()); + new_value_sp = ValueObject::CreateValueObjectFromData( + name, **data, exe_ctx, type_impl_sp->GetCompilerType(true)); + new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad); + } + sb_value.SetSP(new_value_sp); + return sb_value; +} + SBValue SBValue::GetChildAtIndex(uint32_t idx) { LLDB_INSTRUMENT_VA(this, idx); `````````` </details> https://github.com/llvm/llvm-project/pull/108414 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits