Performance optimizations to ClangUserExpression,
mostly related to management of the stack frame
for the interpreter.

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

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

<rdar://problem/13043685>

llvm-svn: 180664
diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp
index be8a589..28c3e5d 100644
--- a/lldb/source/Expression/IRMemoryMap.cpp
+++ b/lldb/source/Expression/IRMemoryMap.cpp
@@ -34,7 +34,8 @@
         for (AllocationMap::value_type &allocation : m_allocations)
         {
             if (allocation.second.m_policy == eAllocationPolicyMirror ||
-                allocation.second.m_policy == eAllocationPolicyHostOnly)
+                allocation.second.m_policy == eAllocationPolicyProcessOnly ||
+                (allocation.second.m_policy == eAllocationPolicyHostOnly && process_sp->CanJIT()))
                 process_sp->DeallocateMemory(allocation.second.m_process_alloc);
             
             if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
@@ -55,6 +56,18 @@
         
     lldb::addr_t ret = LLDB_INVALID_ADDRESS;
     
+    if (process_sp && process_sp->CanJIT())
+    {
+        Error alloc_error;
+        
+        ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error);
+        
+        if (!alloc_error.Success())
+            return LLDB_INVALID_ADDRESS;
+        else
+            return ret;
+    }
+    
     for (int iterations = 0; iterations < 16; ++iterations)
     {
         lldb::addr_t candidate;
@@ -367,12 +380,20 @@
     {
     default:
     case eAllocationPolicyHostOnly:
-        break;
+        {
+            lldb::ProcessSP process_sp = m_process_wp.lock();
+            if (process_sp && process_sp->CanJIT())
+                process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real
+
+            break;
+        }
     case eAllocationPolicyMirror:
     case eAllocationPolicyProcessOnly:
-        lldb::ProcessSP process_sp = m_process_wp.lock();
-        if (process_sp)
-            process_sp->DeallocateMemory(allocation.m_process_alloc);
+        {
+            lldb::ProcessSP process_sp = m_process_wp.lock();
+            if (process_sp)
+                process_sp->DeallocateMemory(allocation.m_process_alloc);
+        }
     }
     
     if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))