[Lldb-commits] [lldb] r177364 - Refactored the expression parser so that the IR

Sean Callanan scallanan at apple.com
Mon Mar 18 17:10:07 PDT 2013


Author: spyffe
Date: Mon Mar 18 19:10:07 2013
New Revision: 177364

URL: http://llvm.org/viewvc/llvm-project?rev=177364&view=rev
Log:
Refactored the expression parser so that the IR
and the JITted code are managed by a standalone
class that handles memory management itself.

I have removed RecordingMemoryManager and
ProcessDataAllocator, which filled similar roles
and had confusing ownership, with a common class
called IRExecutionUnit.  The IRExecutionUnit
manages all allocations ever made for an expression
and frees them when it goes away.  It also contains
the code generator and can vend the Module for an
expression to other clases.

The end goal here is to make the output of the
expression parser re-usable; that is, to avoid
re-parsing when re-parsing isn't necessary.

I've also cleaned up some code and used weak pointers
in more places.  Please let me know if you see any
leaks; I checked myself as well but I might have
missed a case.

Added:
    lldb/trunk/include/lldb/Expression/IRExecutionUnit.h
      - copied, changed from r176918, lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h
    lldb/trunk/source/Expression/IRExecutionUnit.cpp
      - copied, changed from r176918, lldb/trunk/source/Expression/RecordingMemoryManager.cpp
Removed:
    lldb/trunk/include/lldb/Expression/ProcessDataAllocator.h
    lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h
    lldb/trunk/source/Expression/ProcessDataAllocator.cpp
    lldb/trunk/source/Expression/RecordingMemoryManager.cpp
Modified:
    lldb/trunk/include/lldb/Expression/ClangExpression.h
    lldb/trunk/include/lldb/Expression/ClangExpressionParser.h
    lldb/trunk/include/lldb/Expression/ClangUserExpression.h
    lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h
    lldb/trunk/include/lldb/Expression/IRForTarget.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Expression/ClangFunction.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Expression/ClangUtilityFunction.cpp
    lldb/trunk/source/Expression/IRForTarget.cpp

Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpression.h?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpression.h Mon Mar 18 19:10:07 2013
@@ -48,7 +48,6 @@ public:
     
     ClangExpression () :
         m_jit_process_wp(),
