This revision seems to have created a hang on startup on Windows. LLDB now hangs during global static initialization on this line:
const ConstString RenderScriptRuntime::Element::FallbackStructName("struct"); Perhaps its an initialization order problem? Adrian. On Mon, Nov 30, 2015 at 2:29 AM, Ewan Crawford via lldb-commits < lldb-commits@lists.llvm.org> wrote: > Author: ewancrawford > Date: Mon Nov 30 04:29:49 2015 > New Revision: 254294 > > URL: http://llvm.org/viewvc/llvm-project?rev=254294&view=rev > Log: > [RS] Support RenderScript struct allocations > > This patch adds functionality for dumping allocations of struct elements. > This involves: > > + Jitting the runtime for details on all the struct fields. > > + Finding the name of the struct type by looking for a global variable > of the same type, which will have been reflected back to the java host code. > > + Using this struct type name to pass into expression evaluation for > pretty printing the data for the dump command. > > 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=254294&r1=254293&r2=254294&view=diff > > ============================================================================== > --- > lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp > (original) > +++ > lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp > Mon Nov 30 04:29:49 2015 > @@ -18,7 +18,9 @@ > #include "lldb/Core/Error.h" > #include "lldb/Core/Log.h" > #include "lldb/Core/PluginManager.h" > +#include "lldb/Core/ValueObjectVariable.h" > #include "lldb/Core/RegularExpression.h" > +#include "lldb/DataFormatters/DumpValueObjectOptions.h" > #include "lldb/Host/StringConvert.h" > #include "lldb/Symbol/Symbol.h" > #include "lldb/Symbol/Type.h" > @@ -133,42 +135,61 @@ struct RenderScriptRuntime::ScriptDetail > empirical_type<lldb::addr_t> script; > }; > > +// This Element class represents the Element object in RS, > +// defining the type associated with an Allocation. > +struct RenderScriptRuntime::Element > +{ > + // 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 > + }; > + > + std::vector<Element> children; // Child Element > fields for structs > + empirical_type<lldb::addr_t> element_ptr; // Pointer to > the RS Element of the Type > + 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<uint32_t> field_count; // Number of > Subelements > + empirical_type<uint32_t> datum_size; // Size of a > single Element with padding > + empirical_type<uint32_t> padding; // Number of > padding bytes > + empirical_type<uint32_t> array_size; // Number of > items in array, only needed for strucrs > + ConstString type_name; // Name of type, > only needed for structs > + > + static const ConstString FallbackStructName; // Print this as > the type name of a struct Element > + // If we can't > resolve the actual struct name > +}; > + > // This AllocationDetails class collects data associated with a single > // allocation instance. > struct RenderScriptRuntime::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 > - }; > - > struct Dimension > { > uint32_t dim_1; > @@ -214,14 +235,11 @@ struct RenderScriptRuntime::AllocationDe > // 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 > + RenderScriptRuntime::Element element; // Allocation Element type > 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 > empirical_type<uint32_t> size; // Size of the allocation > empirical_type<uint32_t> stride; // Stride between rows of > the allocation > @@ -232,6 +250,8 @@ struct RenderScriptRuntime::AllocationDe > } > }; > > +const ConstString > RenderScriptRuntime::Element::FallbackStructName("struct"); > + > unsigned int RenderScriptRuntime::AllocationDetails::ID = 1; > > const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] = > @@ -1099,7 +1119,11 @@ enum ExpressionStrings > eExprTypeElemPtr, > eExprElementType, > eExprElementKind, > - eExprElementVec > + eExprElementVec, > + eExprElementFieldCount, > + eExprSubelementsId, > + eExprSubelementsName, > + eExprSubelementsArrSize > }; > > // Format strings containing the expressions we may need to evaluate. > @@ -1122,9 +1146,22 @@ const char runtimeExpressions[][256] = > > // 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 > + "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, > 5); data[0]", // Type > + "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, > 5); data[1]", // Kind > + "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, > 5); data[3]", // Vector Size > + "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, > 5); data[4]", // Field Count > + > + // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t > *ids, const char **names, > + // size_t *arraySizes, uint32_t dataSize) > + // Needed for Allocations of structs to gather details about > fields/Subelements > + "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];" > + "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, > %u); ids[%u]", // Element* of field > + > + "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];" > + "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, > %u); names[%u]", // Name of field > + > + "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];" > + "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, > %u); arr_size[%u]" // Array size of field > }; > > // JITs the RS runtime for the internal data pointer of an allocation. > @@ -1272,7 +1309,7 @@ RenderScriptRuntime::JITTypePacked(Alloc > allocation->dimension = dims; > > addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]); > - allocation->element_ptr = elem_ptr; > + allocation->element.element_ptr = elem_ptr; > > if (log) > log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, > %u) Element*: 0x%" PRIx64, > @@ -1282,23 +1319,23 @@ RenderScriptRuntime::JITTypePacked(Alloc > } > > // 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. > +// Then sets type, type_vec_size, field_count and type_kind members in > Element with the result. > // Returns true on success, false otherwise > bool > -RenderScriptRuntime::JITElementPacked(AllocationDetails* allocation, > StackFrame* frame_ptr) > +RenderScriptRuntime::JITElementPacked(Element& elem, const lldb::addr_t > context, StackFrame* frame_ptr) > { > Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); > > - if (!allocation->element_ptr.isValid() || > !allocation->context.isValid()) > + if (!elem.element_ptr.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"); > + // We want 4 elements from packed data > + const unsigned int num_exprs = 4; > + assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1) > && "Invalid number of expressions"); > > const int max_expr_size = 512; // Max expression size > char buffer[num_exprs][max_expr_size]; > @@ -1306,11 +1343,11 @@ RenderScriptRuntime::JITElementPacked(Al > > 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()); > + int chars_written = snprintf(buffer[i], max_expr_size, > runtimeExpressions[eExprElementType + i], context, *elem.element_ptr.get()); > if (chars_written < 0) > { > if (log) > - log->Printf("RenderScriptRuntime::JITDataPointer - > Encoding error in snprintf()"); > + log->Printf("RenderScriptRuntime::JITElementPacked - > Encoding error in snprintf()"); > return false; > } > else if (chars_written >= max_expr_size) > @@ -1326,13 +1363,109 @@ RenderScriptRuntime::JITElementPacked(Al > } > > // 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]); > + elem.type = > static_cast<RenderScriptRuntime::Element::DataType>(results[0]); > + elem.type_kind = > static_cast<RenderScriptRuntime::Element::DataKind>(results[1]); > + elem.type_vec_size = static_cast<uint32_t>(results[2]); > + elem.field_count = static_cast<uint32_t>(results[3]); > > 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()); > + log->Printf("RenderScriptRuntime::JITElementPacked - data type > %u, pixel type %u, vector size %u, field count %u", > + *elem.type.get(), *elem.type_kind.get(), > *elem.type_vec_size.get(), *elem.field_count.get()); > + > + // If this Element has subelements then JIT > rsaElementGetSubElements() for details about its fields > + if (*elem.field_count.get() > 0 && !JITSubelements(elem, context, > frame_ptr)) > + return false; > + > + return true; > +} > + > +// JITs the RS runtime for information about the subelements/fields of a > struct allocation > +// This is necessary for infering the struct type so we can pretty print > the allocation's contents. > +// Returns true on success, false otherwise > +bool > +RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t > context, StackFrame* frame_ptr) > +{ > + Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); > + > + if (!elem.element_ptr.isValid() || !elem.field_count.isValid()) > + { > + if (log) > + log->Printf("RenderScriptRuntime::JITSubelements - Failed to > find allocation details"); > + return false; > + } > + > + const short num_exprs = 3; > + assert(num_exprs == (eExprSubelementsArrSize - eExprSubelementsId + > 1) && "Invalid number of expressions"); > + > + const int max_expr_size = 512; // Max expression size > + char expr_buffer[max_expr_size]; > + uint64_t results; > + > + // Iterate over struct fields. > + const uint32_t field_count = *elem.field_count.get(); > + for (unsigned int field_index = 0; field_index < field_count; > ++field_index) > + { > + Element child; > + for (unsigned int expr_index = 0; expr_index < num_exprs; > ++expr_index) > + { > + int chars_written = snprintf(expr_buffer, max_expr_size, > runtimeExpressions[eExprSubelementsId + expr_index], > + field_count, field_count, > field_count, > + context, > *elem.element_ptr.get(), field_count, field_index); > + if (chars_written < 0) > + { > + if (log) > + log->Printf("RenderScriptRuntime::JITSubelements - > Encoding error in snprintf()"); > + return false; > + } > + else if (chars_written >= max_expr_size) > + { > + if (log) > + log->Printf("RenderScriptRuntime::JITSubelements - > Expression too long"); > + return false; > + } > + > + // Perform expression evaluation > + if (!EvalRSExpression(expr_buffer, frame_ptr, &results)) > + return false; > + > + if (log) > + log->Printf("RenderScriptRuntime::JITSubelements - Expr > result 0x%" PRIx64, results); > + > + switch(expr_index) > + { > + case 0: // Element* of child > + child.element_ptr = static_cast<addr_t>(results); > + break; > + case 1: // Name of child > + { > + lldb::addr_t address = static_cast<addr_t>(results); > + Error err; > + std::string name; > + GetProcess()->ReadCStringFromMemory(address, name, > err); > + if (!err.Fail()) > + child.type_name = ConstString(name); > + else > + { > + if (log) > + > log->Printf("RenderScriptRuntime::JITSubelements - Warning: Couldn't read > field name"); > + } > + break; > + } > + case 2: // Array size of child > + child.array_size = static_cast<uint32_t>(results); > + break; > + } > + } > + > + // We need to recursively JIT each Element field of the struct > since > + // structs can be nested inside structs. > + if (!JITElementPacked(child, context, frame_ptr)) > + return false; > + elem.children.push_back(child); > + } > + > + // Try to infer the name of the struct type so we can pretty print > the allocation contents. > + FindStructTypeName(elem, frame_ptr); > > return true; > } > @@ -1343,28 +1476,43 @@ RenderScriptRuntime::JITElementPacked(Al > // Using this offset minus the starting address we can calculate the size > of the allocation. > // Returns true on success, false otherwise > bool > -RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, > StackFrame* frame_ptr, > - const uint32_t elem_size) > +RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, > StackFrame* frame_ptr) > { > Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); > > if (!allocation->address.isValid() || !allocation->dimension.isValid() > - || !allocation->data_ptr.isValid()) > + || !allocation->data_ptr.isValid() || > !allocation->element.datum_size.isValid()) > { > if (log) > log->Printf("RenderScriptRuntime::JITAllocationSize - 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]; > - > // Find dimensions > unsigned int dim_x = allocation->dimension.get()->dim_1; > unsigned int dim_y = allocation->dimension.get()->dim_2; > unsigned int dim_z = allocation->dimension.get()->dim_3; > > + // Our plan of jitting the last element address doesn't seem to work > for struct Allocations > + // Instead try to infer the size ourselves without any inter element > padding. > + if (allocation->element.children.size() > 0) > + { > + if (dim_x == 0) dim_x = 1; > + if (dim_y == 0) dim_y = 1; > + if (dim_z == 0) dim_z = 1; > + > + allocation->size = dim_x * dim_y * dim_z * > *allocation->element.datum_size.get(); > + > + if (log) > + log->Printf("RenderScriptRuntime::JITAllocationSize - Infered > size of struct allocation %u", *allocation->size.get()); > + > + return true; > + } > + > + const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr]; > + const int max_expr_size = 512; > + char buffer[max_expr_size]; > + > // Calculate last element > dim_x = dim_x == 0 ? 0 : dim_x - 1; > dim_y = dim_y == 0 ? 0 : dim_y - 1; > @@ -1391,7 +1539,7 @@ RenderScriptRuntime::JITAllocationSize(A > > addr_t mem_ptr = static_cast<lldb::addr_t>(result); > // Find pointer to last element and add on size of an element > - allocation->size = static_cast<uint32_t>(mem_ptr - > *allocation->data_ptr.get()) + elem_size; > + allocation->size = static_cast<uint32_t>(mem_ptr - > *allocation->data_ptr.get()) + *allocation->element.datum_size.get(); > > return true; > } > @@ -1457,31 +1605,140 @@ RenderScriptRuntime::RefreshAllocation(A > return false; > > // rsaElementGetNativeData() > - if (!JITElementPacked(allocation, frame_ptr)) > + if (!JITElementPacked(allocation->element, > *allocation->context.get(), frame_ptr)) > return false; > > + // Sets the datum_size member in Element > + SetElementSize(allocation->element); > + > // Use GetOffsetPointer() to infer size of the allocation > - const unsigned int element_size = GetElementSize(allocation); > - if (!JITAllocationSize(allocation, frame_ptr, element_size)) > + if (!JITAllocationSize(allocation, frame_ptr)) > return false; > > return true; > } > > -// Returns the size of a single allocation element including padding. > +// Function attempts to set the type_name member of the paramaterised > Element object. > +// This string should be the name of the struct type the Element > represents. > +// We need this string for pretty printing the Element to users. > +void > +RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* > frame_ptr) > +{ > + Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); > + > + if (!elem.type_name.IsEmpty()) // Name already set > + return; > + else > + elem.type_name = Element::FallbackStructName; // Default type > name if we don't succeed > + > + // Find all the global variables from the script rs modules > + VariableList variable_list; > + for (auto module_sp : m_rsmodules) > + module_sp->m_module->FindGlobalVariables(RegularExpression("."), > true, UINT32_MAX, variable_list); > + > + // Iterate over all the global variables looking for one with a > matching type to the Element. > + // We make the assumption a match exists since there needs to be a > global variable to reflect the > + // struct type back into java host code. > + for (uint32_t var_index = 0; var_index < variable_list.GetSize(); > ++var_index) > + { > + const VariableSP > var_sp(variable_list.GetVariableAtIndex(var_index)); > + if (!var_sp) > + continue; > + > + ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, > var_sp); > + if (!valobj_sp) > + continue; > + > + // Find the number of variable fields. > + // If it has no fields, or more fields than our Element, then it > can't be the struct we're looking for. > + // Don't check for equality since RS can add extra struct members > for padding. > + size_t num_children = valobj_sp->GetNumChildren(); > + if (num_children > elem.children.size() || num_children == 0) > + continue; > + > + // Iterate over children looking for members with matching field > names. > + // If all the field names match, this is likely the struct we > want. > + // > + // TODO: This could be made more robust by also checking > children data sizes, or array size > + bool found = true; > + for (size_t child_index = 0; child_index < num_children; > ++child_index) > + { > + ValueObjectSP child = valobj_sp->GetChildAtIndex(child_index, > true); > + if (!child || (child->GetName() != > elem.children[child_index].type_name)) > + { > + found = false; > + break; > + } > + } > + > + // RS can add extra struct members for padding in the format > '#rs_padding_[0-9]+' > + if (found && num_children < elem.children.size()) > + { > + const unsigned int size_diff = elem.children.size() - > num_children; > + if (log) > + log->Printf("RenderScriptRuntime::FindStructTypeName - %u > padding struct entries", size_diff); > + > + for (unsigned int padding_index = 0; padding_index < > size_diff; ++padding_index) > + { > + const ConstString& name = elem.children[num_children + > padding_index].type_name; > + if (strcmp(name.AsCString(), "#rs_padding") < 0) > + found = false; > + } > + } > + > + // We've found a global var with matching type > + if (found) > + { > + // Dereference since our Element type isn't a pointer. > + if (valobj_sp->IsPointerType()) > + { > + Error err; > + ValueObjectSP deref_valobj = valobj_sp->Dereference(err); > + if (!err.Fail()) > + valobj_sp = deref_valobj; > + } > + > + // Save name of variable in Element. > + elem.type_name = valobj_sp->GetTypeName(); > + if (log) > + log->Printf("RenderScriptRuntime::FindStructTypeName - > Element name set to %s", elem.type_name.AsCString()); > + > + return; > + } > + } > +} > + > +// Function sets the datum_size member of Element. Representing the size > of a single instance including padding. > // Assumes the relevant allocation information has already been jitted. > -unsigned int > -RenderScriptRuntime::GetElementSize(const AllocationDetails* allocation) > +void > +RenderScriptRuntime::SetElementSize(Element& elem) > { > - const AllocationDetails::DataType type = *allocation->type.get(); > - assert(type >= AllocationDetails::RS_TYPE_NONE && type <= > AllocationDetails::RS_TYPE_BOOLEAN > + Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); > + const Element::DataType type = *elem.type.get(); > + assert(type >= Element::RS_TYPE_NONE && type <= > Element::RS_TYPE_BOOLEAN > && "Invalid allocation > type"); > > - const unsigned int vec_size = *allocation->type_vec_size.get(); > - const unsigned int data_size = vec_size * > AllocationDetails::RSTypeToFormat[type][eElementSize]; > + const unsigned int vec_size = *elem.type_vec_size.get(); > + unsigned int data_size = 0; > const unsigned int padding = vec_size == 3 ? > AllocationDetails::RSTypeToFormat[type][eElementSize] : 0; > > - return data_size + padding; > + // Element is of a struct type, calculate size recursively. > + if ((type == Element::RS_TYPE_NONE) && (elem.children.size() > 0)) > + { > + for (Element& child : elem.children) > + { > + SetElementSize(child); > + const unsigned int array_size = child.array_size.isValid() ? > *child.array_size.get() : 1; > + data_size += *child.datum_size.get() * array_size; > + } > + } > + else > + data_size = vec_size * > AllocationDetails::RSTypeToFormat[type][eElementSize]; > + > + elem.padding = padding; > + elem.datum_size = data_size + padding; > + if (log) > + log->Printf("RenderScriptRuntime::SetElementSize - element size > set to %u", data_size + padding); > } > > // Given an allocation, this function copies the allocation contents from > device into a buffer on the heap. > @@ -1492,8 +1749,8 @@ RenderScriptRuntime::GetAllocationData(A > Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); > > // JIT all the allocation details > - if (!allocation->data_ptr.isValid() || !allocation->type.isValid() || > !allocation->type_vec_size.isValid() > - || !allocation->size.isValid()) > + if (!allocation->data_ptr.isValid() || > !allocation->element.type.isValid() > + || !allocation->element.type_vec_size.isValid() || > !allocation->size.isValid()) > { > if (log) > log->Printf("RenderScriptRuntime::GetAllocationData - > Allocation details not calculated yet, jitting info"); > @@ -1506,7 +1763,7 @@ RenderScriptRuntime::GetAllocationData(A > } > } > > - assert(allocation->data_ptr.isValid() && allocation->type.isValid() > && allocation->type_vec_size.isValid() > + assert(allocation->data_ptr.isValid() && > allocation->element.type.isValid() && > allocation->element.type_vec_size.isValid() > && allocation->size.isValid() && "Allocation information not > available"); > > // Allocate a buffer to copy data into > @@ -1551,7 +1808,8 @@ RenderScriptRuntime::LoadAllocation(Stre > log->Printf("RenderScriptRuntime::LoadAllocation - Found > allocation 0x%" PRIx64, *alloc->address.get()); > > // JIT all the allocation details > - if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || > !alloc->type_vec_size.isValid() || !alloc->size.isValid()) > + if (!alloc->data_ptr.isValid() || !alloc->element.type.isValid() || > !alloc->element.datum_size.isValid() > + || !alloc->element.type_vec_size.isValid() || > !alloc->size.isValid()) > { > if (log) > log->Printf("RenderScriptRuntime::LoadAllocation - Allocation > details not calculated yet, jitting info"); > @@ -1564,8 +1822,8 @@ RenderScriptRuntime::LoadAllocation(Stre > } > } > > - assert(alloc->data_ptr.isValid() && alloc->type.isValid() && > alloc->type_vec_size.isValid() && alloc->size.isValid() > - && "Allocation information not available"); > + assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && > alloc->element.type_vec_size.isValid() > + && alloc->size.isValid() && > alloc->element.datum_size.isValid() && "Allocation information not > available"); > > // Check we can read from file > FileSpec file(filename, true); > @@ -1598,16 +1856,15 @@ RenderScriptRuntime::LoadAllocation(Stre > head->type, head->element_size); > > // Check if the target allocation and file both have the same number > of bytes for an Element > - const unsigned int elem_size = GetElementSize(alloc); > - if (elem_size != head->element_size) > + if (*alloc->element.datum_size.get() != head->element_size) > { > strm.Printf("Warning: Mismatched Element sizes - file %u bytes, > allocation %u bytes", > - head->element_size, elem_size); > + head->element_size, *alloc->element.datum_size.get()); > strm.EOL(); > } > > // Check if the target allocation and file both have the same > integral type > - const unsigned int type = static_cast<unsigned > int>(*alloc->type.get()); > + const unsigned int type = static_cast<unsigned > int>(*alloc->element.type.get()); > if (type != head->type) > { > const char* file_type_cstr = > AllocationDetails::RsDataTypeToString[head->type][0]; > @@ -1665,8 +1922,8 @@ RenderScriptRuntime::SaveAllocation(Stre > log->Printf("RenderScriptRuntime::SaveAllocation - Found > allocation 0x%" PRIx64, *alloc->address.get()); > > // JIT all the allocation details > - if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || > !alloc->type_vec_size.isValid() > - || !alloc->type_kind.isValid() || !alloc->dimension.isValid()) > + if (!alloc->data_ptr.isValid() || !alloc->element.type.isValid() || > !alloc->element.type_vec_size.isValid() > + || !alloc->element.type_kind.isValid() || > !alloc->dimension.isValid()) > { > if (log) > log->Printf("RenderScriptRuntime::SaveAllocation - Allocation > details not calculated yet, jitting info"); > @@ -1679,8 +1936,8 @@ RenderScriptRuntime::SaveAllocation(Stre > } > } > > - assert(alloc->data_ptr.isValid() && alloc->type.isValid() && > alloc->type_vec_size.isValid() && alloc->type_kind.isValid() > - && alloc->dimension.isValid() && "Allocation information not > available"); > + assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && > alloc->element.type_vec_size.isValid() && alloc->element.datum_size.get() > + && alloc->element.type_kind.isValid() && > alloc->dimension.isValid() && "Allocation information not available"); > > // Check we can create writable file > FileSpec file_spec(filename, true); > @@ -1705,12 +1962,12 @@ RenderScriptRuntime::SaveAllocation(Stre > AllocationDetails::FileHeader head; > head.ident[0] = 'R'; head.ident[1] = 'S'; head.ident[2] = 'A'; > head.ident[3] = 'D'; > head.hdr_size = > static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader)); > - head.type = static_cast<uint16_t>(*alloc->type.get()); > - head.kind = static_cast<uint32_t>(*alloc->type_kind.get()); > + head.type = static_cast<uint16_t>(*alloc->element.type.get()); > + head.kind = static_cast<uint32_t>(*alloc->element.type_kind.get()); > head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1); > head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2); > head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3); > - head.element_size = static_cast<uint32_t>(GetElementSize(alloc)); > + head.element_size = > static_cast<uint32_t>(*alloc->element.datum_size.get()); > > // Write the file header > size_t num_bytes = sizeof(AllocationDetails::FileHeader); > @@ -2080,8 +2337,8 @@ RenderScriptRuntime::DumpAllocation(Stre > log->Printf("RenderScriptRuntime::DumpAllocation - Found > allocation 0x%" PRIx64, *alloc->address.get()); > > // Check we have information about the allocation, if not calculate it > - if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || > - !alloc->type_vec_size.isValid() || !alloc->dimension.isValid()) > + if (!alloc->data_ptr.isValid() || !alloc->element.type.isValid() || > + !alloc->element.type_vec_size.isValid() || > !alloc->dimension.isValid() || !alloc->element.datum_size.isValid()) > { > if (log) > log->Printf("RenderScriptRuntime::DumpAllocation - Allocation > details not calculated yet, jitting info"); > @@ -2096,22 +2353,19 @@ RenderScriptRuntime::DumpAllocation(Stre > } > > // Establish format and size of each data element > - const unsigned int vec_size = *alloc->type_vec_size.get(); > - const AllocationDetails::DataType type = *alloc->type.get(); > + const unsigned int vec_size = *alloc->element.type_vec_size.get(); > + const Element::DataType type = *alloc->element.type.get(); > > - assert(type >= AllocationDetails::RS_TYPE_NONE && type <= > AllocationDetails::RS_TYPE_BOOLEAN > + assert(type >= Element::RS_TYPE_NONE && type <= > Element::RS_TYPE_BOOLEAN > && "Invalid allocation > type"); > > lldb::Format format = vec_size == 1 ? > static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatSingle]) > : > static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatVector]); > > - const unsigned int data_size = vec_size * > AllocationDetails::RSTypeToFormat[type][eElementSize]; > - // Renderscript pads vector 3 elements to vector 4 > - const unsigned int elem_padding = vec_size == 3 ? > AllocationDetails::RSTypeToFormat[type][eElementSize] : 0; > + const unsigned int data_size = *alloc->element.datum_size.get(); > > if (log) > - log->Printf("RenderScriptRuntime::DumpAllocation - Element size > %u bytes, element padding %u bytes", > - data_size, elem_padding); > + log->Printf("RenderScriptRuntime::DumpAllocation - Element size > %u bytes, including padding", data_size); > > // Allocate a buffer to copy data into > std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr); > @@ -2136,10 +2390,10 @@ RenderScriptRuntime::DumpAllocation(Stre > } > } > const unsigned int stride = *alloc->stride.get(); > - const unsigned int size = *alloc->size.get(); //size of last element > - > + const unsigned int size = *alloc->size.get(); // Size of whole > allocation > + const unsigned int padding = alloc->element.padding.isValid() ? > *alloc->element.padding.get() : 0; > if (log) > - log->Printf("RenderScriptRuntime::DumpAllocation - stride %u > bytes, size %u bytes", stride, size); > + log->Printf("RenderScriptRuntime::DumpAllocation - stride %u > bytes, size %u bytes, padding %u", stride, size, padding); > > // Find dimensions used to index loops, so need to be non-zero > unsigned int dim_x = alloc->dimension.get()->dim_1; > @@ -2173,8 +2427,41 @@ RenderScriptRuntime::DumpAllocation(Stre > for (unsigned int x = 0; x < dim_x; ++x) > { > strm.Printf("\n(%u, %u, %u) = ", x, y, z); > - alloc_data.Dump(&strm, offset, format, data_size, 1, 1, > LLDB_INVALID_ADDRESS, 0, 0); > - offset += data_size + elem_padding; > + if ((type == Element::RS_TYPE_NONE) && > (alloc->element.children.size() > 0) && > + (alloc->element.type_name != > Element::FallbackStructName)) > + { > + // Here we are dumping an Element of struct type. > + // This is done using expression evaluation with the > name of the struct type and pointer to element. > + > + // Don't print the name of the resulting expression, > since this will be '$[0-9]+' > + DumpValueObjectOptions expr_options; > + expr_options.SetHideName(true); > + > + // Setup expression as derefrencing a pointer cast to > element address. > + const int max_expr_size = 512; > + char expr_char_buffer[max_expr_size]; > + int chars_written = snprintf(expr_char_buffer, > max_expr_size, "*(%s*) 0x%" PRIx64, > + > alloc->element.type_name.AsCString(), *alloc->data_ptr.get() + offset); > + > + if (chars_written < 0 || chars_written >= > max_expr_size) > + { > + if (log) > + > log->Printf("RenderScriptRuntime::DumpAllocation- Error in snprintf()"); > + continue; > + } > + > + // Evaluate expression > + ValueObjectSP expr_result; > + > GetProcess()->GetTarget().EvaluateExpression(expr_char_buffer, frame_ptr, > expr_result); > + > + // Print the results to our stream. > + expr_result->Dump(strm, expr_options); > + } > + else > + { > + alloc_data.Dump(&strm, offset, format, data_size - > padding, 1, 1, LLDB_INVALID_ADDRESS, 0, 0); > + } > + offset += data_size; > } > } > } > @@ -2234,27 +2521,29 @@ RenderScriptRuntime::ListAllocations(Str > alloc->dimension.get()->dim_3); > > strm.Indent("Data Type: "); > - if (!alloc->type.isValid() || !alloc->type_vec_size.isValid()) > + if (!alloc->element.type.isValid() || > !alloc->element.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(); > + const int vector_size = *alloc->element.type_vec_size.get(); > + const Element::DataType type = *alloc->element.type.get(); > > - if (vector_size > 4 || vector_size < 1 || > - type < AllocationDetails::RS_TYPE_NONE || type > > AllocationDetails::RS_TYPE_BOOLEAN) > + if (!alloc->element.type_name.IsEmpty()) > + strm.Printf("%s\n", alloc->element.type_name.AsCString()); > + else if (vector_size > 4 || vector_size < 1 || > + type < Element::RS_TYPE_NONE || type > > Element::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()) > + if (!alloc->element.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) > + const Element::DataKind kind = > *alloc->element.type_kind.get(); > + if (kind < Element::RS_KIND_USER || kind > > Element::RS_KIND_PIXEL_YUV) > strm.Printf("invalid kind\n"); > else > strm.Printf("%s\n", > AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]); > > 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=254294&r1=254293&r2=254294&view=diff > > ============================================================================== > --- > lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h > (original) > +++ > lldb/trunk/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h > Mon Nov 30 04:29:49 2015 > @@ -231,6 +231,7 @@ public: > protected: > struct ScriptDetails; > struct AllocationDetails; > + struct Element; > > void InitSearchFilter(lldb::TargetSP target) > { > @@ -311,8 +312,9 @@ private: > > AllocationDetails* FindAllocByID(Stream &strm, const uint32_t > alloc_id); > std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails* > allocation, StackFrame* frame_ptr); > - unsigned int GetElementSize(const AllocationDetails* allocation); > + void SetElementSize(Element& elem); > static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, const > char* var_name, uint64_t& val); > + void FindStructTypeName(Element& elem, StackFrame* frame_ptr); > > // > // Helper functions for jitting the runtime > @@ -324,9 +326,11 @@ private: > > bool JITTypePacked(AllocationDetails* allocation, StackFrame* > frame_ptr); > > - bool JITElementPacked(AllocationDetails* allocation, StackFrame* > frame_ptr); > + bool JITElementPacked(Element& elem, const lldb::addr_t context, > StackFrame* frame_ptr); > > - bool JITAllocationSize(AllocationDetails* allocation, StackFrame* > frame_ptr, const uint32_t elem_size); > + bool JITAllocationSize(AllocationDetails* allocation, StackFrame* > frame_ptr); > + > + bool JITSubelements(Element& elem, const lldb::addr_t context, > StackFrame* frame_ptr); > > bool JITAllocationStride(AllocationDetails* allocation, StackFrame* > frame_ptr); > > > > _______________________________________________ > lldb-commits mailing list > lldb-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits >
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits