[Lldb-commits] [lldb] r179390 - Replicated the materialization logic for persistent

Sean Callanan scallanan at apple.com
Fri Apr 12 11:10:35 PDT 2013


Author: spyffe
Date: Fri Apr 12 13:10:34 2013
New Revision: 179390

URL: http://llvm.org/viewvc/llvm-project?rev=179390&view=rev
Log:
Replicated the materialization logic for persistent
variables in the Materializer.  We don't use this
code yet, but will soon once the other materializers
are online.

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

Modified: lldb/trunk/include/lldb/Expression/IRMemoryMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRMemoryMap.h?rev=179390&r1=179389&r2=179390&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRMemoryMap.h (original)
+++ lldb/trunk/include/lldb/Expression/IRMemoryMap.h Fri Apr 12 13:10:34 2013
@@ -38,6 +38,7 @@ class IRMemoryMap
 {
 public:
     IRMemoryMap (lldb::ProcessSP process_sp);
+    IRMemoryMap (lldb::TargetSP target_sp);
     ~IRMemoryMap ();
     
     enum AllocationPolicy {
@@ -53,8 +54,15 @@ public:
     void Free (lldb::addr_t process_address, Error &error);
     
     void WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error);
+    void WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error);
     void ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error);
+    void ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error);
     
+    lldb::ByteOrder GetByteOrder();
+    uint32_t GetAddressByteSize();
+    
+    ExecutionContextScope *GetBestExecutionContextScope();
+
 protected:
     lldb::ProcessWP GetProcessWP ()
     {
@@ -76,9 +84,10 @@ private:
     };
     
     lldb::ProcessWP                             m_process_wp;
+    lldb::TargetWP                              m_target_wp;
     typedef std::map<lldb::addr_t, Allocation>  AllocationMap;
     AllocationMap                               m_allocations;
-    
+        
     lldb::addr_t FindSpace (size_t size);
     bool ContainsHostOnlyAllocations ();
     AllocationMap::iterator FindAllocation (lldb::addr_t addr, size_t size);

Modified: lldb/trunk/include/lldb/Expression/Materializer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/Materializer.h?rev=179390&r1=179389&r2=179390&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/Materializer.h (original)
+++ lldb/trunk/include/lldb/Expression/Materializer.h Fri Apr 12 13:10:34 2013
@@ -29,7 +29,9 @@ public:
     class Dematerializer
     {
     public:
-        void Dematerialize(Error &err);
+        void Dematerialize(Error &err,
+                           lldb::addr_t frame_top,
+                           lldb::addr_t frame_bottom);
     private:
         friend class Materializer;
 
@@ -54,7 +56,7 @@ public:
     
     uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
     uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
-    uint32_t AddResultVariable (const ClangASTType &type, Error &err);
+    uint32_t AddResultVariable (const ClangASTType &type, bool keep_in_memory, Error &err);
     uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
     uint32_t AddRegister (const RegisterInfo &register_info, Error &err);
     
@@ -83,7 +85,8 @@ public:
         }
         
         virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
