From 347512ff38748ac6ebfacbfda172edb5cf1edbe2 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht Date: Fri, 21 Nov 2025 07:08:15 -0600 Subject: [libc++] Revert fstream::read optimizations (#168894) This causes various runtime failures, as reported in #168628. This reverts both #165223 and #167779 --- libcxx/docs/ReleaseNotes/22.rst | 4 +- libcxx/include/fstream | 19 ---------- libcxx/test/benchmarks/streams/fstream.bench.cpp | 43 ---------------------- libcxx/test/benchmarks/streams/ofstream.bench.cpp | 25 +++++++++++++ .../fstreams/filebuf/traits_mismatch.verify.cpp | 2 +- .../fstreams/traits_mismatch.verify.cpp | 2 +- 6 files changed, 29 insertions(+), 66 deletions(-) delete mode 100644 libcxx/test/benchmarks/streams/fstream.bench.cpp create mode 100644 libcxx/test/benchmarks/streams/ofstream.bench.cpp diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst index 7af1351e8cee..b8e0e9b5a181 100644 --- a/libcxx/docs/ReleaseNotes/22.rst +++ b/libcxx/docs/ReleaseNotes/22.rst @@ -67,8 +67,8 @@ Improvements and New Features by up to 2.5x - The performance of ``erase(iterator, iterator)`` in the unordered containers has been improved by up to 1.9x - The performance of ``map::insert_or_assign`` has been improved by up to 2x -- ``ofstream::write`` and ``ifstream::read`` have been optimized to pass through large reads and writes to system calls - directly instead of copying them in chunks. +- ``ofstream::write`` has been optimized to pass through large strings to system calls directly instead of copying them + in chunks into a buffer. - Multiple internal types have been refactored to use ``[[no_unique_address]]``, resulting in faster compile times and reduced debug information. diff --git a/libcxx/include/fstream b/libcxx/include/fstream index 90e35740c17c..1f88d134fe06 100644 --- a/libcxx/include/fstream +++ b/libcxx/include/fstream @@ -308,25 +308,6 @@ protected: return basic_streambuf<_CharT, _Traits>::xsputn(__str, __len); } - _LIBCPP_HIDE_FROM_ABI_VIRTUAL streamsize xsgetn(char_type* __str, streamsize __len) override { - if (__always_noconv_) { - const streamsize __n = std::min(this->egptr() - this->gptr(), __len); - if (__n != 0) { - traits_type::copy(__str, this->gptr(), __n); - this->__gbump_ptrdiff(__n); - } - const streamsize __remainder = __len - __n; - const streamsize __buffer_space = this->egptr() - this->eback(); - - if (__remainder >= __buffer_space) - return std::fread(__str + __n, sizeof(char_type), __remainder, __file_) + __n; - else if (__remainder > 0) - return basic_streambuf<_CharT, _Traits>::xsgetn(__str + __n, __remainder) + __n; - return __n; - } - return basic_streambuf<_CharT, _Traits>::xsgetn(__str, __len); - } - private: char* __extbuf_; const char* __extbufnext_; diff --git a/libcxx/test/benchmarks/streams/fstream.bench.cpp b/libcxx/test/benchmarks/streams/fstream.bench.cpp deleted file mode 100644 index 3ca1801ca8d0..000000000000 --- a/libcxx/test/benchmarks/streams/fstream.bench.cpp +++ /dev/null @@ -1,43 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include -#include - -#include - -static void bm_ofstream_write(benchmark::State& state) { - std::vector buffer; - buffer.resize(16384); - - std::ofstream stream("/dev/null"); - - for (auto _ : state) - stream.write(buffer.data(), buffer.size()); -} -BENCHMARK(bm_ofstream_write); - -static void bm_ifstream_read(benchmark::State& state) { - std::vector buffer; - buffer.resize(16384); - - std::ofstream gen_testfile("testfile"); - gen_testfile.write(buffer.data(), buffer.size()); - - std::ifstream stream("testfile"); - assert(stream); - - for (auto _ : state) { - stream.read(buffer.data(), buffer.size()); - benchmark::DoNotOptimize(buffer); - stream.seekg(0); - } -} -BENCHMARK(bm_ifstream_read); - -BENCHMARK_MAIN(); diff --git a/libcxx/test/benchmarks/streams/ofstream.bench.cpp b/libcxx/test/benchmarks/streams/ofstream.bench.cpp new file mode 100644 index 000000000000..60606a9d67e2 --- /dev/null +++ b/libcxx/test/benchmarks/streams/ofstream.bench.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include +#include + +#include + +static void bm_write(benchmark::State& state) { + std::vector buffer; + buffer.resize(16384); + + std::ofstream stream("/dev/null"); + + for (auto _ : state) + stream.write(buffer.data(), buffer.size()); +} +BENCHMARK(bm_write); + +BENCHMARK_MAIN(); diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp index 30e7b66d4232..283adbc057d1 100644 --- a/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp +++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/filebuf/traits_mismatch.verify.cpp @@ -19,4 +19,4 @@ std::basic_filebuf > f; // expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}} -// expected-error@*:* 11 {{only virtual member functions can be marked 'override'}} +// expected-error@*:* 10 {{only virtual member functions can be marked 'override'}} diff --git a/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp b/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp index daafb36f9151..ba6f3c31d3e3 100644 --- a/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp +++ b/libcxx/test/libcxx/input.output/file.streams/fstreams/traits_mismatch.verify.cpp @@ -21,7 +21,7 @@ std::basic_fstream > f; // expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}} // expected-error-re@*:* {{static assertion failed{{.*}}traits_type::char_type must be the same type as CharT}} -// expected-error@*:* 13 {{only virtual member functions can be marked 'override'}} +// expected-error@*:* 12 {{only virtual member functions can be marked 'override'}} // FIXME: As of commit r324062 Clang incorrectly generates a diagnostic about mismatching // exception specifications for types which are already invalid for one reason or another. -- cgit v1.2.3