This revision was automatically updated to reflect the committed changes.
Closed by commit rL249380: RenderScript command for printing allocation 
information  (authored by EwanCrawford).

Changed prior to commit:
  http://reviews.llvm.org/D13247?vs=35968&id=36587#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D13247

Files:
  
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
  
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h

Index: lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
===================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -202,6 +202,8 @@
 
     void DumpKernels(Stream &strm) const;
 
+    void ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute);
+
     void AttemptBreakpointAtKernelName(Stream &strm, const char *name, Error &error, lldb::TargetSP target);
 
     void SetBreakAllKernels(bool do_break, lldb::TargetSP target);
@@ -220,6 +222,9 @@
     
   protected:
 
+    struct ScriptDetails;
+    struct AllocationDetails;
+
     void InitSearchFilter(lldb::TargetSP target)
     {
         if (!m_filtersp)
@@ -230,6 +235,10 @@
 
     void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
 
+    bool RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr);
+
+    bool EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result);
+
     lldb::BreakpointSP CreateKernelBreakpoint(const ConstString& name);
 
     void BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
@@ -256,9 +265,6 @@
     
     typedef std::shared_ptr<RuntimeHook> RuntimeHookSP;
 
-    struct ScriptDetails;
-    struct AllocationDetails;
-
     lldb::ModuleSP m_libRS;
     lldb::ModuleSP m_libRSDriver;
     lldb::ModuleSP m_libRSCpuRef;
@@ -292,6 +298,18 @@
     void CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context);
     void CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context);
 
+    //
+    // Helper functions for jitting the runtime
+    //
+    bool JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
+                        unsigned int x = 0, unsigned int y = 0, unsigned int z = 0);
+
+    bool JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr);
+
+    bool JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr);
+
+    bool JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr);
+
     // Search for a script detail object using a target address.
     // If a script does not currently exist this function will return nullptr.
     // If 'create' is true and there is no previous script with this address,
Index: lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
===================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -25,7 +25,7 @@
 #include "lldb/Interpreter/CommandObjectMultiword.h"
 #include "lldb/Breakpoint/StoppointCallbackContext.h"
 #include "lldb/Target/RegisterContext.h"
-
+#include "lldb/Expression/UserExpression.h"
 #include "lldb/Symbol/VariableList.h"
 
 using namespace lldb;
@@ -130,26 +130,116 @@
 // allocation instance.
 struct RenderScriptRuntime::AllocationDetails
 {
-    ~AllocationDetails () {};
+   // Taken from rsDefines.h
+   enum DataKind
+   {
+       RS_KIND_USER,
+       RS_KIND_PIXEL_L = 7,
+       RS_KIND_PIXEL_A,
+       RS_KIND_PIXEL_LA,
+       RS_KIND_PIXEL_RGB,
+       RS_KIND_PIXEL_RGBA,
+       RS_KIND_PIXEL_DEPTH,
+       RS_KIND_PIXEL_YUV,
+       RS_KIND_INVALID = 100
+   };
+
+   // Taken from rsDefines.h
+   enum DataType
+   {
+       RS_TYPE_NONE = 0,
+       RS_TYPE_FLOAT_16,
+       RS_TYPE_FLOAT_32,
+       RS_TYPE_FLOAT_64,
+       RS_TYPE_SIGNED_8,
+       RS_TYPE_SIGNED_16,
+       RS_TYPE_SIGNED_32,
+       RS_TYPE_SIGNED_64,
+       RS_TYPE_UNSIGNED_8,
+       RS_TYPE_UNSIGNED_16,
+       RS_TYPE_UNSIGNED_32,
+       RS_TYPE_UNSIGNED_64,
+       RS_TYPE_BOOLEAN
+    };
 
-    enum DataType
+    struct Dimension
     {
-        eInt,
+        uint32_t dim_1;
+        uint32_t dim_2;
+        uint32_t dim_3;
+        uint32_t cubeMap;
+
+        Dimension()
+        {
+             dim_1 = 0;
+             dim_2 = 0;
+             dim_3 = 0;
+             cubeMap = 0;
+        }
     };
 
-    enum Dimension
+    // Monotonically increasing from 1
+    static unsigned int ID;
+
+    // Maps Allocation DataType enum and vector size to printable strings
+    // using mapping from RenderScript numerical types summary documentation
+    static const char* RsDataTypeToString[][4];
+
+    // Maps Allocation DataKind enum to printable strings
+    static const char* RsDataKindToString[];
+
+    // Give each allocation an ID as a way
+    // for commands to reference it.
+    const unsigned int id;
+
+    empirical_type<DataType> type;            // Type of each data pointer stored by the allocation
+    empirical_type<DataKind> type_kind;       // Defines pixel type if Allocation is created from an image
+    empirical_type<uint32_t> type_vec_size;   // Vector size of each data point, e.g '4' for uchar4
+    empirical_type<Dimension> dimension;      // Dimensions of the Allocation
+    empirical_type<lldb::addr_t> address;     // Pointer to address of the RS Allocation
+    empirical_type<lldb::addr_t> data_ptr;    // Pointer to the data held by the Allocation
+    empirical_type<lldb::addr_t> type_ptr;    // Pointer to the RS Type of the Allocation
+    empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type
+    empirical_type<lldb::addr_t> context;     // Pointer to the RS Context of the Allocation
+
+    // Give each allocation an id, so we can reference it in user commands.
+    AllocationDetails(): id(ID++)
     {
-        e1d,
-        e2d,
-        e3d,
-        eCubeMap,
-    };
+    }
 
