This is an archive of the discontinued LLVM Phabricator instance.

MemoryBlock: Do not automatically extend a given size to a multiple of page size.
ClosedPublic

Authored by ruiu on Jan 18 2019, 2:33 PM.

Details

Summary

Previously, MemoryBlock automatically extends a requested buffer size to a
multiple of page size because (I believe) doing it was thought to be harmless
and with that you could get more memory (on average 2KiB on 4KiB-page systems)
"for free".

That programming interface turned out to be error-prone. If you request N
bytes, you usually expect that a resulting object returns N for size().
That's not the case for MemoryBlock.

Looks like there is only one place where we take the advantage of
allocating more memory than the requested size. So, with this patch, I
simply removed the automatic size expansion feature from MemoryBlock
and do it on the caller side when needed. MemoryBlock now always
returns a buffer whose size is equal to the requested size.

Diff Detail

Repository
rL LLVM

Event Timeline

ruiu created this revision.Jan 18 2019, 2:33 PM
ruiu updated this revision to Diff 182638.Jan 18 2019, 4:31 PM
  • rebase

It's a bit weird that allocateMappedMemory() returns a buffer whose size is larger than what's requested, but the method is explicitly documented as such: http://llvm-cs.pcc.me.uk/include/llvm/Support/Memory.h#64

I looked around a bit through callers and several others seem to get this wrong too, at least from a quick look (e.g. http://llvm-cs.pcc.me.uk/include/llvm/Support/BinaryByteStream.h#205 , used by MSFBuilder::commit() (http://llvm-cs.pcc.me.uk/lib/DebugInfo/MSF/MSFBuilder.cpp#347) -- unless that's supposed to write the extra data.

Did you look through callers and determined that the api as-is is the best compromise, or should we change the Memory::allocateMappedMemory() to set the requested size instead of the actual one?

(Having said that, I don't know this code well and I'm probably not the best person to review it.)

ruiu added a comment.Jan 22 2019, 10:09 AM

Good point. I found that that's very confusing too. Maybe size() should return the requested size instead of the actual allocated size, and if there's a need to get an allocated size, we can provide it as a different member function such as allocatedSize() or something. Let me take a look.

ruiu updated this revision to Diff 182973.Jan 22 2019, 1:33 PM
  • Change allocateMemoryBlock instead of FileOutputBuffer
ruiu retitled this revision from Fix a bug that file size is sometimes silently rounded up to the page size. to MemoryBlock: Do not automatically extend a given size to a multiple of page size..Jan 22 2019, 1:39 PM
ruiu edited the summary of this revision. (Show Details)
thakis accepted this revision.Jan 22 2019, 4:38 PM

This looks fine to me, but as I said I'm not an expert. On the other hand, if someone depended on the old tricky semantics and didn't write a test, it's on them if they get broken :-)

This revision is now accepted and ready to land.Jan 22 2019, 4:38 PM
This revision was automatically updated to reflect the committed changes.
lhames added a subscriber: lhames.May 7 2019, 12:58 PM

Bah -- I missed this at the time. This should be reverted. We can rename methods to clarify, but MemoryBlock should hold the allocated size, not the requested size.

Herald added a project: Restricted Project. · View Herald TranscriptMay 7 2019, 12:58 PM
Herald added a subscriber: MaskRay. · View Herald Transcript
ruiu added a comment.May 7 2019, 6:56 PM

https://reviews.llvm.org/D61599 doesn't seem to revert this, but instead adding a method to obtain an allocated size as well as a requested size (and rename size() to allocatedSize()). That's fine by me.

https://reviews.llvm.org/D61599 doesn't seem to revert this, but instead adding a method to obtain an allocated size as well as a requested size (and rename size() to allocatedSize()). That's fine by me.

D61599 has now been updated as was discussed there. It now does revert this patch. size() was renamed to allocatedSize() and the InMemoryBuffer in FileOutputBuffer.cpp now tracks the requested size separately.