Skip to content

Commit 1f6d7c1

Browse files
Merge branch 'main' into base64-decode-ignore-pad-char
2 parents 92067d2 + 92c0ec2 commit 1f6d7c1

File tree

20 files changed

+240
-33
lines changed

20 files changed

+240
-33
lines changed

Android/testbed/app/build.gradle.kts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ android {
9292
}
9393
throw GradleException("Failed to find API level in $androidEnvFile")
9494
}
95-
targetSdk = 35
95+
96+
// This controls the API level of the maxVersion managed emulator, which is used
97+
// by CI and cibuildwheel. 34 takes up too much disk space (#142289), 35 has
98+
// issues connecting to the internet (#142387), and 36 and later are not
99+
// available as aosp_atd images yet.
100+
targetSdk = 33
96101

97102
versionCode = 1
98103
versionName = "1.0"

Doc/c-api/memory.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,11 @@ The pymalloc allocator
677677
Python has a *pymalloc* allocator optimized for small objects (smaller or equal
678678
to 512 bytes) with a short lifetime. It uses memory mappings called "arenas"
679679
with a fixed size of either 256 KiB on 32-bit platforms or 1 MiB on 64-bit
680-
platforms. It falls back to :c:func:`PyMem_RawMalloc` and
680+
platforms. When Python is configured with :option:`--with-pymalloc-hugepages`,
681+
the arena size on 64-bit platforms is increased to 2 MiB to match the huge page
682+
size, and arena allocation will attempt to use huge pages (``MAP_HUGETLB`` on
683+
Linux, ``MEM_LARGE_PAGES`` on Windows) with automatic fallback to regular pages.
684+
It falls back to :c:func:`PyMem_RawMalloc` and
681685
:c:func:`PyMem_RawRealloc` for allocations larger than 512 bytes.
682686
683687
*pymalloc* is the :ref:`default allocator <default-memory-allocators>` of the

Doc/using/configure.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,21 @@ also be used to improve performance.
783783

784784
See also :envvar:`PYTHONMALLOC` environment variable.
785785

786+
.. option:: --with-pymalloc-hugepages
787+
788+
Enable huge page support for :ref:`pymalloc <pymalloc>` arenas (disabled by
789+
default). When enabled, the arena size on 64-bit platforms is increased to
790+
2 MiB and arena allocation uses ``MAP_HUGETLB`` (Linux) or
791+
``MEM_LARGE_PAGES`` (Windows) with automatic fallback to regular pages.
792+
793+
The configure script checks that the platform supports ``MAP_HUGETLB``
794+
and emits a warning if it is not available.
795+
796+
On Windows, use the ``--pymalloc-hugepages`` flag with ``build.bat`` or
797+
set the ``UsePymallocHugepages`` MSBuild property.
798+
799+
.. versionadded:: 3.15
800+
786801
.. option:: --without-doc-strings
787802

