Author: ewancrawford
Date: Wed Jan 20 06:03:29 2016
New Revision: 258303

URL: http://llvm.org/viewvc/llvm-project?rev=258303&view=rev
Log:
[RenderScript] New command for viewing coordinate of current kernel invocation

Patch adds command 'language renderscript kernel coordinate' for printing the 
kernel index in (x,y,z) format.
This is done by walking the call stack and looking for a function with suffix 
'.expand', as well as the frame variables containing the coordinate data. 

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

Modified: 
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp?rev=258303&r1=258302&r2=258303&view=diff
==============================================================================
--- 
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
 (original)
+++ 
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
 Wed Jan 20 06:03:29 2016
@@ -390,6 +390,8 @@ const unsigned int RenderScriptRuntime::
     {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4} // 
RS_TYPE_MATRIX_2X2
 };
 
+const std::string RenderScriptRuntime::s_runtimeExpandSuffix(".expand");
+const std::array<const char *, 3> 
RenderScriptRuntime::s_runtimeCoordVars{"rsIndex", "p->current.y", 
"p->current.z"};
 //------------------------------------------------------------------
 // Static Functions
 //------------------------------------------------------------------
@@ -3071,6 +3073,79 @@ RenderScriptRuntime::GetFrameVarAsUnsign
     return true;
 }
 
+// Function attempts to find the current coordinate of a kernel invocation by 
investigating the
+// values of frame variables in the .expand function. These coordinates are 
returned via the coord
+// array reference parameter. Returns true if the coordinates could be found, 
and false otherwise.
+bool
+RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, Thread 
*thread_ptr)
+{
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
+
+    if (!thread_ptr)
+    {
+        if (log)
+            log->Printf("%s - Error, No thread pointer", __FUNCTION__);
+
+        return false;
+    }
+
+    // Walk the call stack looking for a function whose name has the suffix 
'.expand'
+    // and contains the variables we're looking for.
+    for (uint32_t i = 0; i < thread_ptr->GetStackFrameCount(); ++i)
+    {
+        if (!thread_ptr->SetSelectedFrameByIndex(i))
+            continue;
+
+        StackFrameSP frame_sp = thread_ptr->GetSelectedFrame();
+        if (!frame_sp)
+            continue;
+
+        // Find the function name
+        const SymbolContext sym_ctx = frame_sp->GetSymbolContext(false);
+        const char *func_name_cstr = sym_ctx.GetFunctionName().AsCString();
+        if (!func_name_cstr)
+            continue;
+
+        if (log)
+            log->Printf("%s - Inspecting function '%s'", __FUNCTION__, 
func_name_cstr);
+
+        // Check if function name has .expand suffix
+        std::string func_name(func_name_cstr);
+        const int length_difference = func_name.length() - 
RenderScriptRuntime::s_runtimeExpandSuffix.length();
+        if (length_difference <= 0)
+            continue;
+
+        const int32_t has_expand_suffix = func_name.compare(length_difference,
+                                                            
RenderScriptRuntime::s_runtimeExpandSuffix.length(),
+                                                            
RenderScriptRuntime::s_runtimeExpandSuffix);
+
+        if (has_expand_suffix != 0)
+            continue;
+
+        if (log)
+            log->Printf("%s - Found .expand function '%s'", __FUNCTION__, 
func_name_cstr);
+
+        // Get values for variables in .expand frame that tell us the current 
kernel invocation
+        bool found_coord_variables = true;
+        assert(RenderScriptRuntime::s_runtimeCoordVars.size() == coord.size());
+
+        for (uint32_t i = 0; i < coord.size(); ++i)
+        {
+            uint64_t value = 0;
+            if (!GetFrameVarAsUnsigned(frame_sp, 
RenderScriptRuntime::s_runtimeCoordVars[i], value))
+            {
+                found_coord_variables = false;
+                break;
+            }
+            coord[i] = value;
+        }
+
+        if (found_coord_variables)
+            return true;
+    }
+    return false;
+}
+
 // Callback when a kernel breakpoint hits and we're looking for a specific 
coordinate.
 // Baton parameter contains a pointer to the target coordinate we want to 
break on.
 // Function then checks the .expand frame for the current coordinate and 