-    empirical_type<DataType> type;
-    empirical_type<Dimension> dimension;
-    empirical_type<lldb::addr_t> address;
-    empirical_type<lldb::addr_t> dataPtr;
-    empirical_type<lldb::addr_t> context;
+};
+
+unsigned int RenderScriptRuntime::AllocationDetails::ID = 1;
+
+const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] =
+{
+   "User",
+   "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
+   "Undefined", "Undefined", "Undefined",
+   "L Pixel",
+   "A Pixel",
+   "LA Pixel",
+   "RGB Pixel",
+   "RGBA Pixel",
+   "Pixel Depth",
+   "YUV Pixel"
+};
+
+const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] =
+{
+    {"None", "None", "None", "None"},
+    {"half", "half2", "half3", "half4"},
+    {"float", "float2", "float3", "float4"},
+    {"double", "double2", "double3", "double4"},
+    {"char", "char2", "char3", "char4"},
+    {"short", "short2", "short3", "short4"},
+    {"int", "int2", "int3", "int4"},
+    {"long", "long2", "long3", "long4"},
+    {"uchar", "uchar2", "uchar3", "uchar4"},
+    {"ushort", "ushort2", "ushort3", "ushort4"},
+    {"uint", "uint2", "uint3", "uint4"},
+    {"ulong", "ulong2", "ulong3", "ulong4"},
+    {"bool", "bool2", "bool3", "bool4"}
 };
 
 //------------------------------------------------------------------
@@ -250,7 +340,7 @@
             return eModuleKindDriver;
         }
 
-        const ConstString rs_cpureflib("libRSCPURef.so");
+        const ConstString rs_cpureflib("libRSCpuRef.so");
         if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
         {
             return eModuleKindImpl;
@@ -820,6 +910,330 @@
     }
 }
 
