diff options
author | Andreas Gampe <agampe@google.com> | 2014-12-04 21:25:04 -0800 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-12-05 11:34:21 -0800 |
commit | 245ee0030e8e2aebf2231a65a3c475ed43fd4987 (patch) | |
tree | e3dc0d99669cd050185ea2da914612ad1017dc36 | |
parent | ab74d3eae37de79444edd1edd70400970d5e85ad (diff) | |
download | art-245ee0030e8e2aebf2231a65a3c475ed43fd4987.tar.gz art-245ee0030e8e2aebf2231a65a3c475ed43fd4987.tar.bz2 art-245ee0030e8e2aebf2231a65a3c475ed43fd4987.zip |
ART: Fix string data leak in image writer
The string intern data is a large object, so it will be recognized
as leaking under valgrind.
Bug: 18628623
Change-Id: I9090db119a50eebd806a82369bd46527c4e7dbf0
-rw-r--r-- | compiler/image_writer.cc | 10 | ||||
-rw-r--r-- | compiler/image_writer.h | 16 |
2 files changed, 25 insertions, 1 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index a45c2d1ba..eb1b5db95 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -548,6 +548,7 @@ void ImageWriter::ProcessStrings() { } // Create character array, copy characters and point the strings there. mirror::CharArray* array = mirror::CharArray::Alloc(self, num_chars); + string_data_array_ = array; uint16_t* array_data = array->GetData(); size_t pos = 0u; prev_s = nullptr; @@ -1234,4 +1235,13 @@ uint32_t ImageWriter::BinSlot::GetIndex() const { return lockword_ & ~kBinMask; } +void ImageWriter::FreeStringDataArray() { + if (string_data_array_ != nullptr) { + gc::space::LargeObjectSpace* los = Runtime::Current()->GetHeap()->GetLargeObjectsSpace(); + if (los != nullptr) { + los->Free(Thread::Current(), reinterpret_cast<mirror::Object*>(string_data_array_)); + } + } +} + } // namespace art diff --git a/compiler/image_writer.h b/compiler/image_writer.h index 8c84b686f..4418879e7 100644 --- a/compiler/image_writer.h +++ b/compiler/image_writer.h @@ -18,6 +18,7 @@ #define ART_COMPILER_IMAGE_WRITER_H_ #include <stdint.h> +#include <valgrind.h> #include <cstddef> #include <memory> @@ -56,7 +57,15 @@ class ImageWriter FINAL { CHECK_NE(image_begin, 0U); } - ~ImageWriter() {} + ~ImageWriter() { + // For interned strings a large array is allocated to hold all the character data and avoid + // overhead. However, no GC is run anymore at this point. As the array is likely large, it + // will be allocated in the large object space, where valgrind can track every single + // allocation. Not explicitly freeing that array will be recognized as a leak. + if (RUNNING_ON_VALGRIND != 0) { + FreeStringDataArray(); + } + } bool PrepareImageAddressSpace(); @@ -254,6 +263,9 @@ class ImageWriter FINAL { // Calculate the sum total of the bin slot sizes in [0, up_to). Defaults to all bins. size_t GetBinSizeSum(Bin up_to = kBinSize) const; + // Release the string_data_array_. + void FreeStringDataArray(); + const CompilerDriver& compiler_driver_; // Beginning target image address for the output image. @@ -306,6 +318,8 @@ class ImageWriter FINAL { size_t bin_slot_sizes_[kBinSize]; // Number of bytes in a bin size_t bin_slot_count_[kBinSize]; // Number of objects in a bin + void* string_data_array_; // The backing for the interned strings. + friend class FixupVisitor; friend class FixupClassVisitor; DISALLOW_COPY_AND_ASSIGN(ImageWriter); |