-        m_jit_alloc (LLDB_INVALID_ADDRESS),
         m_jit_start_addr (LLDB_INVALID_ADDRESS),
         m_jit_end_addr (LLDB_INVALID_ADDRESS)
     {
@@ -59,7 +58,6 @@ public:
     //------------------------------------------------------------------
     virtual ~ClangExpression ()
     {
-        DeallocateJITFunction ();
     }
     
     //------------------------------------------------------------------
@@ -140,20 +138,6 @@ public:
     virtual bool
     NeedsVariableResolution () = 0;
 
-    void
-    DeallocateJITFunction ()
-    {
-        lldb::ProcessSP jit_process_sp(m_jit_process_wp.lock());
-        if (jit_process_sp && m_jit_alloc != LLDB_INVALID_ADDRESS)
-        {
-            jit_process_sp->DeallocateMemory (m_jit_alloc);
-            // If this process is ever used for anything else, we can not clear it 
-            // here. For now it is only used in order to deallocate any code if
-            // m_jit_alloc is a valid address.
-            m_jit_alloc = LLDB_INVALID_ADDRESS;
-        }
-    }
-
     //------------------------------------------------------------------
     /// Return the address of the function's JIT-compiled code, or
     /// LLDB_INVALID_ADDRESS if the function is not JIT compiled
@@ -167,7 +151,6 @@ public:
 protected:
 
     lldb::ProcessWP m_jit_process_wp;
-    lldb::addr_t    m_jit_alloc;            ///< The address of the block containing JITted code.  LLDB_INVALID_ADDRESS if invalid.
     lldb::addr_t    m_jit_start_addr;       ///< The address of the JITted function within the JIT allocation.  LLDB_INVALID_ADDRESS if invalid.
     lldb::addr_t    m_jit_end_addr;         ///< The address of the JITted function within the JIT allocation.  LLDB_INVALID_ADDRESS if invalid.
 

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionParser.h?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionParser.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionParser.h Mon Mar 18 19:10:07 2013
@@ -22,7 +22,7 @@
 namespace lldb_private
 {
 
-class RecordingMemoryManager;
+class IRExecutionUnit;
     
 //----------------------------------------------------------------------
 /// @class ClangExpressionParser ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h"
@@ -76,10 +76,6 @@ public:
     /// Ready an already-parsed expression for execution, possibly
     /// evaluating it statically.
     ///
-    /// @param[out] func_allocation_addr
-    ///     The address which can be used to deallocate the code for this
-    ///     JIT'ed function
-    ///
     /// @param[out] func_addr
     ///     The address to which the function has been written.
     ///
@@ -91,9 +87,6 @@ public:
     /// @param[in] exe_ctx
     ///     The execution context to write the function into.
     ///
-    /// @param[in] data_allocator
-    ///     If non-NULL, the static data allocator to use for literal strings.
-    ///
     /// @param[out] evaluated_statically
     ///     Set to true if the expression could be interpreted statically;
     ///     untouched otherwise.
@@ -113,11 +106,9 @@ public:
     ///     Test with Success().
     //------------------------------------------------------------------
     Error
-    PrepareForExecution (lldb::addr_t &func_allocation_addr, 
-                         lldb::addr_t &func_addr,
+    PrepareForExecution (lldb::addr_t &func_addr,
                          lldb::addr_t &func_end,
                          ExecutionContext &exe_ctx,
-                         IRForTarget::StaticDataAllocator *data_allocator,
                          bool &evaluated_statically,
                          lldb::ClangExpressionVariableSP &const_result,
                          lldb_private::ExecutionPolicy execution_policy);
@@ -137,49 +128,9 @@ public:
     //------------------------------------------------------------------
     Error
     DisassembleFunction (Stream &stream, 
-                         ExecutionContext &exe_ctx,
-                         RecordingMemoryManager *jit_memory_manager);
+                         ExecutionContext &exe_ctx);
     
 private:
-    //----------------------------------------------------------------------
-    /// @class JittedFunction ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h"
-    /// @brief Encapsulates a single function that has been generated by the JIT.
-    ///
-    /// Functions that have been generated by the JIT are first resident in the
-    /// local process, and then placed in the target process.  JittedFunction
-    /// represents a function possibly resident in both.
-    //----------------------------------------------------------------------
-    struct JittedFunction {
-        std::string m_name;             ///< The function's name
-        lldb::addr_t m_local_addr;      ///< The address of the function in LLDB's memory
-        lldb::addr_t m_remote_addr;     ///< The address of the function in the target's memory
-        
-        //------------------------------------------------------------------
-        /// Constructor
-        ///
-        /// Initializes class variabes.
-        ///
-        /// @param[in] name
-        ///     The name of the function.
-        ///
-        /// @param[in] local_addr
-        ///     The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
-        ///     it is not present in LLDB's memory.
-        ///
-        /// @param[in] remote_addr
-        ///     The address of the function in the target, or LLDB_INVALID_ADDRESS
-        ///     if it is not present in the target's memory.
-        //------------------------------------------------------------------
-        JittedFunction (const char *name,
-                        lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
-                        lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
-            m_name (name),
-            m_local_addr (local_addr),
-            m_remote_addr (remote_addr)
-        {
-        }
-    };
-    
     ClangExpression                            &m_expr;                 ///< The expression to be parsed
     
     std::auto_ptr<llvm::LLVMContext>            m_llvm_context;         ///< The LLVM context to generate IR into
@@ -188,8 +139,8 @@ private:
     std::auto_ptr<clang::Builtin::Context>      m_builtin_context;      ///< Context for Clang built-ins
     std::auto_ptr<clang::SelectorTable>         m_selector_table;       ///< Selector table for Objective-C methods
     std::auto_ptr<clang::ASTContext>            m_ast_context;          ///< The AST context used to hold types and names for the parser
-    std::auto_ptr<clang::CodeGenerator>         m_code_generator;       ///< [owned by the Execution Engine] The Clang object that generates IR
-    std::vector<JittedFunction>                 m_jitted_functions;     ///< A vector of all functions that have been JITted into machine code (just one, if ParseExpression() was called)
+    std::auto_ptr<clang::CodeGenerator>         m_code_generator;       ///< The Clang object that generates IR
+    std::auto_ptr<IRExecutionUnit>              m_execution_unit;       ///< The container for the finished Module
 };
     
 }

Modified: lldb/trunk/include/lldb/Expression/ClangUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Mon Mar 18 19:10:07 2013
@@ -26,7 +26,6 @@
 #include "lldb/Expression/ClangExpression.h"
 #include "lldb/Expression/ClangExpressionVariable.h"
 #include "lldb/Expression/IRForTarget.h"
-#include "lldb/Expression/ProcessDataAllocator.h"
 #include "lldb/Symbol/TaggedASTType.h"
 #include "lldb/Target/ExecutionContext.h"
 
@@ -433,7 +432,6 @@ private:
     
     std::auto_ptr<ClangExpressionDeclMap>       m_expr_decl_map;        ///< The map to use when parsing and materializing the expression.
     std::auto_ptr<ClangExpressionVariableList>  m_local_variables;      ///< The local expression variables, if the expression is DWARF.
-    std::auto_ptr<ProcessDataAllocator>         m_data_allocator;       ///< The allocator that the parser uses to place strings for use by JIT-compiled code.
     
     std::auto_ptr<ASTResultSynthesizer>         m_result_synthesizer;   ///< The result synthesizer, if one is needed.
     

Modified: lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUtilityFunction.h Mon Mar 18 19:10:07 2013
@@ -24,7 +24,6 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ProcessDataAllocator.h"
 
 namespace lldb_private 
 {
@@ -170,7 +169,6 @@ public:
     
 private:
     std::auto_ptr<ClangExpressionDeclMap>   m_expr_decl_map;    ///< The map to use when parsing and materializing the expression.
-    std::auto_ptr<ProcessDataAllocator>     m_data_allocator;   ///< The allocator for static data used in the expression.
     
     std::string                             m_function_text;    ///< The text of the function.  Must be a well-formed translation unit.
     std::string                             m_function_name;    ///< The name of the function.

Copied: lldb/trunk/include/lldb/Expression/IRExecutionUnit.h (from r176918, lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRExecutionUnit.h?p2=lldb/trunk/include/lldb/Expression/IRExecutionUnit.h&p1=lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h&r1=176918&r2=177364&rev=177364&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h (original)
+++ lldb/trunk/include/lldb/Expression/IRExecutionUnit.h Mon Mar 18 19:10:07 2013
@@ -1,4 +1,4 @@
-//===-- RecordingMemoryManager.h --------------------------------*- C++ -*-===//
+//===-- IRExecutionUnit.h ---------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,11 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef lldb_RecordingMemoryManager_h_
-#define lldb_RecordingMemoryManager_h_
+#ifndef lldb_IRExecutionUnit_h_
+#define lldb_IRExecutionUnit_h_
 
 // C Includes
 // C++ Includes
+#include <atomic>
 #include <string>
 #include <vector>
 #include <map>
@@ -21,295 +22,82 @@
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-private.h"
 #include "lldb/Core/ClangForward.h"
-#include "lldb/Core/Log.h"
 #include "llvm/ExecutionEngine/JITMemoryManager.h"
 #include "lldb/Expression/ClangExpression.h"
 #include "lldb/Expression/ClangExpressionParser.h"
+#include "lldb/Host/Mutex.h"
+
+namespace llvm {
+    
+class Module;
+class ExecutionEngine;
+    
+}
 
 namespace lldb_private {
 
+class Error;
+    
 //----------------------------------------------------------------------
-/// @class RecordingMemoryManager RecordingMemoryManager.h "lldb/Expression/RecordingMemoryManager.h"
-/// @brief Passthrough memory manager for the JIT that records what was allocated where
+/// @class IRExecutionUnit IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
+/// @brief Contains the IR and, optionally, JIT-compiled code for a module.
 ///
-/// The LLVM JIT is built to compile code for execution in the current
-/// process, so it needs to be able to allocate memory.  Because different
-/// clients have different requirements for the locations of JIT compiled
-/// code, the interface for allocating memory has been abstracted out and
-/// can be implemented by any client.
+/// This class encapsulates the compiled version of an expression, in IR
+/// form (for interpretation purposes) and in raw machine code form (for
+/// execution in the target).
 ///
-/// LLDB, however, needs to move JIT-compiled code into the target process.
-/// Because writing individual bytes of code hasn't been abstracted out of
-/// the JIT, LLDB instead implements a custom memory allocator that records 
-/// what regions have been allocated for code.  When JIT compilation is
-/// complete, these regions are then copied as necessary into the target
-/// process.
-///
-/// Ideally the memory manager would handle this copying, but this class has 
-/// to be built without RTTI, which means it cannot include Process.h.  As a
-/// result, ClangExpression::WriteJITCode() accesses the stored mappings 
-/// directly.
+/// This object wraps an IR module that comes from the expression parser,
+/// and knows how to use the JIT to make it into executable code.  It can
+/// then be used as input to the IR interpreter, or the address of the
+/// executable code can be passed to a thread plan to run in the target.
+/// 
+/// This class creates a subclass of LLVM's JITMemoryManager, because that is
+/// how the JIT emits code.  Because LLDB needs to move JIT-compiled code
+/// into the target process, the IRExecutionUnit knows how to copy the
+/// emitted code into the target process.
 //----------------------------------------------------------------------
-class RecordingMemoryManager : public llvm::JITMemoryManager
+class IRExecutionUnit 
 {
 public:
     //------------------------------------------------------------------
     /// Constructor
     //------------------------------------------------------------------
-    RecordingMemoryManager ();
+    IRExecutionUnit (std::auto_ptr<llvm::Module> &module_ap,
+                     ConstString &name,
+                     lldb::ProcessSP process_sp,
+                     std::vector<std::string> &cpu_features);
     
     //------------------------------------------------------------------
     /// Destructor
     //------------------------------------------------------------------
-    virtual ~RecordingMemoryManager();
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void setMemoryWritable ();
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void setMemoryExecutable ();
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void setPoisonMemory (bool poison)
-    {
-        m_default_mm_ap->setPoisonMemory (poison);
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void AllocateGOT()
-    {
-        m_default_mm_ap->AllocateGOT();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual uint8_t *getGOTBase() const
+    ~IRExecutionUnit();
+        
+    llvm::Module *GetModule()
     {
-        return m_default_mm_ap->getGOTBase();
+        return m_module;
     }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual uint8_t *startFunctionBody(const llvm::Function *F,
-                                       uintptr_t &ActualSize);
-
-    //------------------------------------------------------------------
-    /// Allocate room for a dyld stub for a lazy-referenced function,
-    /// and add it to the m_stubs map
-    ///
-    /// @param[in] F
-    ///     The function being referenced.
-    ///
-    /// @param[in] StubSize
-    ///     The size of the stub.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the stub.
-    ///
-    /// @return
-    ///     Allocated space for the stub.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateStub(const llvm::GlobalValue* F, 
-                                  unsigned StubSize,
-                                  unsigned Alignment);
-
-    //------------------------------------------------------------------
-    /// Complete the body of a function, and add it to the m_functions map
-    ///
-    /// @param[in] F
-    ///     The function being completed.
-    ///
-    /// @param[in] FunctionStart
-    ///     The first instruction of the function.
-    ///
-    /// @param[in] FunctionEnd
-    ///     The last byte of the last instruction of the function.
-    //------------------------------------------------------------------
-    virtual void endFunctionBody(const llvm::Function *F, 
-                                 uint8_t *FunctionStart,
-                                 uint8_t *FunctionEnd);
-    //------------------------------------------------------------------
-    /// Allocate space for an unspecified purpose, and add it to the
-    /// m_spaceBlocks map
-    ///
-    /// @param[in] Size
-    ///     The size of the area.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the area.
-    ///
-    /// @return
-    ///     Allocated space.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
     
-    //------------------------------------------------------------------
-    /// Allocate space for executable code, and add it to the 
-    /// m_spaceBlocks map
-    ///
-    /// @param[in] Size
-    ///     The size of the area.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the area.
-    ///
-    /// @param[in] SectionID
-    ///     A unique identifier for the section.
-    ///
-    /// @return
-    ///     Allocated space.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
-                                         unsigned SectionID);
+    void GetRunnableInfo(Error &error,
+                         lldb::addr_t &func_addr,
+                         lldb::addr_t &func_end);
     
     //------------------------------------------------------------------
-    /// Allocate space for data, and add it to the m_spaceBlocks map
-    ///
-    /// @param[in] Size
-    ///     The size of the area.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the area.
-    ///
-    /// @param[in] SectionID
-    ///     A unique identifier for the section.
-    ///
-    /// @param[in] IsReadOnly
-    ///     Flag indicating the section is read-only.
-    ///
-    /// @return
-    ///     Allocated space.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
-                                         unsigned SectionID, bool IsReadOnly);
-
-    //------------------------------------------------------------------
-    /// Allocate space for a global variable, and add it to the
-    /// m_spaceBlocks map
-    ///
-    /// @param[in] Size
-    ///     The size of the variable.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the variable.
-    ///
-    /// @return
-    ///     Allocated space for the global.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateGlobal(uintptr_t Size, 
-                                    unsigned Alignment);
-
-    //------------------------------------------------------------------
-    /// Called when object loading is complete and section page
-    /// permissions can be applied. Currently unimplemented for LLDB.
-    ///
-    /// @param[out] ErrMsg
-    ///     The error that prevented the page protection from succeeding.
-    ///
-    /// @return
-    ///     True in case of failure, false in case of success.
-    //------------------------------------------------------------------
-    bool applyPermissions(std::string *ErrMsg) { return false; }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void deallocateFunctionBody(void *Body);
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual uint8_t* startExceptionTable(const llvm::Function* F,
-                                         uintptr_t &ActualSize);
-
-    //------------------------------------------------------------------
-    /// Complete the exception table for a function, and add it to the
-    /// m_exception_tables map
-    ///
-    /// @param[in] F
-    ///     The function whose exception table is being written.
-    ///
-    /// @param[in] TableStart
-    ///     The first byte of the exception table.
-    ///
-    /// @param[in] TableEnd
-    ///     The last byte of the exception table.
-    ///
-    /// @param[in] FrameRegister
-    ///     I don't know what this does, but it's passed through.
-    //------------------------------------------------------------------
-    virtual void endExceptionTable(const llvm::Function *F, 
-                                   uint8_t *TableStart,
-                                   uint8_t *TableEnd, 
-                                   uint8_t* FrameRegister);
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void deallocateExceptionTable(void *ET);
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual size_t GetDefaultCodeSlabSize() {
-        return m_default_mm_ap->GetDefaultCodeSlabSize();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual size_t GetDefaultDataSlabSize() {
-        return m_default_mm_ap->GetDefaultDataSlabSize();
-    }
-
-    virtual size_t GetDefaultStubSlabSize() {
-        return m_default_mm_ap->GetDefaultStubSlabSize();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual unsigned GetNumCodeSlabs() {
-        return m_default_mm_ap->GetNumCodeSlabs();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual unsigned GetNumDataSlabs() {
-        return m_default_mm_ap->GetNumDataSlabs();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
+    /// Accessors for IRForTarget and other clients that may want binary
+    /// data placed on their behalf.  The binary data is owned by the
+    /// IRExecutionUnit unless the client explicitly chooses to free it.
     //------------------------------------------------------------------
-    virtual unsigned GetNumStubSlabs() {
-        return m_default_mm_ap->GetNumStubSlabs();
-    }
     
+    lldb::addr_t WriteNow(const uint8_t *bytes,
+                          size_t size,
+                          Error &error);
+    
+    void FreeNow(lldb::addr_t allocation);
+    
+private:
     //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void *getPointerToNamedFunction(const std::string &Name,
-                                            bool AbortOnFailure = true) {
-        return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure);
-    }
-
-    //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Look up the object in
-    /// m_address_map that contains a given address, find where it was
-    /// copied to, and return the remote address at the same offset into
-    /// the copied entity
+    /// Look up the object in m_address_map that contains a given address,
+    /// find where it was copied to, and return the remote address at the
+    /// same offset into the copied entity
     ///
     /// @param[in] local_address
     ///     The address in the debugger.
@@ -321,9 +109,9 @@ public:
     GetRemoteAddressForLocal (lldb::addr_t local_address);
     
     //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Look up the object in
-    /// m_address_map that contains a given address, find where it was
-    /// copied to, and return its address range in the target process
+    /// Look up the object in m_address_map that contains a given address,
+    /// find where it was copied to, and return its address range in the
+    /// target process
     ///
     /// @param[in] local_address
     ///     The address in the debugger.
@@ -336,8 +124,7 @@ public:
     GetRemoteRangeForLocal (lldb::addr_t local_address);
     
     //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Commit all allocations
-    /// to the process and record where they were stored.
+    /// Commit all allocations to the process and record where they were stored.
     ///
     /// @param[in] process
     ///     The process to allocate memory in.
@@ -348,11 +135,10 @@ public:
     ///     operation fails.
     //------------------------------------------------------------------
     bool
-    CommitAllocations (Process &process);
+    CommitAllocations (lldb::ProcessSP &process_sp);
     
     //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Report all committed
-    /// allocations to the execution engine.
+    /// Report all committed allocations to the execution engine.
     ///
     /// @param[in] engine
     ///     The execution engine to notify.
@@ -361,8 +147,7 @@ public:
     ReportAllocations (llvm::ExecutionEngine &engine);
     
     //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Write the contents
-    /// of all allocations to the process. 
+    /// Write the contents of all allocations to the process. 
     ///
     /// @param[in] local_address
     ///     The process containing the allocations.
@@ -371,24 +156,275 @@ public:
     ///     True <=> all allocations were performed successfully.
     //------------------------------------------------------------------
     bool
-    WriteData (Process &process);
-private:
-    std::auto_ptr<JITMemoryManager> m_default_mm_ap;    ///< The memory allocator to use in actually creating space.  All calls are passed through to it.
+    WriteData (lldb::ProcessSP &process_sp);
     
-    lldb::LogSP m_log; ///< The log to use when printing log messages.  May be NULL.
+    Error
+    DisassembleFunction (Stream &stream,
+                         lldb::ProcessSP &process_sp);
 
+    class MemoryManager : public llvm::JITMemoryManager
+    {
+    public:
+        MemoryManager (IRExecutionUnit &parent);
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual void setMemoryWritable ();
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual void setMemoryExecutable ();
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual void setPoisonMemory (bool poison)
+        {
+            m_default_mm_ap->setPoisonMemory (poison);
+        }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual void AllocateGOT()
+        {
+            m_default_mm_ap->AllocateGOT();
+        }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual uint8_t *getGOTBase() const
+        {
+            return m_default_mm_ap->getGOTBase();
+        }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual uint8_t *startFunctionBody(const llvm::Function *F,
+                                           uintptr_t &ActualSize);
+        
+        //------------------------------------------------------------------
+        /// Allocate room for a dyld stub for a lazy-referenced function,
+        /// and add it to the m_stubs map
+        ///
+        /// @param[in] F
+        ///     The function being referenced.
+        ///
+        /// @param[in] StubSize
+        ///     The size of the stub.
+        ///
+        /// @param[in] Alignment
+        ///     The required alignment of the stub.
+        ///
+        /// @return
+        ///     Allocated space for the stub.
+        //------------------------------------------------------------------
+        virtual uint8_t *allocateStub(const llvm::GlobalValue* F,
+                                      unsigned StubSize,
+                                      unsigned Alignment);
+        
+        //------------------------------------------------------------------
+        /// Complete the body of a function, and add it to the m_functions map
+        ///
+        /// @param[in] F
+        ///     The function being completed.
+        ///
+        /// @param[in] FunctionStart
+        ///     The first instruction of the function.
+        ///
+        /// @param[in] FunctionEnd
+        ///     The last byte of the last instruction of the function.
+        //------------------------------------------------------------------
+        virtual void endFunctionBody(const llvm::Function *F,
+                                     uint8_t *FunctionStart,
+                                     uint8_t *FunctionEnd);
+        //------------------------------------------------------------------
+        /// Allocate space for an unspecified purpose, and add it to the
+        /// m_spaceBlocks map
+        ///
+        /// @param[in] Size
+        ///     The size of the area.
+        ///
+        /// @param[in] Alignment
+        ///     The required alignment of the area.
+        ///
+        /// @return
+        ///     Allocated space.
+        //------------------------------------------------------------------
+        virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
+        
+        //------------------------------------------------------------------
+        /// Allocate space for executable code, and add it to the
+        /// m_spaceBlocks map
+        ///
+        /// @param[in] Size
+        ///     The size of the area.
+        ///
+        /// @param[in] Alignment
+        ///     The required alignment of the area.
+        ///
+        /// @param[in] SectionID
+        ///     A unique identifier for the section.
+        ///
+        /// @return
+        ///     Allocated space.
+        //------------------------------------------------------------------
+        virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+                                             unsigned SectionID);
+        
+        //------------------------------------------------------------------
+        /// Allocate space for data, and add it to the m_spaceBlocks map
+        ///
+        /// @param[in] Size
+        ///     The size of the area.
+        ///
+        /// @param[in] Alignment
+        ///     The required alignment of the area.
+        ///
+        /// @param[in] SectionID
+        ///     A unique identifier for the section.
+        ///
+        /// @param[in] IsReadOnly
+        ///     Flag indicating the section is read-only.
+        ///
+        /// @return
+        ///     Allocated space.
+        //------------------------------------------------------------------
+        virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+                                             unsigned SectionID, bool IsReadOnly);
+        
+        //------------------------------------------------------------------
+        /// Allocate space for a global variable, and add it to the
+        /// m_spaceBlocks map
+        ///
+        /// @param[in] Size
+        ///     The size of the variable.
+        ///
+        /// @param[in] Alignment
+        ///     The required alignment of the variable.
+        ///
+        /// @return
+        ///     Allocated space for the global.
+        //------------------------------------------------------------------
+        virtual uint8_t *allocateGlobal(uintptr_t Size,
+                                        unsigned Alignment);
+        
+        //------------------------------------------------------------------
+        /// Called when object loading is complete and section page
+        /// permissions can be applied. Currently unimplemented for LLDB.
+        ///
+        /// @param[out] ErrMsg
+        ///     The error that prevented the page protection from succeeding.
+        ///
+        /// @return
+        ///     True in case of failure, false in case of success.
+        //------------------------------------------------------------------
+        bool applyPermissions(std::string *ErrMsg) { return false; }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual void deallocateFunctionBody(void *Body);
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual uint8_t* startExceptionTable(const llvm::Function* F,
+                                             uintptr_t &ActualSize);
+        
+        //------------------------------------------------------------------
+        /// Complete the exception table for a function, and add it to the
+        /// m_exception_tables map
+        ///
+        /// @param[in] F
+        ///     The function whose exception table is being written.
+        ///
+        /// @param[in] TableStart
+        ///     The first byte of the exception table.
+        ///
+        /// @param[in] TableEnd
+        ///     The last byte of the exception table.
+        ///
+        /// @param[in] FrameRegister
+        ///     I don't know what this does, but it's passed through.
+        //------------------------------------------------------------------
+        virtual void endExceptionTable(const llvm::Function *F,
+                                       uint8_t *TableStart,
+                                       uint8_t *TableEnd,
+                                       uint8_t* FrameRegister);
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual void deallocateExceptionTable(void *ET);
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual size_t GetDefaultCodeSlabSize() {
+            return m_default_mm_ap->GetDefaultCodeSlabSize();
+        }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual size_t GetDefaultDataSlabSize() {
+            return m_default_mm_ap->GetDefaultDataSlabSize();
+        }
+        
+        virtual size_t GetDefaultStubSlabSize() {
+            return m_default_mm_ap->GetDefaultStubSlabSize();
+        }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual unsigned GetNumCodeSlabs() {
+            return m_default_mm_ap->GetNumCodeSlabs();
+        }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual unsigned GetNumDataSlabs() {
+            return m_default_mm_ap->GetNumDataSlabs();
+        }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual unsigned GetNumStubSlabs() {
+            return m_default_mm_ap->GetNumStubSlabs();
+        }
+        
+        //------------------------------------------------------------------
+        /// Passthrough interface stub
+        //------------------------------------------------------------------
+        virtual void *getPointerToNamedFunction(const std::string &Name,
+                                                bool AbortOnFailure = true) {
+            return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure);
+        }
+    private:
+        std::auto_ptr<JITMemoryManager>     m_default_mm_ap;    ///< The memory allocator to use in actually creating space.  All calls are passed through to it.
+        IRExecutionUnit                    &m_parent;           ///< The execution unit this is a proxy for.
+    };
+    
     //----------------------------------------------------------------------
-    /// @class Allocation RecordingMemoryManager.h "lldb/Expression/RecordingMemoryManager.h"
+    /// @class Allocation IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h"
     /// @brief A record of a region that has been allocated by the JIT.
     ///
-    /// The RecordingMemoryManager makes records of all regions that need copying;
+    /// The IRExecutionUnit makes records of all regions that need copying;
     /// upon requests, it allocates and 
     //----------------------------------------------------------------------
     struct Allocation
     {
         lldb::addr_t    m_remote_allocation;///< The (unaligned) base for the remote allocation
         lldb::addr_t    m_remote_start;     ///< The base address of the remote allocation
-        uintptr_t       m_local_start;      ///< The base address of the local allocation
+        uintptr_t       m_local_start;      ///< The base address of the local allocation - LLDB_INVALID_ADDRESS means it was allocated with WriteNow
         uintptr_t       m_size;             ///< The size of the allocation
         unsigned        m_section_id;       ///< The ID of the section
         unsigned        m_alignment;        ///< The required alignment for the allocation
@@ -414,11 +450,63 @@ private:
         
         void dump (lldb::LogSP log);
     };
+    
+    //----------------------------------------------------------------------
+    /// @class JittedFunction ClangExpressionParser.h "lldb/Expression/ClangExpressionParser.h"
+    /// @brief Encapsulates a single function that has been generated by the JIT.
+    ///
+    /// Functions that have been generated by the JIT are first resident in the
+    /// local process, and then placed in the target process.  JittedFunction
+    /// represents a function possibly resident in both.
+    //----------------------------------------------------------------------
+    struct JittedFunction {
+        std::string m_name;             ///< The function's name
+        lldb::addr_t m_local_addr;      ///< The address of the function in LLDB's memory
+        lldb::addr_t m_remote_addr;     ///< The address of the function in the target's memory
+        
+        //------------------------------------------------------------------
+        /// Constructor
+        ///
+        /// Initializes class variabes.
+        ///
+        /// @param[in] name
+        ///     The name of the function.
+        ///
+        /// @param[in] local_addr
+        ///     The address of the function in LLDB, or LLDB_INVALID_ADDRESS if
+        ///     it is not present in LLDB's memory.
+        ///
+        /// @param[in] remote_addr
+        ///     The address of the function in the target, or LLDB_INVALID_ADDRESS
+        ///     if it is not present in the target's memory.
+        //------------------------------------------------------------------
+        JittedFunction (const char *name,
+                        lldb::addr_t local_addr = LLDB_INVALID_ADDRESS,
+                        lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) :
+            m_name (name),
+            m_local_addr (local_addr),
+            m_remote_addr (remote_addr)
+        {
+        }
+    };
+
+    lldb::ProcessWP                         m_process_wp;
+    typedef std::vector<Allocation>         AllocationList;
+    AllocationList                          m_allocations;          ///< The base address of the remote allocation
+    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
+    std::vector<std::string>                m_cpu_features;
+    llvm::SmallVector<JittedFunction, 1>    m_jitted_functions;     ///< A vector of all functions that have been JITted into machine code
+    const ConstString                       m_name;
+    
+    std::atomic<bool>                       m_did_jit;
+    Mutex                                   m_jit_mutex;
 
-    typedef std::vector<Allocation> AllocationList;
-    AllocationList                  m_allocations;  ///< The base address of the remote allocation
+    lldb::addr_t                            m_function_load_addr;
+    lldb::addr_t                            m_function_end_load_addr;
 };
 
 } // namespace lldb_private
 
