[Lldb-commits] [lldb] r180664 - Performance optimizations to ClangUserExpression,

Sean Callanan scallanan at apple.com
Fri Apr 26 19:19:33 PDT 2013


Author: spyffe
Date: Fri Apr 26 21:19:33 2013
New Revision: 180664

URL: http://llvm.org/viewvc/llvm-project?rev=180664&view=rev
Log:
Performance optimizations to ClangUserExpression,
mostly related to management of the stack frame
for the interpreter.

  - First, if the expression can be interpreted,
    allocate the stack frame in the target process
    (to make sure pointers are valid) but only
    read/write to the copy in the host's memory.

  - Second, keep the memory allocations for the
    stack frame and the materialized struct as
    member variables of ClangUserExpression.  This
    avoids memory allocations and deallocations
    each time the expression runs.

<rdar://problem/13043685>

Modified:
    lldb/trunk/include/lldb/Expression/ClangUserExpression.h
    lldb/trunk/include/lldb/Expression/IRInterpreter.h
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/IRInterpreter.cpp
    lldb/trunk/source/Expression/IRMemoryMap.cpp
    lldb/trunk/source/Expression/Materializer.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=180664&r1=180663&r2=180664&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Fri Apr 26 21:19:33 2013
@@ -200,7 +200,8 @@ public:
     FinalizeJITExecution (Stream &error_stream,
                           ExecutionContext &exe_ctx,
                           lldb::ClangExpressionVariableSP &result,
-                          lldb::addr_t function_stack_pointer = LLDB_INVALID_ADDRESS);
+                          lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS,
+                          lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS);
     
     //------------------------------------------------------------------
     /// Return the string that the parser should parse.  Must be a full
@@ -397,6 +398,8 @@ private:
     
     lldb::ProcessWP                             m_process_wp;           ///< The process used as the context for the expression.
     Address                                     m_address;              ///< The address the process is stopped in.
+    lldb::addr_t                                m_stack_frame_bottom;   ///< The bottom of the allocated stack frame.
+    lldb::addr_t                                m_stack_frame_top;      ///< The top of the allocated stack frame.
     
     std::string                                 m_expr_text;            ///< The text of the expression, as typed by the user
     std::string                                 m_expr_prefix;          ///< The text of the translation-level definitions, as provided by the user

Modified: lldb/trunk/include/lldb/Expression/IRInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRInterpreter.h?rev=180664&r1=180663&r2=180664&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRInterpreter.h (original)
+++ lldb/trunk/include/lldb/Expression/IRInterpreter.h Fri Apr 26 21:19:33 2013
@@ -51,8 +51,10 @@ public:
                llvm::Function &function,
                llvm::ArrayRef<lldb::addr_t> args,
                lldb_private::IRMemoryMap &memory_map,
-               lldb_private::Error &error);
-                  
+               lldb_private::Error &error,
+               lldb::addr_t stack_frame_bottom,
+               lldb::addr_t stack_frame_top);
+    
 private:   
     static bool
     supportsFunction (llvm::Function &llvm_function,

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=180664&r1=180663&r2=180664&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Fri Apr 26 21:19:33 2013
@@ -56,6 +56,8 @@ ClangUserExpression::ClangUserExpression
                                           lldb::LanguageType language,
                                           ResultType desired_type) :
     ClangExpression (),
+    m_stack_frame_bottom (LLDB_INVALID_ADDRESS),
+    m_stack_frame_top (LLDB_INVALID_ADDRESS),
     m_expr_text (expr),
     m_expr_prefix (expr_prefix ? expr_prefix : ""),
     m_language (language),
@@ -68,7 +70,8 @@ ClangUserExpression::ClangUserExpression
     m_needs_object_ptr (false),
     m_const_object (false),
     m_target (NULL),
-    m_can_interpret (false)
+    m_can_interpret (false),
+    m_materialized_address (LLDB_INVALID_ADDRESS)
 {
     switch (m_language)
     {
@@ -641,22 +644,48 @@ ClangUserExpression::PrepareToExecuteJIT
             }
         }
         
-        Error alloc_error;
-        
-        struct_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
-                                                     m_materializer_ap->GetStructAlignment(),
-                                                     lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-                                                     IRMemoryMap::eAllocationPolicyMirror,
-                                                     alloc_error);
-        
-        if (!alloc_error.Success())
+        if (m_materialized_address == LLDB_INVALID_ADDRESS)
         {
-            error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
-            return false;
+            Error alloc_error;
+            
+            IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror;
+            
+            m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(),
+                                                                 m_materializer_ap->GetStructAlignment(),
+                                                                 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                                                 policy,
+                                                                 alloc_error);
+            
+            if (!alloc_error.Success())
+            {
+                error_stream.Printf("Couldn't allocate space for materialized struct: %s\n", alloc_error.AsCString());
+                return false;
+            }
         }
         
-        m_materialized_address = struct_address;
+        struct_address = m_materialized_address;
         
