[Lldb-commits] [lldb] r179649 - Flipped the big switch: LLDB now uses the new

Sean Callanan scallanan at apple.com
Tue Apr 16 16:25:35 PDT 2013


Author: spyffe
Date: Tue Apr 16 18:25:35 2013
New Revision: 179649

URL: http://llvm.org/viewvc/llvm-project?rev=179649&view=rev
Log:
Flipped the big switch: LLDB now uses the new 
Materializer for all expressions that need to
run in the target.  This includes the following
changes:

- Removed a bunch of (de-)materialization code
  from ClangExpressionDeclMap and assumed the
  presence of a Materializer where we previously
  had a fallback.

- Ensured that an IRMemoryMap is passed into
  ClangExpressionDeclMap::Materialize().

- Fixed object ownership on LLVMContext; it is
  now owned by the IRExecutionUnit, since the
  Module and the ExecutionEngine both depend on
  its existence.

- Fixed a few bugs in IRMemoryMap and the
  Materializer that showed up during testing.

Modified:
    lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
    lldb/trunk/include/lldb/Expression/IRExecutionUnit.h
    lldb/trunk/include/lldb/Expression/Materializer.h
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/IRExecutionUnit.cpp
    lldb/trunk/source/Expression/IRMemoryMap.cpp
    lldb/trunk/source/Expression/Materializer.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Tue Apr 16 18:25:35 2013
@@ -27,6 +27,7 @@
 #include "lldb/Core/Value.h"
 #include "lldb/Expression/ClangASTSource.h"
 #include "lldb/Expression/ClangExpressionVariable.h"
+#include "lldb/Expression/Materializer.h"
 #include "lldb/Symbol/TaggedASTType.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Target/ExecutionContext.h"
@@ -541,7 +542,8 @@ public:
     ///     True on success; false otherwise.
     //------------------------------------------------------------------
     bool 
-    Materialize (lldb::addr_t &struct_address,
+    Materialize (IRMemoryMap &map,
+                 lldb::addr_t &struct_address,
                  Error &error);
     
     //------------------------------------------------------------------
@@ -618,6 +620,7 @@ public:
     //------------------------------------------------------------------
     bool 
     Dematerialize (lldb::ClangExpressionVariableSP &result_sp,
+                   IRMemoryMap &map,
                    lldb::addr_t stack_frame_top,
                    lldb::addr_t stack_frame_bottom,
                    Error &error);
@@ -782,6 +785,8 @@ private:
         {
         }
         
+        Materializer::DematerializerSP  m_dematerializer_sp;    ///< The dematerializer to use.
+        
         Process                    *m_process;                  ///< The process that the struct is materialized into.
         lldb::addr_t                m_allocated_area;           ///< The base of the memory allocated for the struct.  Starts on a potentially unaligned address and may therefore be larger than the struct.
         lldb::addr_t                m_materialized_location;    ///< The address at which the struct is placed.  Falls inside the allocated area.
@@ -1074,6 +1079,7 @@ private:
     //------------------------------------------------------------------
     bool 
     DoMaterialize (bool dematerialize,
+                   IRMemoryMap &map,
                    lldb::addr_t stack_frame_top,
                    lldb::addr_t stack_frame_bottom,
                    lldb::ClangExpressionVariableSP *result_sp_ptr,
@@ -1084,151 +1090,6 @@ private:
     //------------------------------------------------------------------
     void 
     DidDematerialize ();
-
-    //------------------------------------------------------------------
-    /// Actually do the task of materializing or dematerializing a persistent
-    /// variable.
-    ///
-    /// @param[in] dematerialize
-    ///     True if the variable is to be dematerialized; false if it is to
-    ///     be materialized.
-    ///
-    /// @param[in] var_sp
-    ///     The persistent variable to materialize
-    ///
-    /// @param[in] addr
-    ///     The address at which to materialize the variable.
-    ///
-    /// @param[in] stack_frame_top, stack_frame_bottom
-    ///     If not LLDB_INVALID_ADDRESS, the bounds for the stack frame
-    ///     in which the expression ran.  A result whose address falls
-    ///     inside this stack frame is dematerialized as a value
-    ///     requiring rematerialization.
-    ///
-    /// @param[in] err
-    ///     An Error to populate with any messages related to
-    ///     (de)materializing the persistent variable.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool 
-    DoMaterializeOnePersistentVariable (bool dematerialize,
-                                        lldb::ClangExpressionVariableSP &var_sp,
-                                        lldb::addr_t addr,
-                                        lldb::addr_t stack_frame_top,
-                                        lldb::addr_t stack_frame_bottom,
-                                        Error &err);
-    
-    //------------------------------------------------------------------
-    /// Create a temporary buffer in the target process to store the value
-    /// of a persistent variable that would otherwise not be accessible in
-    /// memory (e.g., register values or constants).
-    ///
-    /// @param[in] process
-    ///     The process to use when allocating the memory.
-    ///
-    /// @param[in] expr_var
-    ///     The variable whose live data will hold this buffer.
-    ///
-    /// @param[in] err
-    ///     An Error to populate with any messages related to
-    ///     allocating the memory.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool
-    CreateLiveMemoryForExpressionVariable (Process &process,
-                                           lldb::ClangExpressionVariableSP &expr_var,
-                                           Error &err);
-    
-    //------------------------------------------------------------------
-    /// Delete a temporary buffer created with
-    /// CreateLiveMemoryForExpressionVariable.
-    ///
-    /// @param[in] process
-    ///     The process to use when deallocating the memory.
-    ///
-    /// @param[in] expr_var
-    ///     The variable whose live data will hold this buffer.
-    ///
-    /// @param[in] err
-    ///     An Error to populate with any messages related to
-    ///     allocating the memory.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool
-    DeleteLiveMemoryForExpressionVariable (Process &process,
-                                           lldb::ClangExpressionVariableSP &expr_var,
-                                           Error &err);
-    
-    //------------------------------------------------------------------
-    /// Actually do the task of materializing or dematerializing a 
-    /// variable.
-    ///
-    /// @param[in] dematerialize
-    ///     True if the variable is to be dematerialized; false if it is to
-    ///     be materialized.
-    ///
-    /// @param[in] sym_ctx
-    ///     The symbol context to use (for looking the variable up).
-    ///
-    /// @param[in] expr_var
-    ///     The entity that the expression parser uses for the variable.
-    ///     In case the variable needs to be copied into the target's
-    ///     memory, this location is stored in the variable during
-    ///     materialization and cleared when it is demateralized.
-    ///
-    /// @param[in] addr
-    ///     The address at which to materialize the variable.
-    ///
-    /// @param[in] err
-    ///     An Error to populate with any messages related to
-    ///     (de)materializing the persistent variable.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool 
-    DoMaterializeOneVariable (bool dematerialize,
-                              const SymbolContext &sym_ctx,
-                              lldb::ClangExpressionVariableSP &expr_var,
-                              lldb::addr_t addr, 
-                              Error &err);
-    
-    //------------------------------------------------------------------
-    /// Actually do the task of materializing or dematerializing a 
-    /// register variable.
-    ///
-    /// @param[in] dematerialize
-    ///     True if the variable is to be dematerialized; false if it is to
-    ///     be materialized.
-    ///
-    /// @param[in] reg_ctx
-    ///     The register context to use.
-    ///
-    /// @param[in] reg_info
-    ///     The information for the register to read/write.
-    ///
-    /// @param[in] addr
-    ///     The address at which to materialize the variable.
-    ///
-    /// @param[in] err
-    ///     An Error to populate with any messages related to
-    ///     (de)materializing the persistent variable.
-    ///
-    /// @return
-    ///     True on success; false otherwise.
-    //------------------------------------------------------------------
-    bool 
-    DoMaterializeOneRegister (bool dematerialize,
-                              RegisterContext &reg_ctx,
-                              const RegisterInfo &reg_info,
-                              lldb::addr_t addr, 
-                              Error &err);
 };
     
 } // namespace lldb_private

