[Lldb-commits] [lldb] 4c36312 - [lldb] Refactor PrepareToExecuteJITExpression (#224888)

via lldb-commits lldb-commits at lists.llvm.org
Mon Sep 21 18:53:03 PDT 2026


Author: Lang Hames
Date: 2026-09-22T11:52:57+10:00
New Revision: 4c36312084fea422bec96f1bdb599b38b144289d

URL: https://github.com/llvm/llvm-project/commit/4c36312084fea422bec96f1bdb599b38b144289d
DIFF: https://github.com/llvm/llvm-project/commit/4c36312084fea422bec96f1bdb599b38b144289d.diff

LOG: [lldb] Refactor PrepareToExecuteJITExpression (#224888)

Refactor the body of PrepareToExecuteJITExpression into two methods:
AllocateInterpreterStackFrame and AllocateAndMaterializeStruct.

This change is purely mechanical, but improves readability and sets up a
future refactor: AllocateAndMaterializeStruct is generic expression
setup and should remain where it is, but AllocateInterpreterStackFrame
is only needed on the interpreter path and can be sunk into that path in
a future commit.

---------

Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>

Added: 
    

Modified: 
    lldb/include/lldb/Expression/LLVMUserExpression.h
    lldb/source/Expression/LLVMUserExpression.cpp
    lldb/test/API/commands/expression/memory-allocation/TestMemoryAllocSettings.py

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Expression/LLVMUserExpression.h b/lldb/include/lldb/Expression/LLVMUserExpression.h
index 568765d9b3d01..c96cfa276be97 100644
--- a/lldb/include/lldb/Expression/LLVMUserExpression.h
+++ b/lldb/include/lldb/Expression/LLVMUserExpression.h
@@ -111,6 +111,23 @@ class LLVMUserExpression : public UserExpression {
                                        ///to the expression have been
                                        ///materialized.
   Materializer::DematerializerSP m_dematerializer_sp; ///< The dematerializer.
+
+private:
+  /// Allocate the interpreter's private, host-only stack, if one has not been
+  /// allocated already. Idempotent.
+  bool AllocateInterpreterStackFrame(DiagnosticManager &diagnostic_manager,
+                                     Target &target, Process *process);
+
+  /// Prepare the struct holding the expression arguments.
+  ///
+  /// Materialize expression arguments into the argument struct
+  /// (m_materialized_address).
+  ///
+  /// This method allocates the struct on first call, and reuses the original
+  /// allocation on subsequent calls.
+  bool PrepareArgumentStruct(DiagnosticManager &diagnostic_manager,
+                             lldb::StackFrameSP &frame,
+                             lldb::addr_t &struct_address);
 };
 
 } // namespace lldb_private

diff  --git a/lldb/source/Expression/LLVMUserExpression.cpp b/lldb/source/Expression/LLVMUserExpression.cpp
index eaecb3dbfe726..8c9a5fefc1703 100644
--- a/lldb/source/Expression/LLVMUserExpression.cpp
+++ b/lldb/source/Expression/LLVMUserExpression.cpp
@@ -319,67 +319,87 @@ bool LLVMUserExpression::PrepareToExecuteJITExpression(
     return false;
   }
 
-  if (m_jit_start_addr != LLDB_INVALID_ADDRESS || m_can_interpret) {
-    if (m_materialized_address == LLDB_INVALID_ADDRESS) {
-      IRMemoryMap::AllocationPolicy policy =
-          m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly
-                          : IRMemoryMap::eAllocationPolicyMirror;
-
-      const bool zero_memory = false;
-      if (auto address_or_error = m_execution_unit_sp->Malloc(
-              m_materializer_up->GetStructByteSize(),
-              m_materializer_up->GetStructAlignment(),
-              lldb::ePermissionsReadable | lldb::ePermissionsWritable, policy,
-              zero_memory)) {
-        m_materialized_address = *address_or_error;
-      } else {
-        diagnostic_manager.Printf(
-            lldb::eSeverityError,
-            "Couldn't allocate space for materialized struct: %s",
-            toString(address_or_error.takeError()).c_str());
-        return false;
-      }
-    }
+  // Early out if no JIT'd expr and can't interpret.
+  if (m_jit_start_addr == LLDB_INVALID_ADDRESS && !m_can_interpret)
+    return true;
 
-    struct_address = m_materialized_address;
+  if (!PrepareArgumentStruct(diagnostic_manager, frame, struct_address))
+    return false;
 
-    if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) {
-      size_t stack_frame_size = target->GetExprAllocSize();
-      if (stack_frame_size == 0) {
-        ABISP abi_sp;
-        if (process && (abi_sp = process->GetABI()))
-          stack_frame_size = abi_sp->GetStackFrameSize();
-        else
-          stack_frame_size = 512 * 1024;
-      }
+  if (m_can_interpret && !AllocateInterpreterStackFrame(diagnostic_manager,
+                                                        *target, process.get()))
+    return false;
 
-      const bool zero_memory = false;
-      if (auto address_or_error = m_execution_unit_sp->Malloc(
-              stack_frame_size, 8,
-              lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-              IRMemoryMap::eAllocationPolicyHostOnly, zero_memory)) {
-        m_stack_frame_bottom = *address_or_error;
-        m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
-      } else {
-        diagnostic_manager.Printf(
-            lldb::eSeverityError,
-            "Couldn't allocate space for the stack frame: %s",
-            toString(address_or_error.takeError()).c_str());
-        return false;
-      }
-    }
+  return true;
+}
 