breaks to user if it matches.
@@ -3086,53 +3161,38 @@ RenderScriptRuntime::KernelBreakpointHit
     assert(baton && "Error: null baton in conditional kernel breakpoint 
callback");
 
     // Coordinate we want to stop on
-    const int* target_coord = static_cast<const int*>(baton);
+    const uint32_t *target_coord = static_cast<const uint32_t *>(baton);
 
     if (log)
-        log->Printf("RenderScriptRuntime::KernelBreakpointHit - Break ID %" 
PRIu64 ", target coord (%d, %d, %d)",
-                    break_id, target_coord[0], target_coord[1], 
target_coord[2]);
+        log->Printf("%s - Break ID %" PRIu64 ", (%" PRIu32 ", %" PRIu32 ", %" 
PRIu32 ")", __FUNCTION__, break_id,
+                    target_coord[0], target_coord[1], target_coord[2]);
 
-    // Go up one stack frame to .expand kernel
+    // Select current thread
     ExecutionContext context(ctx->exe_ctx_ref);
-    ThreadSP thread_sp = context.GetThreadSP();
-    if (!thread_sp->SetSelectedFrameByIndex(1))
-    {
-        if (log)
-            log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, 
couldn't go up stack frame");
+    Thread *thread_ptr = context.GetThreadPtr();
+    assert(thread_ptr && "Null thread pointer");
 
-       return false;
-    }
-
-    StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
-    if (!frame_sp)
+    // Find current kernel invocation from .expand frame variables
+    RSCoordinate current_coord{}; // Zero initialise array
+    if (!GetKernelCoordinate(current_coord, thread_ptr))
     {
         if (log)
-            log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, 
couldn't select .expand stack frame");
+            log->Printf("%s - Error, couldn't select .expand stack frame", 
__FUNCTION__);
 
         return false;
     }
 
-    // Get values for variables in .expand frame that tell us the current 
kernel invocation
-    const char* coord_expressions[] = {"rsIndex", "p->current.y", 
"p->current.z"};
-    uint64_t current_coord[3] = {0, 0, 0};
-
-    for(int i = 0; i < 3; ++i)
-    {
-        if (!GetFrameVarAsUnsigned(frame_sp, coord_expressions[i], 
current_coord[i]))
-            return false;
-
-        if (log)
-            log->Printf("RenderScriptRuntime::KernelBreakpointHit, %s = %" 
PRIu64, coord_expressions[i], current_coord[i]);
-    }
+    if (log)
+        log->Printf("%s - (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", 
__FUNCTION__, current_coord[0], current_coord[1],
+                    current_coord[2]);
 
     // Check if the current kernel invocation coordinate matches our target 
coordinate
-    if (current_coord[0] == static_cast<uint64_t>(target_coord[0]) &&
-        current_coord[1] == static_cast<uint64_t>(target_coord[1]) &&
-        current_coord[2] == static_cast<uint64_t>(target_coord[2]))
+    if (current_coord[0] == target_coord[0] && current_coord[1] == 
target_coord[1] &&
+        current_coord[2] == target_coord[2])
     {
         if (log)
-             log->Printf("RenderScriptRuntime::KernelBreakpointHit, BREAKING 
%" PRIu64 ", %" PRIu64 ", %" PRIu64,
-                         current_coord[0], current_coord[1], current_coord[2]);
+            log->Printf("%s, BREAKING (%" PRIu32 ",%" PRIu32 ",%" PRIu32 ")", 
__FUNCTION__, current_coord[0],
+                        current_coord[1], current_coord[2]);
 
         BreakpointSP breakpoint_sp = 
context.GetTargetPtr()->GetBreakpointByID(break_id);
         assert(breakpoint_sp != nullptr && "Error: Couldn't find breakpoint 
matching break id for callback");
@@ -3169,7 +3229,7 @@ RenderScriptRuntime::PlaceBreakpointOnKe
         strm.EOL();
 
         // Allocate memory for the baton, and copy over coordinate
-        int* baton = new int[3];
+        uint32_t *baton = new uint32_t[coords.size()];
         baton[0] = coords[0]; baton[1] = coords[1]; baton[2] = coords[2];
 
         // Create a callback that will be invoked everytime the breakpoint is 
hit.
@@ -3177,7 +3237,7 @@ RenderScriptRuntime::PlaceBreakpointOnKe
         bp->SetCallback(KernelBreakpointHit, baton, true);
 
         // Store a shared pointer to the baton, so the memory will eventually 
be cleaned up after destruction
-        m_conditional_breaks[bp->GetID()] = std::shared_ptr<int>(baton);
+        m_conditional_breaks[bp->GetID()] = std::shared_ptr<uint32_t>(baton);
     }
 
     if (bp)
@@ -3606,6 +3666,42 @@ public:
     }
 };
 