+// Uses the Target API to evaluate the expression passed as a parameter to the function
+// The result of that expression is returned an unsigned 64 bit int, via the result* paramter.
+// Function returns true on success, and false on failure
+bool
+RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result)
+{
+    Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+    if (log)
+        log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression);
+
+    ValueObjectSP expr_result;
+    // Perform the actual expression evaluation
+    GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result);
+
+    if (!expr_result)
+    {
+       if (log)
+           log->Printf("RenderScriptRuntime::EvalRSExpression -  Error: Couldn't evaluate expression");
+       return false;
+    }
+
+    // The result of the expression is invalid
+    if (!expr_result->GetError().Success())
+    {
+        Error err = expr_result->GetError();
+        if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success
+        {
+            if (log)
+                log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void");
+
+            result = nullptr;
+            return true;
+        }
+
+        if (log)
+            log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString());
+        return false;
+    }
+
+    bool success = false;
+    *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int.
+
+    if (!success)
+    {
+       if (log)
+           log->Printf("RenderScriptRuntime::EvalRSExpression -  Error: Couldn't convert expression result to unsigned int");
+       return false;
+    }
+
+    return true;
+}
+
+// Used to index expression format strings
+enum ExpressionStrings
+{
+   eExprGetOffsetPtr = 0,
+   eExprAllocGetType,
+   eExprTypeDimX,
+   eExprTypeDimY,
+   eExprTypeDimZ,
+   eExprTypeElemPtr,
+   eExprElementType,
+   eExprElementKind,
+   eExprElementVec
+};
+
+// Format strings containing the expressions we may need to evaluate.
+const char runtimeExpressions[][256] =
+{
+ // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
+ "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)",
+
+ // Type* rsaAllocationGetType(Context*, Allocation*)
+ "(void*)rsaAllocationGetType(0x%lx, 0x%lx)",
+
+ // rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
+ // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
+ // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
+ // Need to specify 32 or 64 bit for uint_t since this differs between devices
+ "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim
+ "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim
+ "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim
+ "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr
+
+ // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
+ // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
+ "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type
+ "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind
+ "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]"  // Vector Size
+};
+
+// JITs the RS runtime for the internal data pointer of an allocation.
+// Is passed x,y,z coordinates for the pointer to a specific element.
+// Then sets the data_ptr member in Allocation with the result.
+// Returns true on success, false otherwise
+bool
+RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
+                                    unsigned int x, unsigned int y, unsigned int z)
+{
+    Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+    if (!allocation->address.isValid())
+    {
+        if (log)
+            log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details");
+        return false;
+    }
+
+    const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr];
+    const int max_expr_size = 512; // Max expression size
+    char buffer[max_expr_size];
+
+    int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), x, y, z);
+    if (chars_written < 0)
+    {
+        if (log)
+            log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+        return false;
+    }
+    else if (chars_written >= max_expr_size)
+    {
+        if (log)
+            log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long");
+        return false;
+    }
+
+    uint64_t result = 0;
+    if (!EvalRSExpression(buffer, frame_ptr, &result))
+        return false;
+
+    addr_t mem_ptr = static_cast<lldb::addr_t>(result);
+    allocation->data_ptr = mem_ptr;
+
+    return true;
+}
+
+// JITs the RS runtime for the internal pointer to the RS Type of an allocation
+// Then sets the type_ptr member in Allocation with the result.
+// Returns true on success, false otherwise
+bool
+RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr)
+{
+    Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+    if (!allocation->address.isValid() || !allocation->context.isValid())
+    {
+        if (log)
+            log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details");
+        return false;
+    }
+
+    const char* expr_cstr = runtimeExpressions[eExprAllocGetType];
+    const int max_expr_size = 512; // Max expression size
+    char buffer[max_expr_size];
+
+    int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
+    if (chars_written < 0)
+    {
+        if (log)
+            log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+        return false;
+    }
+    else if (chars_written >= max_expr_size)
+    {
+        if (log)
+            log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long");
+        return false;
+    }
+
+    uint64_t result = 0;
+    if (!EvalRSExpression(buffer, frame_ptr, &result))
+        return false;
+
+    addr_t type_ptr = static_cast<lldb::addr_t>(result);
+    allocation->type_ptr = type_ptr;
+
+    return true;
+}
+
+// JITs the RS runtime for information about the dimensions and type of an allocation
+// Then sets dimension and element_ptr members in Allocation with the result.
+// Returns true on success, false otherwise
+bool
+RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr)
+{
+    Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+    if (!allocation->type_ptr.isValid() || !allocation->context.isValid())
+    {
+        if (log)
+            log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details");
+        return false;
+    }
+
+    // Expression is different depending on if device is 32 or 64 bit
+    uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
+    const unsigned int bits = archByteSize == 4 ? 32 : 64;
+
+    // We want 4 elements from packed data
+    const unsigned int num_exprs = 4;
+    assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions");
+
+    const int max_expr_size = 512; // Max expression size
+    char buffer[num_exprs][max_expr_size];
+    uint64_t results[num_exprs];
+
+    for (unsigned int i = 0; i < num_exprs; ++i)
+    {
+        int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprTypeDimX + i], bits,
+                                     *allocation->context.get(), *allocation->type_ptr.get());
+        if (chars_written < 0)
+        {
+            if (log)
+                log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+            return false;
+        }
+        else if (chars_written >= max_expr_size)
+        {
+            if (log)
+                log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long");
+            return false;
+        }
+
+        // Perform expression evaluation
+        if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
+            return false;
+    }
+
+    // Assign results to allocation members
+    AllocationDetails::Dimension dims;
+    dims.dim_1 = static_cast<uint32_t>(results[0]);
+    dims.dim_2 = static_cast<uint32_t>(results[1]);
+    dims.dim_3 = static_cast<uint32_t>(results[2]);
+    allocation->dimension = dims;
+
+    addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]);
+    allocation->element_ptr = elem_ptr;
+
+    if (log)
+        log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64,
+                    dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr);
+
+    return true;
+}
+
+// JITs the RS runtime for information about the Element of an allocation
+// Then sets type, type_vec_size, and type_kind members in Allocation with the result.
+// Returns true on success, false otherwise
+bool
+RenderScriptRuntime::JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr)
+{
+    Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+    if (!allocation->element_ptr.isValid() || !allocation->context.isValid())
+    {
+        if (log)
+            log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details");
+        return false;
+    }
+
+    // We want 3 elements from packed data
+    const unsigned int num_exprs = 3;
+    assert(num_exprs == (eExprElementVec - eExprElementType + 1) && "Invalid number of expressions");
+
+    const int max_expr_size = 512; // Max expression size
+    char buffer[num_exprs][max_expr_size];
+    uint64_t results[num_exprs];
+
+    for (unsigned int i = 0; i < num_exprs; i++)
+    {
+        int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprElementType + i], *allocation->context.get(), *allocation->element_ptr.get());
+        if (chars_written < 0)
+        {
+            if (log)
+                log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
+            return false;
+        }
+        else if (chars_written >= max_expr_size)
+        {
+            if (log)
+                log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long");
+            return false;
+        }
+
+        // Perform expression evaluation
+        if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
+            return false;
+    }
+
+    // Assign results to allocation members
+    allocation->type = static_cast<RenderScriptRuntime::AllocationDetails::DataType>(results[0]);
+    allocation->type_kind = static_cast<RenderScriptRuntime::AllocationDetails::DataKind>(results[1]);
+    allocation->type_vec_size = static_cast<uint32_t>(results[2]);
+
+    if (log)
+        log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u",
+                    *allocation->type.get(), *allocation->type_kind.get(), *allocation->type_vec_size.get());
+
+    return true;
+}
+
+// JIT all the current runtime info regarding an allocation
+bool
+RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr)
+{
+    // GetOffsetPointer()
+    if (!JITDataPointer(allocation, frame_ptr))
+        return false;
+
+    // rsaAllocationGetType()
+    if (!JITTypePointer(allocation, frame_ptr))
+        return false;
+
+    // rsaTypeGetNativeData()
+    if (!JITTypePacked(allocation, frame_ptr))
+        return false;
+
+    // rsaElementGetNativeData()
+    if (!JITElementPacked(allocation, frame_ptr))
+        return false;
+
+    return true;
+}
+
 bool
 RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
 {
@@ -1114,6 +1528,89 @@
     strm.IndentLess();
 }
 