Modified: lldb/trunk/include/lldb/Expression/IRExecutionUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRExecutionUnit.h?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRExecutionUnit.h (original)
+++ lldb/trunk/include/lldb/Expression/IRExecutionUnit.h Tue Apr 16 18:25:35 2013
@@ -64,7 +64,8 @@ public:
     //------------------------------------------------------------------
     /// Constructor
     //------------------------------------------------------------------
-    IRExecutionUnit (std::auto_ptr<llvm::Module> &module_ap,
+    IRExecutionUnit (std::auto_ptr<llvm::LLVMContext> &context_ap,
+                     std::auto_ptr<llvm::Module> &module_ap,
                      ConstString &name,
                      const lldb::TargetSP &target_sp,
                      std::vector<std::string> &cpu_features);
@@ -491,6 +492,7 @@ private:
     typedef std::vector<AllocationRecord>   RecordVector;
     RecordVector                            m_records;
 
+    std::auto_ptr<llvm::LLVMContext>        m_context_ap;
     std::auto_ptr<llvm::ExecutionEngine>    m_execution_engine_ap;
     std::auto_ptr<llvm::Module>             m_module_ap;            ///< Holder for the module until it's been handed off
     llvm::Module                           *m_module;               ///< Owned by the execution engine

Modified: lldb/trunk/include/lldb/Expression/Materializer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/Materializer.h?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/Materializer.h (original)
+++ lldb/trunk/include/lldb/Expression/Materializer.h Tue Apr 16 18:25:35 2013
@@ -25,13 +25,33 @@ class Materializer
 {
 public:
     Materializer ();
+    ~Materializer ();
     
     class Dematerializer
     {
     public:
-        void Dematerialize(Error &err,
-                           lldb::addr_t frame_top,
-                           lldb::addr_t frame_bottom);
+        Dematerializer () :
+            m_materializer(NULL),
+            m_map(NULL),
+            m_process_address(LLDB_INVALID_ADDRESS)
+        {
+        }
+        
+        ~Dematerializer ()
+        {
+            Wipe ();
+        }
+        
+        void Dematerialize (Error &err,
+                            lldb::addr_t frame_top,
+                            lldb::addr_t frame_bottom);
+        
+        void Wipe ();
+        
+        bool IsValid ()
+        {
+            return m_materializer && m_map && (m_process_address != LLDB_INVALID_ADDRESS);
+        }
     private:
         friend class Materializer;
 
@@ -39,20 +59,23 @@ public:
                         lldb::StackFrameSP &frame_sp,
                         IRMemoryMap &map,
                         lldb::addr_t process_address) :
-            m_materializer(materializer),
+            m_materializer(&materializer),
             m_frame_wp(frame_sp),
-            m_map(map),
+            m_map(&map),
             m_process_address(process_address)
         {
         }
         
-        Materializer       &m_materializer;
+        Materializer       *m_materializer;
         lldb::StackFrameWP  m_frame_wp;
-        IRMemoryMap        &m_map;
+        IRMemoryMap        *m_map;
         lldb::addr_t        m_process_address;
     };
     
-    Dematerializer Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
+    typedef std::shared_ptr<Dematerializer> DematerializerSP;
+    typedef std::weak_ptr<Dematerializer> DematerializerWP;
+    
+    DematerializerSP Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
     
     uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
     uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
@@ -88,6 +111,7 @@ public:
         virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
                                     lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) = 0;
         virtual void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) = 0;
+        virtual void Wipe (IRMemoryMap &map, lldb::addr_t process_address) = 0;
         
         uint32_t GetAlignment ()
         {
@@ -122,11 +146,11 @@ private:
     typedef std::unique_ptr<Entity> EntityUP;
     typedef std::vector<EntityUP>   EntityVector;
     
-    unsigned            m_result_index;
-    Mutex               m_needs_dematerialize;
-    EntityVector        m_entities;
-    uint32_t            m_current_offset;
-    uint32_t            m_struct_alignment;
+    unsigned                        m_result_index;
+    DematerializerWP                m_dematerializer_wp;
+    EntityVector                    m_entities;
+    uint32_t                        m_current_offset;
+    uint32_t                        m_struct_alignment;
 };
     
 }

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Apr 16 18:25:35 2013
@@ -629,44 +629,11 @@ ClangExpressionDeclMap::DoStructLayout (
     if (m_struct_vars->m_struct_laid_out)
         return true;
     
-    if (m_parser_vars->m_materializer)
-    {
-        m_struct_vars->m_struct_alignment = m_parser_vars->m_materializer->GetStructAlignment();
-        m_struct_vars->m_struct_size = m_parser_vars->m_materializer->GetStructByteSize();
-        m_struct_vars->m_struct_laid_out = true;
-        return true;
-    }
-    
-    off_t cursor = 0;
-    
-    m_struct_vars->m_struct_alignment = 0;
-    m_struct_vars->m_struct_size = 0;
-    
-    for (size_t member_index = 0, num_members = m_struct_members.GetSize();
-         member_index < num_members;
-         ++member_index)
-    {
-        ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index));
-        if (!member_sp)
-            return false;
-        
-        ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID());
-
-        if (!jit_vars)
-            return false;
-        
-        if (member_index == 0)
-            m_struct_vars->m_struct_alignment = jit_vars->m_alignment;
-        
-        if (cursor % jit_vars->m_alignment)
-            cursor += (jit_vars->m_alignment - (cursor % jit_vars->m_alignment));
-        
-        jit_vars->m_offset = cursor;
-        cursor += jit_vars->m_size;
-    }
-    
-    m_struct_vars->m_struct_size = cursor;
+    if (!m_parser_vars->m_materializer)
+        return false;
     
+    m_struct_vars->m_struct_alignment = m_parser_vars->m_materializer->GetStructAlignment();
+    m_struct_vars->m_struct_size = m_parser_vars->m_materializer->GetStructByteSize();
     m_struct_vars->m_struct_laid_out = true;
     return true;
 }
@@ -1315,6 +1282,7 @@ ClangExpressionDeclMap::GetSpecialValue
 bool 
 ClangExpressionDeclMap::Materialize 
 (
+    IRMemoryMap &map,
     lldb::addr_t &struct_address,
     Error &err
 )
@@ -1326,7 +1294,8 @@ ClangExpressionDeclMap::Materialize
     
     m_material_vars->m_process = m_parser_vars->m_exe_ctx.GetProcessPtr();
     
