summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime
diff options
context:
space:
mode:
authorEwan Crawford <ewan@codeplay.com>2016-01-20 12:03:29 +0000
committerEwan Crawford <ewan@codeplay.com>2016-01-20 12:03:29 +0000
commit4f8817c2db7a355f8131310c4e2e0c57fc452c5a (patch)
tree550a53e7a7517fa63bcdab24f361a23814452f67 /lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime
parentcc018c1713720b9da56922a2d83329ad97e1bb06 (diff)
downloadbcm5719-llvm-4f8817c2db7a355f8131310c4e2e0c57fc452c5a.tar.gz
bcm5719-llvm-4f8817c2db7a355f8131310c4e2e0c57fc452c5a.zip
[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. llvm-svn: 258303
Diffstat (limited to 'lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime')
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp165
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h8
2 files changed, 138 insertions, 35 deletions
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index a4d24445236..a1c6fa69cec 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -390,6 +390,8 @@ const unsigned int RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] =
{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::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const ch
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(void *baton, StoppointCallbackContext *
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::PlaceBreakpointOnKernel(Stream &strm, const char* name, con
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::PlaceBreakpointOnKernel(Stream &strm, const char* name, con
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;
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
index 715539e126b..0c63fd09be2 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h
@@ -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.
OpenPOWER on IntegriCloud