glibc:fw/vfprintf-2

Last commit made on 2022-12-12
Get this branch:
git clone -b fw/vfprintf-2 https://git.launchpad.net/glibc

Branch merges

Branch information

Name:
fw/vfprintf-2
Repository:
lp:glibc

Recent commits

b30518e... by Florian Weimer

libio: Convert __vswprintf_internal to buffers (bug 27857)

Always null-terminate the buffer and set E2BIG if the buffer is too
small. This fixes bug 27857.

45234c5... by Florian Weimer

libio: Convert __obstack_vprintf_internal to buffers (bug 27124)

This fixes bug 27124 because the problematic built-in vtable is gone.

2deb7d2... by Florian Weimer

libio: Convert __vdprintf_internal to buffers

The internal buffer size is set to 2048 bytes. This is less than
the original BUFSIZ value used by buffered_vfprintf before
the conversion, but it hopefully covers all cases where write
boundaries matter.

214908c... by Florian Weimer

libio: Convert __vasprintf_internal to buffers

The buffer resizing algorithm is slightly different. The initial
buffer is on the stack, and small buffers are directly allocated
on the heap using the exact required size. The overhead of the
additional copy is compensated by the lowered setup cost for buffers
compared to libio streams.

b5edce5... by Florian Weimer

libio: Convert __vsprintf_internal to buffers

a407f05... by Florian Weimer

stdio-common: Add lock optimization to vfprintf and vfwprintf

After the rewrite and the implicit unbuffered streams handling, this
is very straightforward to add.

2706c12... by Florian Weimer

stdio-common: Convert vfprintf and related functions to buffers

vfprintf is entangled with vfwprintf (of course), __printf_fp,
__printf_fphex, __vstrfmon_l_internal, and the strfrom family of
functions. The latter use the internal snprintf functionality,
so vsnprintf is converted as well.

The simples conversion is __printf_fphex, followed by
__vstrfmon_l_internal and __printf_fp, and finally
__vfprintf_internal and __vfwprintf_internal. __vsnprintf_internal
and strfrom* are mostly consuming the new interfaces, so they
are comparatively simple.

__printf_fp is a public symbol, so the FILE *-based interface
had to preserved.

The __printf_fp rewrite does not change the actual binary-to-decimal
conversion algorithm, and digits are still not emitted directly to
the target buffer. However, the staging buffer now uses bytes
instead of wide characters, and one buffer copy is eliminated.

The changes are at least performance-neutral in my testing.
Floating point printing and snprintf improved measurably, so that
this Lua script

  for i=1,5000000 do
      print(i, i * math.pi)
  end

runs about 5% faster for me. To preserve fprintf performance for
a simple "%d" format, this commit has some logic changes under
LABEL (unsigned_number) to avoid additional function calls. There
are certainly some very easy performance improvements here: binary,
octal and hexadecimal formatting can easily avoid the temporary work
buffer (the number of digits can be computed ahead-of-time using one
of the __builtin_clz* built-ins). Decimal formatting can use a
specialized version of _itoa_word for base 10.

The existing (inconsistent) width handling between strfmon and printf
is preserved here. __print_fp_buffer_1 would have to use
__translated_number_width to achieve ISO conformance for printf.

Test expectations in libio/tst-vtables-common.c are adjusted because
the internal staging buffer merges all virtual function calls into
one.

In general, stack buffer usage is greatly reduced, particularly for
unbuffered input streams. __printf_fp can still use a large buffer
in binary128 mode for %g, though.

8566149... by Florian Weimer

stdio-common: Add __translated_number_width

This function will be used to compute the width of a number
after i18n digit translation.

8699991... by Florian Weimer

stdio-common: Add __printf_function_invoke

And __wprintf_function_invoke. These functions will be used to
to call registered printf specifier callbacks on printf buffers
after vfprintf and vfwprintf have been converted to buffers. The new
implementation avoids alloca/variable length arrays.

9e6084a... by Florian Weimer

stdio-common: Introduce buffers for implementing printf

These buffers will eventually be used instead of FILE * objects
to implement printf functions. The multibyte buffer is struct
__printf_buffer, the wide buffer is struct __wprintf_buffer.

To enable writing type-generic code, the header files
printf_buffer-char.h and printf_buffer-wchar_t.h define the
Xprintf macro differently, enabling Xprintf (buffer) to stand
for __printf_buffer and __wprintf_buffer as appropriate. For
common cases, macros like Xprintf_buffer are provided as a more
syntactically convenient shortcut.

Buffer-specific flush callbacks are implemented with a switch
statement instead of a function pointer, to avoid hardening issues
similar to those of libio vtables. struct __printf_buffer_as_file
is needed to support custom printf specifiers because the public
interface for that requires passing a FILE *, which is why there
is a trapdoor back from these buffers to FILE * streams.

Since the immediate user of these interfaces knows when processing
has finished, there is no flush callback for the end of processing,
only a flush callback for the intermediate buffer flush.