-    bool result = DoMaterialize(false /* dematerialize */, 
+    bool result = DoMaterialize(false /* dematerialize */,
+                                map,
                                 LLDB_INVALID_ADDRESS /* top of stack frame */, 
                                 LLDB_INVALID_ADDRESS /* bottom of stack frame */, 
                                 NULL, /* result SP */
@@ -1453,12 +1422,13 @@ bool
 ClangExpressionDeclMap::Dematerialize 
 (
     ClangExpressionVariableSP &result_sp,
+    IRMemoryMap &map,
     lldb::addr_t stack_frame_top,
     lldb::addr_t stack_frame_bottom,
     Error &err
 )
 {
-    return DoMaterialize(true, stack_frame_top, stack_frame_bottom, &result_sp, err);
+    return DoMaterialize(true, map, stack_frame_top, stack_frame_bottom, &result_sp, err);
     
     DidDematerialize();
 }
@@ -1567,6 +1537,7 @@ bool
 ClangExpressionDeclMap::DoMaterialize 
 (
     bool dematerialize,
+    IRMemoryMap &map,
     lldb::addr_t stack_frame_top,
     lldb::addr_t stack_frame_bottom,
     lldb::ClangExpressionVariableSP *result_sp_ptr,
@@ -1606,873 +1577,103 @@ ClangExpressionDeclMap::DoMaterialize
         return true;
     }
     
-    const SymbolContext &sym_ctx(frame->GetSymbolContext(lldb::eSymbolContextEverything));
-    
-    if (!dematerialize)
+    if (!m_parser_vars->m_materializer)
     {
-        Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
-        if (m_material_vars->m_materialized_location)
-        {
-            process->DeallocateMemory(m_material_vars->m_materialized_location);
-            m_material_vars->m_materialized_location = 0;
-        }
-        
-        if (log)
-            log->PutCString("Allocating memory for materialized argument struct");
+        err.SetErrorString("No materializer");
         
-        lldb::addr_t mem = process->AllocateMemory(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size, 
-                                                   lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-                                                   err);
-        
-        if (mem == LLDB_INVALID_ADDRESS)
-        {
-            err.SetErrorStringWithFormat("Couldn't allocate 0x%llx bytes for materialized argument struct",
-                                         (unsigned long long)(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size));
-            return false;
-        }
-            
-        m_material_vars->m_allocated_area = mem;
+        return false;
     }
     
-    m_material_vars->m_materialized_location = m_material_vars->m_allocated_area;
+    lldb::StackFrameSP frame_sp = frame->shared_from_this();
+    ClangExpressionVariableSP result_sp;
     
-    if (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment)
-        m_material_vars->m_materialized_location += (m_struct_vars->m_struct_alignment - (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment));
-    
-    for (uint64_t member_index = 0, num_members = m_struct_members.GetSize();
-         member_index < num_members;
-         ++member_index)
+    if (dematerialize)
     {
-        ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index));
+        Error dematerialize_error;
         
-        ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID());
+        bool ret = true;
         
-        if (!jit_vars)
-        {
-            err.SetErrorString("Variable being materialized doesn't have JIT state");
-            return false;
-        }
+        m_material_vars->m_dematerializer_sp->Dematerialize(dematerialize_error, stack_frame_top, stack_frame_bottom);
+        m_material_vars->m_dematerializer_sp.reset();
         
-        if (m_found_entities.ContainsVariable (member_sp))
+        if (!dematerialize_error.Success())
         {
-            if (!member_sp->GetValueObject())
-            {
-                err.SetErrorString("Variable being materialized doesn't have a frozen version");
-                return false;
-            }
-            
-            RegisterInfo *reg_info = member_sp->GetRegisterInfo ();
-            if (reg_info)
-            {
-                // This is a register variable
-                
-                RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext();
-                
-                if (!reg_ctx)
-                {
-                    err.SetErrorString("Couldn't get register context");
-                    return false;
-                }
-                    
-                if (!DoMaterializeOneRegister (dematerialize, 
-                                               *reg_ctx, 
-                                               *reg_info, 
-                                               m_material_vars->m_materialized_location + jit_vars->m_offset,
-                                               err))
-                    return false;
-            }
-            else
-            {                
-                if (!DoMaterializeOneVariable (dematerialize, 
-                                               sym_ctx,
-                                               member_sp,
-                                               m_material_vars->m_materialized_location + jit_vars->m_offset,
-                                               err))
-                    return false;
-            }
+            err.SetErrorStringWithFormat("Couldn't dematerialize: %s", dematerialize_error.AsCString());
+            ret = false;
         }
         else
         {
-            // No need to look for presistent variables if the name doesn't start 
-            // with with a '$' character...
-            if (member_sp->GetName().AsCString ("!")[0] == '$' && persistent_vars.ContainsVariable(member_sp))
-            {
-                
-                if (member_sp->GetName() == m_struct_vars->m_result_name)
-                {
-                    if (log)
-                        log->PutCString("Found result member in the struct");
-
-                    if (result_sp_ptr)
-                        *result_sp_ptr = member_sp;
-                    
-                }
-
-                if (!DoMaterializeOnePersistentVariable (dematerialize, 
-                                                         member_sp, 
-                                                         m_material_vars->m_materialized_location + jit_vars->m_offset,
-                                                         stack_frame_top,
-                                                         stack_frame_bottom,
-                                                         err))
-                    return false;
-            }
-            else
+            Error free_error;
+            map.Free(m_material_vars->m_materialized_location, free_error);
+            if (!free_error.Success())
             {
-                err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString());
-                return false;
+                err.SetErrorStringWithFormat("Couldn't free struct from materialization: %s", free_error.AsCString());
+                ret = false;
             }
         }
