[Lldb-commits] [lldb] Avoid expression evaluation in libStdC++ std::vector<bool> synthetic children provider (PR #108414)

via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 12 09:15:23 PDT 2024


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


More information about the lldb-commits mailing list