[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