-        virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
+        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;
         
         uint32_t GetAlignment ()
         {
@@ -192,141 +195,6 @@ public:
 
     class Entity
     {
-    public:
-        Entity () :
-            m_alignment(1),
-            m_size(0),
-            m_offset(0)
-        {
-        }
-        
-        virtual ~Entity ()
-        {
-        }
-        
-        virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
-        virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
-        
-        uint32_t GetAlignment ()
-        {
-            return m_alignment;
-        }
-        
-        uint32_t GetSize ()
-        {
-            return m_size;
-        }
-        
-        uint32_t GetOffset ()
-        {
-            return m_offset;
-        }
-        
-        void SetOffset (uint32_t offset)
-        {
-            m_offset = offset;
-        }
-    protected:
-        void SetSizeAndAlignmentFromType (ClangASTType &type);
-        
-        uint32_t    m_alignment;
-        uint32_t    m_size;
-        uint32_t    m_offset;
-    };
-
-private:
-    uint32_t AddStructMember (Entity &entity);
-    
-    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;
-};
-    
-}
-
-#endif
-//===-- Materializer.h ------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_Materializer_h
-#define lldb_Materializer_h
-
-#include "lldb/lldb-private-types.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Expression/IRMemoryMap.h"
-#include "lldb/Host/Mutex.h"
-#include "lldb/Symbol/SymbolContext.h"
-
-#include <vector>
-
-namespace lldb_private
-{
-    
-class Materializer
-{
-public:
-    Materializer ();
-    
-    class Dematerializer
-    {
-    public:
-        void Dematerialize(Error &err);
-    private:
-        friend class Materializer;
-
-        Dematerializer (Materializer &materializer,
-                        lldb::StackFrameSP &frame_sp,
-                        IRMemoryMap &map,
-                        lldb::addr_t process_address) :
-            m_materializer(materializer),
-            m_frame_wp(frame_sp),
-            m_map(map),
-            m_process_address(process_address)
-        {
-        }
-        
-        Materializer       &m_materializer;
-        lldb::StackFrameWP  m_frame_wp;
-        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);
-    
-    uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
-    uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
-    uint32_t AddResultVariable (const ClangASTType &type, Error &err);
-    uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
-    uint32_t AddRegister (const RegisterInfo &register_info, Error &err);
-    
-    uint32_t GetStructAlignment ()
-    {
-        return m_struct_alignment;
-    }
-    
-    uint32_t GetStructSize ()
-    {
-        return m_current_offset;
-    }
-    
-    uint32_t GetNumEntities ()
-    {
-        return m_entities.size();
-    }
-
-    class Entity
-    {
     public:
         Entity () :
             m_alignment(1),

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=179390&r1=179389&r2=179390&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Apr 12 13:10:34 2013
@@ -510,6 +510,11 @@ ClangExpressionDeclMap::AddPersistentVar
         var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
     }
     
+    if (m_keep_result_in_memory)
+    {
+        var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget;
+    }
+    
     if (log)
         log->Printf("Created persistent variable with flags 0x%hx", var_sp->m_flags);
     
@@ -523,7 +528,7 @@ ClangExpressionDeclMap::AddPersistentVar
     if (m_parser_vars->m_materializer)
     {
         Error err;
-        m_parser_vars->m_materializer->AddResultVariable(user_type, err);
+        m_parser_vars->m_materializer->AddResultVariable(user_type, m_keep_result_in_memory, err);
     }
     
     return true;

Modified: lldb/trunk/source/Expression/IRMemoryMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRMemoryMap.cpp?rev=179390&r1=179389&r2=179390&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRMemoryMap.cpp (original)
+++ lldb/trunk/source/Expression/IRMemoryMap.cpp Fri Apr 12 13:10:34 2013
@@ -7,15 +7,26 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Scalar.h"
 #include "lldb/Expression/IRMemoryMap.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
 
 using namespace lldb_private;
 
 IRMemoryMap::IRMemoryMap (lldb::ProcessSP process_sp) :
-    m_process_wp(process_sp)
+    m_process_wp(process_sp),
+    m_target_wp(process_sp->GetTarget().shared_from_this())
+{
+}
+
+IRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) :
+    m_process_wp(),
+    m_target_wp(target_sp)
 {
 }
 
@@ -97,6 +108,54 @@ IRMemoryMap::FindAllocation (lldb::addr_
     return m_allocations.end();
 }
 
+lldb::ByteOrder
+IRMemoryMap::GetByteOrder()
+{
+    lldb::ProcessSP process_sp = m_process_wp.lock();
+    
+    if (process_sp)
+        return process_sp->GetByteOrder();
+    
+    lldb::TargetSP target_sp = m_target_wp.lock();
+    
+    if (target_sp)
+        return target_sp->GetDefaultArchitecture().GetByteOrder();
+    
+    return lldb::eByteOrderInvalid;
+}
+
+uint32_t
+IRMemoryMap::GetAddressByteSize()
+{
+    lldb::ProcessSP process_sp = m_process_wp.lock();
+    
+    if (process_sp)
+        return process_sp->GetAddressByteSize();
+    
+    lldb::TargetSP target_sp = m_target_wp.lock();
+    
+    if (target_sp)
+        return target_sp->GetDefaultArchitecture().GetAddressByteSize();
+    
+    return UINT32_MAX;
+}
+
+ExecutionContextScope *
+IRMemoryMap::GetBestExecutionContextScope()
+{
+    lldb::ProcessSP process_sp = m_process_wp.lock();
+    
+    if (process_sp)
+        return process_sp.get();
+    
+    lldb::TargetSP target_sp = m_target_wp.lock();
+    
+    if (target_sp)
+        return target_sp.get();
+    
+    return NULL;
+}
+
 lldb::addr_t
 IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
 {
@@ -336,6 +395,34 @@ IRMemoryMap::WriteMemory (lldb::addr_t p
 }
 
 void
+IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
+{    
+    if (size == UINT32_MAX)
+        size = scalar.GetByteSize();
+    
+    if (size > 0)
+    {
+        uint8_t buf[32];
+        const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
+        if (mem_size > 0)
+        {
+            return WriteMemory(process_address, buf, mem_size, error);
+        }
+        else
+        {
+            error.SetErrorToGenericError();
+            error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
+        }
+    }
+    else
+    {
+        error.SetErrorToGenericError();
+        error.SetErrorString ("Couldn't write scalar: its size was zero");
+    }
+    return;
+}
+
+void
 IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
 {
     AllocationMap::iterator iter = FindAllocation(process_address, size);
@@ -408,3 +495,39 @@ IRMemoryMap::ReadMemory (uint8_t *bytes,
                     (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
     }
 }
+
+void
+IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
+{ 
+    if (size > 0)
+    {
+        DataBufferHeap buf(size, 0);
+        ReadMemory(buf.GetBytes(), process_address, size, error);
+        
+        if (!error.Success())
+            return;
+        
+        DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
+        
+        lldb::offset_t offset = 0;
+        
+        switch (size)
+        {
+        default:
+            error.SetErrorToGenericError();
+            error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
+            return;
+        case 1: scalar = extractor.GetU8(&offset);  break;
+        case 2: scalar = extractor.GetU16(&offset); break;
+        case 4: scalar = extractor.GetU32(&offset); break;
+        case 8: scalar = extractor.GetU64(&offset); break;
+        }
+    }
+    else
+    {
+        error.SetErrorToGenericError();
+        error.SetErrorString ("Couldn't write scalar: its size was zero");
+    }
+    return;
+}
+

Modified: lldb/trunk/source/Expression/Materializer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/Materializer.cpp?rev=179390&r1=179389&r2=179390&view=diff
==============================================================================
--- lldb/trunk/source/Expression/Materializer.cpp (original)
+++ lldb/trunk/source/Expression/Materializer.cpp Fri Apr 12 13:10:34 2013
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "lldb/Core/Log.h"
+#include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Expression/ClangExpressionVariable.h"
 #include "lldb/Expression/Materializer.h"
 #include "lldb/Symbol/ClangASTContext.h"
@@ -67,12 +69,234 @@ public:
         SetSizeAndAlignmentFromType(type);
     }
     
+    void MakeAllocation (IRMemoryMap &map, Error &err)
+    {
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+        // Allocate a spare memory area to store the persistent variable's contents.
+        
+        Error allocate_error;
+        
+        lldb::addr_t mem = map.Malloc(m_persistent_variable_sp->GetByteSize(),
+                                      8,
+                                      lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                      IRMemoryMap::eAllocationPolicyMirror,
+                                      allocate_error);
+        
+        if (!allocate_error.Success())
+        {
+            err.SetErrorToGenericError();
+            err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", m_persistent_variable_sp->GetName().GetCString(), allocate_error.AsCString());
+            return;
+        }
+        
+        if (log)
+            log->Printf("Allocated %s (0x%" PRIx64 ") sucessfully", m_persistent_variable_sp->GetName().GetCString(), mem);
+        
+        // Put the location of the spare memory into the live data of the ValueObject.
+                
+        m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope(),
+                                                                              m_persistent_variable_sp->GetTypeFromUser().GetASTContext(),
+                                                                              m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(),
+                                                                              m_persistent_variable_sp->GetName(),
+                                                                              mem,
+                                                                              eAddressTypeLoad,
+                                                                              m_persistent_variable_sp->GetByteSize());
+        
+        // Clear the flag if the variable will never be deallocated.
+        
+        if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
+            m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation;
+        
+        // Write the contents of the variable to the area.
+        
+        Error write_error;
+        
+        map.WriteMemory (mem,
+                         m_persistent_variable_sp->GetValueBytes(),
+                         m_persistent_variable_sp->GetByteSize(),
+                         write_error);
+        
+        if (!write_error.Success())
+        {
+            err.SetErrorToGenericError();
+            err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", m_persistent_variable_sp->GetName().AsCString(),
+                                          write_error.AsCString());
+            return;
+        }
+    }
+    
+    void DestroyAllocation (IRMemoryMap &map, Error &err)
+    {
+        Error deallocate_error;
+        
+        map.Free((lldb::addr_t)m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong(), deallocate_error);
+            
+        if (!deallocate_error.Success())
+        {
+            err.SetErrorToGenericError();
+            err.SetErrorStringWithFormat ("Couldn't deallocate memory for %s: %s", m_persistent_variable_sp->GetName().GetCString(), deallocate_error.AsCString());
+        }
+    }
+    
     virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
     {
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+        if (log)
+        {
+            log->Printf("EntityPersistentVariable::Materialize [process_address = 0x%llx, m_name = %s, m_flags = 0x%hx]",
+                        (uint64_t)process_address,
+                        m_persistent_variable_sp->GetName().AsCString(),
+                        m_persistent_variable_sp->m_flags);
+        }
+        
+        if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation)
+        {
+            MakeAllocation(map, err);
+            if (!err.Success())
+                return;
+        }
+        
+        if ((m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && m_persistent_variable_sp->m_live_sp) ||
+            m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated)
+        {
+            Error write_error;
+            
+            map.WriteScalarToMemory(process_address + m_offset,
+                                    m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(),
+                                    m_persistent_variable_sp->m_live_sp->GetProcessSP()->GetAddressByteSize(),
+                                    write_error);
+            
+            if (!write_error.Success())
+            {
+                err.SetErrorToGenericError();
+                err.SetErrorStringWithFormat("Couldn't write the location of %s to memory: %s", m_persistent_variable_sp->GetName().AsCString(), write_error.AsCString());
+            }
+        }
+        else
+        {
+            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 process_address, Error &err)
+    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)
     {
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+        
+        if (log)
+        {
+            log->Printf("EntityPersistentVariable::Dematerialize [process_address = 0x%llx, m_name = %s, m_flags = 0x%hx]",
+                        (uint64_t)process_address,
+                        m_persistent_variable_sp->GetName().AsCString(),
+                        m_persistent_variable_sp->m_flags);
+        }
+        
+        if ((m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) ||
+            (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference))
+        {
+            if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference &&
+                !m_persistent_variable_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.
+                
+                Scalar location_scalar;
+                Error read_error;
+                
+                map.ReadScalarFromMemory(location_scalar, process_address + m_offset, map.GetAddressByteSize(), read_error);
+                                
+                if (!read_error.Success())
+                {
+                    err.SetErrorToGenericError();
+                    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(),
+                                                                                      m_persistent_variable_sp->GetName(),
+                                                                                      location,
+                                                                                      eAddressTypeLoad,
+                                                                                      m_persistent_variable_sp->GetByteSize());
+                
+                if (frame_top != LLDB_INVALID_ADDRESS &&
+                    frame_bottom != LLDB_INVALID_ADDRESS &&
+                    location >= frame_bottom &&
+                    location <= 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.
+                    m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
+                    m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
+                    m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
+                    m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVIsProgramReference;
+                }
+            }
+            
+            lldb::addr_t mem = m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong();
+            
+            if (!m_persistent_variable_sp->m_live_sp)
+            {
+                err.SetErrorToGenericError();
+                err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", m_persistent_variable_sp->GetName().GetCString());
+                return;
+            }
+            
+            if (m_persistent_variable_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad)
+            {
+                err.SetErrorToGenericError();
+                err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", m_persistent_variable_sp->GetName().GetCString());
+                return;
+            }
+            
+            if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry ||
+                m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
+            {                
+                if (log)
+                    log->Printf("Dematerializing %s from 0x%" PRIx64 " (size = %llu)", m_persistent_variable_sp->GetName().GetCString(), (uint64_t)mem, (unsigned long long)m_persistent_variable_sp->GetByteSize());
+                
+                // Read the contents of the spare memory area
+                
+                m_persistent_variable_sp->ValueUpdated ();
+                
+                Error read_error;
+                
+                map.ReadMemory(m_persistent_variable_sp->GetValueBytes(),
+                               mem,
+                               m_persistent_variable_sp->GetByteSize(),
+                               read_error);
+                
+                if (!read_error.Success())
+                {
+                    err.SetErrorStringWithFormat ("Couldn't read the contents of %s from memory: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString());
+                    return;
+                }
+                    
+                m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsFreezeDry;
+            }
+        }
+        else
+        {
+            err.SetErrorToGenericError();
+            err.SetErrorStringWithFormat("No dematerialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString());
+            return;
+        }
+        
+        if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation &&
+            !(m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget))
+        {
+            DestroyAllocation(map, err);
+            if (!err.Success())
+                return;
+        }
     }
 private:
     lldb::ClangExpressionVariableSP m_persistent_variable_sp;