+// Prints infomation regarding all the currently loaded allocations.
+// These details are gathered by jitting the runtime, which has as latency.
+void
+RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute)
+{
+    strm.Printf("RenderScript Allocations:");
+    strm.EOL();
+    strm.IndentMore();
+
+    for (auto &alloc : m_allocations)
+    {
+        // JIT the allocation info if we haven't done it, or the user forces us to.
+        bool do_refresh = !alloc->data_ptr.isValid() || recompute;
+
+        // JIT current allocation information
+        if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr))
+        {
+            strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id);
+            continue;
+        }
+
+        strm.Printf("%u:\n",alloc->id);
+        strm.IndentMore();
+
+        strm.Indent("Context: ");
+        if (!alloc->context.isValid())
+            strm.Printf("unknown\n");
+        else
+            strm.Printf("0x%" PRIx64 "\n", *alloc->context.get());
+
+        strm.Indent("Address: ");
+        if (!alloc->address.isValid())
+            strm.Printf("unknown\n");
+        else
+            strm.Printf("0x%" PRIx64 "\n", *alloc->address.get());
+
+        strm.Indent("Data pointer: ");
+        if (!alloc->data_ptr.isValid())
+            strm.Printf("unknown\n");
+        else
+            strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get());
+
+        strm.Indent("Dimensions: ");
+        if (!alloc->dimension.isValid())
+            strm.Printf("unknown\n");
+        else
+            strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1,
+                                          alloc->dimension.get()->dim_2,
+                                          alloc->dimension.get()->dim_3);
+
+        strm.Indent("Data Type: ");
+        if (!alloc->type.isValid() || !alloc->type_vec_size.isValid())
+            strm.Printf("unknown\n");
+        else
+        {
+            const int vector_size = *alloc->type_vec_size.get();
+            const AllocationDetails::DataType type = *alloc->type.get();
+
+            if (vector_size > 4 || vector_size < 1 ||
+                type < AllocationDetails::RS_TYPE_NONE || type > AllocationDetails::RS_TYPE_BOOLEAN)
+                strm.Printf("invalid type\n");
+            else
+                strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]);
+        }
+
+        strm.Indent("Data Kind: ");
+        if (!alloc->type_kind.isValid())
+            strm.Printf("unknown\n");
+        else
+        {
+            const AllocationDetails::DataKind kind = *alloc->type_kind.get();
+            if (kind < AllocationDetails::RS_KIND_USER || kind > AllocationDetails::RS_KIND_PIXEL_YUV)
+                strm.Printf("invalid kind\n");
+            else
+                strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]);
+        }
+
+        strm.EOL();
+        strm.IndentLess();
+    }
+    strm.IndentLess();
+}
+
 // Set breakpoints on every kernel found in RS module
 void
 RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
