Fix some memory leaks found by valgrind.
Bug: 29921113
Change-Id: If70d475a3317751d206658c5794a32d78bc33e47
Test: valgrind-test-art-host-gtest (with --trace-children=yes)
diff --git a/dexlayout/dex_ir.h b/dexlayout/dex_ir.h
index 514d6fd..cbb4404 100644
--- a/dexlayout/dex_ir.h
+++ b/dexlayout/dex_ir.h
@@ -359,22 +359,25 @@
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 @@
~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);
};
diff --git a/dexlayout/dex_ir_builder.cc b/dexlayout/dex_ir_builder.cc
index 38f35e7..30f57d9 100644
--- a/dexlayout/dex_ir_builder.cc
+++ b/dexlayout/dex_ir_builder.cc
@@ -39,15 +39,15 @@
}
// 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 @@
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 @@
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 @@
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 @@
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 @@
case DexFile::kDexAnnotationNull:
break;
case DexFile::kDexAnnotationBoolean:
- item->bool_val_ = (length != 0);
+ item->u_.bool_val_ = (length != 0);
break;
default:
break;
diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc
index 0d0b37a..3a3f417 100644
--- a/dexlayout/dexlayout.cc
+++ b/dexlayout/dexlayout.cc
@@ -767,10 +767,10 @@
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 @@
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 @@
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 @@
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.