+        if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS)
+        {
+            Error alloc_error;
+
+            const size_t stack_frame_size = 512 * 1024;
+            
+            m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size,
+                                                               8,
+                                                               lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                                               IRMemoryMap::eAllocationPolicyHostOnly,
+                                                               alloc_error);
+            
+            m_stack_frame_top = m_stack_frame_bottom + stack_frame_size;
+            
+            if (!alloc_error.Success())
+            {
+                error_stream.Printf("Couldn't allocate space for the stack frame: %s\n", alloc_error.AsCString());
+                return false;
+            }
+        }
+                
         Error materialize_error;
         
         m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error);
@@ -703,7 +732,8 @@ bool
 ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
                                            ExecutionContext &exe_ctx,
                                            lldb::ClangExpressionVariableSP &result,
-                                           lldb::addr_t function_stack_pointer)
+                                           lldb::addr_t function_stack_bottom,
+                                           lldb::addr_t function_stack_top)
 {
     Error expr_error;
     
@@ -711,9 +741,7 @@ ClangUserExpression::FinalizeJITExecutio
     
     if (log)
         log->Printf("-- [ClangUserExpression::FinalizeJITExecution] Dematerializing after execution --");
-    
-    lldb::addr_t function_stack_bottom = function_stack_pointer - Host::GetPageSize();
-    
+        
     if (!m_dematerializer_sp)
     {
         error_stream.Printf ("Couldn't dematerialize struct : no dematerializer is present");
@@ -722,7 +750,7 @@ ClangUserExpression::FinalizeJITExecutio
     
     Error dematerialize_error;
     
-    m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_pointer, function_stack_bottom);
+    m_dematerializer_sp->Dematerialize(dematerialize_error, result, function_stack_bottom, function_stack_top);
 
     if (!dematerialize_error.Success())
     {
@@ -765,7 +793,8 @@ ClangUserExpression::Execute (Stream &er
             return eExecutionSetupError;
         }
         
-        lldb::addr_t function_stack_pointer = 0;
+        lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS;
+        lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS;
         
         if (m_can_interpret)
         {            
@@ -792,11 +821,16 @@ ClangUserExpression::Execute (Stream &er
             
             args.push_back(struct_address);
             
+            function_stack_bottom = m_stack_frame_bottom;
+            function_stack_top = m_stack_frame_top;
+            
             IRInterpreter::Interpret (*module,
                                       *function,
                                       args,
                                       *m_execution_unit_ap.get(),
-                                      interpreter_error);
+                                      interpreter_error,
+                                      function_stack_bottom,
+                                      function_stack_top);
             
             if (!interpreter_error.Success())
             {
@@ -823,8 +857,11 @@ ClangUserExpression::Execute (Stream &er
             if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
                 return eExecutionSetupError;
             
-            function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
+            lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
 
+            function_stack_bottom = function_stack_pointer - Host::GetPageSize();
+            function_stack_top = function_stack_pointer;
+            
             if (log)
                 log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
             
@@ -876,8 +913,10 @@ ClangUserExpression::Execute (Stream &er
             }
         }
         
-        if  (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_pointer))
+        if  (FinalizeJITExecution (error_stream, exe_ctx, result, function_stack_bottom, function_stack_top))
+        {
             return eExecutionCompleted;
+        }
         else
         {
             error_stream.Printf("Errored out in %s: Couldn't FinalizeJITExpression", __FUNCTION__);

Modified: lldb/trunk/source/Expression/IRInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRInterpreter.cpp?rev=180664&r1=180663&r2=180664&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRInterpreter.cpp (original)
+++ lldb/trunk/source/Expression/IRInterpreter.cpp Fri Apr 26 21:19:33 2013
@@ -77,42 +77,22 @@ public:
     size_t                                  m_addr_byte_size;
     
     InterpreterStackFrame (DataLayout &target_data,
-                           lldb_private::IRMemoryMap &memory_map) :
+                           lldb_private::IRMemoryMap &memory_map,
+                           lldb::addr_t stack_frame_bottom,
+                           lldb::addr_t stack_frame_top) :
         m_target_data (target_data),
         m_memory_map (memory_map)
     {
         m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig);
         m_addr_byte_size = (target_data.getPointerSize(0));
-        
-        m_frame_size = 512 * 1024;
-        
-        lldb_private::Error alloc_error;
-        
-        m_frame_process_address = memory_map.Malloc(m_frame_size,
-                                                    m_addr_byte_size,
-                                                    lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-                                                    lldb_private::IRMemoryMap::eAllocationPolicyMirror,
-                                                    alloc_error);
-        
-        if (alloc_error.Success())
-        {
-            m_stack_pointer = m_frame_process_address + m_frame_size;
-        }
-        else
-        {
-            m_frame_process_address = LLDB_INVALID_ADDRESS;
-            m_stack_pointer = LLDB_INVALID_ADDRESS;
-        }    
+                        
+        m_frame_process_address = stack_frame_bottom;
+        m_frame_size = stack_frame_top - stack_frame_bottom;
+        m_stack_pointer = stack_frame_top;
     }
     
     ~InterpreterStackFrame ()
     {
-        if (m_frame_process_address != LLDB_INVALID_ADDRESS)
-        {
-            lldb_private::Error free_error;
-            m_memory_map.Free(m_frame_process_address, free_error);
-            m_frame_process_address = LLDB_INVALID_ADDRESS;
-        }
     }
     
     void Jump (const BasicBlock *bb)
@@ -535,7 +515,9 @@ IRInterpreter::Interpret (llvm::Module &
                           llvm::Function &function,
                           llvm::ArrayRef<lldb::addr_t> args,
                           lldb_private::IRMemoryMap &memory_map,
-                          lldb_private::Error &error)
+                          lldb_private::Error &error,
+                          lldb::addr_t stack_frame_bottom,
+                          lldb::addr_t stack_frame_top)
 {
     lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
@@ -553,7 +535,7 @@ IRInterpreter::Interpret (llvm::Module &
     
     DataLayout data_layout(&module);
     
-    InterpreterStackFrame frame(data_layout, memory_map);
+    InterpreterStackFrame frame(data_layout, memory_map, stack_frame_bottom, stack_frame_top);
     
     if (frame.m_frame_process_address == LLDB_INVALID_ADDRESS)
     {

Modified: lldb/trunk/source/Expression/IRMemoryMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRMemoryMap.cpp?rev=180664&r1=180663&r2=180664&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRMemoryMap.cpp (original)
+++ lldb/trunk/source/Expression/IRMemoryMap.cpp Fri Apr 26 21:19:33 2013
@@ -34,7 +34,8 @@ IRMemoryMap::~IRMemoryMap ()
         for (AllocationMap::value_type &allocation : m_allocations)
         {
             if (allocation.second.m_policy == eAllocationPolicyMirror ||
-                allocation.second.m_policy == eAllocationPolicyHostOnly)
+                allocation.second.m_policy == eAllocationPolicyProcessOnly ||
+                (allocation.second.m_policy == eAllocationPolicyHostOnly && process_sp->CanJIT()))
                 process_sp->DeallocateMemory(allocation.second.m_process_alloc);
             
             if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
@@ -55,6 +56,18 @@ IRMemoryMap::FindSpace (size_t size)
         
     lldb::addr_t ret = LLDB_INVALID_ADDRESS;
     
+    if (process_sp && process_sp->CanJIT())
+    {
+        Error alloc_error;
+        
+        ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
+        
+        if (!alloc_error.Success())
+            return LLDB_INVALID_ADDRESS;
+        else
+            return ret;
+    }
+    
     for (int iterations = 0; iterations < 16; ++iterations)
     {
         lldb::addr_t candidate;
@@ -367,12 +380,20 @@ IRMemoryMap::Free (lldb::addr_t process_
     {
     default:
     case eAllocationPolicyHostOnly:
-        break;
+        {
+            lldb::ProcessSP process_sp = m_process_wp.lock();
+            if (process_sp && process_sp->CanJIT())
+                process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
+
+            break;
+        }
     case eAllocationPolicyMirror:
     case eAllocationPolicyProcessOnly:
-        lldb::ProcessSP process_sp = m_process_wp.lock();
-        if (process_sp)
-            process_sp->DeallocateMemory(allocation.m_process_alloc);
+        {
+            lldb::ProcessSP process_sp = m_process_wp.lock();
+            if (process_sp)
+                process_sp->DeallocateMemory(allocation.m_process_alloc);
+        }
     }
     
     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))

Modified: lldb/trunk/source/Expression/Materializer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/Materializer.cpp?rev=180664&r1=180663&r2=180664&view=diff
==============================================================================
--- lldb/trunk/source/Expression/Materializer.cpp (original)
+++ lldb/trunk/source/Expression/Materializer.cpp Fri Apr 26 21:19:33 2013
@@ -822,7 +822,7 @@ public:
         
         lldb::ProcessSP process_sp = map.GetBestExecutionContextScope()->CalculateProcess();
         
-        bool can_persist = (process_sp && process_sp->CanJIT());
+        bool can_persist = (m_is_program_reference && process_sp && process_sp->CanJIT() && !(address >= frame_bottom && address < frame_top));
 
         if (can_persist && m_keep_in_memory)
         {
@@ -1316,7 +1316,7 @@ Materializer::Materialize (lldb::StackFr
 }
 
 void
-Materializer::Dematerializer::Dematerialize (Error &error, lldb::ClangExpressionVariableSP &result_sp, lldb::addr_t frame_top, lldb::addr_t frame_bottom)
+Materializer::Dematerializer::Dematerialize (Error &error, lldb::ClangExpressionVariableSP &result_sp, lldb::addr_t frame_bottom, lldb::addr_t frame_top)
 {
     lldb::StackFrameSP frame_sp = m_frame_wp.lock();
     





More information about the lldb-commits mailing list