Skip to content

Commit ccaa772

Browse files
committed
[Support] mmap when possible in getSTDIN.
When stdin is executed like ./prog < file, we are able to mmap the buffer so that we can reduce the total memory usage if we try to open a large file.
1 parent 5401210 commit ccaa772

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

llvm/lib/Support/MemoryBuffer.cpp

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,10 +569,30 @@ ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getOpenFileSlice(
569569

570570
ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() {
571571
// Read in all of the data from stdin, we cannot mmap stdin.
572-
//
573-
// FIXME: That isn't necessarily true, we should try to mmap stdin and
574-
// fallback if it fails.
575572
sys::ChangeStdinMode(sys::fs::OF_Text);
573+
std::error_code EC;
574+
sys::fs::file_type Type;
575+
sys::fs::file_status Status;
576+
EC = sys::fs::status(sys::fs::getStdinHandle(), Status);
577+
if (EC)
578+
return EC;
579+
580+
Type = Status.type();
581+
582+
// If the FD is regular file or block file,
583+
// we try to create a mmap buffer first.
584+
// If failed, rollback to read and copy.
585+
if ((Type == sys::fs::file_type::regular_file ||
586+
Type == sys::fs::file_type::block_file) &&
587+
shouldUseMmap(sys::fs::getStdinHandle(), Status.getSize(),
588+
Status.getSize(), 0, false,
589+
sys::Process::getPageSizeEstimate(), false)) {
590+
std::unique_ptr<MemoryBuffer> Result(
591+
new (NamedBufferAlloc("<stdin>")) MemoryBufferMMapFile<MemoryBuffer>(
592+
false, sys::fs::getStdinHandle(), Status.getSize(), 0, EC));
593+
if (!EC)
594+
return std::move(Result);
595+
}
576596

577597
return getMemoryBufferForStream(sys::fs::getStdinHandle(), "<stdin>");
578598
}

0 commit comments

Comments
 (0)