-    Status materialize_error;
+bool LLVMUserExpression::AllocateInterpreterStackFrame(
+    DiagnosticManager &diagnostic_manager, Target &target, Process *process) {
+  if (m_stack_frame_bottom != LLDB_INVALID_ADDRESS)
+    return true;
+
+  size_t stack_frame_size = target.GetExprAllocSize();
+  if (stack_frame_size == 0) {
+    ABISP abi_sp;
+    if (process && (abi_sp = process->GetABI()))
+      stack_frame_size = abi_sp->GetStackFrameSize();
+    else
+      stack_frame_size = 512 * 1024;
+  }
 
-    m_dematerializer_sp = m_materializer_up->Materialize(
-        frame, *m_execution_unit_sp, struct_address, materialize_error);
+  const bool zero_memory = false;
+  if (auto address_or_error = m_execution_unit_sp->Malloc(
+          stack_frame_size, 8,
+          lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+          IRMemoryMap::eAllocationPolicyHostOnly, zero_memory)) {
+    m_stack_frame_bottom = *address_or_error;
+    m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
+    return true;
+  } else {
+    diagnostic_manager.Printf(lldb::eSeverityError,
+                              "Couldn't allocate space for the stack frame: %s",
+                              toString(address_or_error.takeError()).c_str());
+    return false;
+  }
+}
 
-    if (!materialize_error.Success()) {
-      diagnostic_manager.Printf(lldb::eSeverityError,
-                                "Couldn't materialize: %s",
-                                materialize_error.AsCString());
+bool LLVMUserExpression::PrepareArgumentStruct(
+    DiagnosticManager &diagnostic_manager, lldb::StackFrameSP &frame,
+    lldb::addr_t &struct_address) {
+
+  if (m_materialized_address == LLDB_INVALID_ADDRESS) {
+    IRMemoryMap::AllocationPolicy policy =
+        m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly
+                        : IRMemoryMap::eAllocationPolicyMirror;
+
+    const bool zero_memory = false;
+    if (auto address_or_error = m_execution_unit_sp->Malloc(
+            m_materializer_up->GetStructByteSize(),
+            m_materializer_up->GetStructAlignment(),
+            lldb::ePermissionsReadable | lldb::ePermissionsWritable, policy,
+            zero_memory)) {
+      m_materialized_address = *address_or_error;
+    } else {
+      diagnostic_manager.Printf(
+          lldb::eSeverityError,
+          "Couldn't allocate space for materialized struct: %s",
+          toString(address_or_error.takeError()).c_str());
       return false;
     }
   }
+
+  struct_address = m_materialized_address;
+
+  Status materialize_error;
+
+  m_dematerializer_sp = m_materializer_up->Materialize(
+      frame, *m_execution_unit_sp, struct_address, materialize_error);
+
+  if (!materialize_error.Success()) {
+    diagnostic_manager.Printf(lldb::eSeverityError, "Couldn't materialize: %s",
+                              materialize_error.AsCString());
+    return false;
+  }
+
   return true;
 }

diff  --git a/lldb/test/API/commands/expression/memory-allocation/TestMemoryAllocSettings.py b/lldb/test/API/commands/expression/memory-allocation/TestMemoryAllocSettings.py
index a82141a0792f2..e7fae4d4066f6 100644
--- a/lldb/test/API/commands/expression/memory-allocation/TestMemoryAllocSettings.py
+++ b/lldb/test/API/commands/expression/memory-allocation/TestMemoryAllocSettings.py
@@ -27,10 +27,17 @@ def test(self):
         with open(self.log_file, "r") as f:
             log = f.read()
 
+        # The materialized struct is allocated first, so it lands at
+        # expr-alloc-address.
         alloc0 = re.search("^.*IRMemoryMap::Malloc.+?0xdead0000.*$", log, re.MULTILINE)
-        # Malloc adds additional bytes to allocation size, hence 10007
+        # The interpreter's stack frame is allocated last. Materializing the
+        # struct allocates the persistent result variable in between, so the
+        # stack frame lands two expr-alloc-align boundaries along, at 0xdead2000.
+        # Its size comes from expr-alloc-size: Malloc rounds the request up to the
+        # requested alignment (8 here) and then adds alignment - 1 bytes, so
+        # 10000 becomes 10007.
         alloc1 = re.search(
-            r"^.*IRMemoryMap::Malloc\s*?\(10007.+?0xdead1000.*$", log, re.MULTILINE
+            r"^.*IRMemoryMap::Malloc\s*?\(10007.+?0xdead2000.*$", log, re.MULTILINE
         )
         self.assertTrue(alloc0, "Couldn't find an allocation at a given address.")
         self.assertTrue(


        


More information about the lldb-commits mailing list