-#endif  // lldb_RecordingMemoryManager_h_
+#endif  // lldb_IRExecutionUnit_h_

Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/IRForTarget.h (original)
+++ lldb/trunk/include/lldb/Expression/IRForTarget.h Mon Mar 18 19:10:07 2013
@@ -14,6 +14,7 @@
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
 #include "lldb/Symbol/TaggedASTType.h"
 #include "llvm/Pass.h"
 
@@ -35,6 +36,7 @@ namespace llvm {
 
 namespace lldb_private {
     class ClangExpressionDeclMap;
+    class IRExecutionUnit;
 }
 
 //----------------------------------------------------------------------
@@ -54,14 +56,6 @@ namespace lldb_private {
 class IRForTarget : public llvm::ModulePass
 {
 public:
-    class StaticDataAllocator {
-    public:
-        StaticDataAllocator();
-        virtual ~StaticDataAllocator();
-        virtual lldb_private::StreamString &GetStream() = 0;
-        virtual lldb::addr_t Allocate() = 0;
-    };
-    
     //------------------------------------------------------------------
     /// Constructor
     ///
@@ -84,8 +78,8 @@ public:
     ///     of the function, if it has no side-effects and the result can
     ///     be computed statically.
     ///
-    /// @param[in] data_allocator
-    ///     If non-NULL, the static data allocator to use for literal strings.
+    /// @param[in] execution_unit
+    ///     The holder for raw data associated with the expression.
     ///
     /// @param[in] error_stream
     ///     If non-NULL, a stream on which errors can be printed.
@@ -97,7 +91,7 @@ public:
                 bool resolve_vars,
                 lldb_private::ExecutionPolicy execution_policy,
                 lldb::ClangExpressionVariableSP &const_result,
-                StaticDataAllocator *data_allocator,
+                lldb_private::IRExecutionUnit &execution_unit,
                 lldb_private::Stream *error_stream,
                 const char* func_name = "$__lldb_expr");
     
@@ -653,6 +647,20 @@ private:
     bool
     StripAllGVs (llvm::Module &llvm_module);
     
+    class StaticDataAllocator {
+    public:
+        StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit);
+        lldb_private::StreamString &GetStream()
+        {
+            return m_stream_string;
+        }
+        lldb::addr_t Allocate();
+    private:
+        lldb_private::IRExecutionUnit  &m_execution_unit;
+        lldb_private::StreamString      m_stream_string;
+        lldb::addr_t                    m_allocation;
+    };
+    
     /// Flags
     bool                                    m_resolve_vars;             ///< True if external variable references and persistent variable references should be resolved
     lldb_private::ExecutionPolicy           m_execution_policy;         ///< True if the interpreter should be used to attempt to get a static result
@@ -663,7 +671,7 @@ private:
     llvm::Module                           *m_module;                   ///< The module being processed, or NULL if that has not been determined yet.
     std::auto_ptr<llvm::DataLayout>         m_target_data;              ///< The target data for the module being processed, or NULL if there is no module.
     lldb_private::ClangExpressionDeclMap   *m_decl_map;                 ///< The DeclMap containing the Decls 
-    StaticDataAllocator                    *m_data_allocator;           ///< If non-NULL, the allocator to use for constant strings
+    StaticDataAllocator                     m_data_allocator;           ///< The allocator to use for constant strings
     llvm::Constant                         *m_CFStringCreateWithBytes;  ///< The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type
     llvm::Constant                         *m_sel_registerName;         ///< The address of the function sel_registerName, cast to the appropriate function pointer type
     lldb::ClangExpressionVariableSP        &m_const_result;             ///< This value should be set to the return value of the expression if it is constant and the expression has no side effects

Removed: lldb/trunk/include/lldb/Expression/ProcessDataAllocator.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ProcessDataAllocator.h?rev=177363&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/ProcessDataAllocator.h (original)
+++ lldb/trunk/include/lldb/Expression/ProcessDataAllocator.h (removed)
@@ -1,72 +0,0 @@
-//===-- ProcessDataAllocator.h ----------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_ProcessDataAllocator_h_
-#define liblldb_ProcessDataAllocator_h_
-
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-#include "lldb/Expression/IRForTarget.h"
-#include "lldb/Target/Process.h"
-
-namespace lldb_private 
-{
-
-class ProcessDataAllocator : public IRForTarget::StaticDataAllocator {
-public:
-    ProcessDataAllocator(Process &process) : 
-        IRForTarget::StaticDataAllocator(),
-        m_process(process),
-        m_stream_string(StreamString::eBinary, process.GetAddressByteSize(), process.GetByteOrder()),
-        m_allocation(0)
-    {
-    }
-    
-    ~ProcessDataAllocator()
-    {
-        if (m_allocation)
-            m_process.DeallocateMemory(m_allocation);
-    }
-    
-    lldb_private::StreamString &GetStream()
-    {
-        return m_stream_string;
-    }
-    
-    lldb::addr_t Allocate()
-    {
-        Error err;
-        
-        if (m_allocation)
-            m_process.DeallocateMemory(m_allocation);
-        
-        m_allocation = m_process.AllocateMemory(m_stream_string.GetSize(), lldb::ePermissionsReadable | lldb::ePermissionsWritable, err);
-        
-        if (!err.Success())
-            return 0;
-        
-        if (m_allocation)
-            m_process.WriteMemory(m_allocation, m_stream_string.GetData(), m_stream_string.GetSize(), err);
-        
-        if (!err.Success())
-            return 0;
-        
-        return m_allocation;
-    }
-    
-    void Dump(lldb_private::Stream &stream);
-private:
-    Process        &m_process;
-    StreamString    m_stream_string;
-    lldb::addr_t    m_allocation;
-};
-    
-} // namespace lldb_private
-
-#endif

Removed: lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h?rev=177363&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h (original)
+++ lldb/trunk/include/lldb/Expression/RecordingMemoryManager.h (removed)
@@ -1,424 +0,0 @@
-//===-- RecordingMemoryManager.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_RecordingMemoryManager_h_
-#define lldb_RecordingMemoryManager_h_
-
-// C Includes
-// C++ Includes
-#include <string>
-#include <vector>
-#include <map>
-
-// Other libraries and framework includes
-// Project includes
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-private.h"
-#include "lldb/Core/ClangForward.h"
-#include "lldb/Core/Log.h"
-#include "llvm/ExecutionEngine/JITMemoryManager.h"
-#include "lldb/Expression/ClangExpression.h"
-#include "lldb/Expression/ClangExpressionParser.h"
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-/// @class RecordingMemoryManager RecordingMemoryManager.h "lldb/Expression/RecordingMemoryManager.h"
-/// @brief Passthrough memory manager for the JIT that records what was allocated where
-///
-/// The LLVM JIT is built to compile code for execution in the current
-/// process, so it needs to be able to allocate memory.  Because different
-/// clients have different requirements for the locations of JIT compiled
-/// code, the interface for allocating memory has been abstracted out and
-/// can be implemented by any client.
-///
-/// LLDB, however, needs to move JIT-compiled code into the target process.
-/// Because writing individual bytes of code hasn't been abstracted out of
-/// the JIT, LLDB instead implements a custom memory allocator that records 
-/// what regions have been allocated for code.  When JIT compilation is
-/// complete, these regions are then copied as necessary into the target
-/// process.
-///
-/// Ideally the memory manager would handle this copying, but this class has 
-/// to be built without RTTI, which means it cannot include Process.h.  As a
-/// result, ClangExpression::WriteJITCode() accesses the stored mappings 
-/// directly.
-//----------------------------------------------------------------------
-class RecordingMemoryManager : public llvm::JITMemoryManager
-{
-public:
-    //------------------------------------------------------------------
-    /// Constructor
-    //------------------------------------------------------------------
-    RecordingMemoryManager ();
-    
-    //------------------------------------------------------------------
-    /// Destructor
-    //------------------------------------------------------------------
-    virtual ~RecordingMemoryManager();
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void setMemoryWritable ();
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void setMemoryExecutable ();
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void setPoisonMemory (bool poison)
-    {
-        m_default_mm_ap->setPoisonMemory (poison);
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void AllocateGOT()
-    {
-        m_default_mm_ap->AllocateGOT();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual uint8_t *getGOTBase() const
-    {
-        return m_default_mm_ap->getGOTBase();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual uint8_t *startFunctionBody(const llvm::Function *F,
-                                       uintptr_t &ActualSize);
-
-    //------------------------------------------------------------------
-    /// Allocate room for a dyld stub for a lazy-referenced function,
-    /// and add it to the m_stubs map
-    ///
-    /// @param[in] F
-    ///     The function being referenced.
-    ///
-    /// @param[in] StubSize
-    ///     The size of the stub.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the stub.
-    ///
-    /// @return
-    ///     Allocated space for the stub.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateStub(const llvm::GlobalValue* F, 
-                                  unsigned StubSize,
-                                  unsigned Alignment);
-
-    //------------------------------------------------------------------
-    /// Complete the body of a function, and add it to the m_functions map
-    ///
-    /// @param[in] F
-    ///     The function being completed.
-    ///
-    /// @param[in] FunctionStart
-    ///     The first instruction of the function.
-    ///
-    /// @param[in] FunctionEnd
-    ///     The last byte of the last instruction of the function.
-    //------------------------------------------------------------------
-    virtual void endFunctionBody(const llvm::Function *F, 
-                                 uint8_t *FunctionStart,
-                                 uint8_t *FunctionEnd);
-    //------------------------------------------------------------------
-    /// Allocate space for an unspecified purpose, and add it to the
-    /// m_spaceBlocks map
-    ///
-    /// @param[in] Size
-    ///     The size of the area.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the area.
-    ///
-    /// @return
-    ///     Allocated space.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
-    
-    //------------------------------------------------------------------
-    /// Allocate space for executable code, and add it to the 
-    /// m_spaceBlocks map
-    ///
-    /// @param[in] Size
-    ///     The size of the area.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the area.
-    ///
-    /// @param[in] SectionID
-    ///     A unique identifier for the section.
-    ///
-    /// @return
-    ///     Allocated space.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
-                                         unsigned SectionID);
-    
-    //------------------------------------------------------------------
-    /// Allocate space for data, and add it to the m_spaceBlocks map
-    ///
-    /// @param[in] Size
-    ///     The size of the area.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the area.
-    ///
-    /// @param[in] SectionID
-    ///     A unique identifier for the section.
-    ///
-    /// @param[in] IsReadOnly
-    ///     Flag indicating the section is read-only.
-    ///
-    /// @return
-    ///     Allocated space.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
-                                         unsigned SectionID, bool IsReadOnly);
-
-    //------------------------------------------------------------------
-    /// Allocate space for a global variable, and add it to the
-    /// m_spaceBlocks map
-    ///
-    /// @param[in] Size
-    ///     The size of the variable.
-    ///
-    /// @param[in] Alignment
-    ///     The required alignment of the variable.
-    ///
-    /// @return
-    ///     Allocated space for the global.
-    //------------------------------------------------------------------
-    virtual uint8_t *allocateGlobal(uintptr_t Size, 
-                                    unsigned Alignment);
-
-    //------------------------------------------------------------------
-    /// Called when object loading is complete and section page
-    /// permissions can be applied. Currently unimplemented for LLDB.
-    ///
-    /// @param[out] ErrMsg
-    ///     The error that prevented the page protection from succeeding.
-    ///
-    /// @return
-    ///     True in case of failure, false in case of success.
-    //------------------------------------------------------------------
-    bool applyPermissions(std::string *ErrMsg) { return false; }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void deallocateFunctionBody(void *Body);
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual uint8_t* startExceptionTable(const llvm::Function* F,
-                                         uintptr_t &ActualSize);
-
-    //------------------------------------------------------------------
-    /// Complete the exception table for a function, and add it to the
-    /// m_exception_tables map
-    ///
-    /// @param[in] F
-    ///     The function whose exception table is being written.
-    ///
-    /// @param[in] TableStart
-    ///     The first byte of the exception table.
-    ///
-    /// @param[in] TableEnd
-    ///     The last byte of the exception table.
-    ///
-    /// @param[in] FrameRegister
-    ///     I don't know what this does, but it's passed through.
-    //------------------------------------------------------------------
-    virtual void endExceptionTable(const llvm::Function *F, 
-                                   uint8_t *TableStart,
-                                   uint8_t *TableEnd, 
-                                   uint8_t* FrameRegister);
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void deallocateExceptionTable(void *ET);
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual size_t GetDefaultCodeSlabSize() {
-        return m_default_mm_ap->GetDefaultCodeSlabSize();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual size_t GetDefaultDataSlabSize() {
-        return m_default_mm_ap->GetDefaultDataSlabSize();
-    }
-
-    virtual size_t GetDefaultStubSlabSize() {
-        return m_default_mm_ap->GetDefaultStubSlabSize();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual unsigned GetNumCodeSlabs() {
-        return m_default_mm_ap->GetNumCodeSlabs();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual unsigned GetNumDataSlabs() {
-        return m_default_mm_ap->GetNumDataSlabs();
-    }
-
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual unsigned GetNumStubSlabs() {
-        return m_default_mm_ap->GetNumStubSlabs();
-    }
-    
-    //------------------------------------------------------------------
-    /// Passthrough interface stub
-    //------------------------------------------------------------------
-    virtual void *getPointerToNamedFunction(const std::string &Name,
-                                            bool AbortOnFailure = true) {
-        return m_default_mm_ap->getPointerToNamedFunction(Name, AbortOnFailure);
-    }
-
-    //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Look up the object in
-    /// m_address_map that contains a given address, find where it was
-    /// copied to, and return the remote address at the same offset into
-    /// the copied entity
-    ///
-    /// @param[in] local_address
-    ///     The address in the debugger.
-    ///
-    /// @return
-    ///     The address in the target process.
-    //------------------------------------------------------------------
-    lldb::addr_t
-    GetRemoteAddressForLocal (lldb::addr_t local_address);
-    
-    //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Look up the object in
-    /// m_address_map that contains a given address, find where it was
-    /// copied to, and return its address range in the target process
-    ///
-    /// @param[in] local_address
-    ///     The address in the debugger.
-    ///
-    /// @return
-    ///     The range of the containing object in the target process.
-    //------------------------------------------------------------------
-    typedef std::pair <lldb::addr_t, uintptr_t> AddrRange;
-    AddrRange
-    GetRemoteRangeForLocal (lldb::addr_t local_address);
-    
-    //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Commit all allocations
-    /// to the process and record where they were stored.
-    ///
-    /// @param[in] process
-    ///     The process to allocate memory in.
-    ///
-    /// @return
-    ///     True <=> all allocations were performed successfully.
-    ///     This method will attempt to free allocated memory if the
-    ///     operation fails.
-    //------------------------------------------------------------------
-    bool
-    CommitAllocations (Process &process);
-    
-    //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Report all committed
-    /// allocations to the execution engine.
-    ///
-    /// @param[in] engine
-    ///     The execution engine to notify.
-    //------------------------------------------------------------------
-    void
-    ReportAllocations (llvm::ExecutionEngine &engine);
-    
-    //------------------------------------------------------------------
-    /// [Convenience method for ClangExpressionParser] Write the contents
-    /// of all allocations to the process. 
-    ///
-    /// @param[in] local_address
-    ///     The process containing the allocations.
-    ///
-    /// @return
-    ///     True <=> all allocations were performed successfully.
-    //------------------------------------------------------------------
-    bool
-    WriteData (Process &process);
-private:
-    std::auto_ptr<JITMemoryManager> m_default_mm_ap;    ///< The memory allocator to use in actually creating space.  All calls are passed through to it.
-    
-    lldb::LogSP m_log; ///< The log to use when printing log messages.  May be NULL.
-
-    //----------------------------------------------------------------------
-    /// @class Allocation RecordingMemoryManager.h "lldb/Expression/RecordingMemoryManager.h"
-    /// @brief A record of a region that has been allocated by the JIT.
-    ///
-    /// The RecordingMemoryManager makes records of all regions that need copying;
-    /// upon requests, it allocates and 
-    //----------------------------------------------------------------------
-    struct Allocation
-    {
-        lldb::addr_t    m_remote_allocation;///< The (unaligned) base for the remote allocation
-        lldb::addr_t    m_remote_start;     ///< The base address of the remote allocation
-        uintptr_t       m_local_start;      ///< The base address of the local allocation
-        uintptr_t       m_size;             ///< The size of the allocation
-        unsigned        m_section_id;       ///< The ID of the section
-        unsigned        m_alignment;        ///< The required alignment for the allocation
-        bool            m_executable;       ///< True <=> the allocation must be executable in the target
-        bool            m_allocated;        ///< True <=> the allocation has been propagated to the target
-
-        static const unsigned eSectionIDNone = (unsigned)-1;
-        
-        //------------------------------------------------------------------
-        /// Constructor
-        //------------------------------------------------------------------
-        Allocation () :
-            m_remote_allocation(0),
-            m_remote_start(0),
-            m_local_start(0),
-            m_size(0),
-            m_section_id(eSectionIDNone),
-            m_alignment(0),
-            m_executable(false),
-            m_allocated(false)
-        {
-        }
-        
-        void dump (lldb::LogSP log);
-    };
-
-    typedef std::vector<Allocation> AllocationList;
-    AllocationList                  m_allocations;  ///< The base address of the remote allocation
-};
-
-} // namespace lldb_private
-
-#endif  // lldb_RecordingMemoryManager_h_

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Mar 18 19:10:07 2013
@@ -255,7 +255,7 @@
 		2689006913353E0E00698AC0 /* ASTStructExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 491193501226386000578B7F /* ASTStructExtractor.cpp */; };
 		2689006A13353E0E00698AC0 /* IRDynamicChecks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49CF9829122C70BD007A0B96 /* IRDynamicChecks.cpp */; };
 		2689006B13353E0E00698AC0 /* IRForTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49307AAD11DEA4D90081F992 /* IRForTarget.cpp */; };