-    }
-    
-    return true;
-}
-
-bool
-ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
-(
-    bool dematerialize,
-    ClangExpressionVariableSP &var_sp,
-    lldb::addr_t addr,
-    lldb::addr_t stack_frame_top,
-    lldb::addr_t stack_frame_bottom,
-    Error &err
-)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
-    if (!var_sp)
-    {
-        err.SetErrorString("Invalid persistent variable");
-        return LLDB_INVALID_ADDRESS;
-    }
-    
-    const size_t pvar_byte_size = var_sp->GetByteSize();
-    
-    uint8_t *pvar_data = var_sp->GetValueBytes();
-    if (pvar_data == NULL)
-    {
-        err.SetErrorString("Persistent variable being materialized contains no data");
-        return false;
-    }
-    
-    Error error;
-    Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
-
-    lldb::addr_t mem; // The address of a spare memory area used to hold the persistent variable.
-    
-    if (dematerialize)
-    {
-        if (log)
-            log->Printf("Dematerializing persistent variable with flags 0x%hx", var_sp->m_flags);
         
-        if ((var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) ||
-            (var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference))
+        if (ret)
         {
-            // Get the location of the target out of the struct.
-            
-            Error read_error;
-            mem = process->ReadPointerFromMemory (addr, read_error);
-            
-            if (mem == LLDB_INVALID_ADDRESS)
-            {
-                err.SetErrorStringWithFormat("Couldn't read address of %s from struct: %s", var_sp->GetName().GetCString(), error.AsCString());
-                return false;
-            }
-            
-            if (var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference &&
-                !var_sp->m_live_sp)
-            {
-                // If the reference comes from the program, then the ClangExpressionVariable's
-                // live variable data hasn't been set up yet.  Do this now.
-                
-                var_sp->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
-                                                                    var_sp->GetTypeFromUser().GetASTContext(),
-                                                                    var_sp->GetTypeFromUser().GetOpaqueQualType(),
-                                                                    var_sp->GetName(),
-                                                                    mem,
-                                                                    eAddressTypeLoad,
-                                                                    pvar_byte_size);
-            }
-            
-            if (!var_sp->m_live_sp)
-            {
-                err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", var_sp->GetName().GetCString());
-                return false;
-            }
-            
-            if (var_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad)
-            {
-                err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", var_sp->GetName().GetCString());
-                return false;
-            }
-            
-            if (var_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry ||
-                var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
-            {
-                mem = var_sp->m_live_sp->GetValue().GetScalar().ULongLong();
-                
-                if (log)
-                    log->Printf("Dematerializing %s from 0x%" PRIx64 " (size = %u)", var_sp->GetName().GetCString(), (uint64_t)mem, (unsigned)pvar_byte_size);
-                
-                // Read the contents of the spare memory area
-                                
-                var_sp->ValueUpdated ();
-                if (process->ReadMemory (mem, pvar_data, pvar_byte_size, error) != pvar_byte_size)
-                {
-                    err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
-                    return false;
-                }
-                
-                if (stack_frame_top != LLDB_INVALID_ADDRESS &&
-                    stack_frame_bottom != LLDB_INVALID_ADDRESS &&
-                    mem >= stack_frame_bottom &&
-                    mem <= stack_frame_top)
-                {
-                    // If the variable is resident in the stack frame created by the expression,
-                    // then it cannot be relied upon to stay around.  We treat it as needing
-                    // reallocation.
-                    
-                    var_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
-                    var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
-                    var_sp->m_flags &= ~ClangExpressionVariable::EVIsProgramReference;
-                }
-                
-                var_sp->m_flags &= ~ClangExpressionVariable::EVNeedsFreezeDry;
-            }
-            
-            if (var_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation &&
-                !(var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget))
+            for (uint64_t member_index = 0, num_members = m_struct_members.GetSize();
+                 member_index < num_members;
+                 ++member_index)
             {
-                if (m_keep_result_in_memory)
-                {
-                    var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget;
-                }
-                else
+                ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index));
+
+                if (!m_found_entities.ContainsVariable (member_sp))
                 {
-                    Error deallocate_error = process->DeallocateMemory(mem);
-                    
-                    if (!err.Success())
+                    // No need to look for presistent variables if the name doesn't start
+                    // with with a '$' character...
+                    if (member_sp->GetName().AsCString ("!")[0] == '$' && persistent_vars.ContainsVariable(member_sp))
                     {
-                        err.SetErrorStringWithFormat ("Couldn't deallocate memory for %s: %s", var_sp->GetName().GetCString(), deallocate_error.AsCString());
-                        return false;
+                        if (member_sp->GetName() == m_struct_vars->m_result_name)
+                        {
+                            if (log)
+                                log->PutCString("Found result member in the struct");
+                            
+                            if (result_sp_ptr)
+                                *result_sp_ptr = member_sp;
+                            
+                            break;
+                        }
                     }
                 }
             }
         }