+class CommandObjectRenderScriptRuntimeKernelCoordinate : public 
CommandObjectParsed
+{
+public:
+    CommandObjectRenderScriptRuntimeKernelCoordinate(CommandInterpreter 
&interpreter)
+        : CommandObjectParsed(interpreter, "renderscript kernel coordinate",
+                              "Shows the (x,y,z) coordinate of the current 
kernel invocation.",
+                              "renderscript kernel coordinate",
+                              eCommandRequiresProcess | 
eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
+    {
+    }
+
+    ~CommandObjectRenderScriptRuntimeKernelCoordinate() override = default;
+
+    bool
+    DoExecute(Args &command, CommandReturnObject &result) override
+    {
+        RSCoordinate coord{}; // Zero initialize array
+        bool success = RenderScriptRuntime::GetKernelCoordinate(coord, 
m_exe_ctx.GetThreadPtr());
+        Stream &stream = result.GetOutputStream();
+
+        if (success)
+        {
+            stream.Printf("Coordinate: (%" PRIu32 ", %" PRIu32 ", %" PRIu32 
")", coord[0], coord[1], coord[2]);
+            stream.EOL();
+            result.SetStatus(eReturnStatusSuccessFinishResult);
+        }
+        else
+        {
+            stream.Printf("Error: Coordinate could not be found.");
+            stream.EOL();
+            result.SetStatus(eReturnStatusFailed);
+        }
+        return true;
+    }
+};
+
 class CommandObjectRenderScriptRuntimeKernelBreakpoint : public 
CommandObjectMultiword
 {
 public:
@@ -3629,6 +3725,7 @@ public:
     {
         LoadSubCommand("list", CommandObjectSP(new 
CommandObjectRenderScriptRuntimeKernelList(interpreter)));
         LoadSubCommand("breakpoint", CommandObjectSP(new 
CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
+        LoadSubCommand("coordinate", CommandObjectSP(new 
CommandObjectRenderScriptRuntimeKernelCoordinate(interpreter)));
     }
 
     ~CommandObjectRenderScriptRuntimeKernel() override = default;

Modified: 
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h?rev=258303&r1=258302&r2=258303&view=diff
==============================================================================
--- 
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
 (original)
+++ 
lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
 Wed Jan 20 06:03:29 2016
@@ -36,6 +36,7 @@ struct RSKernelDescriptor;
 typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
 typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
 typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
+typedef std::array<uint32_t, 3> RSCoordinate;
 
 // Breakpoint Resolvers decide where a breakpoint is placed,
 // so having our own allows us to limit the search scope to RS kernel modules.
@@ -224,6 +225,9 @@ public:
 
     uint32_t GetPluginVersion() override;
 
+    static bool
+    GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, Thread 
*thread_ptr);
+
 protected:
     struct ScriptDetails;
     struct AllocationDetails;
@@ -279,7 +283,7 @@ protected:
 
     std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> 
m_scriptMappings;
     std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
-    std::map<lldb::user_id_t, std::shared_ptr<int>> m_conditional_breaks;
+    std::map<lldb::user_id_t, std::shared_ptr<uint32_t>> m_conditional_breaks;
 
     lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through 
Target API
 
@@ -288,6 +292,8 @@ protected:
     bool m_breakAllKernels;
     static const HookDefn s_runtimeHookDefns[];
     static const size_t s_runtimeHookCount;
+    static const std::string s_runtimeExpandSuffix;
+    static const std::array<const char *, 3> s_runtimeCoordVars;
 
 private:
     RenderScriptRuntime(Process *process); // Call CreateInstance instead.


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to