[llvm] [llvm-strings] Use small buffer instead of reading whole file (PR #163073)

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 02:03:46 PDT 2026


================
@@ -88,41 +90,83 @@ static void parseIntArg(const opt::InputArgList &Args, int ID, T &Value) {
   }
 }
 
-static void strings(raw_ostream &OS, StringRef FileName, StringRef Contents) {
-  auto print = [&OS, FileName](unsigned Offset, StringRef L) {
-    if (L.size() < static_cast<size_t>(MinLength))
-      return;
+static bool isStringChar(char C) { return isPrint(C) || C == '\t'; }
+
+static void strings(raw_ostream &OS, StringRef FileName,
+                    sys::fs::file_t Handle) {
+  SmallString<sys::fs::DefaultReadChunkSize> Buffer;
+  auto printHeader = [&OS, FileName](unsigned StringStart) {
     if (PrintFileName)
       OS << FileName << ": ";
     switch (Radix) {
     case none:
       break;
     case octal:
-      OS << format("%7o ", Offset);
+      OS << format("%7o ", StringStart);
       break;
     case hexadecimal:
-      OS << format("%7x ", Offset);
+      OS << format("%7x ", StringStart);
       break;
     case decimal:
-      OS << format("%7u ", Offset);
+      OS << format("%7u ", StringStart);
       break;
     }
-    OS << L << '\n';
   };
 
-  const char *B = Contents.begin();
-  const char *P = nullptr, *E = nullptr, *S = nullptr;
-  for (P = Contents.begin(), E = Contents.end(); P < E; ++P) {
-    if (isPrint(*P) || *P == '\t') {
-      if (S == nullptr)
-        S = P;
-    } else if (S) {
-      print(S - B, StringRef(S, P - S));
-      S = nullptr;
+  // llvm-strings should be able to process a very large file on a
+  // memory-budgeted machine, so the file is read in chunks. To handle this, we
+  // read the file in chunk instead of copying the whole file into memory.
+  SmallString<DefaultMinLength> Candidate;
+  bool InString = false;
+  unsigned StringStart = 0, Offset = 0;
+
+  Buffer.resize_for_overwrite(sys::fs::DefaultReadChunkSize);
+  while (true) {
+    Expected<size_t> ReadBytesOrErr = sys::fs::readNativeFile(
+        Handle, MutableArrayRef(Buffer.data(), Buffer.size()));
+    if (!ReadBytesOrErr) {
+      errs() << FileName << ": "
+             << errorToErrorCode(ReadBytesOrErr.takeError()).message() << '\n';
+      return;
+    }
+    std::size_t CurSize = *ReadBytesOrErr;
----------------
jh7370 wrote:

I'd name this `ChunkSize` for clarity as to what size we're specifically  talking about.

https://github.com/llvm/llvm-project/pull/163073


More information about the llvm-commits mailing list