@@ -104,7 +328,8 @@ public:
     {
     }
     
-    virtual void Dematerialize (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,
+                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
     }
 private:
@@ -124,9 +349,10 @@ Materializer::AddVariable (lldb::Variabl
 class EntityResultVariable : public Materializer::Entity
 {
 public:
-    EntityResultVariable (const ClangASTType &type) :
+    EntityResultVariable (const ClangASTType &type, bool keep_in_memory) :
         Entity(),
-        m_type(type)
+        m_type(type),
+        m_keep_in_memory(keep_in_memory)
     {
         SetSizeAndAlignmentFromType(m_type);
     }
@@ -135,18 +361,20 @@ public:
     {
     }
     
-    virtual void Dematerialize (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,
+                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
     }
 private:
-    ClangASTType m_type;
+    ClangASTType    m_type;
+    bool            m_keep_in_memory;
 };
 
 uint32_t
-Materializer::AddResultVariable (const ClangASTType &type, Error &err)
+Materializer::AddResultVariable (const ClangASTType &type, bool keep_in_memory, Error &err)
 {
     EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
-    iter->reset (new EntityResultVariable (type));
+    iter->reset (new EntityResultVariable (type, keep_in_memory));
     uint32_t ret = AddStructMember(**iter);
     (*iter)->SetOffset(ret);
     return ret;
@@ -168,7 +396,8 @@ public:
     {
     }
     
-    virtual void Dematerialize (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,
+                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
     }
 private:
@@ -201,7 +430,8 @@ public:
     {
     }
     
-    virtual void Dematerialize (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,
+                                lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
     {
     }
 private:
@@ -243,7 +473,7 @@ Materializer::Materialize (lldb::StackFr
 }
 
 void
-Materializer::Dematerializer::Dematerialize (Error &error)
+Materializer::Dematerializer::Dematerialize (Error &error, lldb::addr_t frame_top, lldb::addr_t frame_bottom)
 {
     lldb::StackFrameSP frame_sp = m_frame_wp.lock();
     
@@ -256,7 +486,7 @@ Materializer::Dematerializer::Dematerial
     {
         for (EntityUP &entity_up : m_materializer.m_entities)
         {
-            entity_up->Dematerialize (frame_sp, m_map, m_process_address, error);
+            entity_up->Dematerialize (frame_sp, m_map, m_process_address, frame_top, frame_bottom, error);
             
             if (!error.Success())
                 break;





More information about the lldb-commits mailing list