-		2689006D13353E0E00698AC0 /* RecordingMemoryManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3DB118FB96F00E575D0 /* RecordingMemoryManager.cpp */; };
+		2689006D13353E0E00698AC0 /* IRExecutionUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C98D3DB118FB96F00E575D0 /* IRExecutionUnit.cpp */; };
 		2689006E13353E1A00698AC0 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C6EA213011581005E16B0 /* File.cpp */; };
 		2689006F13353E1A00698AC0 /* FileSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FA43171301048600E71120 /* FileSpec.cpp */; };
 		2689007013353E1A00698AC0 /* Condition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69A01E1B1236C5D400C660B5 /* Condition.cpp */; };
@@ -495,7 +495,6 @@
 		49A1CAC51430E8DE00306AC9 /* ExpressionSourceCode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A1CAC31430E8BD00306AC9 /* ExpressionSourceCode.cpp */; };
 		49A71FE7141FFA5C00D59478 /* IRInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 496B01581406DE8900F830D5 /* IRInterpreter.cpp */; };
 		49A71FE8141FFACF00D59478 /* DataEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 268ED0A4140FF54200DE830F /* DataEncoder.cpp */; };
-		49C8507C1384A786007DB519 /* ProcessDataAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49C850781384A0CA007DB519 /* ProcessDataAllocator.cpp */; };
 		49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D8FB3513B558DE00411094 /* ClangASTImporter.cpp */; };
 		49DA65031485C92A005FF180 /* AppleObjCTypeVendor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA65021485C92A005FF180 /* AppleObjCTypeVendor.cpp */; };
 		4C6649A014EEE7F100B0316F /* StreamCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C66499F14EEE7F100B0316F /* StreamCallback.h */; };
@@ -1444,8 +1443,6 @@
 		49A8A3A311D568BF00AD3B68 /* ASTResultSynthesizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTResultSynthesizer.h; path = include/lldb/Expression/ASTResultSynthesizer.h; sourceTree = "<group>"; };
 		49B01A2D15F67B1700666829 /* TypeVendor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeVendor.h; path = include/lldb/Symbol/TypeVendor.h; sourceTree = "<group>"; };
 		49BB309511F79450001A4197 /* TaggedASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedASTType.h; path = include/lldb/Symbol/TaggedASTType.h; sourceTree = "<group>"; };
-		49C850761384A02F007DB519 /* ProcessDataAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProcessDataAllocator.h; path = include/lldb/Expression/ProcessDataAllocator.h; sourceTree = "<group>"; };
-		49C850781384A0CA007DB519 /* ProcessDataAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessDataAllocator.cpp; path = source/Expression/ProcessDataAllocator.cpp; sourceTree = "<group>"; };
 		49CF9829122C70BD007A0B96 /* IRDynamicChecks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRDynamicChecks.cpp; path = source/Expression/IRDynamicChecks.cpp; sourceTree = "<group>"; };
 		49CF9833122C718B007A0B96 /* IRDynamicChecks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRDynamicChecks.h; path = include/lldb/Expression/IRDynamicChecks.h; sourceTree = "<group>"; };
 		49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangPersistentVariables.h; path = include/lldb/Expression/ClangPersistentVariables.h; sourceTree = "<group>"; };
@@ -1484,9 +1481,9 @@
 		4C7CF7E31295E10E00B4FBB5 /* ThreadPlanCallUserExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanCallUserExpression.h; path = include/lldb/Target/ThreadPlanCallUserExpression.h; sourceTree = "<group>"; };
 		4C7CF7E51295E12B00B4FBB5 /* ThreadPlanCallUserExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanCallUserExpression.cpp; path = source/Target/ThreadPlanCallUserExpression.cpp; sourceTree = "<group>"; };
 		4C98D3DA118FB96F00E575D0 /* ClangFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangFunction.cpp; path = source/Expression/ClangFunction.cpp; sourceTree = "<group>"; };
-		4C98D3DB118FB96F00E575D0 /* RecordingMemoryManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecordingMemoryManager.cpp; path = source/Expression/RecordingMemoryManager.cpp; sourceTree = "<group>"; };
+		4C98D3DB118FB96F00E575D0 /* IRExecutionUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRExecutionUnit.cpp; path = source/Expression/IRExecutionUnit.cpp; sourceTree = "<group>"; };
 		4C98D3E0118FB98F00E575D0 /* ClangFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangFunction.h; path = include/lldb/Expression/ClangFunction.h; sourceTree = "<group>"; };
-		4C98D3E1118FB98F00E575D0 /* RecordingMemoryManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecordingMemoryManager.h; path = include/lldb/Expression/RecordingMemoryManager.h; sourceTree = "<group>"; };
+		4C98D3E1118FB98F00E575D0 /* IRExecutionUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IRExecutionUnit.h; path = include/lldb/Expression/IRExecutionUnit.h; sourceTree = "<group>"; };
 		4CA9637911B6E99A00780E28 /* CommandObjectApropos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectApropos.cpp; path = source/Commands/CommandObjectApropos.cpp; sourceTree = "<group>"; };
 		4CA9637A11B6E99A00780E28 /* CommandObjectApropos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectApropos.h; path = source/Commands/CommandObjectApropos.h; sourceTree = "<group>"; };
 		4CAA56121422D96A001FFA01 /* BreakpointResolverFileRegex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverFileRegex.h; path = include/lldb/Breakpoint/BreakpointResolverFileRegex.h; sourceTree = "<group>"; };
@@ -2883,14 +2880,12 @@
 				491193501226386000578B7F /* ASTStructExtractor.cpp */,
 				49CF9833122C718B007A0B96 /* IRDynamicChecks.h */,
 				49CF9829122C70BD007A0B96 /* IRDynamicChecks.cpp */,
+				4C98D3E1118FB98F00E575D0 /* IRExecutionUnit.h */,
+				4C98D3DB118FB96F00E575D0 /* IRExecutionUnit.cpp */,
 				49307AB111DEA4F20081F992 /* IRForTarget.h */,
 				49307AAD11DEA4D90081F992 /* IRForTarget.cpp */,
 				496B015A1406DEB100F830D5 /* IRInterpreter.h */,
 				496B01581406DE8900F830D5 /* IRInterpreter.cpp */,