-        else
-        {
-            err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported.");
-            return false;
-        }
-    }
-    else 
-    {
-        if (log)
-            log->Printf("Materializing persistent variable with flags 0x%hx", var_sp->m_flags);
-        
-        if (var_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation)
-        {
-            // Allocate a spare memory area to store the persistent variable's contents.
-            
-            Error allocate_error;
-            
-            mem = process->AllocateMemory(pvar_byte_size, 
-                                          lldb::ePermissionsReadable | lldb::ePermissionsWritable, 
-                                          allocate_error);
-            
-            if (mem == LLDB_INVALID_ADDRESS)
-            {
-                err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", var_sp->GetName().GetCString(), allocate_error.AsCString());
-                return false;
-            }
-            
-            if (log)
-                log->Printf("Allocated %s (0x%" PRIx64 ") sucessfully", var_sp->GetName().GetCString(), mem);
-            
-            // Put the location of the spare memory into the live data of the ValueObject.
-            
-            var_sp->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
-                                                                var_sp->GetTypeFromUser().GetASTContext(),
-                                                                var_sp->GetTypeFromUser().GetOpaqueQualType(),
-                                                                var_sp->GetName(),
-                                                                mem,
-                                                                eAddressTypeLoad,
-                                                                pvar_byte_size);
-            
-            // Clear the flag if the variable will never be deallocated.
-            
-            if (var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
-                var_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation;
-            
-            // Write the contents of the variable to the area.
-            
-            if (process->WriteMemory (mem, pvar_data, pvar_byte_size, error) != pvar_byte_size)
-            {
-                err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
-                return false;
-            }
-        }
-        
-        if ((var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && var_sp->m_live_sp) ||
-            var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated)
-        {
-            // Now write the location of the area into the struct.
-            Error write_error;
-            if (!process->WriteScalarToMemory (addr, 
-                                               var_sp->m_live_sp->GetValue().GetScalar(), 
-                                               process->GetAddressByteSize(), 
-                                               write_error))
-            {
-                err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", var_sp->GetName().GetCString(), write_error.AsCString());
-                return false;
-            }
-            
-            if (log)
-                log->Printf("Materialized %s into 0x%llx", var_sp->GetName().GetCString(), var_sp->m_live_sp->GetValue().GetScalar().ULongLong());
-        }
-        else if (!(var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference))
-        {
-            err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported.");
-            return false;
-        }
-    }
-    
-    return true;
-}
-
-bool
-ClangExpressionDeclMap::CreateLiveMemoryForExpressionVariable
-(
-    Process &process,
-    ClangExpressionVariableSP &expr_var,
-    Error &err
-)
-{
-    Error allocate_error;
-    TypeFromUser type(expr_var->GetTypeFromUser());
-    const ConstString &name(expr_var->GetName());
-    
-    size_t value_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
-    size_t value_byte_size = value_bit_size % 8 ? ((value_bit_size + 8) / 8) : (value_bit_size / 8);
-
-    Scalar val_addr (process.AllocateMemory (value_byte_size,
-                                             lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-                                             allocate_error));
-    
-    if (val_addr.ULongLong() == LLDB_INVALID_ADDRESS)
-    {
-        err.SetErrorStringWithFormat ("Couldn't allocate a memory area to store %s: %s",
-                                      name.GetCString(),
-                                      allocate_error.AsCString());
-        return false;
-    }
-    
-    // Put the location of the spare memory into the live data of the ValueObject.
-    
-    expr_var->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
-                                                          type.GetASTContext(),
-                                                          type.GetOpaqueQualType(),
-                                                          name,
-                                                          val_addr.ULongLong(),
-                                                          eAddressTypeLoad,
-                                                          value_byte_size);
-    
-    return true;
-}
-
-bool
-ClangExpressionDeclMap::DeleteLiveMemoryForExpressionVariable
-(
-    Process &process,
-    ClangExpressionVariableSP &expr_var,
-    Error &err
-)
-{
-    const ConstString &name(expr_var->GetName());
-    
-    Scalar &val_addr = expr_var->m_live_sp->GetValue().GetScalar();
-    
-    Error deallocate_error = process.DeallocateMemory(val_addr.ULongLong());
-    
-    if (!deallocate_error.Success())
-    {
-        err.SetErrorStringWithFormat ("Couldn't deallocate spare memory area for %s: %s",
-                                      name.GetCString(),
-                                      deallocate_error.AsCString());
-        return false;
-    }
-    
-    expr_var->m_live_sp.reset();
-    
-    return true;
-}
-
-bool
-ClangExpressionDeclMap::DoMaterializeOneVariable
-(
-    bool dematerialize,
-    const SymbolContext &sym_ctx,
-    ClangExpressionVariableSP &expr_var,
-    lldb::addr_t addr,
-    Error &err
-)
-{
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
-    Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
-    StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
-    
-    ClangExpressionVariable::ParserVars *var_parser_vars = expr_var->GetParserVars(GetParserID());
-
-    if (!frame || !process || !target || !m_parser_vars.get() || !var_parser_vars)
-    {
-        err.SetErrorString("Necessary state for variable materialization isn't present");
-        return false;
-    }
-    
-    // Vital information about the value
-    
-    const ConstString &name(expr_var->GetName());
-    TypeFromUser type(expr_var->GetTypeFromUser());
-    
-    VariableSP &var(var_parser_vars->m_lldb_var);
-    const lldb_private::Symbol *symbol = var_parser_vars->m_lldb_sym;
-    
-    bool is_reference(expr_var->m_flags & ClangExpressionVariable::EVTypeIsReference);
-    
-    std::auto_ptr<lldb_private::Value> location_value;
-
-    if (var)
-    {
-        location_value.reset(GetVariableValue(var,
-                                              NULL));
-    }
-    else if (symbol)
-    {
-        addr_t location_load_addr = GetSymbolAddress(*target, process, name, lldb::eSymbolTypeAny);
-        
-        if (location_load_addr == LLDB_INVALID_ADDRESS)
-        {
-            if (log)
-                err.SetErrorStringWithFormat ("Couldn't find value for global symbol %s", 
-                                              name.GetCString());
-        }
         
-        location_value.reset(new Value);
-        
-        location_value->SetValueType(Value::eValueTypeLoadAddress);
-        location_value->GetScalar() = location_load_addr;
+        return ret;
     }
     else
     {
-        err.SetErrorStringWithFormat ("Couldn't find %s with appropriate type", 
-                                      name.GetCString());
-        return false;
-    }
-    
-    if (log)
-    {
-        StreamString my_stream_string;
+        Error malloc_error;
         
-        ClangASTType::DumpTypeDescription (type.GetASTContext(),
-                                           type.GetOpaqueQualType(),
-                                           &my_stream_string);
+        m_material_vars->m_allocated_area = LLDB_INVALID_ADDRESS;
+        m_material_vars->m_materialized_location = map.Malloc(m_parser_vars->m_materializer->GetStructByteSize(),
+                                                              m_parser_vars->m_materializer->GetStructAlignment(),
+                                                              lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                                              IRMemoryMap::eAllocationPolicyMirror,
+                                                              malloc_error);
         
-        log->Printf ("%s %s with type %s", 
-                     dematerialize ? "Dematerializing" : "Materializing", 
-                     name.GetCString(), 
-                     my_stream_string.GetString().c_str());
-    }
-    
-    if (!location_value.get())
-    {
-        err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
-        return false;
-    }
-
-    // The size of the type contained in addr
-    
-    size_t value_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
-    size_t value_byte_size = value_bit_size % 8 ? ((value_bit_size + 8) / 8) : (value_bit_size / 8);
-    
-    Value::ValueType value_type = location_value->GetValueType();
-    
-    switch (value_type)
-    {
-    default:
+        if (!malloc_error.Success())
         {
-            StreamString ss;
-            
-            location_value->Dump(&ss);
+            err.SetErrorStringWithFormat("Couldn't malloc struct for materialization: %s", malloc_error.AsCString());
             
-            err.SetErrorStringWithFormat ("%s has a value of unhandled type: %s", 
-                                          name.GetCString(), 
-                                          ss.GetString().c_str());
-            return false;
-        }
-        break;
-    case Value::eValueTypeHostAddress:
-        {
-            if (dematerialize)
-            {
-                if (!DeleteLiveMemoryForExpressionVariable(*process, expr_var, err))
-                    return false;
-            }
-            else
-            {                
-                DataExtractor value_data_extractor;
-                
-                if (location_value->GetData(value_data_extractor))
-                {
-                    if (value_byte_size != value_data_extractor.GetByteSize())
-                    {
-                        err.SetErrorStringWithFormat ("Size mismatch for %s: %" PRIu64 " versus %" PRIu64,
-                                                      name.GetCString(),
-                                                      (uint64_t)value_data_extractor.GetByteSize(),
-                                                      (uint64_t)value_byte_size);
-                        return false;
-                    }
-                    
-                    if (!CreateLiveMemoryForExpressionVariable(*process, expr_var, err))
-                        return false;
-                    
-                    Scalar &buf_addr = expr_var->m_live_sp->GetValue().GetScalar();
-
-                    Error write_error;
-                    
-                    if (!process->WriteMemory(buf_addr.ULongLong(),
-                                              value_data_extractor.GetDataStart(),
-                                              value_data_extractor.GetByteSize(),
-                                              write_error))
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s",
-                                                      name.GetCString(),
-                                                      write_error.AsCString());
-                        return false;
-                    }
-                    
-                    if (!process->WriteScalarToMemory(addr,
-                                                      buf_addr,
-                                                      process->GetAddressByteSize(),
-                                                      write_error))
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't write the address of %s to the target: %s",
-                                                      name.GetCString(),
-                                                      write_error.AsCString());
-                        return false;
-                    }
-                }
-                else
-                {
-                    err.SetErrorStringWithFormat ("%s is marked as a host address but doesn't contain any data",
-                                                  name.GetCString());
-                    return false;
-                }
-            }
-        }
-        break;
-    case Value::eValueTypeLoadAddress:
-        {
-            if (!dematerialize)
-            {
-                Error write_error;
-
-                if (is_reference)
-                {
-                    Error read_error;
-                    
-                    addr_t ref_value = process->ReadPointerFromMemory(location_value->GetScalar().ULongLong(), read_error);
-                    
-                    if (!read_error.Success())
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't read reference to %s from the target: %s",
-                                                      name.GetCString(),
-                                                      read_error.AsCString());
-                        return false;
-                    }
-                    
-                    if (!process->WritePointerToMemory(addr,
-                                                       ref_value,
-                                                       write_error))
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 
-                                                      name.GetCString(), 
-                                                      write_error.AsCString());
-                        return false;
-                    }
-                }
-                else
-                {
-                    if (!process->WriteScalarToMemory (addr, 
-                                                       location_value->GetScalar(), 
-                                                       process->GetAddressByteSize(), 
-                                                       write_error))
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 
-                                                      name.GetCString(), 
-                                                      write_error.AsCString());
-                        return false;
-                    }
-                }
-            }
-        }
-        break;
-    case Value::eValueTypeScalar:
-        {
-            if (location_value->GetContextType() == Value::eContextTypeRegisterInfo)
-            {
-                RegisterInfo *reg_info = location_value->GetRegisterInfo();
-                
-                if (!reg_info)
-                {
-                    err.SetErrorStringWithFormat ("Couldn't get the register information for %s", 
-                                                  name.GetCString());
-                    return false;
-                }
-                
-                RegisterValue reg_value;
-
-                RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext();
-                
-                if (!reg_ctx)
-                {
-                    err.SetErrorStringWithFormat ("Couldn't read register context to read %s from %s", 
-                                                  name.GetCString(), 
-                                                  reg_info->name);
-                    return false;
-                }
-                
-                uint32_t register_byte_size = reg_info->byte_size;
-                
-                if (dematerialize)
-                {
-                    if (is_reference)
-                        return true; // reference types don't need demateralizing
-                    
-                    // Get the location of the spare memory area out of the variable's live data.
-                    
-                    if (!expr_var->m_live_sp)
-                    {
-                        err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", name.GetCString());
-                        return false;
-                    }
-                    
-                    if (expr_var->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad)
-                    {
-                        err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", name.GetCString());
-                        return false;
-                    }
-                    
-                    Scalar &reg_addr = expr_var->m_live_sp->GetValue().GetScalar();
-                    
-                    err = reg_ctx->ReadRegisterValueFromMemory (reg_info, 
-                                                                reg_addr.ULongLong(), 
-                                                                value_byte_size, 
-                                                                reg_value);
-                    if (err.Fail())
-                        return false;
-
-                    if (!reg_ctx->WriteRegister (reg_info, reg_value))
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't write %s to register %s", 
-                                                      name.GetCString(), 
-                                                      reg_info->name);
-                        return false;
-                    }
-                    
-                    if (!DeleteLiveMemoryForExpressionVariable(*process, expr_var, err))
-                        return false;
-                }
-                else
-                {
-                    Error write_error;
-                    
-                    RegisterValue reg_value;
-                    
-                    if (!reg_ctx->ReadRegister (reg_info, reg_value))
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't read %s from %s", 
-                                                      name.GetCString(), 
-                                                      reg_info->name);
-                        return false;
-                    }
-
-                    if (is_reference)
-                    {
-                        write_error = reg_ctx->WriteRegisterValueToMemory(reg_info, 
-                                                                          addr,
-                                                                          process->GetAddressByteSize(), 
-                                                                          reg_value);
-                        
-                        if (!write_error.Success())
-                        {
-                            err.SetErrorStringWithFormat ("Couldn't write %s from register %s to the target: %s", 
-                                                          name.GetCString(),
-                                                          reg_info->name,
-                                                          write_error.AsCString());
-                            return false;
-                        }
-                        
-                        return true;
-                    }
-                    
-                    // Allocate a spare memory area to place the register's contents into.  This memory area will be pointed to by the slot in the
-                    // struct.
-                    
-                    if (!CreateLiveMemoryForExpressionVariable (*process, expr_var, err))
-                        return false;
-                    
-                    // Now write the location of the area into the struct.
-                    
-                    Scalar &reg_addr = expr_var->m_live_sp->GetValue().GetScalar();
-                    
-                    if (!process->WriteScalarToMemory (addr, 
-                                                      reg_addr, 
-                                                      process->GetAddressByteSize(), 
-                                                      write_error))
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 
-                                                      name.GetCString(), 
-                                                      write_error.AsCString());
-                        return false;
-                    }
-                    
-                    if (value_byte_size > register_byte_size)
-                    {
-                        err.SetErrorStringWithFormat ("%s is too big to store in %s", 
-                                                      name.GetCString(), 
-                                                      reg_info->name);
-                        return false;
-                    }
-
-                    if (!reg_ctx->ReadRegister (reg_info, reg_value))
-                    {
-                        err.SetErrorStringWithFormat ("Couldn't read %s from %s", 
-                                                      name.GetCString(), 
-                                                      reg_info->name);
-                        return false;
-                    }
-                    
-                    err = reg_ctx->WriteRegisterValueToMemory (reg_info, 
-                                                              reg_addr.ULongLong(), 
-                                                              value_byte_size, 
-                                                              reg_value);
-                    if (err.Fail())
-                        return false;
-                }
-            }
-            else
-            {
-                // The location_value is a scalar. We need to make space for it
-                // or delete the space we made previously.
-                if (dematerialize)
-                {
-                    if (!DeleteLiveMemoryForExpressionVariable(*process, expr_var, err))
-                        return false;
-                }
-                else
-                {
-                    DataExtractor value_data_extractor;
-
-                    if (location_value->GetData(value_data_extractor))
-                    {
-                        if (value_byte_size != value_data_extractor.GetByteSize())
-                        {
-                            err.SetErrorStringWithFormat ("Size mismatch for %s: %" PRIu64 " versus %" PRIu64,
-                                                          name.GetCString(),
-                                                          (uint64_t)value_data_extractor.GetByteSize(),
-                                                          (uint64_t)value_byte_size);
-                            return false;
-                        }
-
-                        if (!CreateLiveMemoryForExpressionVariable(*process, expr_var, err))
-                            return false;
-
-                        Scalar &buf_addr = expr_var->m_live_sp->GetValue().GetScalar();
-
-                        Error write_error;
-
-                        if (!process->WriteMemory(buf_addr.ULongLong(),
-                                                  value_data_extractor.GetDataStart(),
-                                                  value_data_extractor.GetByteSize(),
-                                                  write_error))
-                        {
-                            err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s",
-                                                          name.GetCString(),
-                                                          write_error.AsCString());
-                            return false;
-                        }
-
-                        if (!process->WriteScalarToMemory(addr,
-                                                          buf_addr,
-                                                          process->GetAddressByteSize(),
-                                                          write_error))
-                        {
-                            err.SetErrorStringWithFormat ("Couldn't write the address of %s to the target: %s",
-                                                          name.GetCString(),
-                                                          write_error.AsCString());
-                            return false;
-                        }
-                    }
-                    else
-                    {
-                        err.SetErrorStringWithFormat ("%s is marked as a scalar value but doesn't contain any data",
-                                                      name.GetCString());
-                        return false;
-                    }
-                }
-            }
-        }
-    }
-    
-    return true;
-}
-
-bool 
-ClangExpressionDeclMap::DoMaterializeOneRegister
-(
-    bool dematerialize,
-    RegisterContext &reg_ctx,
-    const RegisterInfo &reg_info,
-    lldb::addr_t addr, 
-    Error &err
-)
-{
-    uint32_t register_byte_size = reg_info.byte_size;
-    RegisterValue reg_value;
-    if (dematerialize)
-    {
-        Error read_error (reg_ctx.ReadRegisterValueFromMemory(&reg_info, addr, register_byte_size, reg_value));
-        if (read_error.Fail())
-        {
-            err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, read_error.AsCString());
             return false;
         }
         
-        if (!reg_ctx.WriteRegister (&reg_info, reg_value))
-        {
-            err.SetErrorStringWithFormat("Couldn't write register %s (dematerialize)", reg_info.name);
-            return false;
-        }
-    }
-    else
-    {
+        Error materialize_error;
         
-        if (!reg_ctx.ReadRegister(&reg_info, reg_value))
-        {
-            err.SetErrorStringWithFormat("Couldn't read %s (materialize)", reg_info.name);
-            return false;
-        }
+        m_material_vars->m_dematerializer_sp = m_parser_vars->m_materializer->Materialize(frame_sp, result_sp, map, m_material_vars->m_materialized_location, materialize_error);
         
-        Error write_error (reg_ctx.WriteRegisterValueToMemory(&reg_info, addr, register_byte_size, reg_value));
-        if (write_error.Fail())
+        if (!materialize_error.Success())
         {
-            err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", reg_info.name, write_error.AsCString());
+            err.SetErrorStringWithFormat("Couldn't materialize: %s", materialize_error.AsCString());
+            
             return false;
         }
+        
+        return true;
     }
