OSDN Git Service

Fix some memory leaks found by valgrind.
authorDavid Sehr <sehr@google.com>
Wed, 7 Sep 2016 20:04:01 +0000 (13:04 -0700)
committerDavid Sehr <sehr@google.com>
Wed, 7 Sep 2016 22:56:40 +0000 (15:56 -0700)
Bug: 29921113
Change-Id: If70d475a3317751d206658c5794a32d78bc33e47
Test: valgrind-test-art-host-gtest (with --trace-children=yes)

dexlayout/dex_ir.h
dexlayout/dex_ir_builder.cc
dexlayout/dexlayout.cc

index 514d6fd..cbb4404 100644 (file)
@@ -359,22 +359,25 @@ class ArrayItem : public Item {
     DISALLOW_COPY_AND_ASSIGN(NameValuePair);
   };
 
-  union PayloadUnion {
-    bool bool_val_;
-    int8_t byte_val_;
-    int16_t short_val_;
-    uint16_t char_val_;
-    int32_t int_val_;
-    int64_t long_val_;
-    float float_val_;
-    double double_val_;
-    StringId* string_val_;
-    FieldId* field_val_;
-    MethodId* method_val_;
-    std::vector<std::unique_ptr<ArrayItem>>* annotation_array_val_;
+  struct ArrayItemVariant {
+   public:
+    union {
+      bool bool_val_;
+      int8_t byte_val_;
+      int16_t short_val_;
+      uint16_t char_val_;
+      int32_t int_val_;
+      int64_t long_val_;
+      float float_val_;
+      double double_val_;
+      StringId* string_val_;
+      FieldId* field_val_;
+      MethodId* method_val_;
+    } u_;
+    std::unique_ptr<std::vector<std::unique_ptr<ArrayItem>>> annotation_array_val_;
     struct {
       StringId* string_;
-      std::vector<std::unique_ptr<NameValuePair>>* array_;
+      std::unique_ptr<std::vector<std::unique_ptr<NameValuePair>>> array_;
     } annotation_annotation_val_;
   };
 
@@ -382,34 +385,34 @@ class ArrayItem : public Item {
   ~ArrayItem() OVERRIDE { }
 
   int8_t Type() const { return type_; }
-  bool GetBoolean() const { return item_.bool_val_; }
-  int8_t GetByte() const { return item_.byte_val_; }
-  int16_t GetShort() const { return item_.short_val_; }
-  uint16_t GetChar() const { return item_.char_val_; }
-  int32_t GetInt() const { return item_.int_val_; }
-  int64_t GetLong() const { return item_.long_val_; }
-  float GetFloat() const { return item_.float_val_; }
-  double GetDouble() const { return item_.double_val_; }
-  StringId* GetStringId() const { return item_.string_val_; }
-  FieldId* GetFieldId() const { return item_.field_val_; }
-  MethodId* GetMethodId() const { return item_.method_val_; }
+  bool GetBoolean() const { return item_.u_.bool_val_; }
+  int8_t GetByte() const { return item_.u_.byte_val_; }
+  int16_t GetShort() const { return item_.u_.short_val_; }
+  uint16_t GetChar() const { return item_.u_.char_val_; }
+  int32_t GetInt() const { return item_.u_.int_val_; }
+  int64_t GetLong() const { return item_.u_.long_val_; }
+  float GetFloat() const { return item_.u_.float_val_; }
+  double GetDouble() const { return item_.u_.double_val_; }
+  StringId* GetStringId() const { return item_.u_.string_val_; }
+  FieldId* GetFieldId() const { return item_.u_.field_val_; }
+  MethodId* GetMethodId() const { return item_.u_.method_val_; }
   std::vector<std::unique_ptr<ArrayItem>>* GetAnnotationArray() const {
-    return item_.annotation_array_val_;
+    return item_.annotation_array_val_.get();
   }
   StringId* GetAnnotationAnnotationString() const {
     return item_.annotation_annotation_val_.string_;
   }
   std::vector<std::unique_ptr<NameValuePair>>* GetAnnotationAnnotationNameValuePairArray() const {
-    return item_.annotation_annotation_val_.array_;
+    return item_.annotation_annotation_val_.array_.get();
   }
   // Used to construct the item union.  Ugly, but necessary.
-  PayloadUnion* GetPayloadUnion() { return &item_; }
+  ArrayItemVariant* GetArrayItemVariant() { return &item_; }
 
   void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
 
  private:
   uint8_t type_;
-  PayloadUnion item_;
+  ArrayItemVariant item_;
   DISALLOW_COPY_AND_ASSIGN(ArrayItem);
 };
 
index 38f35e7..30f57d9 100644 (file)
@@ -39,15 +39,15 @@ static uint64_t ReadVarWidth(const uint8_t** data, uint8_t length, bool sign_ext
 }
 
 // Prototype to break cyclic dependency.
-void ReadPayloadUnion(Header& header,
-                      const uint8_t** data,
-                      uint8_t type,
-                      uint8_t length,
-                      ArrayItem::PayloadUnion* item);
+void ReadArrayItemVariant(Header& header,
+                          const uint8_t** data,
+                          uint8_t type,
+                          uint8_t length,
+                          ArrayItem::ArrayItemVariant* item);
 
 ArrayItem* ReadArrayItem(Header& header, const uint8_t** data, uint8_t type, uint8_t length) {
   ArrayItem* item = new ArrayItem(type);
-  ReadPayloadUnion(header, data, type, length, item->GetPayloadUnion());
+  ReadArrayItemVariant(header, data, type, length, item->GetArrayItemVariant());
   return item;
 }
 
@@ -55,30 +55,30 @@ ArrayItem* ReadArrayItem(Header& header, const uint8_t** data) {
   const uint8_t encoded_value = *(*data)++;
   const uint8_t type = encoded_value & 0x1f;
   ArrayItem* item = new ArrayItem(type);
-  ReadPayloadUnion(header, data, type, encoded_value >> 5, item->GetPayloadUnion());
+  ReadArrayItemVariant(header, data, type, encoded_value >> 5, item->GetArrayItemVariant());
   return item;
 }
 
-void ReadPayloadUnion(Header& header,
-                      const uint8_t** data,
-                      uint8_t type,
-                      uint8_t length,
-                      ArrayItem::PayloadUnion* item) {
+void ReadArrayItemVariant(Header& header,
+                          const uint8_t** data,
+                          uint8_t type,
+                          uint8_t length,
+                          ArrayItem::ArrayItemVariant* item) {
   switch (type) {
     case DexFile::kDexAnnotationByte:
-      item->byte_val_ = static_cast<int8_t>(ReadVarWidth(data, length, false));
+      item->u_.byte_val_ = static_cast<int8_t>(ReadVarWidth(data, length, false));
       break;
     case DexFile::kDexAnnotationShort:
-      item->short_val_ = static_cast<int16_t>(ReadVarWidth(data, length, true));
+      item->u_.short_val_ = static_cast<int16_t>(ReadVarWidth(data, length, true));
       break;
     case DexFile::kDexAnnotationChar:
-      item->char_val_ = static_cast<uint16_t>(ReadVarWidth(data, length, false));
+      item->u_.char_val_ = static_cast<uint16_t>(ReadVarWidth(data, length, false));
       break;
     case DexFile::kDexAnnotationInt:
-      item->int_val_ = static_cast<int32_t>(ReadVarWidth(data, length, true));
+      item->u_.int_val_ = static_cast<int32_t>(ReadVarWidth(data, length, true));
       break;
     case DexFile::kDexAnnotationLong:
-      item->long_val_ = static_cast<int64_t>(ReadVarWidth(data, length, true));
+      item->u_.long_val_ = static_cast<int64_t>(ReadVarWidth(data, length, true));
       break;
     case DexFile::kDexAnnotationFloat: {
       // Fill on right.
@@ -87,7 +87,7 @@ void ReadPayloadUnion(Header& header,
         uint32_t data;
       } conv;
       conv.data = static_cast<uint32_t>(ReadVarWidth(data, length, false)) << (3 - length) * 8;
-      item->float_val_ = conv.f;
+      item->u_.float_val_ = conv.f;
       break;
     }
     case DexFile::kDexAnnotationDouble: {
@@ -97,32 +97,32 @@ void ReadPayloadUnion(Header& header,
         uint64_t data;
       } conv;
       conv.data = ReadVarWidth(data, length, false) << (7 - length) * 8;
-      item->double_val_ = conv.d;
+      item->u_.double_val_ = conv.d;
       break;
     }
     case DexFile::kDexAnnotationString: {
       const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
-      item->string_val_ = header.StringIds()[string_index].get();
+      item->u_.string_val_ = header.StringIds()[string_index].get();
       break;
     }
     case DexFile::kDexAnnotationType: {
       const uint32_t string_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
-      item->string_val_ = header.TypeIds()[string_index]->GetStringId();
+      item->u_.string_val_ = header.TypeIds()[string_index]->GetStringId();
       break;
     }
     case DexFile::kDexAnnotationField:
     case DexFile::kDexAnnotationEnum: {
       const uint32_t field_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
-      item->field_val_ = header.FieldIds()[field_index].get();
+      item->u_.field_val_ = header.FieldIds()[field_index].get();
       break;
     }
     case DexFile::kDexAnnotationMethod: {
       const uint32_t method_index = static_cast<uint32_t>(ReadVarWidth(data, length, false));
-      item->method_val_ = header.MethodIds()[method_index].get();
+      item->u_.method_val_ = header.MethodIds()[method_index].get();
       break;
     }
     case DexFile::kDexAnnotationArray: {
-      item->annotation_array_val_ = new ArrayItemVector();
+      item->annotation_array_val_.reset(new ArrayItemVector());
       // Decode all elements.
       const uint32_t size = DecodeUnsignedLeb128(data);
       for (uint32_t i = 0; i < size; i++) {
@@ -134,8 +134,8 @@ void ReadPayloadUnion(Header& header,
     case DexFile::kDexAnnotationAnnotation: {
       const uint32_t type_idx = DecodeUnsignedLeb128(data);
       item->annotation_annotation_val_.string_ = header.TypeIds()[type_idx]->GetStringId();
-      item->annotation_annotation_val_.array_ =
-          new std::vector<std::unique_ptr<ArrayItem::NameValuePair>>();
+      item->annotation_annotation_val_.array_.reset(
+          new std::vector<std::unique_ptr<ArrayItem::NameValuePair>>());
       // Decode all name=value pairs.
       const uint32_t size = DecodeUnsignedLeb128(data);
       for (uint32_t i = 0; i < size; i++) {
@@ -150,7 +150,7 @@ void ReadPayloadUnion(Header& header,
     case DexFile::kDexAnnotationNull:
       break;
     case DexFile::kDexAnnotationBoolean:
-      item->bool_val_ = (length != 0);
+      item->u_.bool_val_ = (length != 0);
       break;
     default:
       break;
index 0d0b37a..3a3f417 100644 (file)
@@ -767,10 +767,10 @@ static std::unique_ptr<char[]> IndexString(dex_ir::Header* header,
       if (index < header->MethodIdsSize()) {
         dex_ir::MethodId* method_id = header->MethodIds()[index].get();
         const char* name = method_id->Name()->Data();
-        char* type_descriptor = strdup(GetSignatureForProtoId(method_id->Proto()).c_str());
+        std::string type_descriptor = GetSignatureForProtoId(method_id->Proto());
         const char* back_descriptor = method_id->Class()->GetStringId()->Data();
         outSize = snprintf(buf.get(), buf_size, "%s.%s:%s // method@%0*x",
-                           back_descriptor, name, type_descriptor, width, index);
+                           back_descriptor, name, type_descriptor.c_str(), width, index);
       } else {
         outSize = snprintf(buf.get(), buf_size, "<method?> // method@%0*x", width, index);
       }
@@ -1030,13 +1030,13 @@ static void DumpBytecodes(dex_ir::Header* header, uint32_t idx,
                           const dex_ir::CodeItem* code, uint32_t code_offset) {
   dex_ir::MethodId* method_id = header->MethodIds()[idx].get();
   const char* name = method_id->Name()->Data();
-  const char* type_descriptor = strdup(GetSignatureForProtoId(method_id->Proto()).c_str());
+  std::string type_descriptor = GetSignatureForProtoId(method_id->Proto());
   const char* back_descriptor = method_id->Class()->GetStringId()->Data();
 
   // Generate header.
   std::string dot(DescriptorToDotWrapper(back_descriptor));
   fprintf(out_file_, "%06x:                                        |[%06x] %s.%s:%s\n",
-          code_offset, code_offset, dot.c_str(), name, type_descriptor);
+          code_offset, code_offset, dot.c_str(), name, type_descriptor.c_str());
 
   // Iterate over all instructions.
   const uint16_t* insns = code->Insns();
@@ -1490,11 +1490,11 @@ static void ProcessDexFile(const char* file_name, const DexFile* dex_file) {
     fprintf(out_file_, "Opened '%s', DEX version '%.3s'\n",
             file_name, dex_file->GetHeader().magic_ + 4);
   }
-  dex_ir::Header* header = dex_ir::DexIrBuilder(*dex_file);
+  std::unique_ptr<dex_ir::Header> header(dex_ir::DexIrBuilder(*dex_file));
 
   // Headers.
   if (options_.show_file_headers_) {
-    DumpFileHeader(header);
+    DumpFileHeader(header.get());
   }
 
   // Open XML context.
@@ -1506,7 +1506,7 @@ static void ProcessDexFile(const char* file_name, const DexFile* dex_file) {
   char* package = nullptr;
   const uint32_t class_defs_size = header->ClassDefsSize();
   for (uint32_t i = 0; i < class_defs_size; i++) {
-    DumpClass(dex_file, header, i, &package);
+    DumpClass(dex_file, header.get(), i, &package);
   }  // for
 
   // Free the last package allocated.