-				4C98D3E1118FB98F00E575D0 /* RecordingMemoryManager.h */,
-				4C98D3DB118FB96F00E575D0 /* RecordingMemoryManager.cpp */,
-				49C850761384A02F007DB519 /* ProcessDataAllocator.h */,
-				49C850781384A0CA007DB519 /* ProcessDataAllocator.cpp */,
 			);
 			name = Expression;
 			sourceTree = "<group>";
@@ -3938,7 +3933,6 @@
 			files = (
 				9456F2241616671900656F91 /* DynamicLibrary.cpp in Sources */,
 				26D1804216CEDF0700EDFB5B /* TimeSpecTimeout.cpp in Sources */,
-				49C8507C1384A786007DB519 /* ProcessDataAllocator.cpp in Sources */,
 				2689FFDA13353D9D00698AC0 /* lldb.cpp in Sources */,
 				2689FFDB13353DA300698AC0 /* lldb-log.cpp in Sources */,
 				2689FFEF13353DB600698AC0 /* Breakpoint.cpp in Sources */,
@@ -4048,7 +4042,7 @@
 				2689006913353E0E00698AC0 /* ASTStructExtractor.cpp in Sources */,
 				2689006A13353E0E00698AC0 /* IRDynamicChecks.cpp in Sources */,
 				2689006B13353E0E00698AC0 /* IRForTarget.cpp in Sources */,
-				2689006D13353E0E00698AC0 /* RecordingMemoryManager.cpp in Sources */,
+				2689006D13353E0E00698AC0 /* IRExecutionUnit.cpp in Sources */,
 				2689006E13353E1A00698AC0 /* File.cpp in Sources */,
 				94D6A0AB16CEB55F00833B6E /* NSDictionary.cpp in Sources */,
 				2689006F13353E1A00698AC0 /* FileSpec.cpp in Sources */,

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Mon Mar 18 19:10:07 2013
@@ -20,8 +20,8 @@
 #include "lldb/Expression/ClangASTSource.h"
 #include "lldb/Expression/ClangExpression.h"
 #include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Expression/IRDynamicChecks.h"
-#include "lldb/Expression/RecordingMemoryManager.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 #include "lldb/Target/Process.h"
@@ -188,8 +188,7 @@ ClangExpressionParser::ClangExpressionPa
                                               ClangExpression &expr) :
     m_expr (expr),
     m_compiler (),
-    m_code_generator (NULL),
-    m_jitted_functions ()
+    m_code_generator (NULL)
 {
     // Initialize targets first, so that --version shows registered targets.
     static struct InitializeLLVM {
@@ -441,7 +440,7 @@ ClangExpressionParser::Parse (Stream &st
     return num_errors;
 }
 
-static bool FindFunctionInModule (std::string &mangled_name,
+static bool FindFunctionInModule (ConstString &mangled_name,
                                   llvm::Module *module,
                                   const char *orig_name)
 {
@@ -451,7 +450,7 @@ static bool FindFunctionInModule (std::s
     {        
         if (fi->getName().str().find(orig_name) != std::string::npos)
         {
-            mangled_name = fi->getName().str();
+            mangled_name.SetCString(fi->getName().str().c_str());
             return true;
         }
     }
@@ -460,16 +459,13 @@ static bool FindFunctionInModule (std::s
 }
 
 Error
-ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, 
-                                            lldb::addr_t &func_addr, 
+ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, 
                                             lldb::addr_t &func_end, 
                                             ExecutionContext &exe_ctx,
-                                            IRForTarget::StaticDataAllocator *data_allocator,
                                             bool &evaluated_statically,
                                             lldb::ClangExpressionVariableSP &const_result,
                                             ExecutionPolicy execution_policy)
 {
-    func_allocation_addr = LLDB_INVALID_ADDRESS;
 	func_addr = LLDB_INVALID_ADDRESS;
 	func_end = LLDB_INVALID_ADDRESS;
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -489,7 +485,7 @@ ClangExpressionParser::PrepareForExecuti
     
     // Find the actual name of the function (it's often mangled somehow)
     
-    std::string function_name;
+    ConstString function_name;
     
     if (!FindFunctionInModule(function_name, module_ap.get(), m_expr.FunctionName()))
     {
@@ -500,9 +496,14 @@ ClangExpressionParser::PrepareForExecuti
     else
     {
         if (log)
-            log->Printf("Found function %s for %s", function_name.c_str(), m_expr.FunctionName());
+            log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
     }
     
+    m_execution_unit.reset(new IRExecutionUnit(module_ap, // handed off here
+                                               function_name,
+                                               exe_ctx.GetProcessSP(),
+                                               m_compiler->getTargetOpts().Features));
+        
     ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
     
     if (decl_map)
@@ -516,11 +517,11 @@ ClangExpressionParser::PrepareForExecuti
                                   m_expr.NeedsVariableResolution(),
                                   execution_policy,
                                   const_result,
-                                  data_allocator,
+                                  *m_execution_unit,
                                   error_stream,
-                                  function_name.c_str());
+                                  function_name.AsCString());
         
-        bool ir_can_run = ir_for_target.runOnModule(*module_ap);
+        bool ir_can_run = ir_for_target.runOnModule(*m_execution_unit->GetModule());
         
         Error &interpreter_error(ir_for_target.getInterpreterError());
         
@@ -579,9 +580,9 @@ ClangExpressionParser::PrepareForExecuti
                     log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
             }
             
-            IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.c_str());
+            IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());
         
-            if (!ir_dynamic_checks.runOnModule(*module_ap))
+            if (!ir_dynamic_checks.runOnModule(*m_execution_unit->GetModule()))
             {
                 err.SetErrorToGenericError();
                 err.SetErrorString("Couldn't add dynamic checks to the expression");
@@ -590,264 +591,7 @@ ClangExpressionParser::PrepareForExecuti
         }
     }
     
-    // llvm will own this pointer when llvm::ExecutionEngine::createJIT is called 
-    // below so we don't need to free it.
-    RecordingMemoryManager *jit_memory_manager = new RecordingMemoryManager();
-    
-    std::string error_string;
-
-    if (log)
-    {
-        std::string s;
-        raw_string_ostream oss(s);
-        
-        module_ap->print(oss, NULL);
-        
-        oss.flush();
-        
-        log->Printf ("Module being sent to JIT: \n%s", s.c_str());
-    }
-    llvm::Triple triple(module_ap->getTargetTriple());
-    llvm::Function *function = module_ap->getFunction (function_name.c_str());
-    llvm::Reloc::Model relocModel;
-    llvm::CodeModel::Model codeModel;
-    if (triple.isOSBinFormatELF())
-    {
-        relocModel = llvm::Reloc::Static;
-        // This will be small for 32-bit and large for 64-bit.
-        codeModel = llvm::CodeModel::JITDefault;
-    }
-    else
-    {
-        relocModel = llvm::Reloc::PIC_;
-        codeModel = llvm::CodeModel::Small;
-    }
-    EngineBuilder builder(module_ap.release());
-    builder.setEngineKind(EngineKind::JIT)
-        .setErrorStr(&error_string)
-        .setRelocationModel(relocModel)
-        .setJITMemoryManager(jit_memory_manager)
-        .setOptLevel(CodeGenOpt::Less)
-        .setAllocateGVsWithCode(true)
-        .setCodeModel(codeModel)
-        .setUseMCJIT(true);
-    
-    StringRef mArch;
-    StringRef mCPU;
-    SmallVector<std::string, 0> mAttrs;
-    
-    for (std::string &feature : m_compiler->getTargetOpts().Features)
-        mAttrs.push_back(feature);
-    
-    TargetMachine *target_machine = builder.selectTarget(triple,
-                                                         mArch,
-                                                         mCPU,
-                                                         mAttrs);
-    
-    execution_engine_ap.reset(builder.create(target_machine));
+    m_execution_unit->GetRunnableInfo(err, func_addr, func_end);
         
-    if (!execution_engine_ap.get())
-    {
-        err.SetErrorToGenericError();
-        err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
-        return err;
-    }
-    
-    execution_engine_ap->DisableLazyCompilation();
-    
-    
-    // We don't actually need the function pointer here, this just forces it to get resolved.
-    
-    void *fun_ptr = execution_engine_ap->getPointerToFunction(function);
-        
-    // Errors usually cause failures in the JIT, but if we're lucky we get here.
-    
-    if (!function)
-    {
-        err.SetErrorToGenericError();
-        err.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", function_name.c_str());
-        return err;
-    }
-    
-    if (!fun_ptr)
-    {
-        err.SetErrorToGenericError();
-        err.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", function_name.c_str());
-        return err;
-    }
-    
-    m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(function_name.c_str(), (lldb::addr_t)fun_ptr));
-    
-
-    Process *process = exe_ctx.GetProcessPtr();
-    if (process == NULL)
-    {
-        err.SetErrorToGenericError();
-        err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target");
-        return err;
-    }
-        
-    jit_memory_manager->CommitAllocations(*process);
-    jit_memory_manager->ReportAllocations(*execution_engine_ap);
-    jit_memory_manager->WriteData(*process);
-    
-    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
-    
-    for (pos = m_jitted_functions.begin(); pos != end; pos++)
-    {
-        (*pos).m_remote_addr = jit_memory_manager->GetRemoteAddressForLocal ((*pos).m_local_addr);
-    
-        if (!(*pos).m_name.compare(function_name.c_str()))
-        {
-            RecordingMemoryManager::AddrRange func_range = jit_memory_manager->GetRemoteRangeForLocal((*pos).m_local_addr);
-            func_end = func_range.first + func_range.second;
-            func_addr = (*pos).m_remote_addr;
-        }
-    }
-    
-    if (log)
-    {
-        log->Printf("Code can be run in the target.");
-        
-        StreamString disassembly_stream;
-        
-        Error err = DisassembleFunction(disassembly_stream, exe_ctx, jit_memory_manager);
-        
-        if (!err.Success())
-        {
-            log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
-        }
-        else
-        {
-            log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
-        }
-    }
-    
-    err.Clear();
     return err;
 }
-
-Error
-ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &exe_ctx, RecordingMemoryManager *jit_memory_manager)
-{
-    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-    
-    const char *name = m_expr.FunctionName();
-    
-    Error ret;
-    
-    ret.Clear();
-    
-    lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
-    lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
-    
-    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
-    
-    for (pos = m_jitted_functions.begin(); pos < end; pos++)
-    {
-        if (strstr(pos->m_name.c_str(), name))
-        {
-            func_local_addr = pos->m_local_addr;
-            func_remote_addr = pos->m_remote_addr;
-        }
-    }
-    
-    if (func_local_addr == LLDB_INVALID_ADDRESS)
-    {
-        ret.SetErrorToGenericError();
-        ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", name);
-        return ret;
-    }
-    
-    if (log)
-        log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
-    
-    std::pair <lldb::addr_t, lldb::addr_t> func_range;
-    
-    func_range = jit_memory_manager->GetRemoteRangeForLocal(func_local_addr);
-    
-    if (func_range.first == 0 && func_range.second == 0)
-    {
-        ret.SetErrorToGenericError();
-        ret.SetErrorStringWithFormat("Couldn't find code range for function %s", name);
-        return ret;
-    }
-    
-    if (log)
-        log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);
-    
-    Target *target = exe_ctx.GetTargetPtr();
-    if (!target)
-    {
-        ret.SetErrorToGenericError();
-        ret.SetErrorString("Couldn't find the target");
-        return ret;
-    }
-    
-    lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
-    
-    Process *process = exe_ctx.GetProcessPtr();
-    Error err;
-    process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
-    
-    if (!err.Success())
-    {
-        ret.SetErrorToGenericError();
-        ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
-        return ret;
-    }
-    
-    ArchSpec arch(target->GetArchitecture());
-    
-    const char *plugin_name = NULL;
-    const char *flavor_string = NULL;
-    lldb::DisassemblerSP disassembler = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
-    
-    if (!disassembler)
-    {
-        ret.SetErrorToGenericError();
-        ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
-        return ret;
-    }
-    
-    if (!process)
-    {
-        ret.SetErrorToGenericError();
-        ret.SetErrorString("Couldn't find the process");
-        return ret;
-    }
-    
-    DataExtractor extractor(buffer_sp, 
-                            process->GetByteOrder(),
-                            target->GetArchitecture().GetAddressByteSize());
-    
-    if (log)
-    {
-        log->Printf("Function data has contents:");
-        extractor.PutToLog (log.get(),
-                            0,
-                            extractor.GetByteSize(),
-                            func_remote_addr,
-                            16,
-                            DataExtractor::TypeUInt8);
-    }
-    
-    disassembler->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false);
-    
-    InstructionList &instruction_list = disassembler->GetInstructionList();
-    const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
-    for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
-         instruction_index < num_instructions; 
-         ++instruction_index)
-    {
-        Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
-        instruction->Dump (&stream,
-                           max_opcode_byte_size,
-                           true,
-                           true,
-                           &exe_ctx);
-        stream.PutChar('\n');
-    }
-    
-    return ret;
-}

Modified: lldb/trunk/source/Expression/ClangFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangFunction.cpp Mon Mar 18 19:10:07 2013
@@ -264,18 +264,17 @@ ClangFunction::WriteFunctionWrapper (Exe
     
     bool evaluated_statically = false; // should stay that way
     
-    Error jit_error (m_parser->PrepareForExecution (m_jit_alloc,
-                                                    m_jit_start_addr,
+    Error jit_error (m_parser->PrepareForExecution (m_jit_start_addr,
                                                     m_jit_end_addr,
                                                     exe_ctx, 
-                                                    NULL,
                                                     evaluated_statically,
                                                     const_result,
                                                     eExecutionPolicyAlways));
     
     if (!jit_error.Success())
         return false;
-    if (process && m_jit_alloc != LLDB_INVALID_ADDRESS)
+    
+    if (process && m_jit_start_addr)
         m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
     
     m_JITted = true;

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Mon Mar 18 19:10:07 2013
@@ -460,30 +460,17 @@ ClangUserExpression::Parse (Stream &erro
     //////////////////////////////////////////////////////////////////////////////////////////
     // Prepare the output of the parser for execution, evaluating it statically if possible
     //
-        
-    if (execution_policy != eExecutionPolicyNever && process)
-        m_data_allocator.reset(new ProcessDataAllocator(*process));
-    
-    Error jit_error = parser.PrepareForExecution (m_jit_alloc,
-                                                  m_jit_start_addr,
+            
+    Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
                                                   m_jit_end_addr,
                                                   exe_ctx,
-                                                  m_data_allocator.get(),
                                                   m_evaluated_statically,
                                                   m_const_result,
                                                   execution_policy);
-    
-    if (log && m_data_allocator.get())
-    {
-        StreamString dump_string;
-        m_data_allocator->Dump(dump_string);
-        
-        log->Printf("Data buffer contents:\n%s", dump_string.GetString().c_str());
-    }
         
     if (jit_error.Success())
     {
-        if (process && m_jit_alloc != LLDB_INVALID_ADDRESS)
+        if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
             m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
         return true;
     }

Modified: lldb/trunk/source/Expression/ClangUtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUtilityFunction.cpp?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUtilityFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangUtilityFunction.cpp Mon Mar 18 19:10:07 2013
@@ -104,8 +104,6 @@ ClangUtilityFunction::Install (Stream &e
     
     m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
     
-    m_data_allocator.reset(new ProcessDataAllocator(*process));
-    
     if (!m_expr_decl_map->WillParse(exe_ctx))
     {
         error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
@@ -133,23 +131,13 @@ ClangUtilityFunction::Install (Stream &e
     
     bool evaluated_statically = false; // should stay that way
     
-    Error jit_error = parser.PrepareForExecution (m_jit_alloc, 
-                                                  m_jit_start_addr, 
+    Error jit_error = parser.PrepareForExecution (m_jit_start_addr, 
                                                   m_jit_end_addr, 
                                                   exe_ctx,
-                                                  m_data_allocator.get(),
                                                   evaluated_statically,
                                                   const_result,
                                                   eExecutionPolicyAlways);
     
-    if (log)
-    {
-        StreamString dump_string;
-        m_data_allocator->Dump(dump_string);
-        
-        log->Printf("Data buffer contents:\n%s", dump_string.GetString().c_str());
-    }
-    
     if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
         m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
     

Copied: lldb/trunk/source/Expression/IRExecutionUnit.cpp (from r176918, lldb/trunk/source/Expression/RecordingMemoryManager.cpp)
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRExecutionUnit.cpp?p2=lldb/trunk/source/Expression/IRExecutionUnit.cpp&p1=lldb/trunk/source/Expression/RecordingMemoryManager.cpp&r1=176918&r2=177364&rev=177364&view=diff
==============================================================================
--- lldb/trunk/source/Expression/RecordingMemoryManager.cpp (original)
+++ lldb/trunk/source/Expression/IRExecutionUnit.cpp Mon Mar 18 19:10:07 2013
@@ -1,4 +1,4 @@
-//===-- RecordingMemoryManager.cpp ------------------------------*- C++ -*-===//
+//===-- IRExecutionUnit.cpp ------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -11,46 +11,459 @@
 // C++ Includes
 // Other libraries and framework includes
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/IR/Module.h"
 // Project includes
-#include "lldb/Expression/RecordingMemoryManager.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Expression/IRExecutionUnit.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
 
 using namespace lldb_private;
 
-RecordingMemoryManager::RecordingMemoryManager () :
-    llvm::JITMemoryManager(),
-    m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
-    m_log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
+IRExecutionUnit::IRExecutionUnit (std::auto_ptr<llvm::Module> &module_ap,
+                                  ConstString &name,
+                                  lldb::ProcessSP process_sp,
+                                  std::vector<std::string> &cpu_features) :
+    m_process_wp(process_sp),
+    m_module_ap(module_ap),
+    m_module(m_module_ap.get()),
+    m_cpu_features(),
+    m_name(name),
+    m_did_jit(false),
+    m_function_load_addr(LLDB_INVALID_ADDRESS),
+    m_function_end_load_addr(LLDB_INVALID_ADDRESS)
+{
+    for (std::string &feature : cpu_features)
+    {
+        m_cpu_features.push_back(std::string(feature.c_str()));
+    }
+}
+
+lldb::addr_t
+IRExecutionUnit::WriteNow (const uint8_t *bytes,
+                           size_t size,
+                           Error &error)
+{    
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    Allocation allocation;
+    allocation.m_size = size;
+    allocation.m_alignment = 8;
+    allocation.m_local_start = LLDB_INVALID_ADDRESS;
+    allocation.m_section_id = Allocation::eSectionIDNone;
+        
+    lldb_private::Error err;
+    
+    size_t allocation_size = (allocation.m_size ? allocation.m_size : 1) + allocation.m_alignment - 1;
+    
+    if (allocation_size == 0)
+        allocation_size = 1;
+    
+    lldb::ProcessSP process_sp = m_process_wp.lock();
+    
+    if (!process_sp)
+    {
+        err.SetErrorToGenericError();
+        err.SetErrorString("Couldn't find the process");
+    }
+    
+    allocation.m_remote_allocation = process_sp->AllocateMemory(allocation_size,
+                                                                (lldb::ePermissionsReadable | lldb::ePermissionsWritable),
+                                                                err);
+    
+    if (!err.Success())
+        return LLDB_INVALID_ADDRESS;
+    
+    process_sp->WriteMemory(allocation.m_remote_allocation, bytes, size, err);
+    
+    if (!err.Success())
+    {
+        process_sp->DeallocateMemory(allocation.m_remote_allocation);
+        allocation.m_remote_allocation = LLDB_INVALID_ADDRESS;
+        return LLDB_INVALID_ADDRESS;
+    }
+    
+    uint64_t mask = allocation.m_alignment - 1;
+    
+    allocation.m_remote_start = (allocation.m_remote_allocation + mask) & (~mask);
+    
+    allocation.m_allocated = true;
+    
+    if (log)
+    {
+        log->Printf("IRExecutionUnit::WriteNow() wrote to 0x%llx", allocation.m_remote_start);
+        allocation.dump(log);
+    }
+    
+    m_allocations.push_back(allocation);
+    
+    return allocation.m_remote_start;
+}
+
+void
+IRExecutionUnit::FreeNow (lldb::addr_t allocation)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    if (allocation == LLDB_INVALID_ADDRESS)
+        return;
+    
+    lldb::ProcessSP process_sp = m_process_wp.lock();
+
+    if (!process_sp)
+        return;
+    
+    for (auto ai = m_allocations.begin(), ae = m_allocations.end();
+         ai != ae;
+         ++ai)
+    {
+        if (ai->m_remote_allocation == allocation)
+        {
+            m_allocations.erase(ai);
+            log->Printf("IRExecutionUnit::FreeNow() freed 0x%llx", allocation);
+            return;
+        }
+    }
+}
+
+Error
+IRExecutionUnit::DisassembleFunction (Stream &stream,
+                                      lldb::ProcessSP &process_wp)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    
+    ExecutionContext exe_ctx(process_wp);
+        
+    Error ret;
+    
+    ret.Clear();
+    
+    lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
+    lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
+        
+    for (JittedFunction &function : m_jitted_functions)
+    {
+        if (strstr(function.m_name.c_str(), m_name.AsCString()))
+        {
+            func_local_addr = function.m_local_addr;
+            func_remote_addr = function.m_remote_addr;
+        }
+    }
+    
+    if (func_local_addr == LLDB_INVALID_ADDRESS)
+    {
+        ret.SetErrorToGenericError();
+        ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", m_name.AsCString());
+        return ret;
+    }
+    
+    if (log)
+        log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
+    
+    std::pair <lldb::addr_t, lldb::addr_t> func_range;
+    
+    func_range = GetRemoteRangeForLocal(func_local_addr);
+    
+    if (func_range.first == 0 && func_range.second == 0)
+    {
+        ret.SetErrorToGenericError();
+        ret.SetErrorStringWithFormat("Couldn't find code range for function %s", m_name.AsCString());
+        return ret;
+    }
+    
+    if (log)
+        log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);
+    
+    Target *target = exe_ctx.GetTargetPtr();
+    if (!target)
+    {
+        ret.SetErrorToGenericError();
+        ret.SetErrorString("Couldn't find the target");
+        return ret;
+    }
+    
+    lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
+    
+    Process *process = exe_ctx.GetProcessPtr();
+    Error err;
+    process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
+    
+    if (!err.Success())
+    {
+        ret.SetErrorToGenericError();
+        ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
+        return ret;
+    }
+    
+    ArchSpec arch(target->GetArchitecture());
+    
+    const char *plugin_name = NULL;
+    const char *flavor_string = NULL;
+    lldb::DisassemblerSP disassembler = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
+    
+    if (!disassembler)
+    {
+        ret.SetErrorToGenericError();
+        ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
+        return ret;
+    }
+    
+    if (!process)
+    {
+        ret.SetErrorToGenericError();
+        ret.SetErrorString("Couldn't find the process");
+        return ret;
+    }
+    
+    DataExtractor extractor(buffer_sp,
+                            process->GetByteOrder(),
+                            target->GetArchitecture().GetAddressByteSize());
+    
+    if (log)
+    {
+        log->Printf("Function data has contents:");
+        extractor.PutToLog (log.get(),
+                            0,
+                            extractor.GetByteSize(),
+                            func_remote_addr,
+                            16,
+                            DataExtractor::TypeUInt8);
+    }
+    
+    disassembler->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false);
+    
+    InstructionList &instruction_list = disassembler->GetInstructionList();
+    const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
+    
+    for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
+         instruction_index < num_instructions;
+         ++instruction_index)
+    {
+        Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
+        instruction->Dump (&stream,
+                           max_opcode_byte_size,
+                           true,
+                           true,
+                           &exe_ctx);
+        stream.PutChar('\n');
+    }
+    
+    return ret;
+}
+
+void
+IRExecutionUnit::GetRunnableInfo(Error &error,
+                                 lldb::addr_t &func_addr,
+                                 lldb::addr_t &func_end)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    lldb::ProcessSP process_sp(m_process_wp.lock());
+    
+    func_addr = LLDB_INVALID_ADDRESS;
+    func_end = LLDB_INVALID_ADDRESS;
+    
+    if (!process_sp)
+    {
+        error.SetErrorToGenericError();
+        error.SetErrorString("Couldn't write the JIT compiled code into the process because the process is invalid");
+        return;
+    }
+    
+    if (m_did_jit)
+    {
+        func_addr = m_function_load_addr;
+        func_end = m_function_end_load_addr;
+        
+        return;
+    }; // someone else may have gotten the mutex first
+    
+    {
+        Mutex::Locker jit_mutex_locker(m_jit_mutex);
+        
+        if (m_did_jit)
+        {
+            func_addr = m_function_load_addr;
+            func_end = m_function_end_load_addr;
+            
+            return;
+        }; // someone else may have gotten the mutex first
+        
+        m_did_jit = true;
+        
+        lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+        
+        std::string error_string;
+        
+        if (log)
+        {
+            std::string s;
+            llvm::raw_string_ostream oss(s);
+            
+            m_module->print(oss, NULL);
+            
+            oss.flush();
+            
+            log->Printf ("Module being sent to JIT: \n%s", s.c_str());
+        }
+        
+        llvm::Triple triple(m_module->getTargetTriple());
+        llvm::Function *function = m_module->getFunction (m_name.AsCString());
+        llvm::Reloc::Model relocModel;
+        llvm::CodeModel::Model codeModel;
+        
+        if (triple.isOSBinFormatELF())
+        {
+            relocModel = llvm::Reloc::Static;
+            // This will be small for 32-bit and large for 64-bit.
+            codeModel = llvm::CodeModel::JITDefault;
+        }
+        else
+        {
+            relocModel = llvm::Reloc::PIC_;
+            codeModel = llvm::CodeModel::Small;
+        }
+        
+        llvm::EngineBuilder builder(m_module_ap.get());
+        
+        builder.setEngineKind(llvm::EngineKind::JIT)
+        .setErrorStr(&error_string)
+        .setRelocationModel(relocModel)
+        .setJITMemoryManager(new MemoryManager(*this))
+        .setOptLevel(llvm::CodeGenOpt::Less)
+        .setAllocateGVsWithCode(true)
+        .setCodeModel(codeModel)
+        .setUseMCJIT(true);
+        
+        llvm::StringRef mArch;
+        llvm::StringRef mCPU;
+        llvm::SmallVector<std::string, 0> mAttrs;
+        
+        for (std::string &feature : m_cpu_features)
+            mAttrs.push_back(feature);
+        
+        llvm::TargetMachine *target_machine = builder.selectTarget(triple,
+                                                                   mArch,
+                                                                   mCPU,
+                                                                   mAttrs);
+        
+        m_execution_engine_ap.reset(builder.create(target_machine));
+        
+        if (!m_execution_engine_ap.get())
+        {
+            error.SetErrorToGenericError();
+            error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
+            return;
+        }
+        else
+        {
+            m_module_ap.release(); // ownership was transferred
+        }
+        
+        m_execution_engine_ap->DisableLazyCompilation();
+        
+        // We don't actually need the function pointer here, this just forces it to get resolved.
+        
+        void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
+        
+        // Errors usually cause failures in the JIT, but if we're lucky we get here.
+        
+        if (!function)
+        {
+            error.SetErrorToGenericError();
+            error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
+            return;
+        }
+        
+        if (!fun_ptr)
+        {
+            error.SetErrorToGenericError();
+            error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
+            return;
+        }
+        
+        m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
+        
+        CommitAllocations(process_sp);
+        ReportAllocations(*m_execution_engine_ap);
+        WriteData(process_sp);
+                
+        for (JittedFunction &jitted_function : m_jitted_functions)
+        {
+            jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
+            
+            if (!jitted_function.m_name.compare(m_name.AsCString()))
+            {
+                AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
+                m_function_end_load_addr = func_range.first + func_range.second;
+                m_function_load_addr = jitted_function.m_remote_addr;
+            }
+        }
+        
+        if (log)
+        {
+            log->Printf("Code can be run in the target.");
+            
+            StreamString disassembly_stream;
+            
+            Error err = DisassembleFunction(disassembly_stream, process_sp);
+            
+            if (!err.Success())
+            {
+                log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
+            }
+            else
+            {
+                log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
+            }
+        }
+        
+        func_addr = m_function_load_addr;
+        func_end = m_function_end_load_addr;
+        
+        return;
+    }
+}
+
+IRExecutionUnit::~IRExecutionUnit ()
 {
 }
 
-RecordingMemoryManager::~RecordingMemoryManager ()
+IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :
+    m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
+    m_parent (parent)
 {
 }
 
 void
-RecordingMemoryManager::setMemoryWritable ()
+IRExecutionUnit::MemoryManager::setMemoryWritable ()
 {
     m_default_mm_ap->setMemoryWritable();
 }
 
 void
-RecordingMemoryManager::setMemoryExecutable ()
+IRExecutionUnit::MemoryManager::setMemoryExecutable ()
 {
     m_default_mm_ap->setMemoryExecutable();
 }
 
 
 uint8_t *
-RecordingMemoryManager::startFunctionBody(const llvm::Function *F,
-                     uintptr_t &ActualSize)
+IRExecutionUnit::MemoryManager::startFunctionBody(const llvm::Function *F,
+                                                  uintptr_t &ActualSize)
 {
     return m_default_mm_ap->startFunctionBody(F, ActualSize);
 }
 
 uint8_t *
-RecordingMemoryManager::allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
-                unsigned Alignment)
+IRExecutionUnit::MemoryManager::allocateStub(const llvm::GlobalValue* F,
+                                             unsigned StubSize,
+                                             unsigned Alignment)
 {
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
     uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
     
     Allocation allocation;
@@ -58,28 +471,31 @@ RecordingMemoryManager::allocateStub(con
     allocation.m_alignment = Alignment;
     allocation.m_local_start = (uintptr_t)return_value;
 
-    if (m_log)
+    if (log)
     {
-        m_log->Printf("RecordingMemoryManager::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
-                      F, StubSize, Alignment, return_value);
-        allocation.dump(m_log);
+        log->Printf("IRExecutionUnit::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
+                    F, StubSize, Alignment, return_value);
+        allocation.dump(log);
     }
     
-    m_allocations.push_back(allocation);
+    m_parent.m_allocations.push_back(allocation);
     
     return return_value;
 }
 
 void
-RecordingMemoryManager::endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
-               uint8_t *FunctionEnd)
+IRExecutionUnit::MemoryManager::endFunctionBody(const llvm::Function *F,
+                                                uint8_t *FunctionStart,
+                                                uint8_t *FunctionEnd)
 {
     m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
 }
 
 uint8_t *
-RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
+IRExecutionUnit::MemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
 {
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
     uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
     
     Allocation allocation;
@@ -87,21 +503,25 @@ RecordingMemoryManager::allocateSpace(in
     allocation.m_alignment = Alignment;
     allocation.m_local_start = (uintptr_t)return_value;
     
-    if (m_log)
+    if (log)
     {
-        m_log->Printf("RecordingMemoryManager::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
-                      (uint64_t)Size, Alignment, return_value);
-        allocation.dump(m_log);
+        log->Printf("IRExecutionUnit::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
+                               (uint64_t)Size, Alignment, return_value);
+        allocation.dump(log);
     }
     
-    m_allocations.push_back(allocation);
+    m_parent.m_allocations.push_back(allocation);
     
     return return_value;
 }
 
 uint8_t *
-RecordingMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
+IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
+                                                    unsigned Alignment,
+                                                    unsigned SectionID)
 {
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+    
     uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID);
     
     Allocation allocation;
@@ -111,21 +531,26 @@ RecordingMemoryManager::allocateCodeSect
     allocation.m_section_id = SectionID;
     allocation.m_executable = true;
     
-    if (m_log)
+    if (log)
     {
-        m_log->Printf("RecordingMemoryManager::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
-                      (uint64_t)Size, Alignment, SectionID, return_value);
-        allocation.dump(m_log);
+        log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
+                    (uint64_t)Size, Alignment, SectionID, return_value);
+        allocation.dump(log);
     }
     
