Home | History | Annotate | Download | only in profiler
      1 /*
      2  * Copyright 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "ProfilerCodeGenBase.h"
     18 #include "utils/InterfaceSpecUtil.h"
     19 #include "utils/StringUtil.h"
     20 #include "VtsCompilerUtils.h"
     21 
     22 namespace android {
     23 namespace vts {
     24 
     25 void ProfilerCodeGenBase::GenerateAll(
     26     Formatter& header_out, Formatter& source_out,
     27     const ComponentSpecificationMessage& message) {
     28   GenerateHeaderFile(header_out, message);
     29   GenerateSourceFile(source_out, message);
     30 }
     31 
     32 void ProfilerCodeGenBase::GenerateHeaderFile(
     33     Formatter& out, const ComponentSpecificationMessage& message) {
     34   FQName component_fq_name = GetFQName(message);
     35   out << "#ifndef __VTS_PROFILER_" << component_fq_name.tokenName()
     36       << "__\n";
     37   out << "#define __VTS_PROFILER_" << component_fq_name.tokenName()
     38       << "__\n";
     39   out << "\n\n";
     40   GenerateHeaderIncludeFiles(out, message);
     41   GenerateUsingDeclaration(out, message);
     42   GenerateOpenNameSpaces(out, message);
     43 
     44   if (message.has_interface()) {
     45     InterfaceSpecificationMessage interface = message.interface();
     46     // First generate the declaration of profiler functions for all user
     47     // defined types within the interface.
     48     for (const auto attribute : interface.attribute()) {
     49       GenerateProfilerMethodDeclForAttribute(out, attribute);
     50     }
     51 
     52     out << "extern \"C\" {\n";
     53     out.indent();
     54 
     55     // Generate the declaration of main profiler function.
     56     FQName component_fq_name = GetFQName(message);
     57     out << "\nvoid HIDL_INSTRUMENTATION_FUNCTION_" << component_fq_name.tokenName()
     58         << "(\n";
     59     out.indent();
     60     out.indent();
     61     out << "details::HidlInstrumentor::InstrumentationEvent event,\n";
     62     out << "const char* package,\n";
     63     out << "const char* version,\n";
     64     out << "const char* interface,\n";
     65     out << "const char* method,\n";
     66     out << "std::vector<void *> *args);\n";
     67     out.unindent();
     68     out.unindent();
     69 
     70     out.unindent();
     71     out << "}\n\n";
     72   } else {
     73     // For types.vts, just generate the declaration of profiler functions
     74     // for all user defined types.
     75     for (const auto attribute : message.attribute()) {
     76       GenerateProfilerMethodDeclForAttribute(out, attribute);
     77     }
     78   }
     79 
     80   GenerateCloseNameSpaces(out, message);
     81   out << "#endif\n";
     82 }
     83 
     84 void ProfilerCodeGenBase::GenerateSourceFile(
     85     Formatter& out, const ComponentSpecificationMessage& message) {
     86   GenerateSourceIncludeFiles(out, message);
     87   GenerateUsingDeclaration(out, message);
     88   GenerateMacros(out, message);
     89   GenerateOpenNameSpaces(out, message);
     90 
     91   if (message.has_interface()) {
     92     InterfaceSpecificationMessage interface = message.interface();
     93     // First generate profiler functions for all user defined types within
     94     // the interface.
     95     for (const auto attribute : interface.attribute()) {
     96       GenerateProfilerMethodImplForAttribute(out, attribute);
     97     }
     98     // Generate the main profiler function.
     99     FQName component_fq_name = GetFQName(message);
    100     out << "\nvoid HIDL_INSTRUMENTATION_FUNCTION_" << component_fq_name.tokenName()
    101         << "(\n";
    102     out.indent();
    103     out.indent();
    104     out << "details::HidlInstrumentor::InstrumentationEvent event "
    105            "__attribute__((__unused__)),\n";
    106     out << "const char* package,\n";
    107     out << "const char* version,\n";
    108     out << "const char* interface,\n";
    109     out << "const char* method __attribute__((__unused__)),\n";
    110     out << "std::vector<void *> *args __attribute__((__unused__))) {\n";
    111     out.unindent();
    112 
    113     // Generate code for sanity check.
    114     GenerateProfilerSanityCheck(out, message);
    115 
    116     if (interface.api_size() > 0) {
    117       // Generate code to define local variables.
    118       GenerateLocalVariableDefinition(out, message);
    119 
    120       // Generate the profiler code for each method.
    121       for (const FunctionSpecificationMessage api : interface.api()) {
    122         out << "if (strcmp(method, \"" << api.name() << "\") == 0) {\n";
    123         out.indent();
    124         GenerateProfilerForMethod(out, api);
    125         out.unindent();
    126         out << "}\n";
    127       }
    128     }
    129 
    130     out.unindent();
    131     out << "}\n\n";
    132   } else {
    133     // For types.vts, just generate profiler functions for the user defined
    134     // types.
    135     for (const auto attribute : message.attribute()) {
    136       GenerateProfilerMethodImplForAttribute(out, attribute);
    137     }
    138   }
    139 
    140   GenerateCloseNameSpaces(out, message);
    141 }
    142 
    143 void ProfilerCodeGenBase::GenerateProfilerForTypedVariable(Formatter& out,
    144   const VariableSpecificationMessage& val, const std::string& arg_name,
    145   const std::string& arg_value) {
    146   switch (val.type()) {
    147     case TYPE_SCALAR:
    148     {
    149       GenerateProfilerForScalarVariable(out, val, arg_name, arg_value);
    150       break;
    151     }
    152     case TYPE_STRING:
    153     {
    154       GenerateProfilerForStringVariable(out, val, arg_name, arg_value);
    155       break;
    156     }
    157     case TYPE_ENUM:
    158     {
    159       GenerateProfilerForEnumVariable(out, val, arg_name, arg_value);
    160       break;
    161     }
    162     case TYPE_VECTOR:
    163     {
    164       GenerateProfilerForVectorVariable(out, val, arg_name, arg_value);
    165       break;
    166     }
    167     case TYPE_ARRAY:
    168     {
    169       GenerateProfilerForArrayVariable(out, val, arg_name, arg_value);
    170       break;
    171     }
    172     case TYPE_STRUCT:
    173     {
    174       GenerateProfilerForStructVariable(out, val, arg_name, arg_value);
    175       break;
    176     }
    177     case TYPE_UNION: {
    178        GenerateProfilerForUnionVariable(out, val, arg_name, arg_value);
    179        break;
    180     }
    181     case TYPE_HIDL_CALLBACK:
    182     {
    183       GenerateProfilerForHidlCallbackVariable(out, val, arg_name, arg_value);
    184       break;
    185     }
    186     case TYPE_HIDL_INTERFACE:
    187     {
    188       GenerateProfilerForHidlInterfaceVariable(out, val, arg_name, arg_value);
    189       break;
    190     }
    191     case TYPE_MASK:
    192     {
    193       GenerateProfilerForMaskVariable(out, val, arg_name, arg_value);
    194       break;
    195     }
    196     case TYPE_HANDLE: {
    197       GenerateProfilerForHandleVariable(out, val, arg_name, arg_value);
    198       break;
    199     }
    200     case TYPE_HIDL_MEMORY:
    201     {
    202       GenerateProfilerForHidlMemoryVariable(out, val, arg_name, arg_value);
    203       break;
    204     }
    205     case TYPE_POINTER:
    206     {
    207       GenerateProfilerForPointerVariable(out, val, arg_name, arg_value);
    208       break;
    209     }
    210     case TYPE_FMQ_SYNC:
    211     {
    212       GenerateProfilerForFMQSyncVariable(out, val, arg_name, arg_value);
    213       break;
    214     }
    215     case TYPE_FMQ_UNSYNC:
    216     {
    217       GenerateProfilerForFMQUnsyncVariable(out, val, arg_name, arg_value);
    218       break;
    219     }
    220     default:
    221     {
    222       cout << "not supported.\n";
    223     }
    224   }
    225 }
    226 
    227 void ProfilerCodeGenBase::GenerateProfilerMethodDeclForAttribute(Formatter& out,
    228   const VariableSpecificationMessage& attribute) {
    229   if (attribute.type() == TYPE_STRUCT || attribute.type() == TYPE_UNION) {
    230     // Recursively generate profiler method declaration for all sub_types.
    231     for (const auto sub_struct : attribute.sub_struct()) {
    232       GenerateProfilerMethodDeclForAttribute(out, sub_struct);
    233     }
    234     for (const auto sub_union : attribute.sub_union()) {
    235       GenerateProfilerMethodDeclForAttribute(out, sub_union);
    236     }
    237   }
    238   std::string attribute_name = attribute.name();
    239   ReplaceSubString(attribute_name, "::", "__");
    240   out << "void profile__" << attribute_name
    241       << "(VariableSpecificationMessage* arg_name,\n" << attribute.name()
    242       << " arg_val_name);\n";
    243 }
    244 
    245 void ProfilerCodeGenBase::GenerateProfilerMethodImplForAttribute(
    246     Formatter& out, const VariableSpecificationMessage& attribute) {
    247   if (attribute.type() == TYPE_STRUCT || attribute.type() == TYPE_UNION) {
    248     // Recursively generate profiler method implementation for all sub_types.
    249     for (const auto sub_struct : attribute.sub_struct()) {
    250       GenerateProfilerMethodImplForAttribute(out, sub_struct);
    251     }
    252     for (const auto sub_union : attribute.sub_union()) {
    253       GenerateProfilerMethodImplForAttribute(out, sub_union);
    254     }
    255   }
    256   std::string attribute_name = attribute.name();
    257   ReplaceSubString(attribute_name, "::", "__");
    258   out << "void profile__" << attribute_name
    259       << "(VariableSpecificationMessage* arg_name,\n"
    260       << attribute.name() << " arg_val_name __attribute__((__unused__))) {\n";
    261   out.indent();
    262   GenerateProfilerForTypedVariable(out, attribute, "arg_name", "arg_val_name");
    263   out.unindent();
    264   out << "}\n\n";
    265 }
    266 
    267 void ProfilerCodeGenBase::GenerateOpenNameSpaces(Formatter& out,
    268     const ComponentSpecificationMessage& /*message*/) {
    269   out << "namespace android {\n";
    270   out << "namespace vts {\n";
    271 }
    272 
    273 void ProfilerCodeGenBase::GenerateCloseNameSpaces(Formatter& out,
    274     const ComponentSpecificationMessage& /*message*/) {
    275   out << "}  // namespace vts\n";
    276   out << "}  // namespace android\n";
    277 }
    278 
    279 }  // namespace vts
    280 }  // namespace android
    281