-    
-    return true;
 }
 
 lldb::VariableSP

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Tue Apr 16 18:25:35 2013
@@ -501,7 +501,8 @@ ClangExpressionParser::PrepareForExecuti
             log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
     }
     
-    m_execution_unit.reset(new IRExecutionUnit(module_ap, // handed off here
+    m_execution_unit.reset(new IRExecutionUnit(m_llvm_context, // handed off here
+                                               module_ap, // handed off here
                                                function_name,
                                                exe_ctx.GetTargetSP(),
                                                m_compiler->getTargetOpts().Features));

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Tue Apr 16 18:25:35 2013
@@ -29,6 +29,7 @@
 #include "lldb/Expression/ClangFunction.h"
 #include "lldb/Expression/ClangUserExpression.h"
 #include "lldb/Expression/ExpressionSourceCode.h"
+#include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Expression/Materializer.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Symbol/Block.h"
@@ -551,7 +552,7 @@ ClangUserExpression::PrepareToExecuteJIT
             }
         }
                 
-        if (!m_expr_decl_map->Materialize(struct_address, materialize_error))
+        if (!m_expr_decl_map->Materialize(*m_execution_unit_ap, struct_address, materialize_error))
         {
             error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString());
             return false;
@@ -654,7 +655,7 @@ ClangUserExpression::FinalizeJITExecutio
     lldb::addr_t function_stack_bottom = function_stack_pointer - Host::GetPageSize();
     
         
-    if (!m_expr_decl_map->Dematerialize(result, function_stack_pointer, function_stack_bottom, expr_error))
+    if (!m_expr_decl_map->Dematerialize(result, *m_execution_unit_ap, function_stack_pointer, function_stack_bottom, expr_error))
     {
         error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
         return false;

Modified: lldb/trunk/source/Expression/IRExecutionUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRExecutionUnit.cpp?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRExecutionUnit.cpp (original)
+++ lldb/trunk/source/Expression/IRExecutionUnit.cpp Tue Apr 16 18:25:35 2013
@@ -25,11 +25,13 @@
 
 using namespace lldb_private;
 
-IRExecutionUnit::IRExecutionUnit (std::auto_ptr<llvm::Module> &module_ap,
+IRExecutionUnit::IRExecutionUnit (std::auto_ptr<llvm::LLVMContext> &context_ap,
+                                  std::auto_ptr<llvm::Module> &module_ap,
                                   ConstString &name,
                                   const lldb::TargetSP &target_sp,
                                   std::vector<std::string> &cpu_features) :
     IRMemoryMap(target_sp),
+    m_context_ap(context_ap),
     m_module_ap(module_ap),
     m_module(m_module_ap.get()),
     m_cpu_features(cpu_features),
@@ -400,6 +402,9 @@ IRExecutionUnit::GetRunnableInfo(Error &
 
 IRExecutionUnit::~IRExecutionUnit ()
 {
+    m_module_ap.reset();
+    m_execution_engine_ap.reset();
+    m_context_ap.reset();
 }
 
 IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :

Modified: lldb/trunk/source/Expression/IRMemoryMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRMemoryMap.cpp?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRMemoryMap.cpp (original)
+++ lldb/trunk/source/Expression/IRMemoryMap.cpp Tue Apr 16 18:25:35 2013
@@ -87,10 +87,8 @@ IRMemoryMap::FindAllocation (lldb::addr_
 {
     AllocationMap::iterator iter = m_allocations.lower_bound (addr);
     
-    if (iter == m_allocations.end())
-        return iter;
-    
-    if (iter->first > addr)
+    if (iter == m_allocations.end() ||
+        iter->first > addr)
     {
         if (iter == m_allocations.begin())
             return m_allocations.end();

Modified: lldb/trunk/source/Expression/Materializer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/Materializer.cpp?rev=179649&r1=179648&r2=179649&view=diff
==============================================================================
--- lldb/trunk/source/Expression/Materializer.cpp (original)
+++ lldb/trunk/source/Expression/Materializer.cpp Tue Apr 16 18:25:35 2013
@@ -67,10 +67,9 @@ public:
         Entity(),
         m_persistent_variable_sp(persistent_variable_sp)
     {
-        ClangASTType type(m_persistent_variable_sp->GetClangAST(),
-                          m_persistent_variable_sp->GetClangType());
-
-        SetSizeAndAlignmentFromType(type);
+        // Hard-coding to maximum size of a pointer since persistent variables are materialized by reference
+        m_size = 8;
+        m_alignment = 8;
     }
     
     void MakeAllocation (IRMemoryMap &map, Error &err)
@@ -143,7 +142,7 @@ public:
         }
     }
     
-    virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+    void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
@@ -180,14 +179,17 @@ public:
         }
         else
         {
+            // This is the result variable
+            /*
             err.SetErrorToGenericError();
             err.SetErrorStringWithFormat("No materialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString());
+            */
             return;
         }
     }
     
-    virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
-                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, lldb::addr_t process_address, Error &err)
+    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
+                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
@@ -208,10 +210,10 @@ public:
                 // If the reference comes from the program, then the ClangExpressionVariable's
                 // live variable data hasn't been set up yet.  Do this now.
                 
-                Scalar location_scalar;
+                lldb::addr_t location;
                 Error read_error;
                 
-                map.ReadScalarFromMemory(location_scalar, process_address + m_offset, map.GetAddressByteSize(), read_error);
+                map.ReadPointerFromMemory(&location, process_address + m_offset, read_error);
                                 
                 if (!read_error.Success())
                 {
@@ -219,9 +221,7 @@ public:
                     err.SetErrorStringWithFormat("Couldn't read the address of program-allocated variable %s: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString());
                     return;
                 }
-                
-                lldb::addr_t location = location_scalar.ULongLong();
-                
+                                
                 m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope (),
                                                                                       m_persistent_variable_sp->GetTypeFromUser().GetASTContext(),
                                                                                       m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(),
@@ -327,6 +327,8 @@ public:
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
                 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                
+                dump_stream.PutChar('\n');
             }
         }
         
@@ -356,6 +358,8 @@ public:
                     DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                     
                     extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, target_address);
+                    
+                    dump_stream.PutChar('\n');
                 }
             }
         }
@@ -363,7 +367,9 @@ public:
         log->PutCString(dump_stream.GetData());
     }
     
-    
+    void Wipe (IRMemoryMap &map, lldb::addr_t process_address)
+    {
+    }
 private:
     lldb::ClangExpressionVariableSP m_persistent_variable_sp;
 };
@@ -394,7 +400,7 @@ public:
         m_is_reference = ClangASTContext::IsReferenceType(m_variable_sp->GetType()->GetClangForwardType());
     }
     
-    virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+    void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
@@ -515,7 +521,7 @@ public:
         }
     }
     
-    virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
+    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
                                 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -607,10 +613,12 @@ public:
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
                 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                
+                dump_stream.PutChar('\n');
             }
         }
         
-        if (m_is_reference)
+        if (m_temporary_allocation == LLDB_INVALID_ADDRESS)
         {
             dump_stream.Printf("Points to process memory.\n");
         }