788803
Disable static documentation strings to reduce the memory footprint (enabled

Doc/whatsnew/3.15.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,12 @@ Build changes
14771477
modules that are missing or packaged separately.
14781478
(Contributed by Stan Ulbrych and Petr Viktorin in :gh:`139707`.)
14791479

1480+
* The new configure option :option:`--with-pymalloc-hugepages` enables huge
1481+
page support for :ref:`pymalloc <pymalloc>` arenas. When enabled, arena size
1482+
increases to 2 MiB and allocation uses ``MAP_HUGETLB`` (Linux) or
1483+
``MEM_LARGE_PAGES`` (Windows) with automatic fallback to regular pages.
1484+
On Windows, use ``build.bat --pymalloc-hugepages``.
1485+
14801486
* Annotating anonymous mmap usage is now supported if Linux kernel supports
14811487
:manpage:`PR_SET_VMA_ANON_NAME <PR_SET_VMA(2const)>` (Linux 5.17 or newer).
14821488
Annotations are visible in ``/proc/<pid>/maps`` if the kernel supports the feature

Include/internal/pycore_obmalloc.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,11 @@ typedef unsigned int pymem_uint; /* assuming >= 16 bits */
208208
* mappings to reduce heap fragmentation.
209209
*/
210210
#ifdef USE_LARGE_ARENAS
211-
#define ARENA_BITS 20 /* 1 MiB */
211+
# ifdef PYMALLOC_USE_HUGEPAGES
212+
# define ARENA_BITS 21 /* 2 MiB */
213+
# else
214+
# define ARENA_BITS 20 /* 1 MiB */
215+
# endif
212216
#else
213217
#define ARENA_BITS 18 /* 256 KiB */
214218
#endif
@@ -469,7 +473,7 @@ nfp free pools in usable_arenas.
469473
*/
470474

471475
/* How many arena_objects do we initially allocate?
472-
* 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the
476+
* 16 = can allocate 16 arenas = 16 * ARENA_SIZE before growing the
473477
* `arenas` vector.
474478
*/
475479
#define INITIAL_ARENA_OBJECTS 16
@@ -512,14 +516,26 @@ struct _obmalloc_mgmt {
512516
513517
memory address bit allocation for keys
514518
515-
64-bit pointers, IGNORE_BITS=0 and 2^20 arena size:
519+
ARENA_BITS is configurable: 20 (1 MiB) by default on 64-bit, or
520+
21 (2 MiB) when PYMALLOC_USE_HUGEPAGES is enabled. All bit widths
521+
below are derived from ARENA_BITS automatically.
522+
523+
64-bit pointers, IGNORE_BITS=0 and 2^20 arena size (default):
516524
15 -> MAP_TOP_BITS
517525
15 -> MAP_MID_BITS
518526
14 -> MAP_BOT_BITS
519527
20 -> ideal aligned arena
520528
----
521529
64
522530
531+
64-bit pointers, IGNORE_BITS=0 and 2^21 arena size (hugepages):
532+
15 -> MAP_TOP_BITS
533+
15 -> MAP_MID_BITS
534+
13 -> MAP_BOT_BITS
535+
21 -> ideal aligned arena
536+
----
537+
64
538+
523539
64-bit pointers, IGNORE_BITS=16, and 2^20 arena size:
524540
16 -> IGNORE_BITS
525541
10 -> MAP_TOP_BITS

Lib/test/test_binascii.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,17 @@ def assertNonBase64Data(data, expected, ignorechars):
214214
assertNonBase64Data(b'a\nb==', b'i', ignorechars=bytearray(b'\n'))
215215
assertNonBase64Data(b'a\nb==', b'i', ignorechars=memoryview(b'\n'))
216216

217+
# Same cell in the cache: '\r' >> 3 == '\n' >> 3.
218+
data = self.type2test(b'\r\n')
219+
with self.assertRaises(binascii.Error):
220+
binascii.a2b_base64(data, ignorechars=b'\r')
221+
self.assertEqual(binascii.a2b_base64(data, ignorechars=b'\r\n'), b'')
222+
# Same bit mask in the cache: '*' & 31 == '\n' & 31.
223+
data = self.type2test(b'*\n')
224+
with self.assertRaises(binascii.Error):
225+
binascii.a2b_base64(data, ignorechars=b'*')
226+
self.assertEqual(binascii.a2b_base64(data, ignorechars=b'*\n'), b'')
227+
217228
data = self.type2test(b'a\nb==')
218229
with self.assertRaises(TypeError):
219230
binascii.a2b_base64(data, ignorechars='')
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Build Python with POSIX 2024, instead of POSIX 2008. Patch by Victor Stinner.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add huge pages support for the pymalloc allocator. Patch by Pablo Galindo
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Speed up Base64 decoding of data containing ignored characters (both in
2+
non-strict mode and with an explicit *ignorechars* argument).
3+
It is now up to 2 times faster for multiline Base64 data.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve error messages for buffer overflow in :func:`fcntl.fcntl` and
2+
:func:`fcntl.ioctl`.

0 commit comments

Comments
 (0)