@@ -1608,6 +2105,108 @@
     ~CommandObjectRenderScriptRuntimeContext() {}
 };
 
+class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed
+{
+  public:
+    CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter)
+        : CommandObjectParsed(interpreter, "renderscript allocation list",
+                              "List renderscript allocations and their information.", "renderscript allocation list",
+                              eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
+    {
+    }
+
+    virtual Options*
+    GetOptions()
+    {
+        return &m_options;
+    }
+
+    class CommandOptions : public Options
+    {
+      public:
+        CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false)
+        {
+        }
+
+        virtual
+        ~CommandOptions()
+        {
+        }
+
+        virtual Error
+        SetOptionValue(uint32_t option_idx, const char *option_arg)
+        {
+            Error error;
+            const int short_option = m_getopt_table[option_idx].val;
+
+            switch (short_option)
+            {
+                case 'r':
+                    m_refresh = true;
+                    break;
+                default:
+                    error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
+                    break;
+            }
+            return error;
+        }
+
+        void
+        OptionParsingStarting()
+        {
+            m_refresh = false;
+        }
+
+        const OptionDefinition*
+        GetDefinitions()
+        {
+            return g_option_table;
+        }
+
+        static OptionDefinition g_option_table[];
+        bool m_refresh;
+    };
+
+    ~CommandObjectRenderScriptRuntimeAllocationList() {}
+
+    bool
+    DoExecute(Args &command, CommandReturnObject &result)
+    {
+        RenderScriptRuntime *runtime =
+          static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
+        runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh);
+        result.SetStatus(eReturnStatusSuccessFinishResult);
+        return true;
+    }
+
+  private:
+    CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
+      "Recompute allocation details."},
+    { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
+};
+
+
+class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword
+{
+  private:
+  public:
+    CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
+        : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.",
+                                 NULL)
+    {
+        LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter)));
+    }
+
+    ~CommandObjectRenderScriptRuntimeAllocation() {}
+};
+
+
 class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
 {
   private:
@@ -1643,6 +2242,7 @@
         LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
         LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
         LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
+        LoadSubCommand("allocation", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
     }
 
     ~CommandObjectRenderScriptRuntime() {}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to