-    m_allocations.push_back(allocation);
+    m_parent.m_allocations.push_back(allocation);
     
     return return_value;
 }
 
 uint8_t *
-RecordingMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, bool IsReadOnly)
+IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
+                                                    unsigned Alignment,
+                                                    unsigned SectionID,
+                                                    bool IsReadOnly)
 {
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
     uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
     
     Allocation allocation;
@@ -134,21 +559,24 @@ RecordingMemoryManager::allocateDataSect
     allocation.m_local_start = (uintptr_t)return_value;
     allocation.m_section_id = SectionID;
     
-    if (m_log)
+    if (log)
     {
-        m_log->Printf("RecordingMemoryManager::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
-                      (uint64_t)Size, Alignment, SectionID, return_value);
-        allocation.dump(m_log);
+        log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
+                    (uint64_t)Size, Alignment, SectionID, return_value);
+        allocation.dump(log);
     }
     
-    m_allocations.push_back(allocation);
+    m_parent.m_allocations.push_back(allocation);
     
     return return_value; 
 }
 
 uint8_t *
-RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
+IRExecutionUnit::MemoryManager::allocateGlobal(uintptr_t Size,
+                                               unsigned Alignment)
 {
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
     uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
     
     Allocation allocation;
@@ -156,102 +584,100 @@ RecordingMemoryManager::allocateGlobal(u
     allocation.m_alignment = Alignment;
     allocation.m_local_start = (uintptr_t)return_value;
     
-    if (m_log)
+    if (log)
     {
-        m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
-                      (uint64_t)Size, Alignment, return_value);
-        allocation.dump(m_log);
+        log->Printf("IRExecutionUnit::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
+                    (uint64_t)Size, Alignment, return_value);
+        allocation.dump(log);
     }
     
-    m_allocations.push_back(allocation);
+    m_parent.m_allocations.push_back(allocation);
 
     return return_value;
 }
 
 void
-RecordingMemoryManager::deallocateFunctionBody(void *Body)
+IRExecutionUnit::MemoryManager::deallocateFunctionBody(void *Body)
 {
     m_default_mm_ap->deallocateFunctionBody(Body);
 }
 
 uint8_t*
-RecordingMemoryManager::startExceptionTable(const llvm::Function* F,
-                       uintptr_t &ActualSize)
+IRExecutionUnit::MemoryManager::startExceptionTable(const llvm::Function* F,
+                                                    uintptr_t &ActualSize)
 {
     return m_default_mm_ap->startExceptionTable(F, ActualSize);
 }
 
 void
-RecordingMemoryManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
-                 uint8_t *TableEnd, uint8_t* FrameRegister)
+IRExecutionUnit::MemoryManager::endExceptionTable(const llvm::Function *F,
+                                                  uint8_t *TableStart,
+                                                  uint8_t *TableEnd,
+                                                  uint8_t* FrameRegister)
 {
     m_default_mm_ap->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
 }
 
 void
-RecordingMemoryManager::deallocateExceptionTable(void *ET)
+IRExecutionUnit::MemoryManager::deallocateExceptionTable(void *ET)
 {
     m_default_mm_ap->deallocateExceptionTable (ET);
 }
 
 lldb::addr_t
-RecordingMemoryManager::GetRemoteAddressForLocal (lldb::addr_t local_address)
+IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
 {
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
+    for (Allocation &allocation : m_allocations)
     {
-        if (local_address >= ai->m_local_start &&
-            local_address < ai->m_local_start + ai->m_size)
-            return ai->m_remote_start + (local_address - ai->m_local_start);
+        if (local_address >= allocation.m_local_start &&
+            local_address < allocation.m_local_start + allocation.m_size)
+            return allocation.m_remote_start + (local_address - allocation.m_local_start);
     }
 
     return LLDB_INVALID_ADDRESS;
 }
 
-RecordingMemoryManager::AddrRange
-RecordingMemoryManager::GetRemoteRangeForLocal (lldb::addr_t local_address)
+IRExecutionUnit::AddrRange
+IRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
 {
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
+    for (Allocation &allocation : m_allocations)
     {
-        if (local_address >= ai->m_local_start &&
-            local_address < ai->m_local_start + ai->m_size)
-            return AddrRange(ai->m_remote_start, ai->m_size);
+        if (local_address >= allocation.m_local_start &&
+            local_address < allocation.m_local_start + allocation.m_size)
+            return AddrRange(allocation.m_remote_start, allocation.m_size);
     }
     
     return AddrRange (0, 0);
 }
 
 bool
-RecordingMemoryManager::CommitAllocations (Process &process)
+IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
 {
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
     bool ret = true;
     
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
+    for (Allocation &allocation : m_allocations)
     {
-        if (ai->m_allocated)
+        if (allocation.m_allocated)
             continue;
         
         lldb_private::Error err;
         
-        size_t allocation_size = (ai->m_size ? ai->m_size : 1) + ai->m_alignment - 1;
+        size_t allocation_size = (allocation.m_size ? allocation.m_size : 1) + allocation.m_alignment - 1;
         
         if (allocation_size == 0)
             allocation_size = 1;
         
-        ai->m_remote_allocation = process.AllocateMemory(
+        allocation.m_remote_allocation = process_sp->AllocateMemory(
             allocation_size,
-            ai->m_executable ? (lldb::ePermissionsReadable | lldb::ePermissionsExecutable) 
-                             : (lldb::ePermissionsReadable | lldb::ePermissionsWritable), 
+            allocation.m_executable ? (lldb::ePermissionsReadable | lldb::ePermissionsExecutable) 
+                                    : (lldb::ePermissionsReadable | lldb::ePermissionsWritable), 
             err);
         
-        uint64_t mask = ai->m_alignment - 1;
+        uint64_t mask = allocation.m_alignment - 1;
         
-        ai->m_remote_start = (ai->m_remote_allocation + mask) & (~mask);
+        allocation.m_remote_start = (allocation.m_remote_allocation + mask) & (~mask);
         
         if (!err.Success())
         {
@@ -259,23 +685,21 @@ RecordingMemoryManager::CommitAllocation
             break;
         }
         
-        ai->m_allocated = true;
+        allocation.m_allocated = true;
         
-        if (m_log)
+        if (log)
         {
-            m_log->Printf("RecordingMemoryManager::CommitAllocations() committed an allocation");
-            ai->dump(m_log);
+            log->Printf("IRExecutionUnit::CommitAllocations() committed an allocation");
+            allocation.dump(log);
         }
     }
     
     if (!ret)
     {
-        for (AllocationList::iterator ai = m_allocations.end(), ae = m_allocations.end();
-             ai != ae;
-             ++ai)
+        for (Allocation &allocation : m_allocations)
         {
-            if (ai->m_allocated)
-                process.DeallocateMemory(ai->m_remote_start);
+            if (allocation.m_allocated)
+                process_sp->DeallocateMemory(allocation.m_remote_start);
         }
     }
     
@@ -283,44 +707,48 @@ RecordingMemoryManager::CommitAllocation
 }
 
 void
-RecordingMemoryManager::ReportAllocations (llvm::ExecutionEngine &engine)
+IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
 {
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
+    for (Allocation &allocation : m_allocations)
     {
-        if (!ai->m_allocated)
+        if (!allocation.m_allocated)
+            continue;
+        
+        if (allocation.m_local_start == LLDB_INVALID_ADDRESS)
             continue;
         
-        engine.mapSectionAddress((void*)ai->m_local_start, ai->m_remote_start);
+        engine.mapSectionAddress((void*)allocation.m_local_start, allocation.m_remote_start);
     }
     // Trigger re-application of relocations.
     engine.finalizeObject();
 }
 
 bool
-RecordingMemoryManager::WriteData (Process &process)
-{    
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
+IRExecutionUnit::WriteData (lldb::ProcessSP &process_sp)
+{
+    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+    for (Allocation &allocation : m_allocations)
     {
-        if (!ai->m_allocated)
+        if (!allocation.m_allocated)
             return false;
         
+        if (allocation.m_local_start == LLDB_INVALID_ADDRESS)
+            continue;
+        
         lldb_private::Error err;
         
-        if (process.WriteMemory(ai->m_remote_start, 
-                                (void*)ai->m_local_start, 
-                                ai->m_size, 
-                                err) != ai->m_size ||
+        if (process_sp->WriteMemory(allocation.m_remote_start,
+                                    (void*)allocation.m_local_start, 
+                                    allocation.m_size, 
+                                    err) != allocation.m_size ||
             !err.Success())
             return false;
         
-        if (m_log)
+        if (log)
         {
-            m_log->Printf("RecordingMemoryManager::CommitAllocations() wrote an allocation");
-            ai->dump(m_log);
+            log->Printf("IRExecutionUnit::CommitAllocations() wrote an allocation");
+            allocation.dump(log);
         }
     }
     
@@ -328,7 +756,7 @@ RecordingMemoryManager::WriteData (Proce
 }
 
 void 
-RecordingMemoryManager::Allocation::dump (lldb::LogSP log)
+IRExecutionUnit::Allocation::dump (lldb::LogSP log)
 {
     if (!log)
         return;

Modified: lldb/trunk/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=177364&r1=177363&r2=177364&view=diff
==============================================================================
--- lldb/trunk/source/Expression/IRForTarget.cpp (original)
+++ lldb/trunk/source/Expression/IRForTarget.cpp Mon Mar 18 19:10:07 2013
@@ -22,12 +22,14 @@
 
 #include "clang/AST/ASTContext.h"
 
-#include "lldb/Core/ConstString.h"
 #include "lldb/Core/dwarf.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Scalar.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/IRExecutionUnit.h"
 #include "lldb/Expression/IRInterpreter.h"
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
@@ -38,19 +40,32 @@ using namespace llvm;
 
 static char ID;
 
-IRForTarget::StaticDataAllocator::StaticDataAllocator()
+IRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) :
+    m_execution_unit(execution_unit),
+    m_allocation(LLDB_INVALID_ADDRESS)
 {
 }
 
-IRForTarget::StaticDataAllocator::~StaticDataAllocator()
+lldb::addr_t IRForTarget::StaticDataAllocator::Allocate()
 {
+    lldb_private::Error err;
+    
+    if (m_allocation != LLDB_INVALID_ADDRESS)
+    {
+        m_execution_unit.FreeNow(m_allocation);
+        m_allocation = LLDB_INVALID_ADDRESS;
+    }
+    
+    m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err);
+
+    return m_allocation;
 }
 
 IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
                           bool resolve_vars,
                           lldb_private::ExecutionPolicy execution_policy,
                           lldb::ClangExpressionVariableSP &const_result,
-                          StaticDataAllocator *data_allocator,
+                          lldb_private::IRExecutionUnit &execution_unit,
                           lldb_private::Stream *error_stream,
                           const char *func_name) :
     ModulePass(ID),
@@ -60,7 +75,7 @@ IRForTarget::IRForTarget (lldb_private::
     m_func_name(func_name),
     m_module(NULL),
     m_decl_map(decl_map),
-    m_data_allocator(data_allocator),
+    m_data_allocator(execution_unit),
     m_CFStringCreateWithBytes(NULL),
     m_sel_registerName(NULL),
     m_const_result(const_result),
@@ -1559,7 +1574,7 @@ IRForTarget::MaterializeInternalVariable
     if (global_variable == m_reloc_placeholder)
         return true;
     
-    uint64_t offset = m_data_allocator->GetStream().GetSize();
+    uint64_t offset = m_data_allocator.GetStream().GetSize();
     
     llvm::Type *variable_type = global_variable->getType();
     
@@ -1572,7 +1587,7 @@ IRForTarget::MaterializeInternalVariable
     
     const size_t mask = (align - 1);
     uint64_t aligned_offset = (offset + mask) & ~mask;
-    m_data_allocator->GetStream().PutNHex8(aligned_offset - offset, 0);
+    m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
     offset = aligned_offset;
     
     lldb_private::DataBufferHeap data(size, '\0');
@@ -1581,7 +1596,7 @@ IRForTarget::MaterializeInternalVariable
         if (!MaterializeInitializer(data.GetBytes(), initializer))
             return false;
     
-    m_data_allocator->GetStream().Write(data.GetBytes(), data.GetByteSize());
+    m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize());
     
     Constant *new_pointer = BuildRelocation(variable_type, offset);
         
@@ -1960,9 +1975,6 @@ IRForTarget::ReplaceStrings ()
 {
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
     
-    if (!m_data_allocator)
-        return true; // hope for the best; some clients may not want static allocation!
-    
     typedef std::map <GlobalVariable *, size_t> OffsetsTy;
     
     OffsetsTy offsets;
@@ -2014,9 +2026,9 @@ IRForTarget::ReplaceStrings ()
             str = gc_array->getAsString();
         }
             
-        offsets[gv] = m_data_allocator->GetStream().GetSize();
+        offsets[gv] = m_data_allocator.GetStream().GetSize();
         
-        m_data_allocator->GetStream().Write(str.c_str(), str.length() + 1);
+        m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1);
     }
     
     Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
