This is an archive of the discontinued LLVM Phabricator instance.

[Support] Add WritableMemoryBuffer class
ClosedPublic

Authored by labath on Nov 21 2017, 3:16 AM.

Details

Summary

The motivation here is LLDB, where we need to fixup relocations in
mmapped files before their contents can be read correctly. The
MemoryBuffer class does exactly what we need, *except* that it maps the
file in read-only mode.

MutableMemoryBuffer reuses the existing machinery for opening and
mmapping a file. The only difference is in the argument to the
mapped_file_region constructor -- we create a private copy-on-write
mapping, so that we can make changes to the mapped data, but the changes
aren't carried over to the underlying file.

This patch is based on an initial version by Zachary Turner.

Diff Detail

Repository
rL LLVM

Event Timeline

labath created this revision.Nov 21 2017, 3:16 AM
labath updated this revision to Diff 123891.Nov 22 2017, 2:49 AM

Remove the RequiresNullTerminator flag

labath updated this revision to Diff 124046.Nov 23 2017, 1:45 AM

remove unbuffered=true from the test

Adding David Blaikie as a reviewer, as suggested by Rafael.

David: to see the discussion that let to you being involved, please look at the mailing list, as it is not visible on the review directly.

labath added a comment.Dec 4 2017, 9:00 AM

Hi David,

could you look at this by any chance?

thanks.

labath updated this revision to Diff 125484.Dec 5 2017, 2:10 AM

I've added a MemoryBufferRef (which is what most APIs accept) constructor that
takes a WritableMemoryBuffer. Since MemoryBufferRef (as well as MemoryBuffer)
operates with StringRefs, but WritableMemoryBuffer uses
(Mutable)ArrayRef<uint8_t> (I think was done because there is no equivalent to
MutableStringRef and having MutableArrayRef+StringRef combo would be weird),
I've also added a WritableMemoryBuffer::getBufferAsStringRef().

Let me know what you think.

FWIW, I think having a "const MemoryBuffer" mean read-only would not be so bad,
as this class isn't nearly as widespread as ArrayRef.

As there aren't any strong opinions objections to the present implementation (I haven't registered any, at least), and it solves an existing problem in lldb, could we land this soon-ish?

I am open to doing any follow-up cleanups, if we reach a consensus on a direction we want to go in.

zturner accepted this revision.Dec 14 2017, 10:02 AM

If you've addressed all the concerns thus far, I think it's reasonable to put this in with post-commit review and address any remaining concerns in followup patches.

This revision is now accepted and ready to land.Dec 14 2017, 10:02 AM
labath updated this revision to Diff 127356.Dec 18 2017, 7:08 AM

Make WritableMemoryBuffer inherit from MemoryBuffer and use template-base-class
pattern on the two implementations.

I still have a slight feeling that using templates this way is wrong, but I must
admit that the overall result looks much nicer than I expected. In particular,
the fact that WritableMemoryBuffer inherits from the plain one allows us to
remove some const_casts (a couple of them in this patch, and a few more can be
done as a follow-up).

dblaikie accepted this revision.Dec 18 2017, 7:05 PM

Good for me - addressing/removing the base class & type traits test before committing.

lib/Support/MemoryBuffer.cpp
99–100 ↗(On Diff #127356)

Could potentially qualify these (& the MB::init above) as MemoryBuffer::* since we know that's the ultimate base that has these functions?

201–203 ↗(On Diff #127356)

That seems a bit tricky - perhaps this should be a property of the MemoryBuffer class instead? (a static const member or the like?)

labath updated this revision to Diff 127490.Dec 19 2017, 4:14 AM
labath marked 2 inline comments as done.
  • Qualify members as MemoryBuffer::***
  • Add a static constexpr bool Writable member and use that to choose the mmap flags.
This revision was automatically updated to reflect the committed changes.