@@ -618,31 +626,40 @@ public:
         {
             dump_stream.Printf("Temporary allocation:\n");
             
-            if (m_temporary_allocation == LLDB_INVALID_ADDRESS)
+            DataBufferHeap data (m_temporary_allocation_size, 0);
+            
+            map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err);
+            
+            if (!err.Success())
             {
                 dump_stream.Printf("  <could not be read>\n");
             }
             else
             {
-                DataBufferHeap data (m_temporary_allocation_size, 0);
+                DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
-                map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err);
+                extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
                 
-                if (!err.Success())
-                {
-                    dump_stream.Printf("  <could not be read>\n");
-                }
-                else
-                {
-                    DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
-                    
-                    extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
-                }
+                dump_stream.PutChar('\n');
             }
         }
         
         log->PutCString(dump_stream.GetData());
     }
+    
+    void Wipe (IRMemoryMap &map, lldb::addr_t process_address)
+    {
+        if (m_temporary_allocation != LLDB_INVALID_ADDRESS)
+        {
+            Error free_error;
+            
+            map.Free(m_temporary_allocation, free_error);
+            
+            m_temporary_allocation = LLDB_INVALID_ADDRESS;
+            m_temporary_allocation_size = 0;
+        }
+
+    }
 private:
     lldb::VariableSP    m_variable_sp;
     bool                m_is_reference;
@@ -671,11 +688,11 @@ public:
         SetSizeAndAlignmentFromType(m_type);
     }
     
-    virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+    void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
     {
     }
     
-    virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
+    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
                                 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
     }
@@ -688,6 +705,10 @@ public:
         
         log->PutCString(dump_stream.GetData());
     }
+    
+    void Wipe (IRMemoryMap &map, lldb::addr_t process_address)
+    {
+    }
 private:
     ClangASTType    m_type;
     bool            m_keep_in_memory;
@@ -715,7 +736,7 @@ public:
         m_alignment = 8;
     }
     
-    virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+    void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
@@ -759,7 +780,7 @@ public:
         }
     }
     
-    virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
+    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
                                 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -798,11 +819,17 @@ public:
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
                 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                
+                dump_stream.PutChar('\n');
             }
         }
         
         log->PutCString(dump_stream.GetData());
     }
+    
+    void Wipe (IRMemoryMap &map, lldb::addr_t process_address)
+    {
+    }
 private:
     Symbol m_symbol;
 };
@@ -829,7 +856,7 @@ public:
         m_alignment = m_register_info.byte_size;
     }
     
-    virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
+    void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
         
@@ -886,7 +913,7 @@ public:
         }
     }
     
-    virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
+    void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
                                 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -954,11 +981,17 @@ public:
                 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize());
                 
                 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset);
+                
+                dump_stream.PutChar('\n');
             }
         }
         
         log->PutCString(dump_stream.GetData());
     }
+    
+    void Wipe (IRMemoryMap &map, lldb::addr_t process_address)
+    {
+    }
 private:
     RegisterInfo m_register_info;
 };
@@ -974,25 +1007,42 @@ Materializer::AddRegister (const Registe
 }
 
 Materializer::Materializer () :
-    m_needs_dematerialize(Mutex::eMutexTypeNormal),
+    m_dematerializer_wp(),
     m_current_offset(0),
     m_struct_alignment(8)
 {
 }
 
+Materializer::~Materializer ()
+{
+    DematerializerSP dematerializer_sp = m_dematerializer_wp.lock();
+    
+    if (dematerializer_sp)
+        dematerializer_sp->Wipe();
+}
 
-Materializer::Dematerializer
+Materializer::DematerializerSP
 Materializer::Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &error)
 {
     ExecutionContextScope *exe_scope = frame_sp.get();
-    
+        
     if (!exe_scope)
         exe_scope = map.GetBestExecutionContextScope();
     
+    DematerializerSP dematerializer_sp = m_dematerializer_wp.lock();
+    
+    if (dematerializer_sp)
+    {
+        error.SetErrorToGenericError();
+        error.SetErrorString("Couldn't materialize: already materialized");
+    }
+    
+    DematerializerSP ret(new Dematerializer(*this, frame_sp, map, process_address));
+    
     if (!exe_scope)
     {
         error.SetErrorToGenericError();
-        error.SetErrorString("Couldn't dematerialize: target doesn't exist");
+        error.SetErrorString("Couldn't materialize: target doesn't exist");
     }
     
     for (EntityUP &entity_up : m_entities)
@@ -1000,19 +1050,19 @@ Materializer::Materialize (lldb::StackFr
         entity_up->Materialize(frame_sp, map, process_address, error);
         
         if (!error.Success())
-            return Dematerializer (*this, frame_sp, map, LLDB_INVALID_ADDRESS);
+            return DematerializerSP();
     }
     
-    if (Log *log =lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
+    if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
     {
         log->Printf("Materializer::Materialize (frame_sp = %p, process_address = 0x%llx) materialized:", frame_sp.get(), process_address);
         for (EntityUP &entity_up : m_entities)
             entity_up->DumpToLog(map, process_address, log);
     }
-        
-    m_needs_dematerialize.Lock();
     
-    return Dematerializer (*this, frame_sp, map, process_address);
+    m_dematerializer_wp = ret;
+    
+    return ret;
 }
 
 void
@@ -1020,7 +1070,13 @@ Materializer::Dematerializer::Dematerial
 {
     lldb::StackFrameSP frame_sp = m_frame_wp.lock();
     
-    ExecutionContextScope *exe_scope = m_map.GetBestExecutionContextScope();
+    ExecutionContextScope *exe_scope = m_map->GetBestExecutionContextScope();
+    
+    if (!IsValid())
+    {
+        error.SetErrorToGenericError();
+        error.SetErrorString("Couldn't dematerialize: invalid dematerializer");
+    }
     
     if (!exe_scope)
     {
@@ -1032,18 +1088,34 @@ Materializer::Dematerializer::Dematerial
         if (Log *log =lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
         {
             log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address = 0x%llx) about to dematerialize:", frame_sp.get(), m_process_address);
-            for (EntityUP &entity_up : m_materializer.m_entities)
-                entity_up->DumpToLog(m_map, m_process_address, log);
+            for (EntityUP &entity_up : m_materializer->m_entities)
+                entity_up->DumpToLog(*m_map, m_process_address, log);
         }
         
-        for (EntityUP &entity_up : m_materializer.m_entities)
+        for (EntityUP &entity_up : m_materializer->m_entities)
         {
-            entity_up->Dematerialize (frame_sp, m_map, m_process_address, frame_top, frame_bottom, error);
+            entity_up->Dematerialize (frame_sp, *m_map, m_process_address, frame_top, frame_bottom, error);
             
             if (!error.Success())
                 break;
         }
     }
     
-    m_materializer.m_needs_dematerialize.Unlock();
+    Wipe();
+}
+
+void
+Materializer::Dematerializer::Wipe ()
+{
+    if (!IsValid())
+        return;
+    
+    for (EntityUP &entity_up : m_materializer->m_entities)
+    {
+        entity_up->Wipe (*m_map, m_process_address);
+    }
+
+    m_materializer = NULL;
+    m_map = NULL;
+    m_process_address = LLDB_INVALID_ADDRESS;
 }





More information about the lldb-commits mailing list