@@ -2083,9 +2095,6 @@ bool
 IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
 {
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-        
-    if (!m_data_allocator)
-        return true;
     
     typedef SmallVector <Value*, 2> ConstantList;
     typedef SmallVector <llvm::Instruction*, 2> UserList;
@@ -2156,7 +2165,7 @@ IRForTarget::ReplaceStaticLiterals (llvm
             
             lldb_private::DataBufferHeap data(operand_data_size, 0);
             
-            if (lldb::endian::InlHostByteOrder() != m_data_allocator->GetStream().GetByteOrder())
+            if (lldb::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder())
             {
                 uint8_t *data_bytes = data.GetBytes();
                 
@@ -2172,16 +2181,16 @@ IRForTarget::ReplaceStaticLiterals (llvm
                 memcpy(data.GetBytes(), operand_raw_data, operand_data_size);
             }
             
-            uint64_t offset = m_data_allocator->GetStream().GetSize();
+            uint64_t offset = m_data_allocator.GetStream().GetSize();
             
             size_t align = m_target_data->getPrefTypeAlignment(operand_type);
             
             const size_t mask = (align - 1);
             uint64_t aligned_offset = (offset + mask) & ~mask;
-            m_data_allocator->GetStream().PutNHex8(aligned_offset - offset, 0);
+            m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
             offset = aligned_offset;
             
-            m_data_allocator->GetStream().Write(data.GetBytes(), operand_data_size);
+            m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size);
             
             llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo();
             
@@ -2603,16 +2612,13 @@ IRForTarget::BuildRelocation(llvm::Type
 
 bool 
 IRForTarget::CompleteDataAllocation ()
-{
-    if (!m_data_allocator)
-        return true;
-    
+{    
     lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
 
-    if (!m_data_allocator->GetStream().GetSize())
+    if (!m_data_allocator.GetStream().GetSize())
         return true;
     
-    lldb::addr_t allocation = m_data_allocator->Allocate();
+    lldb::addr_t allocation = m_data_allocator.Allocate();
     
     if (log)
     {
@@ -2622,7 +2628,7 @@ IRForTarget::CompleteDataAllocation ()
             log->Printf("Failed to allocate static data");
     }
     
-    if (!allocation)
+    if (!allocation || allocation == LLDB_INVALID_ADDRESS)
         return false;
     
     IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),

Removed: lldb/trunk/source/Expression/ProcessDataAllocator.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ProcessDataAllocator.cpp?rev=177363&view=auto
==============================================================================
--- lldb/trunk/source/Expression/ProcessDataAllocator.cpp (original)
+++ lldb/trunk/source/Expression/ProcessDataAllocator.cpp (removed)
@@ -1,43 +0,0 @@
-//===-- ProcessDataAllocator.cpp --------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Expression/ProcessDataAllocator.h"
-
-using namespace lldb_private;
-
-void
-ProcessDataAllocator::Dump(Stream &stream)
-{
-    size_t data_size = m_stream_string.GetSize();
-    
-    if (!m_allocation)
-        return;
-    
-    lldb::DataBufferSP data(new DataBufferHeap(data_size, 0));    
-    
-    Error error;
-    if (m_process.ReadMemory (m_allocation, data->GetBytes(), data_size, error) != data_size)
-        return;
-    
-    DataExtractor extractor(data, m_process.GetByteOrder(), m_process.GetAddressByteSize());
-    
-    extractor.Dump(&stream,                         // stream
-                   0,                               // offset
-                   lldb::eFormatBytesWithASCII,     // format
-                   1,                               // byte size of individual entries
-                   data_size,                       // number of entries
-                   16,                              // entries per line
-                   m_allocation,                    // address to print
-                   0,                               // bit size (bitfields only; 0 means ignore)
-                   0);                              // bit alignment (bitfields only; 0 means ignore)
-    
-    stream.PutChar('\n');
-}

Removed: lldb/trunk/source/Expression/RecordingMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/RecordingMemoryManager.cpp?rev=177363&view=auto
==============================================================================
--- lldb/trunk/source/Expression/RecordingMemoryManager.cpp (original)
+++ lldb/trunk/source/Expression/RecordingMemoryManager.cpp (removed)
@@ -1,342 +0,0 @@
-//===-- RecordingMemoryManager.cpp ------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
-// Project includes
-#include "lldb/Expression/RecordingMemoryManager.h"
-
-using namespace lldb_private;
-
-RecordingMemoryManager::RecordingMemoryManager () :
-    llvm::JITMemoryManager(),
-    m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
-    m_log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
-{
-}
-
-RecordingMemoryManager::~RecordingMemoryManager ()
-{
-}
-
-void
-RecordingMemoryManager::setMemoryWritable ()
-{
-    m_default_mm_ap->setMemoryWritable();
-}
-
-void
-RecordingMemoryManager::setMemoryExecutable ()
-{
-    m_default_mm_ap->setMemoryExecutable();
-}
-
-
-uint8_t *
-RecordingMemoryManager::startFunctionBody(const llvm::Function *F,
-                     uintptr_t &ActualSize)
-{
-    return m_default_mm_ap->startFunctionBody(F, ActualSize);
-}
-
-uint8_t *
-RecordingMemoryManager::allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
-                unsigned Alignment)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
-    
-    Allocation allocation;
-    allocation.m_size = StubSize;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
-                      F, StubSize, Alignment, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-    
-    return return_value;
-}
-
-void
-RecordingMemoryManager::endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
-               uint8_t *FunctionEnd)
-{
-    m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
-}
-
-uint8_t *
-RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
-    
-    Allocation allocation;
-    allocation.m_size = Size;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-    
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
-                      (uint64_t)Size, Alignment, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-    
-    return return_value;
-}
-
-uint8_t *
-RecordingMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID);
-    
-    Allocation allocation;
-    allocation.m_size = Size;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-    allocation.m_section_id = SectionID;
-    allocation.m_executable = true;
-    
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
-                      (uint64_t)Size, Alignment, SectionID, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-    
-    return return_value;
-}
-
-uint8_t *
-RecordingMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, bool IsReadOnly)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
-    
-    Allocation allocation;
-    allocation.m_size = Size;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-    allocation.m_section_id = SectionID;
-    
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
-                      (uint64_t)Size, Alignment, SectionID, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-    
-    return return_value; 
-}
-
-uint8_t *
-RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
-{
-    uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
-    
-    Allocation allocation;
-    allocation.m_size = Size;
-    allocation.m_alignment = Alignment;
-    allocation.m_local_start = (uintptr_t)return_value;
-    
-    if (m_log)
-    {
-        m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
-                      (uint64_t)Size, Alignment, return_value);
-        allocation.dump(m_log);
-    }
-    
-    m_allocations.push_back(allocation);
-
-    return return_value;
-}
-
-void
-RecordingMemoryManager::deallocateFunctionBody(void *Body)
-{
-    m_default_mm_ap->deallocateFunctionBody(Body);
-}
-
-uint8_t*
-RecordingMemoryManager::startExceptionTable(const llvm::Function* F,
-                       uintptr_t &ActualSize)
-{
-    return m_default_mm_ap->startExceptionTable(F, ActualSize);
-}
-
-void
-RecordingMemoryManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
-                 uint8_t *TableEnd, uint8_t* FrameRegister)
-{
-    m_default_mm_ap->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
-}
-
-void
-RecordingMemoryManager::deallocateExceptionTable(void *ET)
-{
-    m_default_mm_ap->deallocateExceptionTable (ET);
-}
-
-lldb::addr_t
-RecordingMemoryManager::GetRemoteAddressForLocal (lldb::addr_t local_address)
-{
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (local_address >= ai->m_local_start &&
-            local_address < ai->m_local_start + ai->m_size)
-            return ai->m_remote_start + (local_address - ai->m_local_start);
-    }
-
-    return LLDB_INVALID_ADDRESS;
-}
-
-RecordingMemoryManager::AddrRange
-RecordingMemoryManager::GetRemoteRangeForLocal (lldb::addr_t local_address)
-{
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (local_address >= ai->m_local_start &&
-            local_address < ai->m_local_start + ai->m_size)
-            return AddrRange(ai->m_remote_start, ai->m_size);
-    }
-    
-    return AddrRange (0, 0);
-}
-
-bool
-RecordingMemoryManager::CommitAllocations (Process &process)
-{
-    bool ret = true;
-    
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (ai->m_allocated)
-            continue;
-        
-        lldb_private::Error err;
-        
-        size_t allocation_size = (ai->m_size ? ai->m_size : 1) + ai->m_alignment - 1;
-        
-        if (allocation_size == 0)
-            allocation_size = 1;
-        
-        ai->m_remote_allocation = process.AllocateMemory(
-            allocation_size,
-            ai->m_executable ? (lldb::ePermissionsReadable | lldb::ePermissionsExecutable) 
-                             : (lldb::ePermissionsReadable | lldb::ePermissionsWritable), 
-            err);
-        
-        uint64_t mask = ai->m_alignment - 1;
-        
-        ai->m_remote_start = (ai->m_remote_allocation + mask) & (~mask);
-        
-        if (!err.Success())
-        {
-            ret = false;
-            break;
-        }
-        
-        ai->m_allocated = true;
-        
-        if (m_log)
-        {
-            m_log->Printf("RecordingMemoryManager::CommitAllocations() committed an allocation");
-            ai->dump(m_log);
-        }
-    }
-    
-    if (!ret)
-    {
-        for (AllocationList::iterator ai = m_allocations.end(), ae = m_allocations.end();
-             ai != ae;
-             ++ai)
-        {
-            if (ai->m_allocated)
-                process.DeallocateMemory(ai->m_remote_start);
-        }
-    }
-    
-    return ret;
-}
-
-void
-RecordingMemoryManager::ReportAllocations (llvm::ExecutionEngine &engine)
-{
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (!ai->m_allocated)
-            continue;
-        
-        engine.mapSectionAddress((void*)ai->m_local_start, ai->m_remote_start);
-    }
-    // Trigger re-application of relocations.
-    engine.finalizeObject();
-}
-
-bool
-RecordingMemoryManager::WriteData (Process &process)
-{    
-    for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
-         ai != ae;
-         ++ai)
-    {
-        if (!ai->m_allocated)
-            return false;
-        
-        lldb_private::Error err;
-        
-        if (process.WriteMemory(ai->m_remote_start, 
-                                (void*)ai->m_local_start, 
-                                ai->m_size, 
-                                err) != ai->m_size ||
-            !err.Success())
-            return false;
-        
-        if (m_log)
-        {
-            m_log->Printf("RecordingMemoryManager::CommitAllocations() wrote an allocation");
-            ai->dump(m_log);
-        }
-    }
-    
-    return true;
-}
-
-void 
-RecordingMemoryManager::Allocation::dump (lldb::LogSP log)
-{
-    if (!log)
-        return;
-    
-    log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
-                (unsigned long long)m_local_start,
-                (unsigned long long)m_size,
-                (unsigned long long)m_remote_start,
-                (unsigned)m_alignment,
-                (unsigned)m_section_id);
-}





More information about the lldb-commits mailing list