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.

llvm-svn: 179649
This commit is contained in:
Sean Callanan 2013-04-16 23:25:35 +00:00
parent ec924c5232
commit 14b1bae5ee
9 changed files with 255 additions and 1090 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -501,7 +501,8 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
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));

View File

@ -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::PrepareToExecuteJITExpression (Stream &error_stream,
}
}
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::FinalizeJITExecution (Stream &error_stream,
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;

View File

@ -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 &error,
IRExecutionUnit::~IRExecutionUnit ()
{
m_module_ap.reset();
m_execution_engine_ap.reset();
m_context_ap.reset();
}
IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :

View File

@ -87,10 +87,8 @@ IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
{
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();

View File

@ -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 RegisterInfo &register_info, Error &err)
}
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::StackFrameSP &frame_sp, lldb::ClangExpressionVa
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::Dematerialize (Error &error, lldb::addr_t frame_to
{
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::Dematerialize (Error &error, lldb::addr_t frame_to
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;
}